作者:mkmkunming | 来源:互联网 | 2014-05-27 21:08
这个玩意儿不好好找文档看是真心不知道的,中文的iptables和libvirt的资源又比较零碎,所以特此总结下。这两天在配置一个KVM虚拟机在宿主机(MAIN)上的端口转发,环境如下:宿主机MAIN:eth0?连接外网,有一个固定IP(例如12.34.56.78),并且可以被外
这个玩意儿不好好找文档看是真心不知道的,中文的iptables和libvirt的资源又比较零碎,所以特此总结下。
这两天在配置一个KVM虚拟机在宿主机(MAIN)上的端口转发,环境如下:
宿主机MAIN:
eth0 ? 连接外网,有一个固定IP(例如12.34.56.78),并且可以被外网直接访问到
virbr0 ? libvirtd自动建立的虚拟网卡,用于连接内网,IP:192.168.122.1
虚拟机VM:
eth0 ? 连接MAIN的virbr0,IP:192.168.122.100
MySQL在端口3306上提供真实服务
现在要在外网上通过访问外网的MAIN的某个端口(例如12345),实现访问内网VM的3306,最初我想当然的在iptables.rules(CentOS位于/etc/sysconfig/iptables)里面增加了两条规则:
*filter
#... 其他规则
-A FORWARD -p tcp --dport 3306 -d 192.168.122.100 -j ACCEPT
#... 其他规则
COMMIT
#...
*nat
#... 其他规则
-A PREROUTING -p tcp -d 12.34.56.78 --dport 12345 -j DNAT --to 192.168.122.100:80
-A POSTROUTING -p tcp -d 192.168.122.100 --dport 80 -j SNAT --to 192.168.122.1
#... 其他规则
COMMIT
|
结果测试发现,在系统只有这些规则的情况下是没有问题的,但一旦libvirtd启动时自己加入的确保虚拟内网正常访问外网的NAT规则进来的话会产生冲突,原因很简单,就是libvirtd后来加入规则优先级高过我在iptables.rules里面设置的规则,所以就失去作用了。在这里我几乎花费了一天的时间来找问题到底如何解决,其中包括尝试修改iptables的优先级,详细阅读各种iptables的各种文档,用iptables-save导出被libvirtd修改后的iptables表在这基础上进行修改。最后终于搜到了libvirtd官网上的文档,讲libvirt管理下的虚拟机应该如何处理传入的连接,才了解到要用libvirtd的钩子脚本,会在任何虚拟机启动时启动这个脚本,位于/etc/libvirt/hooks/qemu
这个位置,于是编写脚本如下:
#!/bin/sh
Guest_name=vm-database
Host_external_ipaddr=12.34.56.78
Host_port=12345
Host_ipaddr=192.168.122.1
Guest_ipaddr=192.168.122.100
Guest_port=3306
if [ "${1}" = "${Guest_name}" ]; then
if [ "${2}" = "start" ]; then
iptables -t nat -A PREROUTING -p tcp --dport ${Host_port} -d ${Host_external_ipaddr} \
-j DNAT --to ${Guest_ipaddr}:${Guest_port}
iptables -I FORWARD -d ${Guest_ipaddr}/32 -p tcp \
--dport ${Guest_port} -j ACCEPT
elif [ "${2}" = "stopped" ]; then
iptables -t nat -D PREROUTING -p tcp --dport ${Host_port} -d ${Host_external_ipaddr} \
-j DNAT --to ${Guest_ipaddr}:${Guest_port}
iptables -D FORWARD -d ${Guest_ipaddr}/32 -p tcp \
--dport ${Guest_port} -j ACCEPT
fi
fi
|
这样的话,就可以确保新建的FORWARD规则的优先级是最高的了,从而不被libvirtd的规则给盖住。不过要注意的是这里无需做SNAT,因为libvirtd自己添加的在NAT表的MASQUERADE规则相当于已经给你做掉了SNAT转换!
这是值得一看的中文iptables文档,对于理解如何配置iptables的NAT配置非常有帮助!:iptables 应用初探(nat+三层访问控制)
libvirt的官网文档:http://wiki.libvirt.org/page/Networking#Forwarding_Incoming_Connections (里面提供了一个hooks钩子脚本的范例,不过这个里面提供的脚本不够全面,实际的生产环境因为可能更加复杂所以那个无法产生效果,)
最后和本文主题无关的~感谢下