在QEMU/KVM中,默認使用IP偽裝的方式去實現NAT,而不是用SNAT或DNAT的方式。
1、安裝軟件包
# yum -y install bridge-utils iptables dnsmasq # rpm -qa | egrep "bridge-utils|iptables|dnsmasq
2、創建qemu-ifup-nat腳本,主要功能是:建立bridge,設置brdige的內網IP,並且將客戶機的網絡接口與其綁定,然后打開系統中網絡IP包轉發的功能,設置iptables的NAT規則,最后啟動dnsmasq作為一個簡單的DHCP服務器。
#!/bin/bash # qemu-ifup-nat script for QEMU/KVM with NAT netowrk mode # set your bridge name BRIDGE=virbr0 # Network information NETWORK=192.168.122.0 NETMASK=255.255.255.0 # GATEWAY for internal guests is the bridge in host GATEWAY=192.168.122.1 DHCPRANGE=192.168.122.2,192.168.122.254 # Optionally parameters to enable PXE support TFTPROOT= BOOTP= function check_bridge() { if brctl show | grep "^$BRIDGE" &> /dev/null; then return 1 else return 0 fi } function create_bridge() { brctl addbr "$BRIDGE" brctl stp "$BRIDGE" on brctl setfd "$BRIDGE" 0 ifconfig "$BRIDGE" "$GATEWAY" netmask "$NETMASK" up } function enable_ip_forward() { echo 1 > /proc/sys/net/ipv4/ip_forward } function add_filter_rules() { iptables -t nat -A POSTROUTING -s "$NETWORK"/"$NETMASK" \ ! -d "$NETWORK"/"$NETMASK" -j MASQUERADE } function start_dnsmasq() { # don't run dnsmasq repeatedly ps -ef | grep "dnsmasq" | grep -v "grep" &> /dev/null if [ $? -eq 0 ]; then echo "Warning:dnsmasq is already running. No need to run it again." return 1 fi dnsmasq \ --strict-order \ --except-interface=lo \ --interface=$BRIDGE \ --listen-address=$GATEWAY \ --bind-interfaces \ --dhcp-range=$DHCPRANGE \ --conf-file="" \ --pid-file=/var/run/qemu-dnsmasq-$BRIDGE.pid \ --dhcp-leasefile=/var/run/qemu-dnsmasq-$BRIDGE.leases \ --dhcp-no-override \ ${TFTPROOT:+"--enable-tftp"} \ ${TFTPROOT:+"--tftp-root=$TFTPROOT"} \ ${BOOTP:+"--dhcp-boot=$BOOTP"} } function setup_bridge_nat() { check_bridge "$BRIDGE" if [ $? -eq 0 ]; then create_bridge fi enable_ip_forward add_filter_rules "$BRIDGE" start_dnsmasq "$BRIDGE" } # need to check $1 arg before setup if [ -n "$1" ]; then setup_bridge_nat ifconfig "$1" 0.0.0.0 up brctl addif "$BRIDGE" "$1" exit 0 else echo "Error: no interface specified." exit 1 fi
3、創建qemu-ifdown-nat腳本,關閉客戶機時調用該腳本,主要完成解除bridge綁定,刪除bridge和清空iptables的NAT規則。
#!/bin/bash # qemu-ifdown-nat script for QEMU/KVM with NAT network mode # set your bridge name BRIDGE="virbr0" if [ -n "$1" ]; then echo "Tearing down network bridge for $1" > /tmp/temp-nat.log ip link set $1 down brctl delif "$BRIDGE" $1 ip link set "$BRIDGE" down brctl delbr "$BRIDGE" iptables -t nat -F exit 0 else echo "Error: no interface specified" > /tmp/temp-nat.log exit 1 fi
4、啟動虛擬機
# qemu-kvm /root/centos6.img \ -m 1024 \ -smp 2 \ -net nic \ -net tap,script=/etc/qemu-ifup-nat,downscript=/etc/qemu-ifdown-nat
5、查看iptables和綁定情況
# brctl show
# iptables -t nat -vnL
注意區別這兩個bridger的不同:
br0是前面提到的網橋模式使用的,它與一個物理上網絡接口eth0綁定;
而virbr0是NAT方式的brdige,它沒有綁定任何物理網絡接口,只是綁定了tap0這個客戶機使用的虛擬網絡接口。
添加iptables規則進行端口映射,讓外網主機也能訪問客戶機
# iptables -t nat -A PREROUTING -p tcp -d 192.168.100.10 --dport 80 -j DNAT --to 192.168.122.28:80