Overfeeding the Planet April 15, 2011
Posted by jdstrand in canonical, security, ubuntu.3 comments
I just learned to my chagrin that wordpress.com would update my atom feed every time I clicked the ‘Update’ button in my blog. As a result, I have recently been spamming Planet Ubuntu pretty heavily lately, for which I apologize. Thanks to jcastro and especially nigelb for figuring out that the fix was simply to have the planet use the rss feed instead of the atom feed. While this post/apology could be argued to be yet more spam, I thought I’d pass this information along so others might check their feeds and adjust accordingly. The wiki has been updated for this change, and you can reference the change made to my planet-ubuntu settings in Launchpad if you want to check your settings.
A fun hack: triggered reverse ssh connections for remote access to anywhere November 8, 2010
Posted by jdstrand in security, ubuntu.12 comments
So, like a lot people, I get asked to install Ubuntu on friend’s and family’s computers. I talk to them about what their use cases are and more often than not (by far) I install it on their systems. That’s cool. What is less cool is tech support for said installation. Not that I mind doing it or that there is a lot to do, but what becomes problematic is when they go home and are sitting behind their NAT router from their ISP, and I can’t just connect to them to fix something I forgot or to help them out of a jam. Before I go any farther let me say that what I am going to describe is never done on machines without the owner’s permission and that I am always upfront in that my account on his/her machine is an administrative account that has access to everything on the system (barring any encryption they use, of course). I should also mention that what I am describing is more in the ‘fun hack that other people might like’ category, and not in the ‘serious systems administration’ category. In other words, this is total crack, but it is fun crack. :)
Now, there are a lot of ways to do this, and I have tried some and surely missed many others. Here are a few I’ve tried:
- Giving realtime tech support over the phone
- Giving realtime tech support over some secure/encrypted chat mechanism
- Email support
- OpenSSH access from my machine to theirs, including adjusting their router for port forwarding
- VPN access from their machine to my network, at which point I can OpenSSH to their machine
Rather than going through a comparison of all the different techniques, let’s just say they all have issues: realtime support almost always entails describing some obscure incantation to fix the problem, which is neither confidence inspiring for them and is extremely time consuming. Email is too slow. Routers get reset and straight OpenSSH doesn’t work when they are away from home. VPN access is not bad, especially with the use of OpenVPN client and server certificates. It has the added benefit of being opt-in by the user, and is easy to use with the network-manager-openvpn-gnome package. It is probably the most legitimate form of access, and should be highly considered, especially for corporate environments. The only real issues are that some draconian networks will block this VPN traffic and that my IP happens to change so they have to fiddle with their connection setting. So I started doing something different.
Remotely triggered reverse OpenSSH connections
The basic idea is this: on the client install OpenSSH, harden it a bit, install a firewall so that no one can connect to it, then create a cron job to poll an HTTP server you have access to for an IP address to connect to, then create a reverse SSH connection to that IP address. If this sounds a little shady and a bit like a botnet, well, you’d be right, but again, I did ask for permission first. :)
So, more specifically, on the remote machine (ie, the one you want to administer):
- Install openssh-server and set /etc/ssh/sshd_config with the following:
# Force key authentication (ie, no passwords)
Obviously, you will need to copy your ssh key over to this machine (man ssh-copy-id) before restarting OpenSSH and putting the above into effect.
PasswordAuthentication no
# Only allow logins to my account
AllowUsers me
- Setup a firewall. Eg:
$ sudo ufw enable
- Create some passwordless ssh keys. Eg:
$ ssh-keygen -f revssh.id_rsa
- Create a script to poll some HTTP server, then create the reverse connection (this is an abridged script. I’ve omitted error checking and locking for brevity):
#!/bin/sh
hname=`hostname | cut -f 1 -d '.'`
ip=`elinks -no-home -dump "http://your.web.server/$hname" | head -1 | awk '{print $1}' | egrep '^[1-9][0-9\.]*$'` || {
#echo "Could not obtain ip" >&2
exit 0
}
echo "Connecting to $ip"
# we use StrictHostKeyChecking=no so that keys gets added without prompting
ssh -oStrictHostKeyChecking=no -i $HOME/.ssh/revssh.id_rsa -p 8080 -NR 3333:localhost:22 revssh@"$ip" sleep 30 || true
To remotely administer a machine, create a file on the server with the name of the hostname of the client to have only the external IP address of your network in it, and then the remote client will pick it up and try to setup a reverse ssh connection on port 8080 (usually open even on the most draconian firewalls, but you could also use 53/tcp, 80/tcp or 443/tcp), after which you can connect to the remote machine with something like:$ ssh -t -p 3333 localhost
Caveats
This is hardly perfect. For one thing, the client is polling an HTTP server so it can easily be man-in-the-middled, but that isn’t a big deal because even if the attacker had full knowledge of this technique, all it gives is a connection to OpenSSH on the client, which is configured to only allow connections from ‘me’ and with my ssh key. This could of course be fixed by connecting with HTTPS and using connection.ssl.cert_verify=1 with elinks. Similarly, the HTTP server could be subverted and under attacker control. For the client, this is no different than the MITM attack in that the attacker really doesn’t have much to work with due to the OpenSSH configuration. Also, the client completely ignores the fingerprint of the server it is connecting to, but again, not huge deal because of our OpenSSH configuration on the client, but you will need to be extra careful in checking fingerprints when connecting to the reverse connection.
You need to remember to update your webserver (ie, just remove the file) so the client isn’t always trying to connect to you. Also, it is somewhat inconvenient that when you logout the reverse connection is still there, but instead of using ‘exit’ to logout of the remote machine, use something like: $ kill -9 `ps auxww | grep [s]sh | grep 3333 | awk '{print $2}'`
While is it relatively easy to setup the client, it is somewhat harder to setup the initiating end. First off, you need to have a webserver that can be accessed by the client. Then you need to have the ssh server on your local machine listen on port 8080 (done either via a port redirect or a separate ssh server). You also need to setup a non-privileged ‘revssh’ user (eg, /bin/false for the shell, a disabled password, etc) on your machine. If you are behind a firewall/router you need to allow connections through your firewall to your machine so that the connection to port 8080 from the client is not blocked. Finally, if you remotely administer multiple clients you will want to keep track of their ssh fingerprints, because when you connect to ‘-p 3333 localhost’ they will conflict with each other (most annoying, but workable). I have written a ‘revssh_allow’ script to automate the above for me (not included, as it is highly site-specific). It will: fire up an sshd server on port 8080 that is specially configured for this purpose, adjust my local firewall to open port 8080/tcp from the client, connect to my router to set up the port redirection to my machine, then poll (via ‘netstat -atn | grep “:3333.*LISTEN”‘) for the connection from the client, then remind me how to connect to the client and how to properly kill the connection.
Summary
So yeah, this is a fun hack. Is it something to put in production? Probably not. Does it work for administering friend’s and family’s computers? Absolutely, but I’ll have to see how well it works over the long haul.
Have fun!
Proposed chromium-browser available for Lucid July 8, 2010
Posted by jdstrand in security, ubuntu.add a comment
A proposed security update for chromium-browser on Ubuntu 10.04 LTS is available. If you are able, please test and comment in https://launchpad.net/bugs/602142.
Security update for chromium-browser in lucid-proposed June 10, 2010
Posted by jdstrand in security, ubuntu.add a comment
Fabien Tassin (fta) has prepared a security update for chromium-browser for Ubuntu 10.04 LTS (Lucid Lynx). Please test and provide positive and/or negative feedback in: https://bugs.launchpad.net/ubuntu/+source/chromium-browser/+bug/591474.
This update addresses the following upstream issues:
http://googlechromereleases.blogspot.com/2010/06/stable-channel-update.html.
Thanks Fabien!
Chromium saved passwords May 18, 2010
Posted by jdstrand in security, ubuntu.6 comments
I make use of the Master Password feature in Firefox. While not on by default, when enabled this feature encrypts your Firefox saved passwords on disk, and Firefox will prompt you when you need access to a saved password. When your browser is not running, your passwords are safe. There is a tool to try to brute force your master password if your machine is stolen, but as long as you use a strong password you should be ok (or at the very least, give you time to change them). For more information, see http://kb.mozillazine.org/Master_password.
This is a nice feature, and one which Chromium lacks. If you let Chromium save your passwords, they are stored in the ‘~/.config/chromium/Default/Web Data’ sqlite database. Displaying them is surprisingly easy (this is 5.0.342.9~r43360-0ubuntu2 on Ubuntu 10.04 LTS, newer versions may save them somewhere else):
$ echo 'SELECT username_value, password_value FROM logins;' | sqlite3 ~/.config/chromium/Default/Web\ Data | grep -v '^|$'
username|password
username2|password2
As you can see, in essence your passwords are stored in plain text on your disk (though the ~/.config/chromium directory does have 0700 permissions). I won’t go into the reasons why Google hasn’t implemented this feature yet since people can read the bug, but it seems clear that:
- Google is not going to fix this anytime soon
- People need a way to protect themselves
There are some alternatives with LastPass and RoboForm, but these apparently require you to store your passwords online (I’ve not verified this personally). As it stands, there is not a way to lock your saved passwords, so I encourage Chromium users to encrypt their data using eCryptfs or LUKS full disk encryption so that at least when you turn off your computer the passwords are not readily available. In Ubuntu, you can:
- setup LUKS full disk encryption using the alternate installer
- setup an encrypted home directory in all the Desktop and Server installers (or migrate an existing home directory by using ‘ecryptfs-migrate-home’)
- setup an encrypted private directory using ‘ecryptfs-setup-private’ (if you go this route, you’ll want to move ~/.config/chromium and ~/.cache/chromium into the encrypted directory and use symlinks to point to them)
In this scenario, normal DAC permissions will protect your passwords on multiuser systems (though you’ll need to be careful about the security of backups) and encrypted disks/folders will protect them in the case of theft. As always, please be vigilant about screen locking when you leave your computer while logged in though….
ClamAV update May 7, 2010
Posted by jdstrand in security, ubuntu, ubuntu-server.1 comment so far
Upstream ClamAV pushed out an update via freshclam that crashed versions of 0.95 and earlier on 32 bit systems (Ubuntu 9.10 and earlier are affected). Upstream issued an update via freshclam within 15 minutes, but affected users’ clamd daemon will not restart automatically. People running ClamAV should check that it is still running. For details see:
http://lurker.clamav.net/message/20100507.110656.573e90d7.en.html
AppArmor sVirt security driver for libvirt November 3, 2009
Posted by jdstrand in security, ubuntu, ubuntu-server.Tags: canonical
4 comments
Background
Ubuntu has been using libvirt as part of its recommended virtualization management toolkit since Ubuntu 8.04 LTS. In short, libvirt provides a set of tools and APIs for managing virtual machines (VMs) such as creating a VM, modifying its hardware configuration, starting and stopping VMs, and a whole lot more. For more information on using libvirt in Ubuntu, see http://doc.ubuntu.com/ubuntu/serverguide/C/libvirt.html.
Libvirt greatly eases the deployment and management of VMs, but due to the fact that it has traditionally been limited to using POSIX ACLs and sometimes needs to perform privileged actions, using libvirt (or any virtualization technology for that matter) can create a security risk, especially when the guest VM isn’t trusted. It is easy to imagine a bug in the hypervisor which would allow a compromised VM to modify other guests or files on the host. Considering that when using qemu:///system the guest VM process runs as a root (this is configurable in 0.7.0 and later, but still the default in Fedora and Ubuntu 9.10), it is even more important to contain what a guest can do. To address these issues, SELinux developers created a fork of libvirt, called sVirt, which when using kvm/qemu, allows libvirt to add SELinux labels to files required for the VM to run. This work was merged back into upstream libvirt in version 0.6.1, and it’s implementation, features and limitations can be seen in a blog post by Dan Walsh and an article on LWN.net. This is inspired work, and the sVirt folks did a great job implementing it by using a plugin framework so that others could create different security drivers for libvirt.
AppArmor Security Driver for Libvirt
While Ubuntu has SELinux support, by default it uses AppArmor. AppArmor is different from SELinux and some other MAC systems available on Linux in that it is path-based, allows for mixing of enforcement and complain mode profiles, uses include files to ease development, and typically has a far lower barrier to entry than other popular MAC systems. It has been an important security feature of Ubuntu since 7.10, where CUPS was confined by AppArmor in the default installation (more profiles have been added with each new release).
Since virtualization is becoming more and more prevalent, improving the security stance for libvirt users is of primary concern. It was very natural to look at adding an AppArmor security driver to libvirt, and as of libvirt 0.7.2 and Ubuntu 9.10, users have just that. In terms of supported features, the AppArmor driver should be on par with the SELinux driver, where the vast majority of libvirt functionality is supported by both drivers out of the box.
Implementation
First, the libvirtd process is confined with a lenient profile that allows the libvirt daemon to launch VMs, change into another AppArmor profile and use virt-aa-helper to manipulate AppArmor profiles. virt-aa-helper is a helper application that can add, remove, modify, load and unload AppArmor profiles in a limited and restricted way. Specifically, libvirtd is not allowed to adjust anything in /sys/kernel/security directly, or modify the profiles for the virtual machines directly. Instead, libvirtd must use virt-aa-helper, which is itself run under a very restrictive AppArmor profile. Using this architecture helps prevent any opportunities for a subverted libvirtd to change its own profile (especially useful if the libvirtd profile is adjusted to be restrictive) or modify other AppArmor profiles on the system.
Next, there are several profiles that comprise the system:
- /etc/apparmor.d/usr.sbin.libvirtd
- /etc/apparmor.d/usr.bin.virt-aa-helper
- /etc/apparmor.d/abstractions/libvirt-qemu
- /etc/apparmor.d/libvirt/TEMPLATE
- /etc/apparmor.d/libvirt/libvirt-<uuid>
- /etc/apparmor.d/libvirt/libvirt-<uuid>.files
/etc/apparmor.d/usr.sbin.libvirtd and /etc/apparmor.d/usr.bin.virt-aa-helper define the profiles for libvirtd and virt-aa-helper (note that in libvirt 0.7.2, virt-aa-helper is located in /usr/lib/libvirt/virt-aa-helper). /etc/apparmor.d/libvirt/TEMPLATE is consulted when creating a new profile when one does not already exist. /etc/apparmor.d/abstractions/libvirt-qemu is the abstraction shared by all running VMs. /etc/apparmor.d/libvirt/libvirt-<uuid> is the unique base profile for an individual VM, and /etc/apparmor.d/libvirt/libvirt-<uuid>.files contains rules for the guest-specific files required to run this individual VM.
The confinement process is as follows (assume the VM has a libvirt UUID of ‘a22e3930-d87a-584e-22b2-1d8950212bac’):
- When libvirtd is started, it determines if it should use a security driver. If so, it checks which driver to use (eg SELinux or AppArmor). If libvirtd is confined by AppArmor, it will use the AppArmor security driver
- When a VM is started, libvirtd decides whether to ask virt-aa-helper to create a new profile or modify an existing one. If no profile exists, libvirtd asks virt-aa-helper to generate the new base profile, in this case /etc/apparmor.d/libvirt/libvirt-a22e3930-d87a-584e-22b2-1d8950212bac, which it does based on /etc/apparmor.d/libvirt/TEMPLATE. Notice, the new profile has a profile name that is based on the guest’s UUID. Once the base profile is created, virt-aa-helper works the same for create and modify: virt-aa-helper will determine what files are required for the guest to run (eg kernel, initrd, disk, serial, etc), updates /etc/apparmor.d/libvirt/libvirt-a22e3930-d87a-584e-22b2-1d8950212bac.files, then loads the profile into the kernel.
- libvirtd will proceed as normal at this point, until just before it forks a qemu/kvm process, it will call aa_change_profile() to transition into the profile ‘libvirt-a22e3930-d87a-584e-22b2-1d8950212bac’ (the one virt-aa-helper loaded into the kernel in the previous step)
- When the VM is shutdown, libvirtd asks virt-aa-helper to remove the profile, and virt-aa-helper unloads the profile from the kernel
It should be noted that due to current limitations of AppArmor, only qemu:///system is confined by AppArmor. In practice, this is fine because qemu:///session is run as a normal user and does not have privileged access to the system like qemu:///system does.
Basic Usage
By default in Ubuntu 9.10, both AppArmor and the AppArmor security driver for libvirt are enabled, so users benefit from the AppArmor protection right away. To see if libvirtd is using the AppArmor security driver, do:
$ virsh capabilities
Connecting to uri: qemu:///system
<capabilities>
<host>
...
<secmodel>
<model>apparmor</model>
<doi>0</doi>
</secmodel>
</host>
...
</capabilities>
Next, start a VM and see if it is confined:
$ virsh start testqemu
Connecting to uri: qemu:///system
Domain testqemu started
$ virsh domuuid testqemu
Connecting to uri: qemu:///system
a22e3930-d87a-584e-22b2-1d8950212bac
$ sudo aa-status
apparmor module is loaded.
16 profiles are loaded.
16 profiles are in enforce mode.
...
/usr/bin/virt-aa-helper
/usr/sbin/libvirtd
libvirt-a22e3930-d87a-584e-22b2-1d8950212bac
...
0 profiles are in complain mode.
6 processes have profiles defined.
6 processes are in enforce mode :
...
libvirt-a22e3930-d87a-584e-22b2-1d8950212bac (6089)
...
0 processes are in complain mode.
0 processes are unconfined but have a profile defined.
$ ps ww 6089
PID TTY STAT TIME COMMAND
6089 ? R 0:00 /usr/bin/qemu-system-x86_64 -S -M pc-0.11 -no-kvm -m 64 -smp 1 -name testqemu -uuid a22e3930-d87a-584e-22b2-1d8950212bac -monitor unix:/var/run/libvirt/qemu/testqemu.monitor,server,nowait -boot c -drive file=/var/lib/libvirt/images/testqemu.img,if=ide,index=0,boot=on -drive file=,if=ide,media=cdrom,index=2 -net nic,macaddr=52:54:00:86:5b:6e,vlan=0,model=virtio,name=virtio.0 -net tap,fd=17,vlan=0,name=tap.0 -serial none -parallel none -usb -vnc 127.0.0.1:1 -k en-us -vga cirrus
Here is the unique, restrictive profile for this VM:
$ cat /etc/apparmor.d/libvirt/libvirt-a22e3930-d87a-584e-22b2-1d8950212bac
#
# This profile is for the domain whose UUID
# matches this file.
#
#include <tunables/global>
profile libvirt-a22e3930-d87a-584e-22b2-1d8950212bac {
#include <abstractions/libvirt-qemu>
#include <libvirt/libvirt-a22e3930-d87a-584e-22b2-1d8950212bac.files>
}
$ cat /etc/apparmor.d/libvirt/libvirt-a22e3930-d87a-584e-22b2-1d8950212bac.files
# DO NOT EDIT THIS FILE DIRECTLY. IT IS MANAGED BY LIBVIRT.
"/var/log/libvirt/**/testqemu.log" w,
"/var/run/libvirt/**/testqemu.monitor" rw,
"/var/run/libvirt/**/testqemu.pid" rwk,
"/var/lib/libvirt/images/testqemu.img" rw,
Now shut it down:
$ virsh shutdown testqemu
Connecting to uri: qemu:///system
Domain testqemu is being shutdown
$ virsh domstate testqemu
Connecting to uri: qemu:///system
shut off
$ sudo aa-status | grep 'a22e3930-d87a-584e-22b2-1d8950212bac'
[1]
Advanced Usage
In general, you can forget about AppArmor confinement and just use libvirt like normal. The guests will be isolated from each other and user-space protection for the host is provided. However, the design allows for a lot of flexibility in the system. For example:
- If you want to adjust the profile for all future, newly created VMs, adjust /etc/apparmor.d/libvirt/TEMPLATE
- If you need to adjust access controls for all VMs, new or existing, adjust /etc/apparmor.d/abstractions/libvirt-qemu
- If you need to adjust access controls for a single guest, adjust /etc/apparmor.d/libvirt-<uuid>, where <uuid> is the UUID of the guest
- To disable the driver, either adjust /etc/libvirt/qemu.conf to have ‘security_driver = “none”‘ or remove the AppArmor profile for libvirtd from the kernel and restart libvirtd
Of course, you can also adjust the profiles for libvirtd and virt-aa-helper if desired. All the files are simple text files. See AppArmor for more information on using AppArmor in general.
Limitations and the Future
While the sVirt framework provides good guest isolation and user-space host protection, the framework does not provide protection against in-kernel attacks (eg, where a guest process is able to access the host kernel memory). The AppArrmor security driver as included in Ubuntu 9.10 also does not handle access to host devices as well as it could. Allowing a guest to access a local pci device or USB disk is a potentially dangerous operation anyway, and the driver will block this access by default. Users can work around this by adjusting the base profile for the guest.
There are few missing features in the sVirt model, such as labeling state files. The AppArmor driver also needs to better support host devices. Once AppArmor provides the ability for regular users to define profiles, then qemu:///session can be properly supported. Finally, it will be great when distributions take advantage of libvirt’s recently added ability to run guests as non-root when using qemu:///system (while the sVirt framework largely mitigates this risk, it is good to have security in depth).
Summary
While cloud computing feels like it is talked about everywhere and virtualization becoming even more important in the data center, leveraging technologies like libvirt and AppArmor is a must. Virtualization removes the traditional barriers afforded to stand-alone computers, thus increasing the attack surface for hostile users and compromised guests. By using the sVirt framework in libvirt, and in particular AppArmor on Ubuntu 9.10, administrators can better defend themselves against virtualization-specific attacks. Have fun and be safe!
More Information
http://libvirt.org/
https://wiki.ubuntu.com/AppArmor
https://wiki.ubuntu.com/SecurityTeam/Specifications/AppArmorLibvirtProfile
Serving up Sftp and AppArmor September 9, 2009
Posted by jdstrand in security, ubuntu, ubuntu-server.Tags: canonical
10 comments
Recently I decided to replace NFS on a small network with something that was more secure and more resistant to network failures (as in, Nautilus wouldn’t hang because of a symlink to a directory in an autofs mounted NFS share). Most importantly, I wanted something that was secure, simple and robust. I naturally thought of SFTP, but there were at least two problems with a naive SFTP implementation, both of which I decided I must solve to meet the ‘secure’ criteria:
- shell access to the file server
- SFTP can’t restrict users to a particular directory
Of course, there are other alternatives that I could have pursued: sshfs, shfs, SFTP with scponly, patching OpenSSH to support chrooting (see ‘Update’ below), NFSv4, IPsec, etc. Adding all the infrastructure to properly support NFSv4 and IPsec did not meet the simplicity requirement, and neither did running a patched OpenSSH server. sshfs, shfs, and SFTP with scponly did not really fit the bill either.
What did I come up with? A combination of SFTP, a hardened sshd configuration and AppArmor on Ubuntu.
SFTP setup
This was easy because sftp is enabled by default on Ubuntu and Debian systems. This should be enough:
$ sudo apt-get install openssh-server
Just make sure you have the following set in /etc/ssh/sshd_config (see man sshd_config for details).
Subsystem sftp /usr/lib/openssh/sftp-server
With that in place, all I needed to do was add users with strong passwords:
$ sudo adduser sftupser1
$ sudo adduser sftpuser2
Then you can test if it worked with:
$ sftp sftpuser1@server
sftp> ls /
/bin ...
Hardened sshd
Now that SFTP is working, we need to limit access. One way to do this is via a Match rule that uses a ForceCommand. Combined with AllowUsers, adding something like this to /etc/ssh/sshd_config is pretty powerful:
AllowUsers adminuser sftpuser1@192.168.0.10 sftpuser2
Match User sftpuser1,sftpuser2
AllowTcpForwarding no
X11Forwarding no
ForceCommand /usr/lib/openssh/sftp-server -l INFO
Remember to restart ssh with ‘/etc/init.d/ssh restart’. The above allows normal shell access for the adminuser, SFTP-only access to sftpuser1 from 192.168.0.10 and to sftupser2 from anywhere. One can imagine combining this with ‘PasswordAuthentication no’ or GSSAPI to enforce more stringent authentication so access is even more tightly controlled.
AppArmor
The above does a lot to increase security over the standard NFS shares that I had before. Good encryption, strong authentication and reliable UID mappings for DAC (POSIX discretionary access controls) are all in place. However, it doesn’t have the ability to confine access to a certain directory like NFS does. A simple AppArmor profile can achieve this and give even more granularity than just DAC. Imagine the following directory structure:
- /var/exports (top-level ‘exported’ filesystem (where all the files you want to share are))
- /var/exports/users (user-specific files, only to be accessed by the users themselves)
- /var/exports/shared (a free-for-all shared directory where any user can put stuff. The ‘shared’ directory has ‘2775’ permissions with group ‘shared’)
Now add to /etc/apparmor.d/usr.lib.openssh.sftp-server (and enable with ‘sudo apparmor_parser -r /etc/apparmor.d/usr.lib.openssh.sftp-server’):
#include <tunables/global>
/usr/lib/openssh/sftp-server {
#include <abstractions/base>
#include <abstractions/nameservice>
# Served files
# Need read access for every parent directory
/ r,
/var/ r,
/var/exports/ r,
/var/exports/**/ r,
owner /var/exports/** rwkl,
# don't require ownership to read shared files
/var/exports/shared/** rwkl,
}
This is a very simple profile for sftp-server itself, with access to files in /var/exports. Notice that by default the owner must match for any files in /var/exports, but in /var/exports/shared it does not. AppArmor works in conjunction with DAC, so that if DAC denies access, AppArmor is not consulted. If DAC permits access, then AppArmor is consulted and may deny access.
Summary
This is but one man’s implementation for a simple, secure and robust file service. There are limitations with the method as described, notably managing the sshd_config file and not supporting some traditional setups such as $HOME on NFS. That said, with a little creativity, a lot of possibilities exist for file serving with this technique. For my needs, the combination of standard OpenSSH and AppArmor on Ubuntu was very compelling. Enjoy!
Update
OpenSSH 4.8 and higher (available in Ubuntu 8.10 and later) contains the ChrootDirectory option, which may be enough for certain environments. It is simpler to setup (ie AppArmor is not required), but doesn’t have the same granularity and sftp-server protection that the AppArmor method provides. See comment 32 and comment 34 for details. Combining ChrootDirectory and AppArmor would provide even more defense in depth. It’s great to have so many options for secure file sharing! :)
AppArmor now available in Karmic — testing needed July 15, 2009
Posted by jdstrand in security, ubuntu, ubuntu-server.Tags: canonical
6 comments
After a lot of hard work by John Johansen and the Ubuntu kernel team, bug #375422 is well on its way to be fixed. More than just forward ported for Ubuntu, AppArmor has been reworked to use the updated kernel infrastructure for LSMs. As seen in #apparmor on Freenode a couple of days ago:
11:24 < jjohansen> I am working to a point where I can try upstreaming again, base off of the security_path_XXX patches instead of the vfs patches
11:24 < jjohansen> so the module is mostly self contained again
These patches are in the latest 9.10 kernel, and help testing AppArmor in Karmic is needed. To get started, verify you have at least 2.6.31-3.19-generic:
$ cat /proc/version_signature
Ubuntu 2.6.31-3.19-generic
AppArmor will be enabled by default for Karmic just like in previous Ubuntu releases, but it is off for now until a few kinks are worked out. To test it right away, you’ll need to reboot, adding ‘security=apparmor’ to the kernel command line. Then fire up ‘aa-status’ to see if it is enabled. A fresh install of 9.10 as of today should look something like:
$ sudo aa-status
apparmor module is loaded.
8 profiles are loaded.
8 profiles are in enforce mode.
/usr/lib/connman/scripts/dhclient-script
/usr/share/gdm/guest-session/Xsession
/usr/sbin/tcpdump
/usr/lib/cups/backend/cups-pdf
/sbin/dhclient3
/usr/sbin/cupsd
/sbin/dhclient-script
/usr/lib/NetworkManager/nm-dhcp-client.action
0 profiles are in complain mode.
2 processes have profiles defined.
2 processes are in enforce mode :
/sbin/dhclient3 (3271)
/usr/sbin/cupsd (2645)
0 processes are in complain mode.
0 processes are unconfined but have a profile defined.
Please throw all your crazy profiles at it as well as testing the packages with existing profiles, then file bugs:
- For the kernel, add your comments (positive and negative) to bug #375422
- AppArmor tools bugs should be filed with ‘ubuntu-bug apparmor’
- Profile bugs should be filed against the individual source package with ‘ubuntu-bug <source package name>’. See DebuggingApparmor for details.
Thank you Ubuntu Kernel team and especially John for all the hard work on getting the “MAC system for human beings” (as I like to call it) not only working again, but upstreamable — this is really great stuff! :)
Should I disable AppArmor? July 7, 2009
Posted by jdstrand in security, ubuntu, ubuntu-server.Tags: canonical
16 comments
Short answer: Of course not!
Longer answer:
Ubuntu has had AppArmor1 on by default for a while now, and with each new release more and more profiles are added. The Ubuntu community has worked hard to make the installed profiles work well, and by far and large, most people happily use their Ubuntu systems without noticing AppArmor is even there.
Of course, like with any software, there are bugs. I know these AppArmor profile bugs can be frustrating, but because AppArmor is a path-based system, diagnosing, fixing and even working around profile bugs is actually quite easy. AppArmor has the ability to disable specific profiles rather than simply turning it on or off, yet I’ve seen people in IRC and forums advise others to disable AppArmor completely. This is totally misguided and YOU SHOULD NEVER DISABLE APPARMOR ENTIRELY to work around a profiling problem. That is like trying to open your front door with dynamite– it will work, but it’ll leave a big hole and you’ll likely hurt yourself. Think about it, on my regular ol’ Jaunty laptop system, I have 4 profiles in place installed via Ubuntu packages (to see the profiles on your system, look in /etc/apparmor.d). Why would I want to disable all of AppArmor (and therefore all of those profiles) instead of dealing with just the one that is causing me problems? Obviously, the more software you install with AppArmor protection, the more you have to lose by disabling AppArmor completely.
So, when dealing with a profile bug, there are only a few things you need to know:
- AppArmor messages show up in /var/log/kern.log (by default)
- AppArmor profiles are located in /etc/apparmor.d
- The profile name is, by convention, <absolute path with ‘/’ replaced by ‘.’>. E.g ‘/etc/apparmor.d/sbin.dhclient3’ is the profile for ‘/sbin/dhclient3’.
- Profiles are simple text files
With this in mind, let’s say tcpdump is misbehaving. You can check /var/log/kern.log for entries like:
Jul 7 12:21:15 laptop kernel: [272480.175323] type=1503 audit(1246987275.634:324): operation="inode_create" requested_mask="a::" denied_mask="a::" fsuid=0 name="/opt/foo.out" pid=24113 profile="/usr/sbin/tcpdump"
That looks complicated, but it isn’t really, and it tells you everything you need to know to file a bug and fix the problem yourself. Specifically, “/usr/sbin/tcpdump” was denied “a” access to “/opt/foo.out”.
So now what?
If you are using the program with a default configuration or non-default but common configuration, then by all means, file a bug. If unsure, ask on IRC, on a mailing list or just file it anyway.
If you are a non-technical user or just need to put debugging this issue on hold, then you can disable this specific profile (there are others ways of doing this, but this method works best):
$ sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.tcpdump
$ sudo ln -s /etc/apparmor.d/usr.sbin.tcpdump /etc/apparmor.d/disable/usr.sbin.tcpdump
What that does is remove the profile for tcpdump from the kernel, then disables the profile such that AppArmor won’t load it when it is started (eg, on reboot). Now you can use the application without AppArmor protection, but leaving all those other applications with profiles protected.
If you are technically minded, dive into /etc/apparmor.d/usr.sbin.tcpdump and adjust the profile, then reload it:
$ sudo <your favorite editor> /etc/apparmor.d/usr.sbin.tcpdump
$ sudo apparmor_parser -r /etc/apparmor.d/usr.sbin.tcpdump
This will likely be an iterative process, but you can base your new or updated rules on what is already the profile– it is pretty straightforward. After a couple of times, it will be second nature and you might want to start contributing to developing new profiles. Once the profile is working for you, please add your proposed fix to the bug report you filed earlier.
The DebuggingApparmor page has information on how to triage, fix and work-around AppArmor profile bugs. To learn more about AppArmor and the most frequently used access rules, install the apparmor-docs package, and read /usr/share/doc/apparmor-docs/techdoc.pdf.gz.
1. For those of you who don’t know, AppArmor is a path-based (as opposed to SELinux, which is inode-based) mandatory access control (MAC) system that limits access a process has to a predefined set of files and operations. These access controls are known as ‘profiles’ in AppArmor parlance.