giving up on sound daemons

After whipping up a quick script to kill and restart jackd when my laptop goes into S3 (/etc/pm/sleep.d) I had a revelation: any processes connected to jackd would have to reconnect. This doesn’t happen and sound is just lost. So for jackd to be usable on a laptop they need to support S3 directly and currently in the Debian unstable repositories Jackd doesn’t.

I gave esound a try in place of jack but with totem esd ran the cpu up to 20% for a flash movie which is pretty nuts. It had a noticeable impact on the video playback so esound got uninstalled as quickly as it was installed.

Finally I just fell back to using alsa directly. This actually worked perfectly and I’m not sure why I didn’t just go this route in the first place.

jackd won’t wake up

My last post ended with me describing some troubles getting jackd to wake after my laptop went into S3. I managed to get some debug info out of jack after running it as a dbus service through qjackctl:

ERROR: JackAudioDriver::ProcessAsync: read error, skip cycle
alsa_driver_xrun_recovery
ERROR: ALSA: channel flush for playback failed (File descriptor in bad state)

The CPU utilization at this point goes way up.

A quick search turns up a Debian bug #601008 and bugs filed against a number of other Linux distros. There’s also an open ticket on this issue in Jack’s tracker.

So all the right people know about the issue. The Jack folks even recommend a very sane work around which is manually suspend and resume Jack before and after S3 (hacking suspend / resume manually). I like the idea of jack getting a notification over dbus even more though. That would be very clean. Hopefully we’ll see some action on this soon. Till then I’m looking for a work around.

Getting Started with the Awesome Window Manager

I’ve been a Gnome user for a while now. It’s been good to me but I’m a minimalist and lately it feels like I’ve been spending a lot of time fighting against Gnome. This past week I bought a new SSD for my laptop but instead of just copying my system over to this new disk I decided to rebuild it from scratch and give the Awesome Window Manager a try.

First off Awesome is beyond minimal. Get comfortable on the keyboard if you give this a try. I’m a huge fan, the less I have to touch the mouse the happier I am. The one thing that gave me trouble was getting my sound up and running. Here’s how I got to a fix:

Autostart

Gnome does lots of stuff for you that I didn’t even know was happening. I’m not going to get into the complicated stuff like auto mounting encrypted volumes (that’s for next time). This time It’s the simple stuff: running daemons when you log in.

The Awesome wiki has an Autostart page that was super useful. I grabbed the simple run_once function and put this in rc.lua. This works for starting stuff like xscreensaver:

run_once("xscreensaver","--no-splash")

The problem I ran into with sound was actually related. Squeeze changed the way the jackd server gets started. There used to be an init script that fired it up but no more. Squeeze dropped this behavior and now pushes off the responsibility to user space applications so if you app expects jackd to be running be prepared to start it.

So after installing banshee it freaked out crapping errors all over the console. There were tons of exceptions indicating that lots of the expected Gnome infrastructure was missing but the one that’s actually relevant to why sound wasn’t working is:

Cannot connect to server socket err = No such file or directory
Cannot connect to server socket
jack server is not running or cannot be started

With an error message that says “… or cannot be started” you’d think banshee tried to start jackd but once I started jackd manually the problem went away. So starting jackd when awesome starts up is the answer!

run_once("jackd","-d alsa -d hw:0")

gnome-power-manager and S3 sleep

If you’re on a laptop like me you’ll want gnome-power-manager running. It’s comforting having that battery icon in the tray right? Anyway just throw it in your rc.lua file same as before. Squeeze has great support for my ThinkPad x61s so all of the acpi tool and even the function keys work great for putting my system into S3.

jackd and S3 don’t play nice

The problem I’m dealing with now is that after my laptop wakes up from S3 jackd is hosed. It doesn’t crash outright but I don’t get any sound from Totem or other media players (yeah I prefer Totem over Banshee) so I’ve gotta restart it after I wake up from a suspend.

I’m not sure how to automate this yet. Hopefully it won’t come down to hacking the suspend scripts directly. I’m not even sure where these live … till next time.

managing IPsec packets with iptables

A few weeks back I upgraded my wireless router and added an racoon based IPsec VPN. When I built my first home router / wireless access point a few years ago I did so to get some experience configuring Linux systems and writing firewall rules. I’ve revisited this script a number of times as I’ve added new functionality to the access point and now I’ve added a few rules for IPsec traffic that I figured were worth mentioning here.

First off the script is a “default drop” policy. This means that any packets that don’t match a rule in the firewall ending in a jump to ACCEPT target are dropped. More specifically the default policy for the input, output and forward chains are DROP:

iptables --policy INPUT DROP
iptables --policy OUTPUT DROP
iptables --policy FORWARD DROP

This means that any traffic that doesn’t have an explicit rule that allows it to pass will be dropped. The design goal I had in mind is two write all rules that allow traffic to be as exact as possible so as to not match any unintended traffic. This is as close to mandatory access control for network traffic as I can figure.

Rules for IKE exchange

Hopefully I’ll get a chance to publish the whole script but it’s pretty long (600 lines or so) and needs some cleanup. But the rules I’ve added to allow the racoon server are pretty clean and they’re super useful so here they are:

The first stage of establishing the VPN tunnel is direct negotiation between the client and the access point (the wireless router in this case). The racoon server listens on ports 500 and 4500 and it negotiates directly with the clients racoon server on the same ports. I’m including just the raw rules here but you should wrap these up in functions to keep your scripts clean:

iptables --table filter --append INPUT 
  --in-interface extif                 
  --proto udp                          
  --destination ${PUBLIC_IP}           
  --dport 500                          
  --source  0.0.0.0/                   
  --sport 500                          
  --jump ACCEPT

iptables --table filter --append INPUT 
  --in-interface extif                 
  --proto udp                          
  --destination ${PUBLIC_IP}           
  --dport 4500                         
  --source  0.0.0.0/0                  
  --sport 4500                         
  --jump ACCEPT

iptables --table filter --append OUTPUT 
  --out-interface extif                 
  --proto udp                           
  --destination 0.0.0.0/0               
  --dport 500                           
  --source ${PUBLIC_IP}                 
  --sport 500                           
  --jump ACCEPT

iptables --table filter --append OUTPUT 
  --out-interface extif                 
  --proto udp                           
  --destination 0.0.0.0/0               
  --dport 4500                          
  --source ${PUBLIC_IP}                 
  --sport 4500                          
  --jump ACCEPT
}

Notice that I’ve limited the interface through which the IKE traffic can be accepted and transmitted as well as the IP of the server and the source and destination ports. The loosest part is that of the clients IP which we can’t know in advance. These rules are pretty standard, the interesting ones come next.

Rules for VPN traffic

So now our clients can negotiate security associations with the IKE server. This allows them to get IP addresses on the VPN network but they can’t talk to any other systems on the VPN or the other networks connected to the router (my file server etc).

VPN talking to internal network

To enable this we need FOWARD rules allowing traffic from the VPN network (10.0.2.0/24 that arrives on the interface ‘extif’) to go to the other network connected to the router (10.0.1.0/24 that arrives on the interface ‘wirif’). Typically this would look like:

iptables -A FORWARD         
  --in-interface extif      
  --source 10.0.2.0/24      
  --out-interface wirif     
  --destination 10.0.1.0/24 
  --jump ACCEPT

iptables -A FORWARD         
  --in-interface wirif      
  --source 10.0.1.0/24      
  --out-interface extif     
  --destination 10.0.2.0/24 
  --jump ACCEPT

These rules look pretty tight right? We’ve limited the the networks that can communicate and the interfaces on which the traffic should originate. We can do better though.

I’m particularly wary of the interface on the router that’s connected to the internet. The iptables rules above will allow the traffic we want to allow but it doesn’t require that the traffic from the 10.0.2.0/24 network arrive over the VPN! Theoretically an attacker that isn’t on the VPN could spoof traffic with the VPN IP and exchange packets with the protected 10.0.1.0/24 network. This is bad.

Policy Matching

So we need to add to these rules policy that will require the packets come from, and go to the VPN network through the IPsec tunnel. I’d never even heard of the iptables policy module till I was searching for the answer to this problem. Here’s what I came up with:

iptables --append FORWARD    
  --match policy             
  --dir in                   
  --pol ipsec                
  --mode tunnel              
  --tunnel-dst ${PUBLIC_IP}  
  --tunnel-src 0.0.0.0/0     
  --in-interface extif       
  --source 10.0.2.0/24       
  --out-interface wirif      
  --destination 10.0.1.0/24  
  --jump ACCEPT

iptables --append FORWARD    
  --match policy             
  --dir out                  
  --pol ipsec                
  --mode tunnel              
  --tunnel-dst 0.0.0.0/0     
  --tunnel-src ${PUBLIC_IP}  
  --in-interface wirif       
  --source 10.0.1.0/24       
  --out-interface extif      
  --destination 10.0.2.0/24  
  --jump ACCEPT

This allows the two networks to communicate, but this time it specifies that the packets must travel through the IPsec tunnel as we’d expect.

So now our VPN users can connect to the racoon server on the firewall and can talk to hosts behind the firewall. What’s left? Well my router / firewall also happens to have a dnsmasq server that offers clients DHCP leases and DNS service. The DNS service is particularly useful for those connecting to my storage server so they don’t have to memorize IP addresses.

Offering DNS services to VPN users

VPN users should be able to use the DNS service too (they don’t need DHCP since they get their IPs from racoon). The rules to allow this are very similar to the FORWARD rules above:

iptables --append INPUT     
  --match policy            
  --pol ipsec               
  --dir in                  
  --mode tunnel             
  --tunnel-dst ${PUBLIC_IP} 
  --tunnel-src 0.0.0.0/0    
  --protocol udp            
  --in-interface extif      
  --source 10.0.2.0/24      
  --source-port 1024:65535  
  --destination 10.0.1.1/24 
  --destination-port 53     
  --jump ACCEPT

iptables --append OUTPUT        
  --match policy                
  --pol ipsec                   
  --dir out                     
  --mode tunnel                 
  --tunnel-dst 0.0.0.0/0        
  --tunnel-src ${PUBLIC_IP}     
  --protocol udp                
  --source $10.0.1.1/24         
  --source-port 53              
  --out-interface extif         
  --destination 10.0.2.0/24     
  --destination-port 1024:65535 
  --jump ACCEPT

These rules are pretty self explanatory once you understand the syntax. There’s lots of info in these rules too, we identify the direction of the packets through the ipsec tunnel, the endpoints of the tunnel and the standard IP stuff: source address and port, destination and port as well as the interfaces.

That’s it. 8 rules are all that’s required to allow VPN users to connect, speak to hosts on my internal network and to talk to the DNS server. Using the policy match these rules are pretty exact … if there’s anyway I can make them better let me know in the comments.

madwifi on lenny router

For the past two months my day job has taken over my life. As always, during the height of my insane work schedule my wireless router started acting up. I guess I needed something to break so I had an excuse to take a much needed break from work. I’d pretty much forgotten I even had a wireless access point because it had been so long since it required any attention. I learned a few things that are even worth mentioning here in the process

First off the router I had to fix wasn’t an off-the-shelf 802.11 box. It was actually my first PC Engines router built on the old wrap1e103. It ran Debian Sarge and had an Atheros AR5413 802.11abg which was hot shit when I bought it.

Needless to say there wasn’t any reason to try to fix this system. It’s old, tired and wasn’t experiencing any specific problems except running really slow every once in a while. Best bet was to upgrade.

Almost a year ago I blogged about a VPN gateway that I built on a new PCEngines ALIX platform. I drafted that system to replace this dying Sarge box. Upgrading to Lenny and faster hardware was long over due. It wasn’t all smooth sailing though.

Turns out the madwifi drivers are in flux and the drivers available on Lenny are pretty unstable. Luckily a little Googling turned up someone who already did the research for me and solved this problem! Their fix did the trick and likely saved me a full night of scouring the interwebs. Following these directions the madwifi drivers came up fine in hostap mode and were offering DNS and DHCP through dnsmasq within minutes.

I even had enough time left over to set up the VPN so I can login to my home network while I’m on the road. Since I’ve been traveling every other week all summer this is going to come in handy. The iptables rules for this got pretty interesting so I’ll probably post something about that in the near future.