NAT via iptables and virtual interface
Solution 1
With the answers of Christophe Drevet and DukeLion I was able to get the desired configuration working.
I'm going to answer myself explaining my solution. Please feel free to comment on this as I haven't done network stuff in a few years and might very well have missed something very important here.
The configuration below works perfectly and allows for adding more VMs, each using a different public IP address (IPs from 172.16.0.0 used here are "public").
Network Interfaces
VM-Host, eth0 -> 172.16.0.1
VM-Host, eth0:0 -> 172.16.0.2
VM-Host, br0 -> 192.168.10.1
Virt. machine, eth0 -> 192.168.10.2 (added to br0)
gateway: 172.16.0.2
iptables
Connection tracking:
iptables -I FORWARD -m conntrack -d 192.168.10.0/24 --ctstate NEW,RELATED,ESTABLISHED -j ACCEPT
DNAT for the webserver on our VM:
iptables -t nat -A PREROUTING -p tcp -d 172.16.0.2 --dport 80 -j DNAT --to-destination 192.168.10.2:80
SNAT for our VM to reach the outside world:
iptables -t nat -I POSTROUTING -j SNAT --src 192.168.10.2 --to-source 172.16.0.2
Block all other ports on the VM:
iptables -A INPUT -d 172.16.0.2 -j REJECT --reject-with icmp-port-unreachable
Solution 2
to use DNAT like this you need your guest systems to have VM-host as default gateway.
Solution 3
I had a similar network configuration and I used this configuration :
localnetwork (192.168.0.0/24) <-> host eth0 (192.168.0.10)
host tun0 (192.168.1.150) <-> vm1 eth0 (192.168.1.200) gw 192.168.1.150
<-> vm2 eth0 (192.168.1.201) gw 192.168.1.150
All my VMs can ping each other and can access the outside network with this iptable rule :
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
SNAT all -- 192.168.1.0/24 0.0.0.0/0 to:192.168.0.10
The outside network can access services on my VMs with these rules :
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DNAT tcp -- 0.0.0.0/0 192.168.0.10 tcp dpt:22200 to:192.168.1.200:22
DNAT tcp -- 0.0.0.0/0 192.168.0.10 tcp dpt:22201 to:192.168.1.201:22
DNAT tcp -- 0.0.0.0/0 192.168.0.10 tcp dpt:3389 to:192.168.1.202:3389
DNAT tcp -- 0.0.0.0/0 192.168.0.10 tcp dpt:443 to:192.168.1.206:443
DNAT tcp -- 0.0.0.0/0 192.168.0.10 tcp dpt:80 to:192.168.1.206:80
I configured the tun0 interface with these lines on debian in the file /etc/network/interfaces :
auto tun0
iface tun0 inet static
address 192.168.1.150
netmask 255.255.255.0
pre-up tunctl -g uml-net -t tun0
post-down tunctl -d tun0
Comments
-
Alex almost 2 years
I'm trying to implement the following scenario: One VM-host, multiple guest VMs, each one gets its own IP-address (and domain).
Our server has only one physical interface, so the intended use is to add virtual interfaces on eth0. To complicate our situation the provider uses port-security on their switches, so I can't run the guest interfaces in bridged mode, because then the switch detects a "spoofed" MAC-address and kills the interface (permanently, forcing me to call the support, which I'm sure will get them a little bit angry the third time ;) ).
My first guess was to use iptables and NAT to forward all packages from one virtual interface to another one, but iptables doesn't seem to like virtual interfaces (at least I can't get it to work properly). So my second guess is to use the source IP of the packages to the public interface.
Let's assume libvirt creates a virbr0-network with 192.168.100.0/24 and the guest uses 192.168.100.2 as IP-address.
This is what I tried to use:
iptables -t nat -I PREROUTING --src public_ip_on_eth0:0 -p tcp --dport 80 -j DNAT --to-destination 192.168.100.2:80
That doesn't give me the intended results either (accessing the server times out).
Is there a way to do what I'm trying to do, or even to route all traffic to a certain IP on a virtual interface to the VM's device?
-
jetboy about 12 yearsIf you're getting a timeout, it could be that the request is making it to the VM, but the response isn't making it back out. You can check your server log (port 80 means a web server, right?) to see if the request's hitting the server.
-
-
Alex about 12 yearsSo you mean I need to setup the guest to use eth0:0's IP (or whatever virtual device I'm going to use) as default gateway and not 192.168.100.1, which is the virbrX device?