Welcome to Linux Forums! With a comprehensive Linux Forum, information on various types of Linux software and many Linux Reviews articles, we have all the knowledge you need a click away, or accessible via our knowledgeable members.
Find the answer to your Linux question:
Site Navigation
Linux Forums
Linux Articles
Product Showcase
Linux Downloads
Linux Hosting
Free Magazines
Job Board
IRC Chat
RSS Feeds
Free Publications


Been messing around with jailkit over the weekend and ended up writing a lengthy tutorial on how to use jailkit to securely use certain applications on a machine with a default outbound drop iptables firewall. I use rtorrent as an example because there is no way to predict the outbound port connections a bittorrent app needs to make. While rtorrent is the example, this could be used for numerous applications including a host of penetration testing tools (nmap, etc) as well other p2p programs. Really, it can be used to run any apps that use hard to define outbound connection alongside outbound filtering with iptables. Basically this tutorial shows how to set up the rtorrent program in a chroot jail with jailkit and an rtorrent user and then use iptables to allow the necessary port exceptions based on user matching. This allows you to enjoy the security benefits of egress filtering and still run certain applications that don't do outbound connections in a predictable manner. See my original blog post here: http://nightg0at.blogspot.com/2011/03/using-chroot-jails-for-egress-filtering.html

In a perfect world the importance of egress or outbound firewall filtering would be common knowledge and implemented as a de facto standard alongside other common sense techniques such as anti-viruses, frequent patching, and non-admin user accounts and we would all live in a happy world free from many of the devastating worms and rootkits that constantly plague us.

Now instead of going off on a much long tangent on this, I will simply quote Brian Hatch who I think stated it quite aptly:
When your computer is compromised, you are no longer the innocent party trying to defend yourself, to other machines you have become the attacker. You owe it to others to make outbound attacks more difficult to the cracker or worms that have managed to get onto your machine. http://egress filtering for a healthier internet/

With that out of the way, I think its only fair to concede that egress/outbound filtering, while important, can often come into conflict with a few of the common applications that we use on a daily basis on our  workstations.

One if the most popular applications that suffers from this is bittorrent software.  First off let me say that while this article uses the rtorrent peer to peer application as the example, the methods and approach here are relevant for any application that does not communicate in a predictable enough manner to create targeted iptables port rules.  In fact I can think of numerous penetration and security testing tools that this method could work well for (Nmap just to throw one out there).

Now I admit that the use of bittorrent software can introduce a host of security vulnerabilities even if used for legitimate purposes (and YES there are legitimate uses for bit-torrent), the fact is that it is widely used and trends show that this is not going to change anytime soon.

Too often though, I think otherwise very security minded individuals conclude that the risks of using peer to peer technologies just come with the territory and there is not much else that can be done aside from using DMZs and Virtual Machines, which have the extreme disadvantage of significantly increasing system resource utilization.

Fortunately, the there is a better and more targeted way to address this which helps to mitigate this risk.

First I think it is important to provide a bit more detailed summary of the issue I ran into while attempting to implement an egress filtering solution on my home desktop (I'm using Archlinux, but these methods should work with most Linux distributions).  The problem I ran into with bittorrent is that although it does use a set listening port, this port is used only by remote users connecting into your machine and is may not be the port used by your machine to initiate connections with remote users.  Also, each remote user has their own listening port which is not necessarily the same as yours.

This creates a situation where your outgoing source and destination ports are both random, leaving you without much of a way to effectively deploy an egress filtering firewall and still continue using your application.   Now there are numerous and well documented ways of getting around this by using firewall evasion techniques such as tunneling, there is another method that is often overlooked and not only does it get around this problem, it also gives you an extra layer of security.  This is particularly important when using programs such as bittorrent.

The basic idea behind this method involves running your bittorrent application in a chroot jail using a special user account.  While the security benefits of properly configured chroot jails are significant in and of themselves (and I stress properly configured), running them as a special user allows you to utilize iptables match by user feature.  What this does, is allow us to implement a default drop outgoing firewall rule and add special exceptions for certain users.

So the ultimate solution here is to construct a user who operates exclusively within a chroot jail that allows access to the program needed and nothing else (not even a command shell) and then use the iptables match by owner feature to allow this user and this user only access to the ports needed by the application.  This will let you continue to use your application while at the same time significantly reducing the exposed vulnerability landscape on your machines.

In this tutorial Im going to be using the ncurses based bittorrent client rtorrent as the example since that is what I use as it allows me to easily manage my torrents remotely wherever I happen to be using screen and ssh.
More information about rtorrent can be found at http://libtorrent.rakshasa.no/

To create and manage the chroot environment I will be using the jailkit utilities.  The jailkit homepage describes the suite as a set of utilities to limit user accounts to specific files using chroot() and or specific commands.

Using jailkit greatly simplifies the process of setting up a chroot and can help to prevent some bad chroot mis-configurations.  I suppose this is a good time to issue the standard chroot disclaimer:
Warning! An improperly set up a chroot environment can actually create a security hole!

More information on jailkit as well as documentation for many of its other features can me found at  http://olivier.sessink.nl/jailkit/ 
In particular, I strongly recommend reading the SECURITY CONSIDERATIONS section on the homepage for what you should NOT do while setting up your chroot environment. Its short, so read it.

Lastly, this tutorial assumes you have an iptables firewall in place as well as CONFIG_NETFILTER_XT_MATCH_OWNER kernel option either compiled into your kernel or as a module.

Quick word of warning before I get into the commands:  Due to the small page space Google actually gives to the blog, commands may get word wrapped.  Commands will be separated from each other with extra white space to avoid confusion. I'll be looking for a better medium for my articles soon.

Now on to the actual setup

To verify whether the match owner netfilter module is running, do

lsmod | grep xt_owner

If the output indicates that the module is loaded and running, you're good to go

The next thing to do is get jailkit installed on your machine.
There happened to be a jailkit package already available in the Archlinux AUR repository, but I am aware that some distributions may not have one (Ubuntu for instance).  In that case the source code may downloaded from the jailkit website given above.

Once jailkit is installed and the user match iptables module is running, we can start creating our chroot jail.

First thing, we need to actually make the jail. I call mine rtor but you can call it whatever you like, although I would recommend not calling it by the same name as the user that will be operating inside of it.

mkdir /home/rtor

make it owned by root

chown root:root /home/rtor

then

chmod 0755 /home/rtor

Now we need to create the user and group account for the application we will be using.  I use id 1010 for both user and group but you can use whatever id as long as its not already taken

groupadd -g 1010 rtorrent 
usermod -g rtorrent rtorrent

Now

adduser rtorrent

Obviously, lets use a good password here

We need to tell jailkit what capabilities our jail needs.  For rtorrent I used:

jk_init -v -j /home/rtor netbasics limitedshell terminfo

Others can be found in /etc/jailkit/jk_init.ini
You should see numerous files needed for netbasics limitedshell and terminfo being copied over into your chroot jail

Now that the jail is set up, you need to jail your newly created user

jk_jailuser -m -j /home/rtor rtorrent

This will move the home directory of the user into the chroot jail. The new path should be similar to /home/rtor/home/rtorrent

Using Archlinux I had an issue with the way it copied over the /etc/passwd file and ended up with some values cut out of the users passwd entry.  I suggest checking the newly created /home/rtor/etc/passwd and group file to make sure the entries are sane.
The passwd file should look similar to

rtorrent:x:1010:1010::/home/rtor/./home/rtorrent:/usr/sbin/jk_lsh

Now we need to copy over application we want the user to access.
To do this we much add an entry into the /etc/jailkit/jk_init.ini file pertaining to that application

vi /etc/jailkit/jk_init.ini

For rtorrent, mine looks like this

[rtorrent] 
comment = rtorrent 
paths = /usr/bin/rtorrent

now it can be copied over simply with

jk_init -v -j /home/rtor rtorrent 

This copies the program over as well as any of the libraries the program requires to function

Now whats nice about jailkit, is that just having the rtorrent libraries and binaries installed into the chroot isnt enough to actually let the user run the application.

Jailkit has an added configuration file that specifies what binaries the user is allowed to use.  This way if an attacker manages to break into your chroot she is severely restricted by what she is allowed to run.  To allow the user to actually run rtorrent we must add a section for the user in the /home/rtor/etc/jailkit/jk_lsh.ini file

mine looks like this:

[rtorrent] 
paths= /usr/lib/, /usr/bin/ 
executables= usr/bin/rtorrent

Finally, in order to allow the user rtorrent to attach to the terminal, we must edit
/etc/jailkit/jk_chrootsh.ini and add

[rtorrent] 
env= TERM

If you will be using X apps withing the jail make sure include the DISPLAY, XAUTHORITY variables as well

Now Restart jk_socketd to make sure log messages are transferred

killall jk_socketd 
jk_socketd

Now, theoretically all we should need to do to run the application is to su to the user with the -c switch to instruct it to just run that one command (remember, we are not allowing the user a shell so this is the only way to start the program).

su - rtorrent -c rtorrent

Of course theory is theory and it turns out rtorrent needs a few extra things to get up and running.
Specifically, a .session folder as well as the .rtorrent.rc config file.
We need to copy these into the users home directory within the jail and turn them over to the rtorrent user.
So as root we need to

mkdir /home/rtor/home/rtorrent/.session 
chown rtorrent:rtorrent /home/rtor/home/rtorrent/.session 
cp /path/to/your/.rtorrent.rc /home/rtor/home/rtorrent 
chown rtorrent:rtorrent /home/rtor/home/rtorrent/.rtorrent.rc

If you do not have an .rtorrent.rc file yet, you can get the example one from http://libtorrent.rakshasa.no/browser/trunk/rtorrent/doc/rtorrent.rc#latest and modify it for your needs

now we can try and run the program to verify that its working.

su - rtorrent -c rtorrent

If you are having any problems or you find that you are not switching users, you might want to take a look in your /var/log/auth.log to see if there were any permission errors and /var/log/daemon.log to see if there were any jailkit daemon errors.

Now once you've got this all working, you should be able to run

ps aux | grep rtorrent 

and see a line showing rtorrent running as user rtorrent

Now if thats its working, actually setting the exceptions to your iptables firewall is easy.
This assumes that you have egress/outbound filtering in default drop mode. Meaning there should be a line in the beginning of your firewall rule set that looks like this:

$IPTABLES -P OUTPUT DROP

To add the exceptions we add

$IPTABLES -A OUTPUT -p tcp --sport 1024:65535 -m owner --uid-owner rtorrent -j ACCEPT

to the output chain and

$IPTABLES -A INPUT -p tcp --dport 55555 -j ACCEPT

to the input chain.
Of course set the port number to be your application's listening port. Unfortunately, iptables does not have a feature to specify the incoming destination user so this rule applies globally.
You want to be sure that the packets that are accepted by port 55555 are actually valid. All iptables rules should have something similar to this for both the INPUT and OUTPUT chain to enforce this

$IPTABLES -A INPUT -m state --state INVALID -j DROP
$IPTABLES -A OUTPUT -m state --state INVALID -j DROP

Also, if you need to use distributed hash tables (DHT) or some other UDP based peer exchange technologies to find peers (such as pirate bay and other trackerless bittorrent methods) you will need to include similar rules for UDP based on the UDP port set in your torrent application.

Now update the firewall and you should have a proper egress firewall which allows only your one application user to use the ports needed to connect out and since this user is strictly forbidden from using any other executable, you are able to continue using the application while significantly reducing the possibility of an attacker maliciously controlling your machine.

Unfortunately this nifty setup does leave you with one small problem: getting the torrents in and the downloads out.
Well, theres not really any other way aside from using root to do this.
But considering the added security benefits, this is pretty fair trade off.
as root:

mv ./yourtorrent /home/rtor/home/rtorrent/
chmod rtorrent:rtorrent /home/rtor/home/rtorrent/yourtorrent


Rate This Article: poorexcellent
 
Comments about this article

Comment title: * please do not put your response text here