在网上搜索基本有两种方法。一是直接利用QEMU提供的-netuser或-nettap。二是使用Bridge模式。后者较前者来说更方便虚拟机与主机系统互访(似乎),我没有试过,其实-nettap也可以实现的。QEMU本身的两种上网方式我更青睐TAP。关于-netuser的
在网上搜索基本有两种方法。一是直接利用 QEMU 提供的 -net user 或
-net tap 。二是使用Bridge模式。后者较前者来说更方便虚拟机与主机系统互访(似乎),我没有试过,其实 -net tap
也可以实现的。
QEMU 本身的两种上网方式我更青睐 TAP 。关于 -net user
的安全性高或不高我实在找不到资料,也许是我多虑了;TAP 虽然配置麻烦一些,但是能够直接应用我信任的 iptables
感觉心里踏实很多。而且它还可以实现虚拟机与主机互访,虽然我不会麻烦地去搞这个。
言归正传。需要注意的有下面几点:
一、 kvm 的参数
以下几步都完成后,按这行命令启动虚拟机,会自动应用
/etc/kvm/kvm-ifup 脚本:
kvm win.img -net nic,vlan=0 -net
tap,vlan=0,ifname=tap0
二、 相应的 iptables
规则,虽然不确定,我希望这些设置会比较安全。
# FORWARD 默认规则为 抛弃
iptables -P FORWARD DROP
# nat POSTROUTING 默认规则为 抛弃
iptables -t nat -P POSTROUTING DROP
# tap0 向 ppp0 转发的包,即向外的包,全部接受
iptables -A FORWARD -i tap0 -o ppp0 -j
ACCEPT
# 来自的 ppp0 的包,即向内的包,如果是已连接的或相关的,接受
iptables -A FORWARD -i ppp0 -m state
--state RELATED,ESTABLISHED -j ACCEPT
# 其他的 TCP 包,拒绝
iptables -A FORWARD -i ppp0 -p tcp -j
REJECT --reject-with tcp-reset
# UDP 包,拒绝
iptables -A FORWARD -i ppp0 -p udp -j
REJECT --reject-with icmp-port-unreachable
# 用于内网的 IP
伪装,内网即虚拟机访问互联网时会被认为是主机在访问,而互联网来的包也会被自动转发给虚拟机
iptables -t nat -A POSTROUTING -o ppp0
-j MASQUERADE
三、 使能 IP 转发功能
echo "1" >
/proc/sys/net/ipv4/ip_forward
四、 如果 tun 是编译成内核模块的,先要加载
/sbin/modprobe tun
完整文件如下:
为了方便,我把 iptables 的规则用 iptables-save
写入一个文件 enable-kvm ,然后写了一个启动用的脚本,完成启动及之前的准备和最后的恢复工作。
启动脚本如下:
#!/bin/sh
###
# Need to be ROOT.
# Prepare and Start kvm win guest
system.
# Wait and cleanup.
###
test -f /usr/bin/kvm || exit 0
# Load tun module, for TAP network
interface
/sbin/modprobe tun
# Enable ip forward
echo "1" >
/proc/sys/net/ipv4/ip_forward
# Apply enable-kvm rules for
iptables
# Had to create rules in
/etc/iptables
# Had to create /etc/init.d/iptables
first.
# See /etc/init.d/iptables and
/etc/iptables
/etc/init.d/iptables enable-kvm
# Start
# With -m 1G, set virtual RAM size to
1G
# With -localtime, set the real time
clock to local time
# With network, and create a new
interface tap0
# (must named after tap0, because of
iptables rules up)
/usr/bin/kvm win.img \
-m 1G \
-localtime \
-net nic,vlan=0 -net
tap,vlan=0,ifname=tap0
# Restore previous rules
/etc/init.d/iptables disable-kvm
# Disable ip forward
echo "0" >
/proc/sys/net/ipv4/ip_forward
# Unload tun module
/sbin/modprobe -r tun
exit 0
另外,我把 /etc/kvm/kvm-ifup 稍微修改了一下,IP 固定为
192.168.0.1。
虚拟机的配置: IP 设定为 192.168.0.2 ,网关为
192.168.0.1 ,子网掩码 255.255.255.0 ,DNS 看 /etc/resolv.conf ,添成一样的。
/etc/kvm/kvm-ifup 如下:
#!/bin/sh
switch=$(ip route ls | awk '/^default /
{ for(i=0;i
/sbin/ifconfig $1 192.168.0.1 up
/usr/sbin/brctl addif ${switch} $1
exit 0
enable-kvm 是在原来的规则基础上再添加了上述几项,内容如下。
disable-kvm 则是去掉上述几项,恢复原来的规则。
# Generated by iptables-save v1.4.1.1 on
Thu Dec 25 10:15:44 2008
*nat
:PREROUTING ACCEPT [0:0]
:POSTROUTING DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A POSTROUTING -o ppp0 -j MASQUERADE
COMMIT
# Completed on Thu Dec 25 10:15:44
2008
# Generated by iptables-save v1.4.1.1 on
Thu Dec 25 10:15:44 2008
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -i ppp0 -m state --state
RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i ppp0 -p tcp -j REJECT
--reject-with tcp-reset
-A INPUT -i ppp0 -p udp -j REJECT
--reject-with icmp-port-unreachable
-A INPUT -i lo -j ACCEPT
-A FORWARD -i tap0 -o ppp0 -j ACCEPT
-A FORWARD -i ppp0 -m state --state
RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i ppp0 -p tcp -j REJECT
--reject-with tcp-reset
-A FORWARD -i ppp0 -p udp -j REJECT
--reject-with icmp-port-unreachable
COMMIT
# Completed on Thu Dec 25 10:15:44
2008
/etc/init.d/iptables 是自己写的一个脚本用来自动启用
iptables 规则的。
#!/bin/sh
START=/etc/iptables/start.rule
STOP=/etc/iptables/stop.rule
KVM=/etc/iptables/enable-kvm.rule
DISCOnNECT=/etc/iptables/disconnect.rule
case "$1" in
start)
/sbin/iptables-restore
;;
stop)
/sbin/iptables-restore
;;
restart)
/sbin/iptables-restore
;;
enable-kvm)
/sbin/iptables-restore
;;
disable-kvm)
/sbin/iptables-restore
;;
disconnect)
/sbin/iptables-restore
;;
*)
echo "Usage: /etc/init.d/iptables
{start|stop|restart|enable-kvm|disable-kvm|disconnect}"
;;
esac
exit 0
罗罗嗦嗦全文完:)
如果您有任何意见和建议,请让我知道。