Hello Everyone,
In this blog, we'll be learning how to set up an AWS Site-to-Site VPN.
When connecting on-premises network to AWS, there are two main options: IPSec VPN and AWS Direct Connect.
IPSec VPN: This option sets up a secure VPN connection between your AWS VPC and on-premises network, with traffic encrypted and transmitted over the internet. It's a popular choice for small to medium-sized companies due to its ease of setup. Once established, both networks can communicate seamlessly over private IP addresses.
AWS Direct Connect: This is a dedicated, point-to-point physical connection between your on-premises network and an AWS data center. It offers a more stable and faster connection but requires more setup and is generally used by larger enterprises.
In this blog, we will be setting up an AWS VPN connection.
Overview
On the AWS side, we have a VPC and a Virtual Private Gateway (VGW), which function as the AWS-side endpoint for the VPN connection. On the on-premises side, we need a router, known as the Customer Gateway (CGW), which must be accessible over the internet and have a public IP address.
We can set up the AWS-side network in our chosen AWS region. Since we don't have access to an actual on-premises network, we'll simulate the corporate network.
We'll create another VPC in a different region and use an EC2 instance with Openswan software as our router. In a real-world scenario, well-known routers are typically used for VPN connections, but to minimize costs, we'll use this setup.
Openswan is an open-source implementation of IPsec (Internet Protocol Security) for Linux. It enables secure communication between systems over an untrusted network, like the internet, by creating encrypted tunnels. It’s commonly used for setting up VPNs to protect data in transit.
On the left side, we have the AWS network, and on the right side, the simulated corporate network. The EC2 instance on the AWS side does not need internet access, so we will create a private subnet in the VPC with an EC2 instance that has only a private IP address.
On the right side, we'll have a VPC with a public subnet because we need to launch an EC2 instance there and configure Openswan on it. To set up Openswan, we need to connect to this instance over the internet, which is why it must be placed in a public subnet.
The AWS-side instance can only be reached from the on-premises EC2 instance once the VPN connection is established.
Task 1: Set Up AWS Infrastructure
Let's create VPC.
Search for VPC in the search box.
For the AWS side, I'm choosing Mumbai region.
Provide a name & CIDR range for your VPC.
Keeping all other configurations as is, click on Create VPC
.
Now, it's time to create a private subnet.
Select your VPC.
Provide the name and eligible CIDR value for your subnet, then click on Create subnet
.
Let's create route table now.
Provide name for your route table, select your VPC and click on Create route table
.
In the public subnet's route table, we need a route for the internet, and we add the corresponding entry. However, in this case, we don't need that but we need to associate this route table with the subnet we created.
Click on your route table and in the Subnet associations tab, click on Edit subnet associations
.
Select your subnet and click Save associations
.
Alright, now it's time to create an EC2.
Go to the EC2 console.
Click on Launch instances
.
Make sure to select the Amazon Linux 2 AMI, as the latest version (Amazon Linux 2023) does not support Openswan, which we are going to implement.
Create key pair for your instance.
Edit Network settings. Choose your VPC and subnet.
Keep Auto-assign public IP as default.
When configuring the security group (SG), refer to the network diagram and ask yourself, 'From where will this EC2 instance receive traffic?'
Since the traffic will only come from the on-premises network 11.0.0.0.0/16
, we should allow all traffic from that network.
Allow all TCP traffic on every port from the on-premise network's CIDR range.
To enable ping from the on-premises EC2 to the AWS-side EC2, ensure that the ping protocol (ICMP) is also enabled.
Keeping all other configurations as is, click on Launch instance
.
Task 2: Setup On-premise Infrastructures
Let's start by creating a VPC. This time, I am choosing a different region.
Provide a name for your VPC and provide CIDR range.
Note that your VPC's CIDR range must not overlap with each other.
Click on Create VPC
.
Since I need a public subnet, it's required to attach an Internet Gateway to the VPC.
Provide name for your Internet Gateway and click on Create Internet gateway
.
After creating your internet gateway, attach it to your VPC.
Now, let's create our public subnet.
Select your VPC.
Provide a suitable name, provide an eligible CIDR range and then click on Create subnet
.
It's time to create route table.
Provide a name for your route table, select your VPC and click on Create route table
.
In the public subnet's route table, we need a route to the internet, so let's add the corresponding entry.
Click on Save changes
.
Now, let's associate this route table to our subnet.
Click on Edit subnet associations
.
Click on Save associations
.
Now that we have set up the VPC, subnet, and IGW, it's time to create an instance which will act as our Customer Gateway.
Let's select the same AMI to ensure consistency.
Create key pair for your instance.
Edit Network Settings. Choose your VPC and select your public subnet. Make sure to Enable Auto-assign public IP.
In the security group, since we'll be logging into this EC2 instance from our machine, we need to set up an SSH connection, allowing traffic from our IP address. Additionally, we'll allow all TCP traffic from the other side of the network and enable the ping protocol.
With all other configurations unchanged, click on Launch Instance
.
Task 3: Set up VPN Connection
We've set up two VPCs, but they currently have no communication between them. The next step is to create and configure a Virtual Private Gateway (VGW) for the VPN. To do this, we need the public IP address of our EC2 instance acting as a router, as this is required to specify the location of the customer router while creating the VPN connection.
Copy the public IP address and switch to the AWS network side.
Go to the VPC dashboard.
Scroll down to the Virtual private network.
Click on Create virutal private gateway
.
Provide a name and click on Create virtual private gateway
.
Attach to your VPC.
Now, it's time to create Customer Gateway.
Click on Create customer gateway
.
The Customer Gateway (CGW) represents the on-premises side of the network and is not part of the AWS network. It is where we will configure the IP address associated with the on-premises network.
After configuring the details, click on Create customer gateway
.
Now that we have both the VPGW and CGW, we can use them to create a site-to-site VPN connection.
On Site-to-Site VPN connections, click on Create VPN connection
.
When setting up a VPN connection, we can use either static routing or dynamic routing to manage the paths data takes between networks.
Static Routing
Routes are manually configured by specifying the exact paths for traffic.
It's simple to implement and is typically used for small or straightforward networks.
Requires manual updates if network topology changes.
Dynamic Routing
Routes are automatically determined and adjusted by routing protocols like BGP (Border Gateway Protocol).
It's more complex but ideal for large or changing networks.
Automatically adapts to network changes, providing better scalability and resilience.
Static IP Prefixes: It allows the Virtual Private Gateway (VGW) to recognize which IP prefixes belong to the on-premises network, ensuring that traffic destined for those addresses is correctly routed.
For the local IPv4, provide your on-premises CIDR value. For the remote IPv4, provide the AWS-side network CIDR.
For the Tunnel options, we can either keep the default settings or configure specific options, such as the pre-shared key. AWS VPN creates two tunnels for high availability, and the connection uses the secure IPsec protocol. This process involves sharing a key between the two endpoints. We can set up our own pre-shared key, or if we choose not to, AWS will generate one for us.
We'll let AWS handle the configuration, click Create VPN Connection
.
While this is pending, let's set up our Openswan server on the on-premises instance.
Select your EC2 and click on Connect
.
We're establishing an SSH connection to our instance.
Switch to the root user to ensure you have full permissions to install Openswan.
#switching to root user
sudo su
#installing openswan
yum install openswan -y
Now, let's configure Openswan.
In the ipsec.conf
file, ensure there is an uncommented line at the end, allowing us to add additional files to this directory.
The next step is to update the /etc/sysctl.conf
file. This is necessary because this machine will act as a router, forwarding the traffic it receives to another machine within the same on-premises network. We need to configure specific settings by adding a couple of lines to this file.
vim /etc/sysctl.conf
Press i
to enter into insert mode.
# Enable IP forwarding for routing
net.ipv4.ip_forward = 1
# Disable acceptance of ICMP redirects
net.ipv4.conf.all.accept_redirects = 0
# Disable sending of ICMP redirects
net.ipv4.conf.all.send_redirects = 0
After making the changes, press Esc
to exit insert mode, then type :wq!
to save and exit the file.
Now, we need to restart the network service.
service network restart
Next, we need to configure our IPsec VPN. So far, we've only installed the software but haven't configured it yet. We'll need to specify details such as the AWS side of the network, the pre-shared key, and other settings.
To obtain these settings, we can download a text file from AWS that contains all the necessary configuration details, which we can then use to configure the IPsec VPN.
Select your VPN connection and click Download configuration
.
If you open the file in a text editor, you'll find that it covers most of the configurations we've already completed. More importantly, it contains tunnel details.
Now, we need to create the file /etc/ipsec.d/aws.conf
in our instance.
vim /etc/ipsec.d/aws.conf
Simply copy the entire block of tunnel details from the downloaded file and paste it into the /etc/ipsec.d/aws.conf
file.
The default settings may cause issues with the VPN connection, particularly the line auth=esp
, which is not supported. Be sure to delete this line from the file and then save your changes.
Similarly, we need to create the file /etc/ipsec.secrets
. This file should contain the pre-shared key, as we mentioned earlier. Create the file and add the pre-shared key entry to it.
vim /etc/ipsec.d/aws.secrets
In the downloaded configuration file, look for your pre-shared key. Copy & paste it into the created file.
That's it. The /etc/ipsec.conf
file will contain information for two tunnels because AWS provides two tunnels for high availability. While OpenSwan supports multiple VPN tunnels on a single host, careful configuration is essential to prevent conflicts. For this initial setup, we'll establish a single VPN tunnel to ensure a stable foundation.
The leftid
field represents the IP address of the customer-side network, which in this case comes from the EC2 instance running OpenSwan. The rightid
field represents the IP address at the other end of the connection, which is the AWS side.
vim /etc/ipsec.d/aws.conf
Next, we need to configure the leftsubnet
and rightsubnet
values in the file. The leftsubnet
represents the CIDR block of the corporate network side, while the rightsubnet
represents the CIDR block of the AWS side. Update these values in your configuration file to reflect the correct CIDR blocks for each side of the network.
Next, we will configure the route table for the private subnet by adding a route that directs traffic destined for the on-premises CIDR block to the VGW.
For this, go to the AWS side route table. Instead of manually adding a route to the VGW, we will use route propagation. This allows the VGW to automatically update the route table with the CIDR blocks from the AWS side.
Click on Edit route propagation
.
Enable route propagation and save the changes. Once the VPN tunnel is active, the route table will update automatically.
Ok so, we have completed the configuration of the IPsec configuration files and the secrets file. Now, it's time to start the VPN tunnel.
Go back to your terminal and run the command to initiate the VPN tunnel.
systemctl start ipsec
Check the status of the IPsec service to confirm it's running.
systemctl status ipsec
To verify that the tunnel is functioning properly, it's important to remember that the VPN connection is always initiated from the customer side, not from AWS. If there is no traffic flowing from the customer side, the VPN tunnel may go down. To keep the tunnel active, ensure that you are sending keepalive packets or some form of traffic to maintain the connection.
Now, let's return to the AWS Management Console and check the VPN connection status. Navigate to the Site-to-Site VPN connections section. You should see that the tunnel status is up, indicating that the VPN connection has been successfully established.
With the tunnel status showing as 'Up', the final test is to verify connectivity between the machines. From our current machine, let's attempt to ping the private IP address of the EC2 instance in the AWS network.
Copy the private IP of the EC2 instance and use the ping
command to test connectivity.
If you see traffic flowing and responses coming through, it confirms that the VPN tunnel between the AWS network and the OpenSwan router has been successfully established.
Task 4: Set up Extended infrastructure
Alright, now, let's proceed to set up our extended infrastructure.
Switch over to your on-premise region.
Let's create a private subnet.
Provide a name for your subnet, CIDR value then click on Create subnet
.
After creating our private subnet, let's proceed to create route table.
Provide name for your route table, select your VPC and click on Create route table
.
For now, we won't add any routes to this table. We'll specify the routes later. Just ensure that you associate this route table with the private subnet you created.
Now, let's create an EC2 instance.
Create a new Key pair or use existing one for your instance.
Edit Network settings. Select your VPC and choose your subnet.
Leave the Auto-assign public IP
as default.
The only way to reach this server is through the Openswan server. We will log in to the Openswan server via SSH, and from there, we will access the server in the AWS network.
Also, configure the ping protocol to allow ICMP traffic.
Keeping all other configurations as default, click on Launch instance
.
In the diagram, the OpenSwan server is configured as a router and must forward traffic that is not destined for itself. When we configure an instance to act as a router, like the OpenSwan server, we need to disable the source/destination check.
Disabling source/destination check allows the instance to forward traffic that is not necessarily intended for itself, enabling it to route traffic between other instances.
Since this EC2 is acting as a router, it needs to handle all traffic flowing between instances. Therefore, it must accept traffic from the IP addresses of other instances.
To configure this, we need to update the security group associated with the Openswan server.
Click your instance and head to the Security tab & click on your Security group.
Edit the inbound rules of the security group for the router instance.
Currently, there are rules for traffic from the AWS side of the network.
We need to add TCP and ICMP inbound rules to allow connections from our on-premise network and enable ping functionality for network diagnostics.
Click on Save rules
.
Let's verify the connectivity by attempting to ping the target instance.
Ok, so we are able to ping our private instance.
Next, we need to SSH into our private EC2 instance.
On the router instance (Openswan), create a file named as your private EC2 key that you downloaded earlier. e.g., your-key.pem
.
Locate your key file in your device and open it using text editor.
Copy the content and paste it into the created pem file in your terminal.
Save and exit.
Run the command to ensure your key is not publicly viewable.
We have logged in to our private instance via SSH.
Now we've completed the configuration, but we still need to set up a route for the subnet. We need to specify that traffic from the private subnet should be routed through the EC2 instance acting as a NAT.
To do this, go to the route table for the private subnet.
Edit the routes and add a new route indicating that traffic destined for 10.0.0.0/16
should be routed through the NAT instance.
Save the updated routes.
Now, finally we have made the connection. Let's ping the AWS-side EC2 instance from on-premise EC2 instance.
We can see the traffic has started flowing as expected.
Conclusion
We established a VPN connection between our on-premises network and AWS. Our on-premises environment includes a VPC with public and private subnets. An EC2 instance running OpenSwan is located in the public subnet, acting as the Customer Gateway (CGW). The AWS environment consists of a VPC with a private subnet and a private EC2 instance. We successfully configured the VPN tunnel and verified connectivity by pinging the AWS EC2 instance from the on-premises private network.
The successful ping test confirms that the VPN tunnel is operational and traffic can be routed between the on-premises and AWS networks.
Task 5: Clean Up
Let's clean up from on-premise side network.
Terminating instances.
Deleting VPC.
Deleting a VPC will remove all associated resources.
Now, let's clean up resources from our AWS side.
Terminating instance.
Go to VPC dashboard.
Deleting VPN connection.
Select & delete your Customer gateway.
Detach your Virtual private gateway from your VPC.
Select your Virtual private gateway & click
Delete Virtual private gateway
.Now, delete your VPN connection.
Deleting VPC.
Select your VPC and click
Delete VPC
.
Now, we have cleaned up all the resources we used.
Alright, I hope that was fruitful blog.
See you in the next one!