What does acpi_fakekeyd do?

In setting up SELinux on my Laptop running Squeeze I’m taking a pretty standard approach. First off I’m working off the packages provided in Sid maintained by Russell Coker so most of the hard work has been done. There are a few programs, mostly specific to a laptop that still aren’t in the right domains. We can see this by dumping out the running programs and their domains:

ps auxZ

Determining the “right domain” for a process is a bit harder but there’s a pretty obvious place to start. No daemons should be running in initrc_t!

initrc_t is the domain given to scripts run by the init daemon. That’s pretty much any script in /etc/init.d. If a daemon is running in this domain after startup it likely means that there was no transition rule in place to put it into a domain specific to the daemon. I figured I’d take these on alphabetically and started with acpi_fakekeyd 🙂

A policy for acpi_fakekeyd

All of the power management stuff like acpid runs in the apmd_t so the first thing I tried was running acpi_fakekeyd in this domain. You can go through the trouble of adding the path /usr/sbin/acpi_fakekeydto the apmd_t policy module, rebuilding it and reloading it (which really isn’t that hard these days) or you can take a shortcut like so:

echo "system_u:system_r:apmd_exec_t:s0" | sudo attr -S -s selinux /usr/sbin/acpi_setkeyd

This sets the label on the executable such that when init runs the start up script, the daemon will end up in the apmd_t domain.

Once the label is set you can restart the daemon using run_init, assuming your user is in a domain that can run init scripts (unconfined, admin etc). If all goes well the daemon will end up running in the right domain. I then did what I thought was exercising the domain to see if it would cause any AVCs. This required sending the daemon a few characters using the acpi_fakekey command directly as well as putting my laptop to sleep and into hibernation (see the /etc/acpi/sleep.sh script). There weren’t any AVCs so I concluded the apmd_t domain had all of the permissios that the fakekey daemon needed. I was wrong but we’ll get to that.

acpi_fakekeyd in it’s own domain

I was really expecting a few denial messages so I decided to put acpi_fakekeyd into its own domain with no privileges. The idea was to see some AVCs and to get a feeling for what exactly the daemon does.

The policy module I whipped up is super simple:
acpi_fakekeyd.te

policy_module(acpi_fakekeyd, 0.1)

########################################
#
# Declarations
#
type acpi_fakekeyd_t;
type acpi_fakekeyd_exec_t;
init_daemon_domain(acpi_fakekeyd_t, acpi_fakekeyd_exec_t)

acpi_fakekey.fc

/usr/sbin/acpi_fakekeyd --      gen_context(system_u:object_r:acpi_fakekeyd_exec_t,s0)

No interfaces yet so the acpi_fakekeyd.if file was empty.

After restarting the daemon, checking it’s in the right domain and exercising my ACPI system … there still weren’t any AVCs! Obviously I’m missing something so a bit of research turned up this bug report which explains pretty much everything.

acpi_fakekeyd deprecated

To save you a bunch of reading it turns out that toward the end of the discussion thread (about 8 months after the initial post) it’s identified that the functionality of acpi_fakekeyd is deprecated in kernels after 2.6.24. It seems that the functionality should instead be provided by an in-kernel driver which my laptop (ThinkPad x61s) has.

So why is this daemon installed and running? If I disable it my laptop ACPI still works fine. But the acpi_support package which is required to put my laptop to sleep depends on the acpi_fakekey package. This is likely because the scripts provided by acpi_support call the acpi_fakekey application for backwards comparability on some systems. This doesn’t make much sense to me though since Squeeze ships with a 2.6.32 kernel.

The answer to the question I pose as the title of this post is: It doesn’t do anything on my system. I don’t even need to have it running so I just shut it off. Problem solved I guess, and from a security perspective this is an even better solution that running it in it’s own SELinux domain. If it’s not running, it can’t do any damage. I’d rather be able to remove the package completely though.

Does anyone out there have a laptop that requires this daemon? I’m tempted to file a bug against the package … Anyway on to the next daemon 🙂

SELinux on Squeeze Laptop

I’ve been meaning to play around with the SELinux packages in Squeeze for a while now. Over this past weekend I finally got started. Russell Coker maintains these packages and you can find them on his website under the SELinux tag.

The Debian package for the policy is quite nice. The post install script even enumerates the installed packages and attempts to load the necessary policy modules. This is, of course, limited by a mapping in the post-install script that manually maps SELinux policy packages to the packages installed through dpkg. This will likely be difficult to maintain over time and was the source of the first bug that I ran into.

I’ve written in the past about playing around with the racoon daemon so I’ve got the ipsec-tools and racoon packages on my laptop. The selinux-policy-default post install script however was missing the mapping between the ipsec policy package and the Debian packages. 10 minutes of reading the script was enough to whip up a one-line patch even though I’ve never written a line of perl in my life. Russell picked up the patch and … problem solved!

There’s probably lots of little bugs like this lurking in the policy package most of which won’t be discovered until it’s installed on lots of different systems and configurations (servers, desktops, laptops etc). The Debian community in general doesn’t seem very interested in SELinux so this is probably a very good place to make some contributions. More to come.

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.

Xen Network Driver Domain: How

In my last post I went into the reasons why exporting the network hardware from dom0 to an unprivileged driver domain is good for security. This time the “how” is our focus. The documentation out there isn’t perfect and it could use a bit of updating so expect to see a few edits to the relevant Xen wiki page [1] in the near future.

Basic setup

How you configure your Xen system is super important. The remainder of this post assumes you’re running the latest Xen from the unstable mercurial repository (4.0.1) with the latest 2.6.32 paravirt_ops kernel [2] from Jeremy Fitzhardinge’s git tree (2.6.32.16). If you’re running older versions of either Xen or the Linux kernel this may not work so you should consider updating.

For this post I’ll have 3 virtual machines (VMs).

  1. the administrative domain (dom0) which is required to boot the system
  2. an unprivileged domain (domU) that we’ll call “nicdom” which is short for network interface card (NIC) domain. You guessed it, this will become our network driver domain.
  3. another unprivileged domain (domU or client domain) that will get its virtual network interface from nicdom

I don’t really care how you build your virtual machines. Use whatever method you’re comfortable with. Personally I’m a command line junkie so I’ll be debootstrapping mine on LVM partitions as minimal Debian squeeze/sid systems running the latest pvops kernel. Initially the configuration files used to start up these two domUs will be nearly identical:
nicdom:

kernel="/boot/vmlinuz-2.6.32.16-xen-amd64"
ramdisk="/boot/initrd.img-2.6.32.16-xen-amd64"
memory=256
name="nicdom"
disk=["phy:/dev/lvgroup/nicdom_root,xvda,w"]
root="/dev/xvda ro"
extra="console=hvc0 xencons=tty"

client domain

kernel="/boot/vmlinuz-2.6.32.16-xen-amd64"
ramdisk="/boot/initrd.img-2.6.32.16-xen-amd64"
memory=1024
name="client"
disk=[
    "phy:/dev/lvgroup/client_root,xvda,w",
    "phy:/dev/lvgroup/client_swap,xvdb,w",
]
root="/dev/xvda ro"
extra="console=hvc0 xencons=tty"

I’ve given the client a swap partition and more ram because I intend to turn it into a desktop. The nicdom (driver domain) has been kept as small as possible since it’s basically a utility that won’t have many logins. Obviously there’s more to it than just load up these config files but installing VMs is beyond the scope of this document.

PCI pass through

The first step in configuring the nicdom is passing the network card directly through to it. The xen-pciback driver is the first step in this process. It hides the PCI device from dom0 which will later allow us to bind the device to a domU through configuration when we boot it using xm

There’s two ways to configure the xen-pciback driver:

  1. kernel parameters at dom0 boot time
  2. dynamic configuration using sysfs

xen-pciback kernel parameter

The first is the easiest so we’ll start there. You need to pass the kernel some parameters to tell it which PCI device to pass to the xen-pciback driver. Your grub kernel line should look something like this:

module /vmlinuz-2.6.32.16-xen-amd64 /vmlinuz-2.6.32.16-xen-amd64 root=/dev/something ro console=tty0 xen-pciback.hide=(00:19.0) intel_iommu=on

The important part here is the xen-pciback.hide parameter that identifies the PCI device to hide. I’m using a mixed Debian squeeze/sid system so getting used to grub2 is a bit of a task. Automating the configuration through grub is outside the scope of this document so I’ll assume you have a working grub.cfg or a way to build one.

Once you boot up your dom0 you’ll notice that lspci still shows the PCI device. That’s fine because the device is still there, it’s just the kernel is ignoring it. What’s important is that when you issue an ip addr you don’t have a network device for this PCI device. On my system all I see is the loopback (lo) device, no eth0.

dynamic configuration with sysfs

If you don’t want to restart your system you can pass the network device to the xen-pciback driver dynamically. First you need to unload all drivers that access the device: modprobe -r e1000e. This is the e1000e driver in my case.

Next we tell the xen-pciback driver to hide the device by passing it the device address:

echo "0000:00:19.0" | sudo tee /sys/bus/pci/drivers/pciback/new_slot
echo "0000:00:19.0" | sudo tee /sys/bus/pci/drivers/pciback/bind

Some of you may be thinking “what’s a slot” and I’ve got no good answer. If someone reading this knows, leave me something in the comments if you’ve got the time.

passing pci device to driver domain

Now that dom0 isn’t using the PCI device we can pass it off to our nicdom. We do this by including the line:

pci=['00:19.0']

in the configuration file for the nicdom. We can pass more than one device to this domain by placing another address between the square brackets like so:

pci=['00:19.0', '03:00.0']

Also we want to tell Xen that this domain is going to be a network driver domain and we have to configure IOMMU:

netif="yes"
extra="console=hvc0 xencons=tty iommu=soft"

Honestly I’m not sure exactly what these last two configuration lines do. There are a number of mailing list posts giving a number of magic configurations that are required to get PCI passthrough to work right. These ones worked for me so YMMV. If anyone wants to explain please leave a comment.

Now when this domU boots we can lspci and we’ll see these two devices listed. Their address may be the same as in dom0 but this depends on how you’ve configured your kernel. Make sure to read the Xen wiki page for PCIPassthrough [4] as it’s quite complete.

Depending on how you’ve set up your nicdom you may already have some networking configuration in place. I’m partial to debootstrapping my installs on a LVM partition so I end up doing the network configuration by hand. I’ll dedicate a whole post to configuring the networking in the nicdom later. For now just get it working however you know how.

the driver domain

As much as we want to just jump in and make the driver domain work there’s still a few configurations that we need to run through first.

Xen split drivers

Xen split drivers exist in two halves. The backend of the driver is located in the domain that owns the physical device. Each client domain that is serviced by the backend has a frontend driver that exposes a virtual device for the client. This is typically referred to as xen split drivers [3].

The xen networking drivers exist in two halves. For our nicdom to serve its purpose we need to load the xen-netback driver along with the xen-evtchn and the xenfs. We’ve already discussed what the xen-netback driver so let’s talk about what the others are.

The xenfs driver will exposes some xen specific stuff form the kernel to user space through the /proc file system. Exactly what this “stuff” is I’m still figuring out. If you dig into the code for the xen tools (xenstored and the various xenstore-* utilities) you’ll see a number of references to files in proc. From my preliminary reading this is where a lot of the xenstore data is exposed to domUs.

The xen-evtchn is a bit more mysterious to me at the moment. The name makes me think it’s responsible for the events used for communication between backend and frontend drivers but that’s just a guess.

So long story short, we need these modules loaded in nicdom:

modprobe -i xenfs xen-evtchn xen-netback

In the client we need the xenfs, xen-evtchn and the xen-netfront modules loaded.

Xen scripts and udev rules

Just like the Xen wiki says, we need to install the udev rules and the associated networking scripts. If you’re like me you like to know exactly what’s happening though, so you may want to trigger the backend / frontend and see the events coming from udev before you just blindly copy these files over.

udev events

To do this you need both the nicdom and the client VM up and running with no networking configured (see configs above). Once their both up start udevadm monitor --kernel --udev in each VM. Then try to create the network front and backends using xm. This is done from dom0 with a command like:

xm network-attach client mac=XX:XX:XX:XX:XX:XX,backend=nicdom

I’ll let the man page for xm explain the parameters 🙂

In the nicdom you should see the udev events creating the backend vif:

KERNEL[timestamp] online   /devices/vif/-4-0 (xen-backend)
UDEV_LOG=3
ACTION=online
DEVPATH=/devices/vif-4-0
SUBSYSTEM=xen-backend
XENBUS_TYPE=vif
XENBUS_PATH=backend/vif/4/0
XENBUS_BASE_PATH=backend
script=/etc/xen/scripts/vif-nat
vif=vif4.0

There are actually quite a few events but this one is the most important mostly because of the script and vif values. script is how the udev rule configures the network interface in the driver domain and the vif tells us the new interface name.

Really we don’t care what udev events happend in the client since the kernel will just magically create an eth0 device like any other. You can configure it using /etc/network/interfaces or any other method. If you’re interested in which events are triggered in the client I recommend recreating this experiment for yourself.

Without any udev rules and scripts in place the xm network-attach command should fail after a time out period. If you’re into reading network scripts or xend log files you’ll see that xend is waiting for the nicdom to report the status of the network-attach in a xenstore variable:

DEBUG (DevController:144) Waiting for 0.
DEBUG (DevController:628) hotplugStatusCallback /local/domain/1/backend/vif/3/0/hotplug-status

installing rules, scripts and tools

Now that we’ve seen the udev events we want to install the rules for Xen that will wait for the right event and will then trigger the necessary script. From the udevadm output above we’ve seen that dom0 passes the script name through the udev event. This script name is actually configured in the xend-config.xsp file in dom0:

(vif-script vif-whatever)

You can use whatever xen networking script you want (bridge is likely the easiest).

So how to install the udev rules and the scripts? Well you could just copy them over manually (mount the nicdom partition in dom0 and literally cp them into place). This method got me in trouble though and this detail is omitted from the relevant Xen wiki page [1]. What I didn’t know is the info I just supplied above: that dom0 waits for the driver domain to report its status through the xenstore. The networking scripts that get run in nicdom report this status but they require some xenstore-* utilities that aren’t installed in a client domain by default.

Worse yet I couldn’t see any logging out put from the script indicating that it was trying to execute xenstore-write and failing because there wasn’t an executable by that name on it’s path. Once I tracked down this problem (literally two weeks of code reading and bugging people on mailing lists) it was smooth sailing. You can install these utilities by hand to keep your nicdom as minimal as possible. What I did was copy over the whole xen-unstable source tree to my home directory on nicdom with the make tools target already built. Then I just ran make -C tools install to install all of the tools.

This is a bit heavy handed since it installs xend and xenstored which we don’t need. Not a big deal IMHO at this point. That’s pretty much it. If you want your vif to be created when your client VM is created just add a vif line to its configuration:

vif=["mac=XX:XX:XX:XX:XX:XX,backend=nic"]

Conclusion

In short the Xen DriverDomain has nearly all the information you need to get a driver domain up and running. What they’re missing are the little configuation tweeks that likely change from time to time and that the xenstore-* tools need to be installed in the driver domain. This last bit really stumped me since there seems to be virtually no debug info that comes out of the networking scripts.

If anyone out there tries to follow this leave me some feedback. There’s a lot of info here and I’m sure I forgot something. I’m interested in any way I can make this better / more clear so let me know what you think.

[1] http://wiki.xen.org/xenwiki/DriverDomain
[2] http://wiki.xensource.com/xenwiki/XenParavirtOps
[3] http://wiki.xen.org/xenwiki/XenSplitDrivers
[4] http://wiki.xen.org/xenwiki/XenPCIpassthrough

Xen Network Driver Domain: Why

If you’ve been watching the xen-user, xen-devel or the xen channel on freenode you’ve probably seen me asking questions about setting up a driver domain. You also may have noticed that the Xen wiki page dedicated to the topic [1] is a bit light on details. I’ve even had a few people contact me directly through email and my blog to see if I have this working yet which I think is great. I’m glad to know there are other people interested in this besides me.

This post is the first in a series in which I’ll explains how I went about configuring Xen to bind a network device to an unprivileged domain (typically called domU) and how I configured this domU (Linux) to act as a network back end for other Linux domUs. This first post will frame the problem and tell you why you should care. My next post will dig into the details of what needs to be done to set up a network driver domain.

Why

First off why is this important? Every Xen configuration I’ve seen had all devices hosted in the administrative domain (dom0) and everything worked fine. What do we gain by removing the device from dom0 and having it hosted in a domU.

The answer to these questions is all about security. If all you care about is functionality then don’t bother configuring a driver domain. You get no new “features” and no performance improvement (that I know of). What you do get is a dom0, the most security critical domain, with a reduced attack surface.

Let’s consider an attack scenario to make this concrete: Say an exploit exists in whichever Linux network driver you use. This exploit allows a remote attacker to send a specially crafted packet to your NIC and execute arbitrary code in your kernel. This is a worst case scenario, probably not something that will happen but it is possible. If dom0 is hosting this and all other devices and their drivers your system is hosed. The attacker can manipulate all of your domUs, the data in your domUs, everything.

Now suppose you’ve bound your NIC to a domU and configure this domU to act as a network back end for other domUs. Using the same (slightly far-fetched) vulnerability as an example, have we reduced the impact of the exploit?

The driver domain makes a significant difference here. Instead of having malicious code executing in dom0, it’s in an unprivileged domain. This isn’t to say that the exploit has no effect on the system. What we have achieved though is reducing the effects of the exploit. Instead of a full system compromise we’re now faced with a single unprivileged domain compromise and a denial of service on the networking offered to the other VMs.

The attacker can take down the networking for all of your VMs but they can’t get at their disks, they can’t shut them down, and they can’t create new VMs. Sure the attacker could sit in the driver domain and snoop on you domUs traffic but this sort of snooping is possible remotely. The appropriate use of encryption solves the disclosure problem. In the worst case scenario attacker could use this exploit as a first step in a more complex attack on the other VMs by manipulating the network driver front ends and possibly triggering another exploit.

In short a driver domain can reduce the attack surface of your Xen system. It’s not a cure-all but it’s good for your overall system security. I’m pretty burned out so I’ll wrap up with the matching “How” part of this post in the next day or two. Stay tuned.

[1] http://wiki.xen.org/xenwiki/DriverDomain

QNAP 419P Torrent Client

About 6 months ago I purchased a QNAP 419P NAS. I did a bunch of shopping around and settled on this one largely because it’s Linux based, runs on a low powered ARM cpu, and it’s got a pretty active community. After 6 months of operation I can’t say I’m thrilled, but it hasn’t been a complete disaster either.

I bought it to replace an older P4 system I had Frankensteined into a file server. It had an old ATA133 3ware raid card with ~900GB in raid 5. I had it running rtorrent on the console and serving up files using NFS. Pretty basic and it served my purposes just fine. I started running out of disk space so I picked up the QNAP 419P.

The 419P is a departure from my normal setup since everything is done through a web UI. I also mount my files using CIFS so my room mate can mount a drive too. The 419P will allow you to mount CIFS and NFS but the permissions get all borked up and since Linux support for CIFS is pretty good these days (and Windows support for NFS sucks) I made the switch.

Now on to the reason I’m writing all of this down: the torrent client that QNAP packages for the 419P is terrible. It’s custom so in their defense it’s a lot of software to maintain. That said I’ve got no idea why they’re trying to roll their own. There are so many web front ends to rtorrent++ that there’s no excuse to be building your own half-baked web front end.

Now bad UI I can handle but recently the trackers I used have started white listing clients. Naturally the identification string offered up by the QNAP torrent client isn’t on the list. So what to do? Well this is where the QNAP community comes in: package rtorrent++ and a few web front-ends. This is all described in their forums [1] and the person who did the heavy lifiting here is definitely getting a few paypal bucks from me as a thank you.

So I’ve got rtorrent and the front ends running on my 419P but why am I still annoyed? Well for one thing there’s no authentication for it. QNAP spent some time building their auth system and it’s not half bad but from the looks of it there isn’t a way for application developers / packagers to tie into it. So as it is now the web UI for rtorrent is wide open. Even on my home network I like to have at least a login / password.

There may be a way to tie into the QNAP auth infrastructure, or even a way to require some auth for the rtorrent front end (I’m thinking some sort of apache mod_auth foo to get at the URI). In the mountains of spare time I’ve got I’ll take a quick look (thick with sarcasm). For now I’m just happy to be downloading again thanks to the QNAP community.

[1] : http://forum.qnap.com/viewtopic.php?f=146&t=25165

CIS791: OP browser based project statement

As part of the web security class I’m taking this semester we’re required to put together a project in the last 6-ish weeks of class. The intent is to get us familiar with doing research and formulating a project based on our research. This project is a short one, really I don’t expect to do much more than scratch the surface of a project and show how cool it could be given enough time. Gotta have something interesting to talk about by the end of the semester though but little more. What I don’t want it to be though is a boring project that evaluates some platform or technology.

After doing a bunch of reading about “safe” subsets of Java and JavaScript (which has decidedly no relation to Java) I came to the conclusion that JavaScript is a mess. I love the idea of object capability languages but as close to a safe subset of JavaScript as some have got, I’m pretty sure trying to fix JavaScript isn’t for me.

the OP web browser

After reading the OP web browser paper when it was published back in 2008 I started looking for a reason to play around with it. It’s much more in line with my interests (software architecture as well as security). I especially like the idea of structuring an application using well established architectural concepts from OS design.

Separation is a huge deal in the OS (think separate process address spaces) and in the application space its making a come back. Breaking the browser up into smaller components with well defined interfaces and communication semantics is a great idea. From the security perspective it keeps browser plugins / components from stomping all over each other when one gets compromised. It also is an excellent way to exploit multi core systems. I always get super pissed when my flash player pins one of my CPUs to 100% and the whole browser gets dragged down with it while the other CPU is sitting idle.

potential contribution of this work

What I’m interested in is, of course learning some of the insides of this browser. But specifically I’m interested in the code that is interposed between different components of the browser (aptly named the kernel) and how much like a reference monitor it is or can be. Also the range of security policies it does / could enforce would be very interesting to discuss.

This latter point may actually require some work as it’s likely that OP could enforce any number of policies but that may take some heavy lifting to generalize the enforcement logic (this is pure speculation at this point). This would start looking like the LSM work from the Linux kernel.

When we start talking about policies, the granularity with which policies can be specified becomes important. Subjects and objects in operating systems are well understood for the most part. In a web browser that’s not so clear. The obvious things that come to mind are plugins (including instances of the java script engine) as subjects and components of the DOM and passive user data as objects (cookies, history, saved passwords etc).

Being the SELinux fanboy that I am I’m pretty convinced that a lot of the enforcement can be done in a user space object manager. This gives us the policy language (type enforcement) and policy enforcement point (the Linux kernel) for free but leaves the details of object definition anbd labeling us. It also does nothing for us as far as verifying the expected properties of our reference monitor (complete mediation, tamperproof and analysis for correctness). The design of OP itself will likely be a big help in verifying these properties, but this isn’t something I plan to spend much time on.

Conclusion

So there isn’t much to conclude yet. This is a basic statement of the project I’m undertaking for the rest of this semester, a jumping off point. Hopefully it won’t be too painful but just getting OP to install is a non-trivial task (I’m currently waiting for webkit to compile). I’ve already ran into some quirks in their build system which were pretty easily fixed but there isn’t a mailing list for the project or anything so I’m trying to track down a way to communicate with the project owners beyond sending emails to their personal accounts. We’ll see how receptive they are to suggestions soon enough.

MAC SEED Lab Requirements

It’s been way to long since my last post on this subject. I’ve been rolling around ideas in my head for the elements that will make this Lab good, or bad for that matter. I’m just going to dump them here and refine them as I either as I run across new requirements or I realize that something on this list is a bad idea.

  • The lab task should focus on policy development and what it means to the system as a whole. Integrity and secrecy should both be addressed as part of the lab.
  • Set up of the lab should take no effort on the part of the student. SELinux should already be installed with a known good policy on their systems. The only thing they should be concerned with is writing policy, maybe some code to confine, building the policy, inserting it into the kernel and debugging the output.
  • This lab is intended to reinforce the mandatory access control concept. It’s not an SELinux lab per se. SELinux is just the MAC system used to reinforce the MAC concept. This implies that the Lab shouldn’t be bogged down in the details of managing an SELinux system. Since the labs are intended to be run from a Ubuntu VM we have to be sure SELinux is well supported or already set up on this VM.
  • Following the previous point it’s important that the MAC concepts from the class lecture be incorporated into the lab explicitly. It’s been a while since I took the class that this lab will be taught in so getting a copy of the lecture notes and ensuring I’m reinforcing the right concepts is important. I may need to make suggestions for new topics to be discussed in class but I’ll try to keep changes to the lecture minimal.
  • It would be nice if we could make practical links to a previous lab showing how MAC can defend against specific attacks. There is a lab used in this class showing buffer overflows at work. Showing the code previously developed for the buffer overflow lab thwarted by SELinux would be cool. After walking through an example this would make a good independent task for the students to undertake.
  • Simplicity. Keep the policy developed from getting too scary is a must.
  • The Reference policy by far the policy “language” to use when developing “real” policy but exposure to the raw policy is a must. It may make sense to have students determine the raw policy needed to perform a task and then have them hunt through the reference policy interfaces searching for the right interface to use. That could get ugly though. That may not even be practical since reading the reference policy requires a certain amount of skill. This ones gona take some thought.

I’m going to let these sit for a day or two and do some thinking. Refinements will follow as will a task list derived from the “final” requirements. I know, requirements are never final but I’ll pretend they are when I move on to the tasks … at least until they change. I’m interested in any comments or suggestions that the interwebs may have so let me know what you think.

Mandatory Access Control SEED Lab

As part of the graduation requirements for my Masters degree, SU requires that we either complete a “masters project” or a thesis. Working full time while working towards my degree has really limited my ability to interact with the faculty and get involved with their research. This has mad the thesis option difficult since most of my research interests haven’t lined up with the interests of any professors I’ve been able to interact with. So the project seemed like the way to go especially since I’m really looking forward to graduating soon 🙂

The project that I’ve settled on is a lab that hopefully will be used by my advisor, Dr. Wenliang (Kevin) Du as part of his SEED project. He’s been using these labs in his computer security class and I noticed that, though Dr. Du teaches mandatory access control (MAC) he didn’t have a lab to make the topic concrete. I’ve been working with SELinux for a while now so making this lab it seemed a good fit for me.

It turns out that others have attempted this task in the past but have run into difficulties. I haven’t had a chance to see the previous attempts but Dr. Du couldn’t use their labs because they were very long and very complicated. After hearing this my brain starts to file it away under requirements. The lab has to be “short”: something that a graduate student in computer science / computer engineering can accomplish in a two week period (that’s actually a pretty long lab IMHO).

This initial post is just a quick introduction to the topic and to a new tag on my blog. If you’re interested in following this work, subscribe to my MACSEEDLab tag. I’ll be updating this with some brain storming soon.