AWS VPC + IPtables + NAT: Port Forwarding is not working

15,288

Solution 1

Finally, I Cracked it !!!!

On the NAT instance, I had to change below command:

From:

iptables -t nat -A POSTROUTING -o eth0 -s 10.0.0.0/16 -j MASQUERADE

To:

iptables -t nat -A POSTROUTING -j MASQUERADE

And it WORKED!!!!

So, I will be creating a new question soon on ServerFault asking what are the advantages and disadvantages in using above two commands.

Solution 2

  • Make sure that you are allowing tcp port 2222 inboud from 0.0.0.0/0 on the security group for your nat box
  • Make sure you have your VPC "Route Table" setup properly.
  • At least two separate tables (one associated with the private subnet, one associated with the public subnet)
  • Your 10.0.1.0 (private) subnet should have a route table rule like: Destination: 0.0.0.0/0, Target: "Nat box"
  • Your 10.0.0.0 (public) subnet should have a route table rule like: Destination: 0.0.0.0/0, Target: "Internet gateway"
  • Make sure you have Source/destination checking disabled on the NIC for your NAT box, no NATting fun without it. (I know you already have this but its really important, so including it for some future viewer)

  • Make sure outbound packets know where to go:

    iptables --table nat --append POSTROUTING --source 10.0.0.0/16 --destination 0.0.0.0/0 --jump MASQUERADE

  • Make sure inboud packets to 2222 get rerouted properly:

    iptables --table nat --append PREROUTING --protocol tcp --dport 2222 --jump DNAT --to-destination 10.0.1.243:22

Solution 3

This posts helped me a lot in understanding AWS NAT. So I started to investigate what made iptables -t nat -A POSTROUTING -j MASQUERADE it worked.

Well the answer I found the above statement is allowing the NAT box to source NAT the 'LAPTOP' IP to '10.0.0.54' while same time performing destination NAT to 10.0.1.243. At this time the private subnet box is ssh request coming from NAT device only. This command is actually decreasing the security of the private subnet server. It is recommended to use the below command to fine tune the private subnet access through ssh and NAT box as mentioned below;

iptables --table nat --append POSTROUTING --source "INTERNET IP of the Laptop" --destination 10.0.1.243 --jump MASQUERADE
Share:
15,288

Related videos on Youtube

slayedbylucifer
Author by

slayedbylucifer

A Linux/Virtualization Sys-admin working on cloud computing. I do the system administration stuff as well as Datacenter Automation which essentially involves scripting. Been working on shell scripting for long which eventually got me interested in perl scripting. Recently I picked up python and still learning it.

Updated on September 18, 2022

Comments

  • slayedbylucifer
    slayedbylucifer over 1 year

    Yesterday, I posted a question here but I think was not clear enough in my words. BTW, This question is not a duplicate.

    I have AWS VPC Setup as below.

    enter image description here

    GOAL/PROBLEM: SSH to Server A from internet. And It is not working.

    Server A is in private subnet and hence I want to enable iptables NATing on the my NAT instance so that I can ssh to SErver A directly from internet

    I am following this and this

    I ran below command on NAT instance:

    NAT# iptables -t nat -A PREROUTING  -p tcp --dport 2222 -j DNAT --to-destination 10.0.1.243:22
    

    IP forwarding is enableed on NAT instance:

    NAT# sysctl  -p
    net.ipv4.ip_forward = 1
    

    MASQUERADE is running on NAT instance:

    NAT# iptables -t nat -vnL POSTROUTING
    Chain POSTROUTING (policy ACCEPT 6 packets, 312 bytes)
     pkts bytes target     prot opt in     out     source               destination
      199 16466 MASQUERADE  all  --  *      eth0    10.0.0.0/16          0.0.0.0/0
    

    AWS Security groups are configured fine to allow various access needed for this test case.

    Troubleshooting:

    I can telnet from NAT to Server A on port 22. So Access is good.

    When I run telnet 54.213.116.251 2222 on my laptop, I see below entry in tcpdump on NAT:

    NAT# tcpdump -n -i eth0 dst 10.0.1.243 and port 22
    09:59:13.738316 IP xxx.xxx.xxx.xxx.51709 > 10.0.1.243.ssh: Flags [S], seq 1868541786, win 8192, options [mss 1460,nop,wscale 2,nop,nop,sackOK], length 0
    09:59:16.737009 IP xxx.xxx.xxx.xxx.51709 > 10.0.1.243.ssh: Flags [S], seq 1868541786, win 8192, options [mss 1460,nop,wscale 2,nop,nop,sackOK], length 0
    09:59:22.775567 IP xxx.xxx.xxx.xxx.51709 > 10.0.1.243.ssh: Flags [S], seq 1868541786, win 8192, options [mss 1460,nop,nop,sackOK], length 0
    

    So it means the iptables is routing the packets to 10.0.1.243. (BTW, xxx.xxx.xxx.xxx is public ip address of my laptop)

    But When I run tcpdump on Server A, I do not see anything coming from 10.0.0.54 which is the Internal/Private IP address of NAT (And I think this is the problem):

    Server A# tcpdump  -n src 10.0.0.54
    tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
    listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes 
    

    But if I telnet from NAT instance to Server A, I see good stuff in tcpdump on Server A(This means, My overall PREROUTING Rule is not working as expected):

    Server A# tcpdump  -n src 10.0.0.54
    05:01:47.500080 IP 10.0.0.54.44627 > 10.0.1.243.ssh: Flags [S], seq 2862522431, win 14600, options [mss 1460,sackOK,TS val 3013083 ecr 0,nop,wscale 7], length 0
    05:01:47.501601 IP 10.0.0.54.44627 > 10.0.1.243.ssh: Flags [.], ack 760676524, win 115, options [nop,nop,TS val 3013083 ecr 12074896], length 0
    05:01:47.535720 IP 10.0.0.54.44627 > 10.0.1.243.ssh: Flags [.], ack 22, win 115, options [nop,nop,TS val 3013092 ecr 12074928], length 0
    

    Conclusion:

    From tcpdump output on NAT, It seems that Iptables is forwarding my packets fine.

    from TCP dump on Server A, I have good connectivity from NAT to Server A.

    But in End-to-end, I am not able to connect to the server A from my laptop.

    (BTW, I know SSH tunnel and other good stuff. But I want only Iptables to help me with this.)

    • Dusan Bajic
      Dusan Bajic over 10 years
      Did you disable source/destination checking on your NAT instance?
    • slayedbylucifer
      slayedbylucifer over 10 years
      What does it mean? How to check that? I searched the entire Iptables man page but is does not say thing about source/destination checking (unless I missed anything obvious.)
    • Dusan Bajic
      Dusan Bajic over 10 years
      You have to do that in AWS web console (or CLI). docs.aws.amazon.com/AmazonVPC/latest/UserGuide/…
    • slayedbylucifer
      slayedbylucifer over 10 years
      Thanks. I find that it is already Disabled for the NAT instance.
  • slayedbylucifer
    slayedbylucifer over 10 years
    Your every single suggestions are already in place. Thanks.
  • c4urself
    c4urself over 10 years
    I updated it to show all the steps
  • slayedbylucifer
    slayedbylucifer over 10 years
    Thanks. +1 for your efforts. Your MASQUERADE command is not helpful in my case. May be I am missing something. The Only MASQUERADE command that gets me flying is the the one I have mentioned in my answer.
  • Neven
    Neven almost 8 years
    Man thanks in a million. Had the same problem, same.... Every step was in place... but this "-o eth0" was there as well. Removed it, worked like charm. Thanks in million.
  • Ryan Shillington
    Ryan Shillington almost 8 years
    The reason why it works is because the "-s 10.0.0.0/16" says to only translate packets with source ip 10.x.x.x. I'm guessing your home laptop was on your home network and was coming from some external IP so the NAT was ignoring your laptop's requests. Others may want to run "ip r" on the linux command line to see if eth0 is really the name of their ethernet device. If not, change it to whatever your eth device is named (ex. ens192 or whatever).
  • Ryan Shillington
    Ryan Shillington almost 8 years
    Oh, also, I learned the above by reading the iptables man page. It's really good and not a long read. I highly recommend it. Run "man iptables" from the command prompt to see it in all it's glory.