Ok, so I've been racking my brain for DAYS on this dilema. I have a VPC setup with a public subnet, and a private subnet. The NAT is in place of course. I can connect from SSH into a instance in the public subnet, as well as the NAT. I can even ssh connect to the private instance from the public instance. I changed the SSHD configuration on the private instance to accept both port 22 and an arbitrary port number 1300. That works fine.

But I need to set it up so that I can connect to the private instance directly using the 1300 port number, ie.

ssh -i keyfile.pem user@1.2.3.4 -p 1300

and 1.2.3.4 should route it to the internal server 10.10.10.10.

Now I heard iptables is the job for this, so I went ahead and researched and played around with some routing with that. These are the rules I have setup on the public instance (not the NAT). I didn't want to use the NAT for this since AWS apperantly pre-configures the NAT instances when you set them up and I heard using iptables can mess that up.

2 Answers
2

For posterity, this is a 5 step process. Bastion host refers to the public facing server, which you'll want to harden against potential attacks and through which your connections will travel to servers within your private subnet.

Step 1: Enable IP Forwarding (Bastion Host)

SSH to the bastion host and at the prompt, execute the following command:

echo 1 > /proc/sys/net/ipv4/ip_forward

Step 2: Modify IP Tables (Bastion Host)

SSH to the bastion host and at the prompt, execute the following commands:

{PUBLIC_SSH_PORT} is the port on the bastion host you plan to connect through

{PRIVATE_IP_ADDRESS} is the address of the server in the private subnet you plan to connect to

For more detailed information on what these configurations mean, you can run the following commands at the command prompt to view the man pages:

man iptables
man iptables-extensions

Step 3: Configure Security Groups (Amazon AWS Console)

Login to your Amazon AWS console and navigate to the Security Groups dashboard. Edit the security group assigned to your bastion host and add:

Custom TCP Rule to allow inbound and outbound connections on {PUBLIC_SSH_PORT} from whatever IP address you will be connecting from

Custom TCP Rule to allow inbound and outbound connections for All Traffic to/from the security group of the private server (type in the security group ID in the Custom IP field) - you could restrict this to just SSH traffic but if you have other services and servers running that you need to access, this is the simplest configuration

Edit the security group assigned to your private server and add:

Custom TCP Rule to allow inbound and outbound connections for All Traffic to/from the security group of the bastion host (type in the security group ID in the Custom IP field) - you could restrict this to just SSH traffic but if you have other services and servers running that you need to access, this is the simplest configuration

Step 4: Disable Source/Destination check (Amazon AWS Console)

Login to your Amazon AWS console and navigate to the Instances dashboard. Click on the bastion host that you just configured to forward connections. Disable source/destination checks from the action menu. This is the only device for which source/destination checks need to be disabled.

Step 5: Make Configurations Persistent (Across Server Restarts)

Modify the /etc/sysctl.conf file, and update the following line (change 0 to 1):

# Controls IP packet forwarding
net.ipv4.ip_forward = 1

Save the iptables configuration (to /etc/sysconfig/iptables) so it will be reloaded on boot:

sudo service iptables save

And finally, make sure that iptables itself starts up on boot:

sudo chkconfig iptables on

NOTE: You don't need to setup and configure a separate Amazon NAT instance to gain SSH access to private servers. The NAT instance is ideal if you plan to manage Internet access for various devices you may have within your private subnet.

By default AWS will check the source and destination of network traffic, so an instance must be the final destination of any traffic it sends or receives. To route traffic from one instance to another you will need to disable this check:

Actually this question has been answered, and these two steps you mention where actually part of the solution. As well as a bit more involved step of saving the iptables configuration and having it restore on reboot using rc.local.
–
CP510Aug 12 '13 at 0:18