NAT
From Blue-IT.org Wiki
Contents
Commandline Foo
Show all FORWARD rules
iptables -L FORWARD
See all nat rules in live time
watch -n2 iptables -nvL -t nat --line-number
Remove a sepcific rule in a specific CHAIN with a certain LINE-NUMBER. CHAINNAME is e.g. [PREROUTING | INPUT | OUTPUT | POSTROUTING | ...] like in:
Chain POSTROUTING (policy ACCEPT 13551 packets, 823K bytes) num pkts bytes target prot opt in out source destination 1 13551 823K postmodules all -- * * 0.0.0.0/0 0.0.0.0/0 2 0 0 SNAT all -- * eth0 !192.168.1.4 0.0.0.0/0 to:192.168.1.4
#!/bin/bash echo "Usage: nat_remove_line CHAINNAME LINE-NUMBER" echo "view with" echo " iptables -nvL -t nat --line-number" iptables -t nat -D $1 $2
Bug in Ubuntu for accessing virtual machines behind a bridge
On ubuntu 12.04 there is a Ubuntu bug #50093 (mentioned here) which prevents accessing a machine inside the bridges network:
> vim /etc/sysctl.conf net.bridge.bridge-nf-call-ip6tables = 0 net.bridge.bridge-nf-call-iptables = 0 net.bridge.bridge-nf-call-arptables = 0
Acitvate
sysctl -p /etc/sysctl.conf
Make permanent
> vim /etc/rc.local *** Sample rc.local file *** /sbin/sysctl -p /etc/sysctl.conf iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu exit 0
Verify
tail /proc/sys/net/bridge/* iptables -L FORWARD > brctl show bridge name bridge id STP enabled interfaces br1 8000.50e5492d616d no eth1 vnet1 [...]
Accessing ports in servers behind a natted bridge and firewall
Be careful. By doing this, you open up ports to the outside world. If you are using pfSense in front of your host or another firewall you can simply restrict this by using VPN.
Access from internet to guest:
internet -> pfSense (WAN / host ip and port) -> host port -> iptables -> nat bridge -> guest port
Access only via vpn to guest
internet -> pfSense (OpenVPN / host ip and port) -> host port -> iptables -> nat bridge -> guest port
Use the next script ...
Bash script for setting ip tables
Thanks to the scripts mentioned here: http://wiki.libvirt.org/page/Networking#Forwarding_Incoming_Connections I am aware of duplicate code, feel free to reduce and inform me to my email on my site http://www.blue-it.org.
Beware of setting your firewall's ports correctly. They must forwarding for NAT pointing to the hosts (!!!) ip, not the one you mentioned in this script.
This example sets two
To add a rule
set_iptables add
To remove it
set_iptables remove
> vim ~/bin/set_iptables
#!/bin/bash del_prerouting() { iptables -t nat -D PREROUTING -p tcp --dport ${1} -j DNAT --to ${2}:${3} } del_forward() { iptables -D FORWARD -d ${1}/32 -p tcp -m state --state NEW -m tcp --dport ${2} -j ACCEPT } del_output() { #- allows port forwarding from localhost but # only if you use the ip (e.g http://192.168.1.20:8888/) iptables -t nat -D OUTPUT -p tcp -o lo --dport ${1} -j DNAT --to ${2}:${1} } add_prerouting() { iptables -t nat -A PREROUTING -p tcp --dport ${1} -j DNAT --to ${2}:${3} } add_forward() { iptables -I FORWARD -d ${1}/32 -p tcp -m state --state NEW -m tcp --dport ${2} -j ACCEPT } add_output() { #- allows port forwarding from localhost but # only if you use the ip (e.g http://192.168.1.20:8888/) iptables -t nat -I OUTPUT -p tcp -o lo --dport ${1} -j DNAT --to ${2}:${1} } ############################################### # ONLY EDIT HERE Guest_ipaddr=192.168.11.2 Host_port=( '4444' '4445' '993' '587' '25' '465' '143' ) Guest_port=( '80' '443' '993' '587' '25' '465' '143' ) ############################################### length=$(( ${#Host_port[@]} - 1 )) if [ "${1}" = "remove" ]; then for i in $(seq 0 $length); do del_prerouting ${Host_port[$i]} ${Guest_ipaddr} ${Guest_port[$i]} del_forward ${Guest_ipaddr} ${Guest_port[$i]} #- allows port forwarding from localhost but # only if you use the ip (e.g http://192.168.1.20:8888/) del_output ${Host_port[$i]} ${Guest_ipaddr} done fi if [ "${1}" = "add" ]; then for i in `seq 0 $length`; do add_prerouting ${Host_port[$i]} ${Guest_ipaddr} ${Guest_port[$i]} add_forward ${Guest_ipaddr} ${Guest_port[$i]} #- allows port forwarding from localhost but # only if you use the ip (e.g http://192.168.1.20:8888/) add_output ${Host_port[$i]} ${Guest_ipaddr} done fi ############################################### # ONLY EDIT HERE Guest_ipaddr=192.168.33.2 Host_port=( '4444' '4445' '1814' ) Guest_port=( '80' '443' '1814' ) ############################################### length=$(( ${#Host_port[@]} - 1 )) if [ "${1}" = "remove" ]; then for i in $(seq 0 $length); do del_prerouting ${Host_port[$i]} ${Guest_ipaddr} ${Guest_port[$i]} del_forward ${Guest_ipaddr} ${Guest_port[$i]} #- allows port forwarding from localhost but # only if you use the ip (e.g http://192.168.1.20:8888/) del_output ${Host_port[$i]} ${Guest_ipaddr} done fi if [ "${1}" = "add" ]; then for i in `seq 0 $length`; do add_prerouting ${Host_port[$i]} ${Guest_ipaddr} ${Guest_port[$i]} add_forward ${Guest_ipaddr} ${Guest_port[$i]} #- allows port forwarding from localhost but # only if you use the ip (e.g http://192.168.1.20:8888/) add_output ${Host_port[$i]} ${Guest_ipaddr} done fi # To server another guest simply add another block for another host .. # # Guest_ipaddr=another_ip # Host_port=( '123' '456' '789' ) # Guest_port=( '12' '45' '78' ) # length=$(( ${#Host_port[@]} - 1 )) # # and so on