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.
*filter
:INPUT ACCEPT [129:12186]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [84:10472]
-A INPUT -i lo -j ACCEPT
-A INPUT -i eth0 -p tcp -m state --state NEW -m tcp --dport 1300 -j ACCEPT
-A INPUT -d 10.10.10.10/32 -p tcp -m limit --limit 5/min -j LOG --log-prefix "SSH Dropped: "
-A FORWARD -d 10.10.10.10/32 -p tcp -m tcp --dport 1300 -j ACCEPT
-A OUTPUT -o lo -j ACCEPT
COMMIT
# Completed on Wed Apr 17 04:19:29 2013
# Generated by iptables-save v1.4.12 on Wed Apr 17 04:19:29 2013
*nat
:PREROUTING ACCEPT [2:104]
:INPUT ACCEPT [2:104]
:OUTPUT ACCEPT [6:681]
:POSTROUTING ACCEPT [7:745]
-A PREROUTING -i eth0 -p tcp -m tcp --dport 1300 -j DNAT --to-destination 10.10.10.10:1300
-A POSTROUTING -p tcp -m tcp --dport 1300 -j MASQUERADE
COMMIT
So when I try this from home. It just times out. No connection refused messages or anything. And I can't seem to find any log messages about dropped packets.
My security groups and ACL settings allow communications on these ports in both directions in both subnets and on the NAT. I'm at a loss. What am I doing wrong?
Best Answer
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:
Step 2: Modify IP Tables (Bastion Host)
SSH to the bastion host and at the prompt, execute the following commands:
where:
For more detailed information on what these configurations mean, you can run the following commands at the command prompt to view the man pages:
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:
Edit the security group assigned to your private server and add:
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):Save the
iptables
configuration (to/etc/sysconfig/iptables
) so it will be reloaded on boot:And finally, make sure that
iptables
itself starts up on boot: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.