Documentation/Networking/NAT: Difference between revisions
(→Using) |
No edit summary |
||
Line 32: | Line 32: | ||
* '''I get an error about /dev/net/tun permissions''' | * '''I get an error about /dev/net/tun permissions''' | ||
Currently, you need to run qemu as root to use tun/tap networking | Currently, you need to run qemu as root to use tun/tap networking | ||
== Script == | |||
<code><pre> | |||
#!/bin/sh | |||
# | |||
# Copyright IBM, Corp. 2010 | |||
# | |||
# Authors: | |||
# Anthony Liguori <aliguori@us.ibm.com> | |||
# | |||
# This work is licensed under the terms of the GNU GPL, version 2. See | |||
# the COPYING file in the top-level directory. | |||
# Set to the name of your bridge | |||
BRIDGE=br0 | |||
# Network information | |||
NETWORK=192.168.53.0 | |||
NETMASK=255.255.255.0 | |||
GATEWAY=192.168.53.1 | |||
DHCPRANGE=192.168.53.2,192.168.53.254 | |||
# Optionally parameters to enable PXE support | |||
TFTPROOT= | |||
BOOTP= | |||
do_brctl() { | |||
brctl "$@" | |||
} | |||
do_ifconfig() { | |||
ifconfig "$@" | |||
} | |||
do_dd() { | |||
dd "$@" | |||
} | |||
do_iptables_restore() { | |||
iptables-restore "$@" | |||
} | |||
do_dnsmasq() { | |||
dnsmasq "$@" | |||
} | |||
check_bridge() { | |||
if do_brctl show | grep "^$1" > /dev/null 2> /dev/null; then | |||
return 1 | |||
else | |||
return 0 | |||
fi | |||
} | |||
create_bridge() { | |||
do_brctl addbr "$1" | |||
do_brctl stp "$1" off | |||
do_brctl setfd "$1" 0 | |||
do_ifconfig "$1" "$GATEWAY" netmask "$NETMASK" up | |||
} | |||
enable_ip_forward() { | |||
echo 1 | do_dd of=/proc/sys/net/ipv4/ip_forward > /dev/null | |||
} | |||
add_filter_rules() { | |||
do_iptables_restore <<EOF | |||
# Generated by iptables-save v1.3.6 on Fri Aug 24 15:20:25 2007 | |||
*nat | |||
:PREROUTING ACCEPT [61:9671] | |||
:POSTROUTING ACCEPT [121:7499] | |||
:OUTPUT ACCEPT [132:8691] | |||
-A POSTROUTING -s $NETWORK/$NETMASK -j MASQUERADE | |||
COMMIT | |||
# Completed on Fri Aug 24 15:20:25 2007 | |||
# Generated by iptables-save v1.3.6 on Fri Aug 24 15:20:25 2007 | |||
*filter | |||
:INPUT ACCEPT [1453:976046] | |||
:FORWARD ACCEPT [0:0] | |||
:OUTPUT ACCEPT [1605:194911] | |||
-A INPUT -i $BRIDGE -p tcp -m tcp --dport 67 -j ACCEPT | |||
-A INPUT -i $BRIDGE -p udp -m udp --dport 67 -j ACCEPT | |||
-A INPUT -i $BRIDGE -p tcp -m tcp --dport 53 -j ACCEPT | |||
-A INPUT -i $BRIDGE -p udp -m udp --dport 53 -j ACCEPT | |||
-A FORWARD -i $1 -o $1 -j ACCEPT | |||
-A FORWARD -s $NETWORK/$NETMASK -i $BRIDGE -j ACCEPT | |||
-A FORWARD -d $NETWORK/$NETMASK -o $BRIDGE -m state --state RELATED,ESTABLISHED -j ACCEPT | |||
-A FORWARD -o $BRIDGE -j REJECT --reject-with icmp-port-unreachable | |||
-A FORWARD -i $BRIDGE -j REJECT --reject-with icmp-port-unreachable | |||
COMMIT | |||
# Completed on Fri Aug 24 15:20:25 2007 | |||
EOF | |||
} | |||
start_dnsmasq() { | |||
do_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"} | |||
} | |||
setup_bridge_nat() { | |||
if check_bridge "$1" ; then | |||
create_bridge "$1" | |||
enable_ip_forward | |||
add_filter_rules "$1" | |||
start_dnsmasq "$1" | |||
fi | |||
} | |||
setup_bridge_vlan() { | |||
if check_bridge "$1" ; then | |||
create_bridge "$1" | |||
start_dnsmasq "$1" | |||
fi | |||
} | |||
setup_bridge_nat "$BRIDGE" | |||
if test "$1" ; then | |||
do_ifconfig "$1" 0.0.0.0 up | |||
do_brctl addif "$BRIDGE" "$1" | |||
fi | |||
</pre></code> |
Revision as of 14:53, 31 March 2010
Configuring Network Address Translation (NAT) is a useful way to network virtual machines in a desktop environment (particularly, when using wireless networking). A NAT network will allow your guests to fully access the network, allow networking between your host and guests, but prevent the guests from being directly visible on the physical network.
Overview
To configure a NAT network, first create an /etc/qemu-ifup
script that creates a bridge without any physical ports. Configure that bridge with a static IP address as the gateway for your virtual network. Using iptables, create rules that will masquerade traffic from that bridge to the host network. Finally, run dnsmasq on that bridge interface to act as a DHCP and DNS server for the virtual network.
See the script below for an example of such a script.
Using
First, install the bridge utilities, iptables, and dnsmasq:
On Fedora:
yum install bridge-utils iptables dnsmasq
Copy the qemu-ifup script from this wiki, save it to /etc/qemu-ifup
, and make sure that the file has execute permission/
chmod 755 /etc/qemu-ifup
Now launch qemu with tap networking configuring your guests to use DHCP. They should get a valid IP address and be able to access the network.
qemu -net tap -net nic linux.img
Troubleshooting
- I get an error about /dev/net/tun permissions
Currently, you need to run qemu as root to use tun/tap networking
Script
#!/bin/sh
#
# Copyright IBM, Corp. 2010
#
# Authors:
# Anthony Liguori <aliguori@us.ibm.com>
#
# This work is licensed under the terms of the GNU GPL, version 2. See
# the COPYING file in the top-level directory.
# Set to the name of your bridge
BRIDGE=br0
# Network information
NETWORK=192.168.53.0
NETMASK=255.255.255.0
GATEWAY=192.168.53.1
DHCPRANGE=192.168.53.2,192.168.53.254
# Optionally parameters to enable PXE support
TFTPROOT=
BOOTP=
do_brctl() {
brctl "$@"
}
do_ifconfig() {
ifconfig "$@"
}
do_dd() {
dd "$@"
}
do_iptables_restore() {
iptables-restore "$@"
}
do_dnsmasq() {
dnsmasq "$@"
}
check_bridge() {
if do_brctl show | grep "^$1" > /dev/null 2> /dev/null; then
return 1
else
return 0
fi
}
create_bridge() {
do_brctl addbr "$1"
do_brctl stp "$1" off
do_brctl setfd "$1" 0
do_ifconfig "$1" "$GATEWAY" netmask "$NETMASK" up
}
enable_ip_forward() {
echo 1 | do_dd of=/proc/sys/net/ipv4/ip_forward > /dev/null
}
add_filter_rules() {
do_iptables_restore <<EOF
# Generated by iptables-save v1.3.6 on Fri Aug 24 15:20:25 2007
*nat
:PREROUTING ACCEPT [61:9671]
:POSTROUTING ACCEPT [121:7499]
:OUTPUT ACCEPT [132:8691]
-A POSTROUTING -s $NETWORK/$NETMASK -j MASQUERADE
COMMIT
# Completed on Fri Aug 24 15:20:25 2007
# Generated by iptables-save v1.3.6 on Fri Aug 24 15:20:25 2007
*filter
:INPUT ACCEPT [1453:976046]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [1605:194911]
-A INPUT -i $BRIDGE -p tcp -m tcp --dport 67 -j ACCEPT
-A INPUT -i $BRIDGE -p udp -m udp --dport 67 -j ACCEPT
-A INPUT -i $BRIDGE -p tcp -m tcp --dport 53 -j ACCEPT
-A INPUT -i $BRIDGE -p udp -m udp --dport 53 -j ACCEPT
-A FORWARD -i $1 -o $1 -j ACCEPT
-A FORWARD -s $NETWORK/$NETMASK -i $BRIDGE -j ACCEPT
-A FORWARD -d $NETWORK/$NETMASK -o $BRIDGE -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -o $BRIDGE -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -i $BRIDGE -j REJECT --reject-with icmp-port-unreachable
COMMIT
# Completed on Fri Aug 24 15:20:25 2007
EOF
}
start_dnsmasq() {
do_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"}
}
setup_bridge_nat() {
if check_bridge "$1" ; then
create_bridge "$1"
enable_ip_forward
add_filter_rules "$1"
start_dnsmasq "$1"
fi
}
setup_bridge_vlan() {
if check_bridge "$1" ; then
create_bridge "$1"
start_dnsmasq "$1"
fi
}
setup_bridge_nat "$BRIDGE"
if test "$1" ; then
do_ifconfig "$1" 0.0.0.0 up
do_brctl addif "$BRIDGE" "$1"
fi