VirtualBox Wireless Bridging

Posted by admin on July 27, 2008 under Tech Tips | 12 Comments to Read

WARNING! THIS POST HAS BEEN MARKED AS OUTDATED!

While there may be useful information still contained within the article, there may be other more relevant articles out on the Internet. Please pay close attention to version numbers of software that this article refers to. If you're not careful, you could break your system if you do not understand what you are doing. If you would like to see this article updated, please contact the site administrator using the Contact page. Thanks!

UPDATE (12/13/2009): The latest versions of VirtualBox 3 have made great improvements in their guest networking options. It is possible to natively bridge guests over your hosts wireless connection “out of the box”, even allowing guests bridge over wireless with DHCP. The suggestions on this post still work fairly well, and will be left up as it has bits of information that is still useful in some scenarios. Please refer to the latest VirtualBox documentation for more help.

ORIGINAL: Here’s a straight forward explanation on how to bridge (well, technically route) your VirtualBox (VB) guest network interface through your host machines wireless network connection. The guest machine will be configured to use a static IP address that is on the same subnet as the wireless network, and will also be able to communicate directly with any device on the network.

First things first, make sure you have a working VB installation and that your guest operating system is configured with a static IP address outside of your DHCP scope. You also need to install the User Mode Linux utilities. In Ubuntu/Debian, they are found in the uml-utilities package.

sudo apt-get install uml-utilities

You also need to ensure your /dev/net/tun interface has the appropriate permissions for the vboxusers group. You can set the permissions manually and should modify the udev rules to have them apllied at boot up.

sudo chown root.vboxusers /dev/net/tun
sudo chmod g+rw /dev/net/tun

Add the following line of code to /etc/udev/rules.d/20-names.rules:

KERNEL=="tun", NAME="net/%k", GROUP="vboxusers", MODE="0660"

Verify /dev/net/tun permissions:

ls -l /dev/net/tun
crw-rw---- 1 root vboxusers 10, 200 2008-04-24 16:34 /dev/net/tun

How does this all work?
The magic of this process is achieved through a technique called “Proxy ARP”. This technique allows a router, in this case your Linux host computer, to intercept Layer-2 ARP packets, and forward them through the host computer and into adjacent networks. Long story short, to the external network, your guest computers MAC address is masked behind the host computers MAC address. The IP address of your guests remain unique to the network and all devices on either side of the host can communicate directly with each other.

Network Assumptions:
I’m going to assume we’re using a very simple setup typical to most small networks and wireless routers. Feel free to adjust the following values according to your own requirements.

Wireless Network ID: 192.168.1.0/24
Wireless Network DHCP Range: 192.168.1.2-100
Wireless Network Default Gateway: 192.168.1.1
Host Computer Wireless Interface: wlan0 (change accordingly)
Host Computer IP: Any IP (Doesn’t matter; You can use DHCP or static)
Guest Computer IP: 192.168.1.200 (Static IP outside DHCP range to avoid conflicts)
Guest Computer DNS: Any DNS server
Guest Default Gateway: 192.168.1.1 (Same value that other devices on the network use)

Quick scripts for the impatient:
To bring up the the tap interface and apply appropriate settings. Run them with root privileges.

sudo tunctl -u $USER
sudo sysctl net.ipv4.ip_forward=1
sudo sysctl net.ipv4.conf.wlan0.proxy_arp=1
sudo sysctl net.ipv4.conf.tap0.proxy_arp=1
sudo ip link set tap0 up
sudo route add -host 192.168.1.200 dev tap0

To tear down the interface and configuration.

sudo sysctl net.ipv4.ip_forward=0
sudo sysctl net.ipv4.conf.wlan0.proxy_arp=0
sudo sysctl net.ipv4.conf.tap0.proxy_arp=0
sudo tunctl -d tap0

Explanation of steps:
Create TAP interface on the host computer (tap0):

sudo tunctl -u $USER

The $USER variable typically maps to your own user account. If not, simply replace $USER with the account that will be running your guest machine; typically your own username.

Enable IP forwarding, which turns your host computer into a router.

sudo sysctl net.ipv4.ip_forward=1

Enable proxy ARP on both the TAP and wireless interfaces.

sudo sysctl net.ipv4.conf.wlan0.proxy_arp=1
sudo sysctl net.ipv4.conf.tap0.proxy_arp=1

Enable the TAP interface.

sudo ifconfig tap0 up

Add a static host route that points to your guest computer via the tap0 interface.

sudo route add -host 192.168.1.200 dev tap0

This is required for your host computer to be able to know how to forward packets to your guest. Ultimately, this is what allows the kernels proxy ARP feature to work.

Edit the VB guest network settings so that Adapter 0 is attached to the Host Interface, and that the Interface Name is set to tap0. The screenshot below is an example of such a configuration.

Finally, turn on the guest system, and if you have already configured it’s IP address, you should be able to ping it. The guest should also be able to ping every other device on the network. Provided you have used the correct DNS and default gateway for your network, you will also have internet access available.

Some community documents claim that you need to use an application called parprouted to accomplish this, but that is not the case. Linux has native proxy ARP support, and as demonstrated here, using it couldn’t be easier. Parprouted provides the same service, however it runs as a daemon and adds host routes for every IP involved in a proxy ARP exchange. Depending on the network size, your routing table can become large very quickly. In addition to your increased routing table entries, the service also sends ARP queries to refresh the addresses every 50 seconds, adding senseless clutter to your network as well. While it’s a useful tool for certain applications, you don’t need it if you’re doing light VB bridging.

Full Script Example: tap-setup.sh
Save the following script to somewhere in your path and modify the appropriate values accordingly. You must run the script with root privileges and supply the appropriate start and stop variable to bring up and tear down the TAP interface.

#!/bin/bash
# tap-setup.sh
 
# Change username accordingly
USER="username_here"
 
tap_up(){
tunctl -u $USER
sysctl net.ipv4.ip_forward=1
sysctl net.ipv4.conf.wlan0.proxy_arp=1
sysctl net.ipv4.conf.tap0.proxy_arp=1
ip link set tap0 up
route add -host 192.168.1.200 dev tap0
}
 
tap_down(){
sysctl net.ipv4.ip_forward=0
sysctl net.ipv4.conf.wlan0.proxy_arp=0
sysctl net.ipv4.conf.tap0.proxy_arp=0
tunctl -d tap0
}
 
if [[ $EUID -ne 0 ]]; then
  echo "This script must be run as root" 1>&2
  exit 1
else
 
case "$1" in
 
start)
	tap_up
	;;
stop)
	tap_down
	;;
*)
	echo "Usage: $0 {start|stop}"
	;;
esac
 
fi
 
exit 0

Multiple Virtual Guest Machines:
More than likely, you will be running more than just one virtual machine. All that is required for this to work is to add an additional static host route for each guest IP address. Add these manually, or simply modify the script to add them for you. Make sure you are choosing IP addresses outside your DHCP address pool to avoid conflicts.

sudo route add -host 192.168.1.200 dev tap0
sudo route add -host 192.168.1.201 dev tap0
sudo route add -host 192.168.1.202 dev tap0
sudo route add -host 192.168.1.203 dev tap0

You can also use a subnet instead of lots of host routes, but you need to be careful in doing so. Adding the entire subnet of your host network (in this case a 24 bit mask) can cause unpredeictable routing behavior. If you know your DHCP pool never extends above the first 100 addresses, you can simply choose to use a smaller subnet matching the higher IP addresses. This way you dedicate these addresses for your guests, and avoid weird routing issues. The following static route example will allow you to use host addresses between .129 and .254.

sudo route add -net 192.168.1.128 netmask 255.255.255.128 dev tap0

Here’s an example of the routing table. Notice that the output is minimal and extremely clean.

route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.1.128 0.0.0.0 255.255.255.128 U 0 0 0 tap0
192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 wlan0
0.0.0.0 192.168.1.1 0.0.0.0 UG 0 0 0 wlan0

You do NOT have to modify your guest or host subnet masks. Leave them to their respective values. The static route is used simply to help keep your host computer organized and routing appropriately to each side of the network.

Additional FAQ’s:
Q: Does my tap0 interface require it’s own IP address?
A: No. The static route to your guests as shown in the above examples use the tap0 interface as the destination. Packets are simply forwarded out the tap0 interface, and layer-3 information is unaltered.

Q: How does my host computer communicate directly with the guest machine?
A: If your wlan0 interface has an IP address, your host computers routing table will take care of everything for you. You will communicate directly with the guest using the wlan0 IP as the source address.

Q: Does my host computer even require an IP address?
A: No. Your wlan0 interface doesn’t need an IP address for any of this to work. Your host computer won’t be able to communicate directly with anything on the network via layer-3, but will act as a transparent bridge. If you just want your guest on the network, remove all IP addresses and routes from your host, then simply create appropriate static routes for both sides of the host directing traffic out each interface. Using the same strategy of splitting your network in half to avoid DHCP scope conflicts, we add two /25 bit routes, the lower half of the block out wlan0, and the upper half out tap0. You also need a default gateway defined if your guests need internet access.

sudo route add -net 192.168.1.0 netmask 255.255.255.128 dev wlan0
sudo route add -net 192.168.1.128 netmask 255.255.255.128 dev tap0
sudo route add default gw 192.168.1.1

route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.1.0 0.0.0.0 255.255.255.128 U 0 0 0 wlan0
192.168.1.128 0.0.0.0 255.255.255.128 U 0 0 0 tap0
0.0.0.0 192.168.1.1 0.0.0.0 UG 0 0 0 wlan0

If you run tcpdump to inspect the magic taking place, you’ll notice ARP exchanges are proxied from a 0.0.0.0 address on your host computer, which is completely acceptable and works well. However, this represents a highly irregular configuration, and if you have multiple host computers doing the same thing you will run into layer-2 issues. Think layer-2 man in the middle attack… but on accident. :-) This example is simply for educational purposes.

Q: Okay, so I know I don’t need it, but what if I want my tap0 interface to have an IP address?
A: You just want to be careful about the subnet mask you assign to the tap0 interface. I really don’t recommend assigning the same subnet mask as your physical interface, because doing so automatically adds a second route for that subnet, and you can run into routing decision and interface selection issues. I recommend using a 32 bit mask host address.

sudo ip addr add 192.168.1.150/32 dev tap0

This is the cleanest way, because the routing table is only adjusted for that single IP address. Proxy ARP again will work perfectly with that address since the host computer has the route. Also, 32 bit mask address assignments on the host will not show ip in the routing table, so don’t worry if you don’t see it with the route command.

Q: I was messing around with the tunctl commands, and now VirtualBox complains and I can’t start the guest machine.
A: You may have created multiple TAP interfaces inadvertently. If you run “tunctl -u $USER” and the output tells you that it has set a TAP interface with a higher numerical value than tap0 (e.g. tap2, tap3, etc), then you simply need to remove them all, and start over.

sudo tunctl -d tap2
sudo tunctl -d tap1
sudo tunctl -d tap0
sudo tunctl -u $USER

If your tunctl output shows you creating tap0, then you should be good to go.

Set ‘tap0’ persistent and owned by uid 1000

Q: Can I use DHCP on my guest computers?
A: Sure! It is possible, and I will cover this in an upcoming article. You simply need to use a DHCP relay utility that converts your DHCP broadcast messages into unicast messages directed to your networks DHCP server. dhcp3-relay is the tool for the job. However, using DHCP complicates things a bit because now your static route will need to be added dynamically. Now THAT sounds like a job for parprouted! Stay tuned.

Bash User Input Validation

Posted by admin on July 20, 2008 under Tech Tips | 15 Comments to Read

If you are writing your latest and greatest Bash shell script that requires careful user input, then you are probably looking for a way to validate or sanitize the input before using the data in commands or subroutines. Here’s an example shell script that reads user input into a variable, which we in turn echo and sanitize into a new variable. The new variable will then be used to perform whatever function is required, in this case displaying the new value.

#!/bin/bash
read -p "Enter variable: " VAR_INPUT
# Sanitize input and assign to new variable
export VAR_CLEAN="`echo "${VAR_INPUT}" | tr -cd '[:alnum:] [:space:]'`"
echo "New Variable: ${VAR_CLEAN}"

Notice, we use the tr command to delete everything except alphanumeric and space characters. You can also perform further manipulation with any other command that comes to mind. For example, if you would like to also limit the number of characters to 10, use the cut command.

export VAR_CLEAN="`echo "${VAR_INPUT}" | tr -cd '[:alnum:] [:space:]' | cut -c -10`"

I like using tr in this fashion, because instead of trying to exclude specific characters, you have the option to enforce a deny all policy, making it easier for you to allow only what you want.

As one of our readers mentioned, there is an even simpler method using only Bash search and replace! This eliminates the need for the execution of tr. In the following example, we sanitize the input allowing for only alphanumeric characters and spaces. I also show how to trim the string length to a maximum character limit of 10.

#!/bin/bash
read -p "Enter variable: " VAR_INPUT
# Sanitize input and assign to new variable
export VAR_CLEAN_1="${VAR_INPUT//[^a-zA-Z0-9 ]/}"
echo "New Variable 1: ${VAR_CLEAN_1}"
# Sanitize input, assign to new variable but limit it to 10 characters
export VAR_CLEAN_2="`echo "${VAR_INPUT//[^a-zA-Z0-9 ]/}" | cut -c -10`"
echo "New Variable 2: ${VAR_CLEAN_2}"

For more information, be sure to check out the man pages for tr and take a look at the Advanced Bash-Scripting Guide. Additional comments and ideas welcome!

Nautilus File Selection

Posted by admin on under Tech Tips | Be the First to Comment

Nautilus, the default file manager used by Gnome desktop environment, sports many features that make every day use a real joy.  Here’s a brief look at the different file selection options available in Nautilus as of version 2.22.3.

Multiple File Selections:
You can select multiple file ranges with multiple “shift+click” combinations.  Other less advanced file managers typically lose focus on previously selected objects if you try to “shift+click” another set of files, but Nautilus handles this quite well.  The following screenshot demonstrates the feature.

multiple file selection

Pattern Selection:
You can select files by patterns in their naming convention.  For example, if you would like to select only files with a particular extension, go to “Edit… Select Pattern“, or use the keyboard shortcut of “Ctrl+S“.  Type in a search pattern such as “*.ogg” and click OK.  The following screenshot shows the pattern select dialog.

pattern select dialog

Type-Ahead Search:
Simply typing text while focused in a Nautilus window will highlight the first matching file or folder name.  Taking this simple concept one step further, if you hit the keyboard Up or Down arrows, Nautilus will focus the next matching object.  Again, this is quite intuitive, since other file managers simply move the focus from the currently selected object to one that is immediately adjacent.  Keep hitting the Up and Down arrows to jump between matching objects.

type ahead search

Standard File Search:
Of course, when you just want to perform a standard file search, you can hit the Search button, or use the “Ctrl+F” keyboard shortcut.  The dialog is pretty simple to understand, and gives you a decent set of options to choose from.

standard file search

Be sure to keep a lookout for many more exciting features from the Nautilus developers as they continue the trend of inovation at its finest.  Hope you found these quick tips useful for your daily Nautilus usage routine.

Audio Conversion with SoundConverter

Posted by admin on under Tech Tips | Be the First to Comment

If you would like to convert your digital audio files to any number of available formats, SoundConverter is exactly what you’ve been looking for.  Not only can you convert audio files in batch, but the application also maintains tag data and has a number of intuitive output options as well.  The following is an excerpt taken from the projects home page.

“The sound conversion application for the GNOME environment. It reads anything the GStreamer library can read (Ogg Vorbis, AAC, MP3, FLAC, WAV, AVI, MPEG, MOV, M4A, AC3, DTS, ALAC, MPC, Shorten, APE, SID, etc…), and writes WAV, FLAC, MP3, and Ogg Vorbis files.”

Installing SoundConverter is a snap as most distributions have a binary package available, or you can build the latest version from source code.  At the time of writing this aricle, Ubuntu 8.04 repositories have made available version 1.0.1, although the project is currently advertising 1.3.1.  Yikes.  A little out of date, but it still works extremely well.

Installing SoundConverter in Ubuntu/Debian

sudo apt-get install soundconverter

If you take a look at the preferences, you’ll also be pleasantly surprised to find a fine set of available options to control the quality of your newly converted files.  Whether you are converting single files or entire collections, this SoundConverter is at your service.

SoundConverter Main Interface SoundConverter Preferences

MP3 Tag Editing in Linux

Posted by admin on July 12, 2008 under Tech Tips | 15 Comments to Read

There’s a number of MP3 tag editors available for the Linux platform, but there are two I use exclusively. EasyTag by far is the easiest and probably the most popular graphical MP3 tag editors available, and I use it a great deal for a majority of my MP3 tagging and renaming functions. For quickly identifying, converting and stripping unwanted tags, I use a python based command line application called eyeD3.

In my experience, EasyTag is the most versatile tag editor available.  Some often wonder why on first launch that all of their tracks are highlighted in red and why it keeps prompting them to save changes that they didn’t make.  This is because by default EasyTag writes both v1.1 and v2.4 tags to files it touches, and will attempt to automatically upgrade all v2.3 tags it has scanned.  This behavior can be adjusted from “Settings… Preferences… ID3 Tag Settings”.  If you have a player that is not compatible with 2.4 tags, then this is the place to change it back to v2.3.  Uncheck the “Automatically convert old ID3v2 tag versions” option if you would like to stop that behavior. Personally, I also remove the option to save ID3v1.x tags.

EasyTag Preferences Window

It’s easy to get a bit overwhelmed with all the options EasyTag has to offer, but the defaults are typically safe to use.  Here’s a couple screenshots of the main user interface.

EasyTag Main Window EasyTag Album Art

Other useful features include the ability to perform bulk file and directory renaming based on the tag data, or even set the tags based on the directory and file naming convention.  You can clear all tags (be careful), and automatically populate tags from CDDB sources such as freedb.org, musicbrainz.org, and gnudb.org.

There are also a slew of command line tag editors each with their own strengths and weaknesses.  The lack of 2.4 support plagues most of them, with the exception of eyeD3.  This application is wicked cool.  Not only does it support v2.4 tags but it also provides a very clean display of current tags using color and bold text.  You can attach album art, add new or modify existing tags, and of course is easily scriptable.