Enable private resources to communicate outside the VPC
This section describes how to create and work with NAT instances to enable resources in a private subnet to communicate outside the virtual private cloud.
Tasks
1. Create a VPC for the NAT instance
Use the following procedure to create a VPC with a public subnet and a private subnet.
To create the VPC
-
Open the Amazon VPC console at https://console.aws.amazon.com/vpc/
. -
Choose Create VPC.
-
For Resources to create, choose VPC and more.
-
For Name tag auto-generation, enter a name for the VPC.
-
To configure the subnets, do the following:
-
For Number of Availability Zones, choose 1 or 2, depending on your needs.
-
For Number of public subnets, ensure that you have one public subnet per Availability Zone.
-
For Number of private subnets, ensure that you have one private subnet per Availability Zone.
-
-
Choose Create VPC.
2. Create a security group for the NAT instance
Create a security group with the rules described in the following table. These rules enable your NAT instance to receive internet-bound traffic from instances in the private subnet, as well as SSH traffic from your network. The NAT instance can also send traffic to the internet, which enables the instances in the private subnet to get software updates.
The following are the inbound recommended rules.
Source | Protocol | Port range | Comments |
---|---|---|---|
Private subnet CIDR |
TCP | 80 | Allow inbound HTTP traffic from servers in the private subnet |
Private subnet CIDR |
TCP | 443 | Allow inbound HTTPS traffic from servers in the private subnet |
Public IP address range of your network |
TCP | 22 | Allow inbound SSH access to the NAT instance from your network (over the internet gateway) |
The following are the recommended outbound rules.
Destination | Protocol | Port range | Comments |
---|---|---|---|
0.0.0.0/0 | TCP | 80 | Allow outbound HTTP access to the internet |
0.0.0.0/0 | TCP | 443 | Allow outbound HTTPS access to the internet |
To create the security group
-
Open the Amazon VPC console at https://console.aws.amazon.com/vpc/
. -
In the navigation pane, choose Security groups.
-
Choose Create security group.
-
Enter a name and description for the security group.
-
For VPC, select the ID of the VPC for your NAT instance.
-
Add rules for inbound traffic under Inbound rules as follows:
-
Choose Add rule. Choose HTTP for Type and enter the IP address range of your private subnet for Source.
-
Choose Add rule. Choose HTTPS for Type and enter the IP address range of your private subnet for Source.
-
Choose Add rule. Choose SSH for Type and enter the IP address range of your network for Source.
-
-
Add rules for outbound traffic under Outbound rules as follows:
-
Choose Add rule. Choose HTTP for Type and enter 0.0.0.0/0 for Destination.
-
Choose Add rule. Choose HTTPS for Type and enter 0.0.0.0/0 for Destination.
-
-
Choose Create security group.
For more information, see Security groups.
3. Create a NAT AMI
A NAT AMI is configured to run NAT on an EC2 instance. You must create a NAT AMI and then launch your NAT instance using your NAT AMI.
If you plan to use an operating system other than Amazon Linux for your NAT AMI, refer to the documentation for this operating system to learn how to configure NAT. Be sure to save these settings so that they persist even after an instance reboot.
To create a NAT AMI for Amazon Linux
-
Launch an EC2 instance running AL2023 or Amazon Linux 2. Be sure to specify the security group that you created for the NAT instance.
-
Connect to your instance and run the following commands on the instance to enable iptables.
sudo yum install iptables-services -y sudo systemctl enable iptables sudo systemctl start iptables
-
Do the following on the instance to enable IP forwarding such that it persists after reboot:
Using a text editor, such as nano or vim, create the following configuration file:
/etc/sysctl.d/custom-ip-forwarding.conf
.-
Add the following line to the configuration file.
net.ipv4.ip_forward=1
Save the configuration file and exit the text editor.
-
Run the following command to apply the configuration file.
sudo sysctl -p /etc/sysctl.d/custom-ip-forwarding.conf
-
Run the following command on the instance, and note the name of the primary network interface. You'll need this information for the next step.
netstat -i
In the following example output,
docker0
is a network interface created by docker,eth0
is the primary network interface, andlo
is the loopback interface.Iface MTU RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg docker0 1500 0 0 0 0 0 0 0 0 BMU eth0 9001 7276052 0 0 0 5364991 0 0 0 BMRU lo 65536 538857 0 0 0 538857 0 0 0 LRU
In the following example output, the primary network interface is
enX0
.Iface MTU RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg enX0 9001 1076 0 0 0 1247 0 0 0 BMRU lo 65536 24 0 0 0 24 0 0 0 LRU
In the following example output, the primary network interface is
ens5
.Iface MTU RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg ens5 9001 14036 0 0 0 2116 0 0 0 BMRU lo 65536 12 0 0 0 12 0 0 0 LRU
-
Run the following commands on the instance to configure NAT. If the primary network interface is not
eth0
, replaceeth0
with the primary network interface that you noted in the previous step.sudo /sbin/iptables -t nat -A POSTROUTING -o
eth0
-j MASQUERADE sudo /sbin/iptables -F FORWARD sudo service iptables save -
Create a NAT AMI from the EC2 instance. For more information, see Create a Linux AMI from an instance in the Amazon EC2 User Guide.
4. Launch a NAT instance
Use the following procedure to launch a NAT instance using the VPC, security group, and NAT AMI that you created.
To launch a NAT instance
Open the Amazon EC2 console at https://console.aws.amazon.com/ec2/
. -
On the dashboard, choose Launch instance.
-
For Name, enter a name for your NAT instance.
-
For Application and OS Images, select your NAT AMI (choose Browse more AMIs, My AMIs).
-
For Instance type, choose an instance type that provides the compute, memory, and storage resources that your NAT instance needs.
-
For Key pair, select an existing key pair or choose Create new key pair.
-
For Network settings, do the following:
-
Choose Edit.
-
For VPC, choose the VPC that you created.
-
For Subnet, choose the public subnet that you created.
-
For Auto-assign public IP, choose Enable. Alternatively, after you launch the NAT instance, allocate an Elastic IP address and assign it to the NAT instance.
-
For Firewall, choose Select existing security group and then choose the security group that you created.
-
-
Choose Launch instance. Choose the instance ID to open the instance details page. Wait for the instance state to change to Running and for the status checks to succeed.
-
Disable source/destination checks for the NAT instance (see 5. Disable source/destination checks).
-
Update the route table to send traffic to the NAT instance (see 6. Update the route table).
5. Disable source/destination checks
Each EC2 instance performs source/destination checks by default. This means that the instance must be the source or destination of any traffic it sends or receives. However, a NAT instance must be able to send and receive traffic when the source or destination is not itself. Therefore, you must disable source/destination checks on the NAT instance.
To disable source/destination checking
-
Open the Amazon EC2 console at https://console.aws.amazon.com/ec2/
. -
In the navigation pane, choose Instances.
-
Select the NAT instance.
-
Choose Actions, Networking, Change source/destination check.
-
For Source/destination checking, select Stop.
-
Choose Save.
-
If the NAT instance has a secondary network interface, choose it from Network interfaces on the Networking tab. Choose the interface ID to go to the network interfaces page. Choose Actions, Change source/dest. check, clear Enable, and choose Save.
6. Update the route table
The route table for the private subnet must have a route that sends internet traffic to the NAT instance.
To update the route table
-
Open the Amazon VPC console at https://console.aws.amazon.com/vpc/
. -
In the navigation pane, choose Route tables.
-
Select the route table for the private subnet.
-
On the Routes tab, choose Edit routes and then choose Add route.
-
Enter 0.0.0.0/0 for Destination and the instance ID of the NAT instance for Target.
-
Choose Save changes.
For more information, see Configure route tables.
7. Test your NAT instance
After you have launched a NAT instance and completed the configuration steps above, you can test whether an instance in your private subnet can access the internet through the NAT instance by using the NAT instance as a bastion server.
Tasks
Step 1: Update the NAT instance security group
To allow instances in your private subnet to send ping traffic to the NAT instance, add a rule to allow inbound and outbound ICMP traffic. To allow the NAT instance to serve as a bastion server, add a rule to allow outbound SSH traffic to the private subnet.
To update your NAT instance security group
Open the Amazon VPC console at https://console.aws.amazon.com/vpc/
. In the navigation pane, choose Security groups.
Select the check box for the security group associated with your NAT instance.
On the Inbound rules tab, choose Edit inbound rules.
Choose Add rule. Choose All ICMP - IPv4 for Type. Choose Custom for Source and enter the IP address range of your private subnet. Choose Save rules.
-
On the Outbound rules tab, choose Edit outbound rules.
-
Choose Add rule. Choose SSH for Type. Choose Custom for Destination and enter the IP address range of your private subnet.
-
Choose Add rule. Choose All ICMP - IPv4 for Type. Choose Anywhere - IPv4 for Destination. Choose Save rules.
Step 2: Launch a test instance in the private subnet
Launch an instance into your private subnet. You must allow SSH access from the NAT instance, and you must use the same key pair that you used for the NAT instance.
To launch a test instance in the private subnet
Open the Amazon EC2 console at https://console.aws.amazon.com/ec2/
. -
On the dashboard, choose Launch instance.
-
Select your private subnet.
-
Do not assign a public IP address to this instance.
-
Ensure that the security group for this instance allows inbound SSH access from your NAT instance, or from the IP address range of your public subnet, and outbound ICMP traffic.
-
Select the same key pair that you used for the NAT instance.
Step 3: Ping an ICMP-enabled website
To verify that the test instance in your private subnet can use your NAT instance to communicate with the internet, run the ping command.
To test the internet connection from your private instance
-
From your local computer, configure SSH agent forwarding, so that you can use the NAT instance as a bastion server.
-
From your local computer, connect to your NAT instance.
-
From the NAT instance, run the ping command, specifying a website that is enabled for ICMP.
[ec2-user@ip-10-0-4-184]$
pingietf.org
To confirm that your NAT instance has internet access, verify that you received output such as the following, and then press Ctrl+C to cancel the ping command. Otherwise, verify that the NAT instance is in a public subnet (its route table has a route to an internet gateway).
PING ietf.org (104.16.45.99) 56(84) bytes of data. 64 bytes from 104.16.45.99 (104.16.45.99): icmp_seq=1 ttl=33 time=7.88 ms 64 bytes from 104.16.45.99 (104.16.45.99): icmp_seq=2 ttl=33 time=8.09 ms 64 bytes from 104.16.45.99 (104.16.45.99): icmp_seq=3 ttl=33 time=7.97 ms ...
-
From your NAT instance, connect to your instance in your private subnet by using its private IP address.
[ec2-user@ip-10-0-4-184]$
ssh ec2-user@private-server-private-ip-address
-
From your private instance, test that you can connect to the internet by running the ping command.
[ec2-user@ip-10-0-135-25]$
pingietf.org
To confirm that your private instance has internet access through the NAT instance verify that you received output such as the following, and then press Ctrl+C to cancel the ping command.
PING ietf.org (104.16.45.99) 56(84) bytes of data. 64 bytes from 104.16.45.99 (104.16.45.99): icmp_seq=1 ttl=33 time=8.76 ms 64 bytes from 104.16.45.99 (104.16.45.99): icmp_seq=2 ttl=33 time=8.26 ms 64 bytes from 104.16.45.99 (104.16.45.99): icmp_seq=3 ttl=33 time=8.27 ms ...
Troubleshooting
If the ping command fails from the server in the private subnet, use the following steps to troubleshoot the issue:
-
Verify that you pinged a website that has ICMP enabled. Otherwise, your server can't receive reply packets. To test this, run the same ping command from a command line terminal on your own computer.
-
Verify that the security group for your NAT instance allows inbound ICMP traffic from your private subnet. Otherwise, your NAT instance can't receive the ping command from your private instance.
-
Verify that you disabled source/destination checking for your NAT instance. For more information, see 5. Disable source/destination checks.
-
Verify that you configured your route tables correctly. For more information, see 6. Update the route table.
Step 4: Clean up
If you no longer require the test server in the private subnet, terminate the instance so that you are no longer billed for it. For more information, see Terminate your instance in the Amazon EC2 User Guide.
If you no longer require the NAT instance, you can stop or terminate it, so that you are no longer billed for it. If you created a NAT AMI, you can create a new NAT instance whenever you need one.