Firewall VMware Server 1.0.x guest with iptables on the host
Running a linux host with VMware 1.0.x Server you are not able to firewall the VMware guests on the host machine. Because vmware runs in the kernel the traffic to the guest is already handled by vmware before iptables will see the traffic.
Now it is possible to firewall the client by setting up a dummy network interface and bridge the physical interface to the dummy, this way you can let VMware setup his bridge to the dummy interface and you see the traffic passing by.
The layout
Lets say you have the following setup (click for larger):

host01 has a virtual host ‘guest01′ and it is bridged to eth0 and eth1 so it has a connection to the internet and a connection to the backlan to reach the DB0x servers.
However host02 has the same setup, but I don’t want ‘guest02′ to reach ‘guest01′, this could be aranged with a firewall on the guests but thats a bad solution if they are running windows (you don’t want to overload a already bloated windows with a extra firewall right?), so however there are multiple ways to fix this one solution is to setup a bridge on the host machine’s and firewall the traffic before it reaches the guest.
The following image should explain it a little more (click for larger):

The configuration
In this setup the ‘host’ machine is running ubuntu 6.06.1 LTS, has 2 nic’s and we are using VMware Server 1.0.4. that should have a bridge to both nics.
We will be creating 2 dummy network interfaces called ‘dummy0′ and ‘dummy1′ and 2 bridges called ‘br0′ and ‘br1′.
Then bind eth0 to dummy0 with br0 and eth1 to dummy1 with br1.
First install bridge utilities
Now connect to the console of the server as you can’t do this remote (well you can but then do 1 interface at a time)
Shutdown vmware and shutdown the interfaces
trouble@sun:$ ifdown eth0
trouble@sun:$ ifdown eth1
Now be sure to comment out the settings in /etc/network/interfaces for eth0 and eth1 so these are not read anymore.
create the dummy interfaces
trouble@sun:$ modprobe dummy -o dummy1
then create bridge 0 and bridge 1 and bind the interfaces to them, in my network I need to put stp ‘off’ but check in your case.
# br0, eth0 and dummy0
trouble@sun:$ brctl addif br0 eth0
trouble@sun:$ brctl addif br0 dummy0
trouble@sun:$ brctl stp br0 off
# br1, eth1 and dummy1
trouble@sun:$ brctl addif br1 eth1
trouble@sun:$ brctl addif br1 dummy1
trouble@sun:$ brctl stp br1 off
Now with the command ‘brctl show’ you should see the interfaces.
bridge name bridge id STP enabled interfaces
br1 8000.00112f164152 no eth1
dummy1
br0 8000.00112f164151 no eth0
dummy0
Oke now the bridges are configured, time to add a ipaddress to br0 and br1 so we can also connect to the server for management. Currently I will do this with ifconfig instead of putting it in the network file (see below for the complete script)
trouble@sun:$ ifconfig dummy0 0.0.0.0
trouble@sun:$ ifconfig eth1 0.0.0.0
trouble@sun:$ ifconfig dummy1 0.0.0.0
trouble@sun:$ ifconfig br0 10.1.1.2 netmask 255.255.255.0
trouble@sun:$ ifconfig br1 192.168.10.2 netmask 255.255.255.0
trouble@sun:$ route add default gw 10.1.1.1
Now the host should be reachable again on his network interfaces.
Now its time to reconfigure VMware with vmware-config.pl, when it asks for the network settings change them in the ‘editor’ mode and set bridging on ‘vmnet0′ to ‘br0′ and ‘vmnet2′ to ‘br1′.
Edit your virtual machine to use vmnet0 and vmnet2 and you should be ready to go with network on the virtual machines again.
The Firewall Rules
So the bridges are set, now its time to create some firewall rules, I won’t start explaining iptables here so here is an example configuration script that creates the bridged interfaces and configures the firewall.
To explain it a little:
First I will create the bridges and add ipaddresses to them, and only do this if they are not already created.
Then we move all traffic flowing through br0 in ‘Aforward’ (traffic to dummy0), and all traffic flowing through br1 in ‘Bforward’ (traffic to dummy1)(Just give it your own names if you wish this is logical for me
Now make sure to put your firewall rules for the guests in the section marked as:
1 2 | ##### Firewall rules for br0 from here! #### ##### Firewall rules for br0 until here! #### |
And the same for br1, and configure your local firewall rules to the ipaddresses of the host in:
1 2 | #-------- Local Firewall Rules to this host ----------# #-----------------------------------------------------# |
And you should be ready to go firewalled all traffic flowing through the vmware guests. Be sure to understand that this will only firewall the traffic from the ‘outside’ to your guest if you have multiple guests on your vmware host traffic is not firewalled between the 2 guests. This could be fixed by putting every guest in a seperate vmnet and use the host to NAT traffic to it but that won’t work in every setup.
Currently in the setup I am using I only have 2 Windows servers on 2 different hosts so I bridged those, firewalled those on the hosts, and the linux guests on the same hosts have there own firewall rules so I don’t have this problem. (you do firewall all your nodes in a network right?)
And the complete script:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 | #!/bin/bash #----------------------------------------------------# # Arno Haverlach (arno (at) haverlach (dot) nl) # Firewall/Bridge script for vmware # ver 0.1 20071204 #----------------------------------------------------# #--------------IP Variables -------------------------# DNS1=10.1.1.1 # dns server 1 DNS2=10.1.1.2 # dns server 2 MANAGEMENTHOST=x.x.x.x # Management host #-----------------------------------------------------# #---------------- variables --------------------------# # Bridge 0 (WAN) BR0IP="10.1.1.2" # ip of the LAN interface BR0MASK="255.255.255.0" # subnetmask of the LAN BR0IF1="eth0" # The physical LAN interface BR0IF2="dummy0" # This should be the dummy BR0GW="1" # 0 for no 1 for yes to enable the gateway BR0GWIP="10.1.1.1" # the ip of the gateway if BRI1GW=1 # Bridge 1 (LAN) BR1IP="192.168.10.2" # ip of the LAN interface BR1MASK="255.255.255.0" # subnetmask of the LAN BR1IF1="eth1" # The physical LAN interface BR1IF2="dummy1" # This should be the dummy BR1GW="0" # 0 for no 1 for yes to enable the gateway BR1GWIP="0.0.0.0" # the ip of the gateway if BRI1GW=1 # A few paths IPTABLES="/sbin/iptables" # path to iptables MODPROBE="/sbin/modprobe" # path to modprobe BRCTL="/usr/sbin/brctl" # path to brctl IFCONFIG="/sbin/ifconfig" # path to ifconfig ROUTE="/sbin/route" # path to route # Check how we are started CMD=$1 if ( [ -z $CMD ] ); then CMD="start"; fi #-----------------------------------------------------# #--------------- And now the fun stuff ---------------# if ( [ $CMD = "start" ] ); then #---------------- Create br0 -------------------------# # load the module if needed MDCHK1="`lsmod | grep -i dummy0 | awk {' print $1 '}`" if ( [ "$MDCHK1" != "dummy0" ] ); then $MODPROBE dummy -o dummy0; fi # create the bridge if needed BRCHK1="`brctl show | grep br0 | awk {' print $1 '}`" if ( [ "$BRCHK1" != "br0" ] ); then $BRCTL addbr br0 $BRCTL addif br0 $BR0IF1 $BRCTL addif br0 $BR0IF2 $BRCTL stp br0 off $IFCONFIG $BR0IF1 0.0.0.0 $IFCONFIG $BR0IF2 0.0.0.0 $IFCONFIG br0 $BR0IP netmask $BR0MASK if ( [ "$BR0GW" = "1" ] ); then $ROUTE add default gw $BR0GWIP fi fi #-----------------------------------------------------# #---------------- Create br1 -------------------------# # load the module if needed MDCHK1="`lsmod | grep -i dummy1 | awk {' print $1 '}`" if ( [ "$MDCHK1" != "dummy1" ] ); then $MODPROBE dummy -o dummy1; fi # create the bridge if needed BRCHK1="`brctl show | grep br1 | awk {' print $1 '}`" if ( [ "$BRCHK1" != "br1" ] ); then $BRCTL addbr br1 $BRCTL addif br1 $BR1IF1 $BRCTL addif br1 $BR1IF2 $BRCTL stp br1 off $IFCONFIG $BR1IF1 0.0.0.0 $IFCONFIG $BR1IF2 0.0.0.0 $IFCONFIG br1 $BR1IP netmask $BR1MASK if ( [ "$BR1GW" = "1" ] ); then $ROUTE add default gw $BR1GWIP fi fi #-----------------------------------------------------# #--------------- Firewall default --------------------# # Default policy: ACCEPT $IPTABLES -P FORWARD ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P OUTPUT ACCEPT # Flush $IPTABLES -F $IPTABLES -t mangle -F $IPTABLES -F FORWARD $IPTABLES -F INPUT $IPTABLES -F OUTPUT # Default policy: ACCEPT $IPTABLES -P FORWARD ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P OUTPUT ACCEPT #-----------------------------------------------------# #-------------- We put br0 in Aforward ---------------# # Create Aforward $IPTABLES -N Aforward $IPTABLES -A FORWARD -i br0 -j Aforward $IPTABLES -A FORWARD -o br0 -j Aforward # Drop all crap on Aforward $IPTABLES -A Aforward -p TCP --tcp-flags SYN,FIN SYN,FIN -j DROP $IPTABLES -A Aforward -p TCP --tcp-flags SYN,RST SYN,RST -j DROP $IPTABLES -A Aforward -p TCP --tcp-flags FIN,RST FIN,RST -j DROP $IPTABLES -A Aforward -p TCP --tcp-flags ACK,FIN FIN -j DROP $IPTABLES -A Aforward -p TCP --tcp-flags ACK,PSH PSH -j DROP $IPTABLES -A Aforward -p TCP --tcp-flags ACK,URG URG -j DROP ##### Firewall rules for br0 from here! #### ##### Firewall rules for br0 until here! #### # drop the rest on Aforward $IPTABLES -A Aforward -j DROP #-----------------------------------------------------# #-------------- We put br1 in Bforward ---------------# # Create Bforward $IPTABLES -N Bforward $IPTABLES -A FORWARD -i br1 -j Bforward $IPTABLES -A FORWARD -o br1 -j Bforward # Drop all crap on Bforward $IPTABLES -A Bforward -p TCP --tcp-flags SYN,FIN SYN,FIN -j DROP $IPTABLES -A Bforward -p TCP --tcp-flags SYN,RST SYN,RST -j DROP $IPTABLES -A Bforward -p TCP --tcp-flags FIN,RST FIN,RST -j DROP $IPTABLES -A Bforward -p TCP --tcp-flags ACK,FIN FIN -j DROP $IPTABLES -A Bforward -p TCP --tcp-flags ACK,PSH PSH -j DROP $IPTABLES -A Bforward -p TCP --tcp-flags ACK,URG URG -j DROP ##### Firewall rules for br1 from here! #### ##### Firewall rules for br1 until here! #### # drop the rest on Bforward $IPTABLES -A Bforward -j DROP #-----------------------------------------------------# #--------------- Drop on FORWARD ---------------------# $IPTABLES -A FORWARD -j LOG --log-prefix "[DROP-FORWARD] " $IPTABLES -A FORWARD -j DROP #-----------------------------------------------------# #-------- Local Firewall Rules to this host ----------# ## INPUT ## # VMWARE Console management hosts $IPTABLES -A INPUT -p tcp -s $MANAGEMENTHOST --dport 902 -j ACCEPT $IPTABLES -A OUTPUT -p tcp -d $MANAGEMENTHOST --sport 902 ! --syn -j ACCEPT $IPTABLES -A INPUT -p tcp -s $MANAGEMENTHOST --dport 8222 -j ACCEPT $IPTABLES -A OUTPUT -p tcp -d $MANAGEMENTHOST --sport 8222 ! --syn -j ACCEPT $IPTABLES -A INPUT -p tcp -s $MANAGEMENTHOST --dport 8333 -j ACCEPT $IPTABLES -A OUTPUT -p tcp -d $MANAGEMENTHOST --sport 8333 ! --syn -j ACCEPT # ssh in from everyone and all interfaces $IPTABLES -A INPUT -p tcp --dport 22 -j ACCEPT $IPTABLES -A OUTPUT -p tcp --sport 22 ! --syn -j ACCEPT ## OUTPUT ## # port 80 to browse a bit for updates and stuff (you should limit this) $IPTABLES -A OUTPUT -p tcp --dport 80 -j ACCEPT $IPTABLES -A INPUT -p tcp --sport 80 ! --syn -j ACCEPT # DNS lookups DNSSERVERS="$DNS1 $DNS2" for dnsip in $DNSSERVERS do $IPTABLES -A OUTPUT -p udp --sport 53 -d $dnsip -j ACCEPT $IPTABLES -A INPUT -p udp -s $dnsip --sport 53 -j ACCEPT $IPTABLES -A OUTPUT -p udp -d $dnsip --dport 53 -j ACCEPT $IPTABLES -A INPUT -p udp -s $dnsip --dport 53 -j ACCEPT $IPTABLES -A OUTPUT -p tcp -d $dnsip --dport 53 -j ACCEPT $IPTABLES -A INPUT -p tcp -s $dnsip --dport 53 -j ACCEPT $IPTABLES -A OUTPUT -p tcp --sport 53 -d $dnsip ! --syn -j ACCEPT done # deny rest $IPTABLES -A INPUT -j LOG --log-prefix "[DROP-INPUT] " $IPTABLES -A INPUT -j DROP $IPTABLES -A OUTPUT -j LOG --log-prefix "[DROP-OUTPUT] " $IPTABLES -A OUTPUT -j DROP $IPTABLES -A FORWARD -j DROP #-----------------------------------------------------# #---------------- End the if cmd=start ---------------# fi #-----------------------------------------------------# #------------- Set default policy to DROP ------------# $IPTABLES -P FORWARD DROP $IPTABLES -P INPUT DROP $IPTABLES -P OUTPUT DROP #-----------------------------------------------------# #eof |
Comments Off