2

I have written port-forwarding iptables rules that I plan to roll-out to several machines in an automated way using Ansible. However, the POSTROUTING chain rule requires a modification of the source address to be that of the local machine so the machine receiving the forwarded packets knows where to respond. The rule looks like:

iptables -t nat -A POSTROUTING -d 192.168.11.2 -o eth1 -p tcp --dport 22 -j SNAT --to-source 192.168.11.1

That is, after using DNAT in PREROUTING to change the destination address to 192.168.11.2 (and ACCEPTing it), I must then use SNAT to change the source address in the network header before sending the packet into the network.

Can this rule be written in such a way to specify symbolically that --to-source should be "the local machine's IP"? I accomplished this by compiling the necessary commands into a series of piped commands:

iptables -t nat -A POSTROUTING -d 192.168.11.2 -o eth1 -p tcp --dport 22 -j SNAT --to-source $(ifconfig eth1 | grep -i "inet " | awk '{print $2}')

However, my intent is to generate an iptables configuration file and just roll that out to each machine if possible.

sherrellbc
  • 2,461
  • 7
  • 28
  • 41

2 Answers2

2

iptables config scripts are just shell scripts. You can add the local ip address to a variable in the 'normal' way:

LOCALIP=`hostname -i`

and then replace any hard coded ip address instances with

$LOCALIP
slowko
  • 321
  • 1
  • 7
  • Isn't `$(hostname -i)` usually 127.0.0.1 or some other localhost address? – AlexP Jan 04 '17 at 13:56
  • not unless you've specifically added the FQDN to the hosts file – slowko Jan 04 '17 at 13:58
  • `hostname -i` on my Arch Linux machine returns `127.0.0.1 127.0.0.1`. My `/etc/hosts` file has two entries; both are `localhost.localdomain`. – sherrellbc Jan 04 '17 at 14:04
  • You might need to use another method to discern the local ip (parsing the output of ifconfig for example) but the basic point remains. I did test the above on Ubuntu and Centos. – slowko Jan 04 '17 at 14:08
  • I did something similar originally. This is true if I am always writing iptable rules using the command interface. Do you know of a method for doing so using the iptables.rules file? On Arch this file is located at `/etc/iptables/iptables.rules`. My intent was to generate the identical iptables rule files and distribute them to the target machines. – sherrellbc Jan 04 '17 at 14:11
  • I believe that file is the output of `iptables-save` and is not meant to be edited directly, simply invoked with `iptables-restore` – slowko Jan 04 '17 at 14:18
  • Fair enough. I originally was working with [this](https://www.digitalocean.com/community/tutorials/how-to-forward-ports-through-a-linux-gateway-with-iptables) tutorial that showed manual editing on Ubuntu. The associated file was `/etc/iptables/rules.v4`. – sherrellbc Jan 04 '17 at 14:22
  • 1
    @sherrellbc Since you are using ansible, you should be able to use something like `{{ansible_default_ipv4.address}}` – user4556274 Jan 04 '17 at 14:38
0

You could use the MASQUERADE target instead of SNAT.

You might want to read Difference between SNAT and Masquerade however, as MASQUERADE has an overhead.

user2313067
  • 245
  • 2
  • 5