2008/08/10

XBOX Wireless By Proxy (Through Ubuntu Desktop)

I found myself at Best Buy today, and decided to splurge on an XBOX. I didn't really do any research in advance, though -- from playing other XBOXes, I knew that the XBOX was wireless capable, but I wrongly assumed that this capability was native. When I went to adjust the wireless settings on the new device, I was at first puzzled and then disappointed when wireless options were greyed out. A quick Google search suggested that a separate wireless adapter was needed, and being the stubborn prick that I am, there's no way I'm doling out more cash to Microsoft for such a thing (I had a hard enough time coming to terms with the donation I've already made).

At the same time, however, I don't want a wire running across the room from my XBOX to my router. It so happens that I do have my TV situated next to my desk, where my Ubuntu desktop is picking up a wireless signal. So, I decided to run my XBOX to my desktop, and let it feed off of the wireless connection that my desktop already has. This is obviously by no means an ideal network topology, but it's a good solution given the logistics of my situation.

So, I did a bit of searching on how to set up an ubuntu station as a router (like most things, this is not specific to Ubuntu, but the trends indicate that Ubuntu as a search term provides fresher documentation. And, of course, what I'm doing isn't unique to the XBOX either -- in general, the goal is to simply run a wireless-connected linux station as a DHCP/DNS server).

The planned layout looks like this: from the Ubuntu desktop, connect out to wireless network on private network 192.168.1.0 (as 192.168.1.something, DHCP assigned by the wireless access point, on device wlan1), and then serve to a second private network 192.168.2.0 (as gateway 192.168.2.1 on device eth0) . Of course, and private network spaces you would like to choose would work. The XBOX would then connect to the latter private network through a cross-connect cable using DHCP (though I hear that with many modern NICs crossover capability is automatic, and doesn't require a crossover cable -- whatever, I have some lying around anyways, but I could perhaps try it without one sometime).

Now, if there's one thing that I loathe, it's touching wireless on Linux. As much as I hate NetworkManager, I find it to be less offensive than mucking around in /etc/network/interfaces and /etc/wpa_supplicant.conf, and then running down... up... still now working?... down... up... every time I want to touch my wireless settings. Now, when I remove eth0 and wlan1 from from /etc/network/interfaces to allow NetworkManager to manage things, it decides that a hardline is best, sees that eth0 is connected to something (even though it's not something that routes out to the internet), and doesn't even attempt to establish a wireless connection... bleh. I need to hack with my hardline, but I can let NetworkManager take control of the wireless. Now, one nice thing about NetworkManager is that it will try to manage each of the devices -- and only those devices -- that aren't configured manually in /etc/network/interfaces. So, the ideal solution for me was to leave eth0 as a managed device in /etc/network/interfaces, and then NetworkManager takes care of the wireless for me automatically. And so, I put the following as my /etc/network/interfaces configuration:
auto lo
iface lo inet loopback

iface eth0 inet static
address 192.168.2.1
network 192.168.2.0
netmask 255.255.255.0
broadcast 192.168.2.255
pre-up iptables-restore < /etc/iptables.rules
This is about as simple as it gets. Only the address and netmask lines are required (the rest is implied if absent), but I like to include the full thing, if only to document the complete syntax for my own future reference (I find that finding the syntax for things to put in this file is... challenging). The pre-up line we'll discuss in a bit.

Okay, so that's the second network. Now, we need to actually do something with it. First, we need to route the packets. So, in /etc/sysctl.conf, we add/uncomment the line net.ipv4.ip_forward=1 (according to the docs I read, the exact name of this field can vary between distros). Because this only affects the setting for the next time this config file is referenced, we also want to manually set it for right now by running
$ sudo sysctl net.ipv4.ip_forward=1
Once forwarding is enabled, we need to tell iptables to do the actual forwarding magic. For our example, these are the lines to achieve that:
sudo iptables -t nat -A POSTROUTING -s 192.168.2.0/24 -o wlan1 -j MASQUERADE
sudo iptables -A FORWARD -s 192.168.2.0/24 -o wlan1 -j ACCEPT
sudo iptables -A FORWARD -d 192.168.2.0/24 -m state --state ESTABLISHED,RELATED -i wlan1 -j ACCEPT
We want to save this for future use. To do so, we:
$ sudo sh -c "iptables-save > /etc/iptables.rules"
To save our current iptables configuration for later. Remember that pre-up line that we included with our eth0 definition above? Here's that file that we ask it to read from.

Okay. With this we can actually get a machine on the secondary network to ping the outside world, but we still haven't touched DNS and DHCP. Whelp, these can both be addressed together, it turns out, with dnsmasq. In Ubuntu, simply:
$ sudo apt-get install dnsmasq
From here, we just go ahead and edit /etc/dnsmasq.conf to uncomment/add the following changes we need:
listen-address=192.168.2.1
dhcp-range=192.168.2.50,192.168.2.100,12h
The first line states that dnsmasq should listen on 192.168.2.1 (our secondary network). I tried using, alternatively, interface=eth0, which probably should work, but it didn't seem to work when I tried it the first time. The second line here states that this machine should hand out DHCP addresses in the 50-100 range (a fairly arbitrary selection of addresses in this network range). From here, it's a simple
$ sudo /etc/init.d/dnsmasq restart
And we're up and running. Of course, at some point along the line here we need to re-up the interface with:
$ sudo ifup eth0
Additional commands to be aware of (in case you aren't already) are ifconfig (for viewing the configured interfaces) and ifdown (the opposite of ifup, obviously).

So that's it. We connect our XBOX (or other device) via crossover cable to this device, and it should "just work". In particular, the XBOX settings should appear as:
address 192.168.2.53 (the last octect may vary, since it's dynamically assigned)
netmask 255.255.255.0
gateway 192.168.2.1
dns server 192.168.2.1
I haven't tested restarting my machine since I've put these settings in place, but I'm pretty sure it should all come back up as expected. Also, I'm sure that having anyone else replay these exact steps on their machine won't necessarily work flawlessly, but hopefully this serves at least as a starting point. For additional reference, here are some articles that I used as background for this little project:

https://help.ubuntu.com/community/Router
http://ubuntuforums.org/showthread.php?t=376283
http://ubuntu.wordpress.com/2006/08/02/local-dns-cache-for-faster-browsing/
https://help.ubuntu.com/community/Dnsmasq
https://help.ubuntu.com/community/UbuntuWirelessRouter

No comments: