NAT

From Blue-IT.org Wiki

Revision as of 18:25, 1 November 2013 by Apos (talk | contribs) (Bash script for setting ip tables)

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

Pfsense port forward kvm nat bridge.png

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

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.

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}
}

Guest_ipaddr=192.168.23.4
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



Guest_ipaddr=192.168.22.4
Host_port=( '1234' '1235' '1433' )
Guest_port=( '1234' '1235' '1433' )
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

[Category:Virtualisation] [Category:Network] [Category:KVM] [Category:Security]