Ubuntu, Linksys WUSB600N v1, Dish DVR: whose @#$% idea was this?

I love Ubuntu and give myself a little “mental hug” each day for making the switch from Windows to Linux. But, sometimes, the stuff I want/need to do in Linux just isn’t as obvious to me as I’d like; so, I beat my head against a wall trying to figure it out, until my wife gives me that “walk away from it for awhile so you can maintain the little bit of sanity you have left” look. This particular situation is one of those.

What I wanted to do: I have a Dish Network DVR in my living room that has an ethernet card in it, but I don’t have any ethernet wiring where it is. What I do have is an Ubuntu XBMC HTPC with an on-board ethernet card and a Linksys WUSB600N v1 (the version number is important here, I think), connected to a Linksys WAP610N AP (configured for 5GHz 802.11N only), so it stands to reason that I should be able to share the HTPC’s internet connection with the Dish DVR, right?

Network Diagram

Ok, so it wasn’t. Twice. Once for Ubuntu 9.10 (Karmic) and once for 10.04 (Lucid).

The first thing all good Linux users have to learn is just because it works auto-magically in Windows, doesn’t mean it works the same in Linux. It stings a little, but it’s true. The good news is that there are lots of Linux super-geniuses out there to help and most believe in writing stuff down. If you’re willing to do some Google-ing, most Linux questions/problems can be answered relatively quickly. I had to do a bunch of that.

Task #1: Get 5GHz 802.11n wireless working
When I first plugged my new WUSB600N into my Ubuntu HTPC, Ubuntu recognized it right away, though it couldn’t “see” my 5GHz network (WAP610N). It could see and connect to my 2.4GHz network (WRT54GL) with no problem, so I knew it was time to Google. I found all kinds of stuff–using Windows drivers with NDIS, blacklisting, modprobe–and I tried them all, to the point of complete frustration. Nothing seemed to work, so I decided to install Wicd (and remove Network Manager), because I’d had some luck with it in the past.

Unfortunately, Wicd wasn’t the complete answer: it couldn’t see my 5GHz network, either, so I knew there was more I wasn’t doing. After looking through the logs in /var/log/messages and fumbling through more Google searches for wusb600n ubuntu 11n, I happened across some posts like this one that said I needed to blacklist the rt2800usb driver. Once I’d done that, there were different log messages in /var/log/messages, this time saying that /etc/Wireless/RT3070STA/RT3070STA.dat couldn’t be read. So, I looked for it–the directory didn’t even exist! Now, I’m on to something!

Back to Google again, and it looks like I’m definitely on the right track. I took the example file from this post, and edited it for my network, including the SSID and PSK. Reboot, fingers crossed. Wait a sec…what’s that? Is that a 5GHz network? Yessssssssss! One thing I still don’t understand is that even though I specified all of that stuff in RT3070STA.dat, I still had to do the same in Wicd. I may look into that more later, but for now, it’s time to move on to Task #2.

Task #2: Figure out how to give eth1 an IP address
Unlike Network-Manager (built-in with Ubuntu, Gnome), it didn’t seem like Wicd has a facility to have two interfaces up at once, so I had to figure out a way to give it an IP address outside of Wicd. I could have used /etc/network/interfaces, but since Wicd has the ability to let you run scripts before and after network connections are established, it seemed like a good idea to write a script with ifconfig commands in it to assign eth1’s address:

Wicd

[email protected]:~$ more /etc/router_script
#! /bin/sh

# This script is run by the Wicd daemon after the PC boots
# and connects the the WLAN using wlan0. Once run, eth1
# has an IP address on another subnet and provides DHCP
# addresses for that subnet. All packets are routed from
# eth1 through wlan0.

# give ethernet interface an IP address
ifconfig eth1 172.16.5.1 netmask 255.255.255.252

I made my script executable

[email protected]:~$ sudo chmod 755 /etc/router_script

and after a reboot, I could see that both interfaces were up and had IP addresses.

Task #3: Figure out how to give my DVR an IP address
Unfortunately for me, I can’t manually assign an IP address to my DVR, so I have to provide it one using DHCP. My router is already running dhcpd, but the request would have to go through my HTPC to get there, much like an ethernet-to-wireless bridge or wireless game adapter; the problem is that I need for my HTPC to still be able to actively participate on my wireless network, not just bridge for my DVR.

I Google’d a bunch about this topic, too, and read and tried a bunch of stuff with bridge-utils, but could never make it work. Instead, I started thinking about my HTPC as more of a router, which made it a lot easier for me to find stuff about Linux routers and providing DHCP addresses. Turns out, it was really easy to set up a second DHCP server on my HTPC that only serves addresses from eth1–that means only devices connected to that interface (my DVR) will ever get addresses. I read a good bit about using firestarter, and even tried it successfully, but I soon realized that for my purposes, it was over-kill. More on that later.

All I had to do to set up my new DHCP server in Ubuntu was
[email protected]:~$ sudo aptitude install dhcp3-server

After my install, I edited /etc/default/dhcp3-server to choose DHCP for only eth1, then edited /etc/dhcp3/dhcpd.conf for the network settings I wanted:
[email protected]:~$ more /etc/dhcp3/dhcpd.conf
# DHCP configuration
ddns-update-style interim;
ignore client-updates;

subnet 172.16.5.0 netmask 255.255.255.252 {
option routers 172.16.5.1;
option subnet-mask 255.255.255.252;
option domain-name-servers 172.16.4.1;
option ip-forwarding off;
range dynamic-bootp 172.16.5.2 172.16.5.3;
default-lease-time 21600;
max-lease-time 43200;
}

Note that I purposely picked a really small network mask, since I just needed a couple of usable IP addresses for that network. It would do no harm to pick something larger, like 255.255.255.0.

Since the DHCP server’s assigning a default router, I need to be sure that the router exists before dhcpd tries to hand out addresses. Calling the dhcp3-server init script again from my router_script is a good way to do that, so I added to it:

# restart the DHCP server
/etc/init.d/dhcp3-server restart

With the configuration done, I restarted the DHCP daemon and connected my DVR to my HTPC with a cross-over cable, then ran the broadband utility to see if it could get an address from dhcpd. Cool! That worked, but it says it’s not connected (to the Dish Network servers). Hmmm…guess there’s a Task #4, then.

Task #4: Give the DVR access to the interwebs
Though the DVR has an address and a default gateway/router, that doesn’t mean that the HTPC is willing to let it’s traffic pass through it. For that, I need to get some help from iptables. As I mentioned a bit earlier, I actually installed firestarter during this process because it has internet connection sharing built-in, and can work with dhcpd’s scripts. What I didn’t like about it was that it seemed like “too much”, since all I really wanted to do was pass all traffic from one interface to another–I didn’t really want to restrict anything. So, I removed it and tried to do the same thing with ufw. After fumbling around with that for awhile, it seemed again, that I was wasting my energy–ufw is really just an interface for iptables, so why not just learn enough iptables to do what I want?

By default, the Linux kernel doesn’t allow the forwarding of packets from one interface to another, but you can tell it to allow it using /etc/sysctl.conf. Change one value and reboot.

# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1

Now that the kernel will let us forward packets from one interface to another (eth1 to wlan0), we need to tell iptables to accept the traffic into eth1 (filter table), as well as the return traffic to wlan0, back through to eth1 (nat table) Basically, wlan0 is a NAT interface for whatever is behind eth1. We add to those two tables like this:

[email protected]:~$ sudo iptables --table nat --append POSTROUTING --out-interface wlan0 -j MASQUERADE
[email protected]:~$ sudo iptables --append FORWARD --in-interface eth1 -j ACCEPT

Ok, cool: iptables is all set up, so I rebooted and checked to see if my DVR could find the interwebs. “Not so fast, my friend!” Why doesn’t it work? The DVR has an address and I can ping it from the HTPC…gotta be something with iptables, then, so I checked using the command iptables –list.

[email protected]:~$ sudo iptables --list
Chain INPUT (policy ACCEPT)
target prot opt source destination

Chain FORWARD (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination

My masquerade and forwarding are gone. If I run my two iptables commands again, iptables –list looks like this:

[email protected]:~$ sudo iptables --list
Chain INPUT (policy ACCEPT)
target prot opt source destination

Chain FORWARD (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere

Chain OUTPUT (policy ACCEPT)
target prot opt source destination

And if I “print” to STDOUT, I can see both:

[email protected]:~$ sudo iptables-save
# Generated by iptables-save v1.4.4 on Sat Jul 10 19:16:47 2010
*filter
:INPUT ACCEPT [57221:27498502]
:FORWARD ACCEPT [1163:76309]
:OUTPUT ACCEPT [61462:49085429]
COMMIT
# Completed on Sat Jul 10 19:16:47 2010
# Generated by iptables-save v1.4.4 on Sat Jul 10 19:16:47 2010
*nat
:PREROUTING ACCEPT [852:112868]
:POSTROUTING ACCEPT [10:571]
:OUTPUT ACCEPT [112:7142]
-A POSTROUTING -o wlan0 -j MASQUERADE
COMMIT
# Completed on Sat Jul 10 19:16:47 2010

Seems to me that if I’ve already got this super-awesome script that Wicd calls once wlan0 connects, I should just be able to add my iptables stuff to it, so that every time my HTPC is booted the right rules will be in-place. The final version of my router_script looks like this:

[email protected]:~$ more /etc/router_script
#! /bin/sh

# This script is run by the Wicd daemon after the PC boots and connects
# the the WLAN using wlan0. Once run, eth1 has an IP address on another
# subnet and provides DHCP addresses for that subnet. All packets are
# routed from eth1 through wlan0.

# give ethernet interface an IP address
ifconfig eth1 172.16.5.1 netmask 255.255.255.252

# restart the DHCP server
/etc/init.d/dhcp3-server restart

# add needed rules to iptables
iptables --table nat --append POSTROUTING --out-interface wlan0 -j MASQUERADE
iptables --append FORWARD --in-interface eth1 -j ACCEPT

One last time, I checked my DVR: woo-hoo! It says “connected online” and I can manage it from the dish.sling.com website.

Now what? Guess I need to get a DVR with Slingbox built-in, or buy one of the add-ons. Donations will certainly be accepted.

2 Comments

  1. Jorge July 24, 2013 10:28 am 

    Excellent site you’ve got here.. It’s difficult to find quality writing like yours nowadays.
    I seriously appreciate people like you! Take care!!

  2. Ross Eison August 20, 2013 3:51 pm 

    Thanks very much, Jorge.

Leave a Reply