I spent a few days configuring my wireless network card to allow KMV guests to act as if they have a bridged network interface rather then NAT.
As it turns out you can not simply bridge your wireless card with brctl as you do a wired NIC and this type of network configuration is not supported in virt-manager. It also so happens you do not need parprouted either.
Use what is referred to as Proxy arp
Note: Although this how to was written for KVM, it should work with other protocols / guests as well. VirtualBox will configure all this automagically.
1. Install tunctl (Fedora / Centos) or uml-utilities (Debian / Ubuntu).
yum install tunctl
sudo apt-get install uml-utilities
2. Secure the tun. I prefer to configure the tun to be owned by root.kvm by adding the following to /etc/rc.local.
/bin/chown root.kvm /dev/kvm
/bin/chown -R root.kvm /dev/net
/bin/chmod -R 660 /dev/net
3. Bring up a tap device. This command must be run as root. Change “bodhi” to you user name.
tunctl -u bodhi
4. Enable arp proxy. Again these commands are run as root.
echo 1 > /proc/sys/net/ipv4/ip_forward
echo 1 > /proc/sys/net/ipv4/conf/wlan0/proxy_arp
echo 1 > /proc/sys/net/ipv4/conf/tap0/proxy_arp
5. Configuration. This step is a bit complex.
A : Network. Assume a network of 192.168.0.0/24 with a router (used for DNS) at 192.168.0.1
B : Host. Assume the wireless card is wlan0.
The IP of the host does not matter, although we need to know it to configure the guest.
IP Host = 192.168.0.10
The IP address of the host will become the default gateway for the guest.
C : Tap. We do not assign a ip address to the tap, rather we assign a route on the host. This route will become the ip address of the guest.
route = 192.168.0.20
D: Guest. DHCP does not work so you will need to manually configure a static IP address of the guest.
IP address = route we assign to the tap, in this example 192.168.0.20
Netmask = 255.255.255.0
Default gateway = 192.168.0.10
DNS (nameserver) = 192.168.0.1
With that background …
On the host, set a route to be used by the tap / guest. Again, these commands need to be run as root.
ip link set tap0 up
route add -host 192.168.0.20 dev tap0
6. Now start the guest using the tap for networking, For KVM (note, unlike the previous examples, kvm is run as a user, not root !).
kvm -hda ~/fedora.qcow2 -net nic -net tap,ifname=tap0,script=no -usb -usbdevice tables
The guest will boot, but will not obtain an IP address via DHCP. Log into the guest and configure manually configure a static IP for the guest. This varies by guest, for linux guests (running gnome) you may use network manager if you wish :
Right click the NetworkManager icon -> Edit Connections …
Select “Auto eth0″ -> Click the Edit button on the Left.
In the IPv4 tab :
Change Method to “Manual”
In the “Address” section click the “Add button”
Address = 192.168.0.20 <- From the route command.
Netmask = 255.255.255.0
Gateway = 192.168.0.10 <- IP address of the host.
In the DNS Servers box use 192.168.0.1
Click the "Apply" box.
That's it , it should be working.
Extra Credit
For extra credit we can firewall the guest. This is may not be necessary if you are behind a LAN, but it is fun anyways.
Run these commands on the HOST.
# Allow all outgoing traffic from the guest to the LAN or internet.
iptables -A FORWARD -i tap0 -o wlan0 -j ACCEPT
# Allow only related / established connections fron the LAN/internet to the guest
iptables -A FORWARD -i wlan0 -o tap0 -m –state RELATED,ESTABLISHED -j ACCEPT
# As an example, allow connections to port 80 (Apache) to the guest.
iptables -A FORWARD -i wlan0 -o tap0 -p tcp –dport 80 -j ACCEPT
# Drop all other traffic
iptables -A FORWARD -i wlan0 -o tap0 -j DROP
this worked for my VMware installation as well. Super job!
I think that you forgotten a “0″:
iptables -A FORWARD -i tap0 -o wlan -j ACCEPT –> Wrong
iptables -A FORWARD -i tap0 -o wlan0 -j ACCEPT –> Correct
You are correct, updated.
Hope it is otherwise working for you.
LINUX bridge is a way to connect two Ethernet segments together in a protocol independent way.Packets are forwarded based on Ethernet address, rather than IP address (like a router). Since forwarding is done at Layer 2, all protocols can go transparently through a bridge.
FWIW, with Ubuntu 10.10, and qemu (think its 12.5)…
Could not get the following from your example above to be accepted:
# Allow only related / established connections fron the LAN/internet to the guest
iptables -A FORWARD -i wlan0 -o tap0 -m –state RELATED,ESTABLISHED -j ACCEPT
Did get the two following possibilities accepted:
sudo iptables -A FORWARD -i eth0 -o tap0 -m conntrack –ctstate ESTABLISHED,RELATED -j ACCEPT
(replaced “-state” with “conntrack –ctstate)
and
sudo iptables -A FORWARD -i eth0 -o tap0 -m state –state ESTABLISHED,RELATED -j ACCEPT
(replaced “-state” with “state –state”)
I haven’t yet obtained access to the outside world from guest, nor access to guest from outside world, only between guest and host. But I expect I’ll eventually figure it out, or figure out what else I may have done incorrectly. Also not yet sure what difference, if any, there is between –state and –ctstate…
Pingback: Research group digest – ulno.net
Hi
I’m stuck at step number 6. I use virt-manager to start my kvm’s and not cli. I can’t seem to figure out how to get the vm to use tap as you have stated. Please could you provide some guidance? Also tap does not come up automatically on restart – how do I keep settings?
@majikins with virt-manager you do not use a tap at all, you configure your network interface via virt-manager and use the bridged option.
Looks something like this : http://www.linux-kvm.com/sites/default/files/virt-manager-bridged.png
This worked perfectly on Debian (squeeze)! The only step I did differently was that I used openvpn to create the tap device:
openvpn –mktun –dev tap0 –user
Thanks for the info!
@Nathan: Glad it worked for you, thank you for the tip.