Difference between revisions of "NAT"

From Blue-IT.org Wiki

(Bug in Ubuntu for accessing virtual machines behind a bridge)
 
(13 intermediate revisions by the same user not shown)
Line 1: Line 1:
=== Bug in Ubuntu for accessing virtual machines behind a bridge ===
+
== Commandline Foo ==
On ubuntu 12.04 there is a [https://bugs.launchpad.net/ubuntu/+source/procps/+bug/50093 Ubuntu bug #50093] (mentioned [http://wiki.libvirt.org/page/Networking#Debian.2FUbuntu_Bridging here]) which prevents accessing a machine inside the bridges network:
+
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 [https://bugs.launchpad.net/ubuntu/+source/procps/+bug/50093 Ubuntu bug #50093] (mentioned [http://wiki.libvirt.org/page/Networking#Debian.2FUbuntu_Bridging here]) which prevents accessing a machine inside the bridged network:
  
 
  > vim /etc/sysctl.conf
 
  > vim /etc/sysctl.conf
Line 27: Line 47:
 
  [...]
 
  [...]
  
 
+
== Accessing ports in servers behind a natted bridge and firewall ==
=== 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.
 
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.
  
Line 44: Line 63:
  
 
=== Bash script for setting ip tables ===
 
=== 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 correct 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
 
To add a rule
 
  set_iptables add
 
  set_iptables add
Line 52: Line 78:
 
  > vim ~/bin/set_iptables
 
  > vim ~/bin/set_iptables
  
  #!/bin/bash   
+
  #!/bin/bash
 
+
   
if [ ${1} = "" ]  
+
del_prerouting() {
then  
+
iptables -t nat -D PREROUTING -p tcp --dport ${1} -j DNAT --to ${2}:${3}
        echo  "Usage with either 'add' or 'remove' ...  RETRY"  
+
  }
        exit 1
+
   
  fi 
+
  del_forward() {
 +
      iptables -D FORWARD -d ${1}/32 -p tcp -m state --state NEW -m tcp --dport ${2} -j ACCEPT
 +
  }
 
   
 
   
  # the virtual hosts adress
+
  del_output() {
  Guest_ipaddr=192.168.0.3
+
    #- allows port forwarding from localhost but
  Host_port=( '4444' '4445' )  
+
    #  only if you use the ip (e.g http://192.168.1.20:8888/)
  Guest_port=( '80' '443' )  
+
iptables -t nat -D OUTPUT -p tcp -o lo --dport ${1} -j DNAT --to ${2}:${1}
  length=$(( ${#Host_port[@]} - 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' )
 +
  ###############################################
 
    
 
    
  if [ "${1}" = "remove" ]; then
+
  length=$(( ${#Host_port[@]} - 1 ))
    for i in $(seq 0 $length); do
 
            iptables -t nat -D PREROUTING -p tcp --dport ${Host_port[$i]} -j DNAT \
 
                    --to ${Guest_ipaddr}:${Guest_port[$i]}
 
            iptables -D FORWARD -d ${Guest_ipaddr}/32 -p tcp -m state --state NEW \
 
                    -m tcp --dport ${Guest_port[$i]} -j ACCEPT
 
    done
 
fi
 
 
    
 
    
  if [ "${1}" = "add" ]; then  
+
if [ "${1}" = "remove" ]; then
    for i in `seq 0 $length`; do  
+
    for i in $(seq 0 $length); do
            iptables -t nat -A PREROUTING -p tcp --dport ${Host_port[$i]} -j DNAT \
+
        del_prerouting ${Host_port[$i]}  ${Guest_ipaddr} ${Guest_port[$i]}
                    --to ${Guest_ipaddr}:${Guest_port[$i]}  
+
            del_forward ${Guest_ipaddr} ${Guest_port[$i]}
            iptables -I FORWARD -d ${Guest_ipaddr}/32 -p tcp -m state --state NEW \
+
            #- allows port forwarding from localhost but
                    -m tcp --dport ${Guest_port[$i]} -j ACCEPT
+
#  only if you use the ip (e.g http://192.168.1.20:8888/)
    done  
+
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
 
  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 
 +
  
[Category:Virtualisation]
+
[[Category:Virtualisation]]
[Category:Network]
+
[[Category:Network]]
[Category:KVM]
+
[[Category:KVM]]
[Category:Security]
+
[[Category:Security]]
 +
[[Category:NAT]]

Latest revision as of 12:59, 28 June 2017

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 bridged 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 I am aware of duplicate code, feel free to correct 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