How can I forward ports on a server running libvirt/KVM to specified ports on VM's, when using NAT?
For example, the host has a public IP of 1.2.3.4. I want to forward port 80 to 10.0.0.1 and port 22 to 10.0.0.2.
I assume I need to add iptables rules, but I'm not sure where is appropriate and what exactly should be specified.
Output of iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT udp -- anywhere anywhere udp dpt:domain
ACCEPT tcp -- anywhere anywhere tcp dpt:domain
ACCEPT udp -- anywhere anywhere udp dpt:bootps
ACCEPT tcp -- anywhere anywhere tcp dpt:bootps
Chain FORWARD (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere 10.0.0.0/24 state RELATED,ESTABLISHED
ACCEPT all -- 10.0.0.0/24 anywhere
ACCEPT all -- anywhere anywhere
REJECT all -- anywhere anywhere reject-with icmp-port-unreachable
REJECT all -- anywhere anywhere reject-with icmp-port-unreachable
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Output of ifconfig
eth0 Link encap:Ethernet HWaddr 00:1b:fc:46:73:b9
inet addr:192.168.1.14 Bcast:192.168.1.255 Mask:255.255.255.0
inet6 addr: fe80::21b:fcff:fe46:73b9/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:201 errors:0 dropped:0 overruns:0 frame:0
TX packets:85 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:31161 (31.1 KB) TX bytes:12090 (12.0 KB)
Interrupt:17
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
virbr1 Link encap:Ethernet HWaddr ca:70:d1:77:b2:48
inet addr:10.0.0.1 Bcast:10.0.0.255 Mask:255.255.255.0
inet6 addr: fe80::c870:d1ff:fe77:b248/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:6 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:468 (468.0 B)
I'm using Ubuntu 10.04.
-
iptables -t nat -I PREROUTING -d 1.2.3.4 -p tcp --dport 80 -j DNAT --to-destination 10.0.0.1 iptables -t nat -I PREROUTING -d 1.2.3.4 -p tcp --dport 22 -j DNAT --to-destination 10.0.0.1steveh7 : Thank you for this, but with KVM specifically it needed the NEW state flag as wellFrom topdog -
The latest stable release for libvirt for Ubuntu is version 0.7.5, which doesn't have some newer features (i.e. script hooks and network filters) which make automatic network configuration easier. That said, here's how to enable port forwarding for libvirt 0.7.5 on Ubuntu 10.04 Lucid Lynx.
These iptables rules should do the trick:
iptables -t nat -I PREROUTING -p tcp --dport 80 -j DNAT --to-destination 10.0.0.1:80 iptables -t nat -I PREROUTING -p tcp --dport 22 -j DNAT --to-destination 10.0.0.2:22 iptables -I FORWARD -m state -d 10.0.0.0/24 --state NEW,RELATED,ESTABLISHED -j ACCEPTThe default KVM NAT config provides a rule similar to the 3rd I gave above, but it omits the NEW state, which is essential for accepting incoming connections.
If you write a startup script to add these rules and you're not careful, libvirt 0.7.5 overrides them by inserting its own. So, in order to make sure these rules are applied properly on startup, you need to make sure libvirt has initialized before you insert your rules.
Add the following lines to /etc/rc.local, before the line
exit 0:( # Make sure the libvirt has started and has initialized its network. while [ `ps -e | grep -c libvirtd` -lt 1 ]; do sleep 1 done sleep 10 # Set up custom iptables rules. iptables -t nat -I PREROUTING -p tcp --dport 80 -j DNAT --to-destination 10.0.0.1:80 iptables -t nat -I PREROUTING -p tcp --dport 22 -j DNAT --to-destination 10.0.0.2:22 iptables -I FORWARD -m state -d 10.0.0.0/24 --state NEW,RELATED,ESTABLISHED -j ACCEPT ) &The
sleep 10above is a hack to make sure the libvirt daemon has had a chance to initialize its iptables rules before we add our own. I can't wait until they release libvirt version 0.8.3 for Ubuntu.Manuel Faux : Can you explain how you would do this with current libvirt?Isaac Sutherland : You don't need the hacked while loop and sleep commands if one of the hook scripts runs after libvirt has initialized its networking. I'm not sure if the /etc/libvirt/hooks/daemon script is run before or after network initialization, but if you use /etc/libvirt/hooks/qemu you could create and destroy the rules when the appropriate virtual machines start and stop. I'm not sure how you would use network filters (if at all), but some of the examples at http://libvirt.org/firewall.html smell like they could modified to automate the creation of iptables rules.From Isaac Sutherland
0 comments:
Post a Comment