Application-wise network filtering on Linux? [2. Update]

Tux
Recently I was asked if Linux supports application-wise network filters. Despite the debatable sense behind such a function I was interested in the technical possibilities and current implementations. It turned out that there is no currently active project atm.

Background

Application-wise network filtering is a controversial topic: in Windows such frameworks are quite common (ZoneAlarm, Norton Internet Security) and are the nightmare of every Help Desk. Additionally they are designed to interact with the user who most often has no idea – and they tend to spread fear among the users to show how “effective” they are while there is nothing to fear.

For Linux it was often mentioned that application-wise network filters are not needed since Linux cannot be infected as easily as Windows. However, I could imagine other tasks: think for example of computers you offer to your children or to customers, locked down with programs like KDE’s Kiosk. In such cases you would also like to make sure that no one can simply copy an executable and try to launch it to access the Internet somehow. And there the possibility of application-wise network filtering would come in handy.

User friendly solutions

So I searched a bit for existing implementations. It turned out there are three projects which once tried to implement this task together with a handy GUI: Systrace, Tuxguardian and Program Guard.

While the scope and the technical details of all attempts vary, they all share that an additional kernel module is needed to get them running. Together with the module you also get a user space program which lets you control which application is allowed to access the Internet and which is not. So they all fulfil the mentioned needs.
However, all these projects seem to be dead more or less – no one of the mentioned programs had any update in the last 12 months, meaning that they are very like abandoned. It is unlikely that you can compile the over a year old modules on today’s kernels, making these programs useless.

Theoretical solutions

But at least in theory there is also another way: I was told that a application-wise network filtering can also be achieved with SELinux. It does require a certain amount of own work (creating new policies and so on), but it is possible. Also there is work ongoing to make it easier to easily close down a system in this regard.
So while it is supposed to be possible it cannot be compared in terms of user friendliness to the already mentioned solutions in any way.

AppArmor, another well known security solution for Linux, can only block programs it was configured for before. Therefore any new application can do what it want. But yet again there are at least some thoughts that it would be nice to have only “trusted” applications to access the Internet.

The last program I found was LIDS – as SELinux it is also an implementation of a Mandatory access control and therefore should be able to lock down a computer appropriate.
But while there is a LIDS patch available for the kernel 2.6.21 the documentation is outdated and I wasn’t able to figure out if LIDS can really be used for the mentioned filtering.

Conclusion

So the bottom line is that there is currently no easy way to implement application-wise network filtering afaik. It can be discussed how useful it is anyway, but from the technical point of view this is sad.

Update:
Many users responded to the here raised question. The most notable comments are:

  • Kai mentioned that iptables can filter by commands, but also pointed out that this feature was dropped.
  • SMP also suggested iptables, this time pointing to the possibility of filtering by UID as a workaround.
  • Chad Sellers posted a link to Tresys which offer a solution based on SELinux.

Thanks for all these helpful and interesting comments, I really appreciate that.

2. Update:
Two other ways of filtering were proposed:

  • A possible solution could be a system monitoring the PIDs and UIDs dynamically to create iptables filter rules related to the appropriate PID.
  • Marian suggested NuFW, a Netfilter/Iptables based filter extension which requires a user to authenticate and therefore is capable of filtering based on different users and protocols. NuFW is more designed for corporate environments but nevertheless is an interesting solution.

Special thanks for insightful and helpful comments to blackhole, SM and SMP!

38 thoughts on “Application-wise network filtering on Linux? [2. Update]”

  1. Some time ago, when the first Adobe Reader version with JavaScript functionality was released for x86 Linux, I came across a forum post describing how to use iptables/netfilter in a relatively simple way (at least from the perspective of a power user😉 to prevent Adobe Reader from establishing network connections:

    iptables -A OUTPUT -m owner –cmd-owner acroread -j DROP

    The “ipt_owner” module is included in e.g. the Fedora 7 kernel package but regrettably, most of the module’s functionality is broken for SMP kernels according to its “–help” text, so users of dual-core CPU systems (amongst others) are out of luck.

  2. > most of the module’s functionality is
    > broken for SMP kernels according to its “–help” text

    But the question is, will this be addressed? iptables is actively maintained.

  3. I’ve searched a bit, and while I can’t do any queries in the project’s bugtracker (http://bugzilla.iptables.org/), I’ve stumbled upon a changelog entry for the mainline kernel – http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=34b4a4a624bafe089107966a6c56d2a1aca026d4 – which suggests that the functionality I mentioned is gone (since August 2005) and that the user-space tool /sbin/iptables just hasn’t been updated accordingly yet.

  4. The ability to do packet filtering by application is built into the Linux kernel.

    You run an application under a particular UID and in iptables you use the mark target to mark packets from a user and then you can filter the marked packets accordingly.

    eg:
    iptables -A OUTPUT -m owner –uid-owner -j MARK

    See http://lists.kde.org/?l=freenx-knx&m=117190954502903&w=2

  5. SPM: thanks for that comment. However, this is user specific, and not application specific as far as I understand it, and therefore is not exactly what I was looking for.
    Still, nice to know.

  6. >>>SPM: thanks for that comment. However, this is user specific, and not application specific as far as I understand it, and therefore is not exactly what I was looking for.
    Still, nice to know.<<<

    I am not exactly clear about what you are looking for.

    Run the application as a specific user and you get application specific packet filtering – for example on many Linux distros Apache runs under user httpd. While it may not be the case in Windows services, it is the normal practice in Linux to run servers as a non-root user where possible.

    You can also use SELinux to restrict access to system resources, but this is access control, not packet filtering.

    On Linux, services on ports under 1024 can only be initiated by root, and so if you just want to prevent network services provided by applications initiated by non-root users, you simply need to block incoming packets bound for ports above 1024, except any specific ports above used by non-root applications above 1024 that you don’t want blocked.

  7. SPM: I’m looking for a mechanism to also block (or allow) specific (user) programs.
    Think of a user which should be allowed to use Firefox to access the internet only – but not IRC clients or e-mail-clients, and also not eDonkey and torrent apps and not Netscape (this is made up and just illustrates my point).
    So my point is to block outgoing traffic for several user programs. And in such cases ports below 1024 are not interesting, and running specific applications as specific users also is a workaround and not the feature I am looking for.
    Indeed Kai’s first answer was the perfect solution, but as he also pointed out this feature is not developed any more.

    About SELinux: you can use it to block network traffic from specific applications. But this requires a lot of configuration (according to the SELinux people).

  8. It is sad if the filter by application feature in iptables/netfilter has been removed rather than fixed. But while effective for blocking acroread for example, it wouldn’t work for your purpose unless it also paid attention to the path of the running command. Otherwise, the adventerous child (or whoever) could just rename the contraban program to the same name as something that *was* allowed to access the Internet.

    But if you want to lock the box down so extra programs (with or w/o Internet access) can’t be added, you need only put /tmp and /home on partitions that are mounted no-execute (and make /var/tmp a symlink pointing to /tmp).

  9. As soon as I posted, I had a thought of how to use iptables. Put all programs you wish to have Internet access (that don’t already run under a special uid or gid) under a special gid for this purpose and set the setgid bit. Then you may use netfilter to grant Internent access to only programs running under that gid. (If you have services running that need access, you can grant that via their uid or gid).

  10. Sorry, the setgid-trick won’t work. (At least not without some modification unknown to me.) Any user can change the gid of a file he/she owns. Try for yourself, as user;
    $ cp /usr/bin/wget my_exec
    $ chown :internet my_exec
    $ chmod g+s my_exec.

    The best suggestion so far is to set /home and /tmp as no-execute.

    Also, I would like everyone to remember that unless you’ve got a thin-client setup at home, or at LEAST having secured your BIOS with restricted boot options and an admin-password, this is client side security === no security. Many kids will have a friend handing over a LiveCD and off he/she goes.

  11. Thanks for the blog post. I do believe something of this kind is necessary on Linux. As someone attempting to gradually migrate from Windows-exclusive to dual use, it is something I miss on Linux.

    The reason is not so much detection of malware in the ordinary sense. Rather, it’s that deliberately installed applications may not be entirely trustworthy. “Spyware” is usually defined too narrowly, excluding “phone home” behaviors of applications from major vendors. The Adobe example above is a good one. I also have a licence for the Linux version of the closed-source Nero, and would like to prevent it from making network connections.

  12. Ulrik, the post is about technical possibilities. The post is clear on that part: it is not about the pros and cons in different environments.

  13. >>>allowed to use Firefox to access the internet only – but not IRC clients or e-mail-clients, and also not eDonkey and torrent apps and not Netscape (this is made up and just illustrates my point).<<>>About SELinux: you can use it to block network traffic from specific applications. But this requires a lot of configuration (according to the SELinux people).<<<

    Yes SELinux is a pain in the butt to configure, and is best left to the distro vendor. Also SELinux can be used to block access to certain hardware resources, but although I haven’t tried it, it is likely to be a crude allow or deny type permission rather than allow user access to LAN but deny Internet access which iproute/iptables allows.

    AppArmor isn’t of use to protect against local users logged into a machine, it only protects against remote hackers gaining access to a machine via a service that the machine provides, so it isn’t what you are looking for.

    You could create a special user say FFoxUser and run the application under user FFoxUser by making that application executable SUID and owner FFoxUser. This may have security issues if multiple users are present on the PC for example they will be able to all access each others /tmp files. To overcome this, you could give each user a separate copy of the executable owned by that user’s unique special user and executable only by that user’s private user group eg. UID FFoxUserSPM owns my executable and it is executable by group SPM (of which user SPM is the only member). Having done this you can mark filter the packets by user FFoxSPM which you allow through while access is otherwise blocked. This is probably the easiest way to do it. Note that application updates will require you to set permissions again. You may also need to grant the XServer permission to display a GUI application running under a different user on your desktop.

    Another way is to mark and filter by PID. Knowing the PID, you can find the command that started the application that started the packets. This is useful for monitoring IP traffic. The problem for controlling access using this method is that the PID isn’t static, and the application PID changes. You need to grep ps to get the application (and owner), run the iptables command dynamically to allow access for a new connection for that PID only and when you shut down the application, you have to close that access by deleting that rule by running another iptables command dynamically. Perhaps a cron job delete filter rules corresponding to processes PIDs no longer running say every 15 minutes, would be appropriate.
    http://seclists.org/firewall-wizards/2003/Nov/0058.html
    http://iptables-tutorial.frozentux.net/scripts/pid-owner.txt

    Personally I would just do it the Linux way – ie filter by destination port number, preferably on a separate firewall which the user cannot log into.

  14. Just one other point for Windows users converting to Linux. Spyware and viruses are not a problem on Linux – there has never ever been a successful virus on Linux (by successful, I mean something that has spread in the wild). If you are worried about trojans, you can put /home on a separate partition and mount the /home partition as nosuid and noexec, which means that any executable files the user puts in the home directory won’t execute and the user cannot set any executables in the home directory as SUID.

    There have been relatively few worms on Linux compared to Windows and they don’t spread rapidly like they do on Windows because although programming errors that cause exploitable security holes are roughly similar in number on Linux and Windows, the same vulnerabilities that makes Windows susceptable to viruses also makes Windows worms easy to automate.

    If you have Windows machines on your network susceptable to spambots, phone home spyware etc. you are better off putting in a decent separate firewall that can block outgoing packets except for specific ports or proxy ports you allow. Trying to put something on the Windows machine that has the spyware or spambot on it to try to block it by application name is not a secure solution.

  15. >>>Ulrik Mikaelsson Says:
    July 23rd, 2007 at 18:42

    Sorry, the setgid-trick won’t work. (At least not without some modification unknown to me.) Any user can change the gid of a file he/she owns. Try for yourself, as user;
    $ cp /usr/bin/wget my_exec
    $ chown :internet my_exec
    $ chmod g+s my_exec.<<<

    You can stop it being set or executed from the home directory if you have /home on a separate partition and you mount it with the noexec nosuid nosgid. This can be set in /etc/fstab.

    However note that if you have a command line, you can still execute batch files by using the bash . or source command to read and execute the contents of a batch file which you can create, but it will won’t run as SUID or SGID.

  16. How about;
    – put an inotify on the files you want to allow
    – if file is accessed start a script (check user, time, etc.)
    – in script, if allowed get pid an insert iptables –pid-owner in rules
    – if inotify gets a close on the file remove accessrule

    It’s ugly but it should work.

  17. I think running a shell like this (in the background) should work

    #!/bin/bash
    firefox &
    PID=$!

    wait $PID

    exit 0

    the $! returns the last PID
    wait $PID waits until the process corresponding to $PID is terminated.

  18. sorry lines didn’t show up

    #!/bin/bash
    firefox &
    PID=$!
    insert iptable command lines to permit packets to go through for pid $PID
    wait $PID
    insert iptable command lines to remove rules that permit packets to go through
    exit 0

    the $! returns the last PID
    wait $PID waits until the process corresponding to $PID is terminated.

  19. Ulrik Mikaelsson wrote:

    Sorry, the setgid-trick won?t work. (At least not without some modification unknown to me.) Any user can change the gid of a
    file he/she owns. Try for yourself, as user;
    $ cp /usr/bin/wget my_exec
    $ chown :internet my_exec
    $ chmod g+s my_exec.

    ========

    A non-privileged user may only change the group ownership of a file to a group s/he is a member of:

    jim @ratel:~$ groups
    jim adm dialout cdrom floppy audio dip video plugdev lpadmin scanner admin onionplus
    jim @ratel:~$ cp /usr/bin/wget .
    jim @ratel:~$ ll wget
    -rwxr-xr-x 1 jim jim 247008 2007-07-24 00:33 wget
    jim @ratel:~$ chown :onionplus wget
    jim @ratel:~$ ll wget
    -rwxr-xr-x 1 jim onionplus 247008 2007-07-24 00:33 wget
    jim @ratel:~$ grep somebody /etc/group
    somebody:x:1005:
    jim @ratel:~$ chown :somebody wget
    chown: changing group of `wget': Operation not permitted
    jim @ratel:~$

  20. Oops, two mistakes: That last post was mine and I forgot to fill in some fields. I also didn’t think about the prompts with user & host showing up as links. Liquidat, feel free to edit that out so the previous post looks a little more sane.

    Done😉

  21. >>>Ulrik Mikaelsson
    Sorry, the setgid-trick won?t work. (At least not without some modification unknown to me.) Any user can change the gid of a
    file he/she owns. Try for yourself, as user;<<<

    This is correct, otherwise it is possible for users to lock themselves out of their own files. If you want to stop users changing file permissions, then the file must be owned by someone else and the user must not have write permission to the file.

    The bigger problem though is how do you stop users renaming the file or installing another copy of the file in their home directory with whatever permissions the user wants in order to bypass the elaborate measures you have taken. It is possible to stop users running executables, and as SUID or SGID in their home directories etc. so as to limit executables to directories that they don’t have write access to by mounting the home directory as noexec nosuid nosgid.

  22. >>>SM Says:
    July 24th, 2007 at 2:10

    sorry lines didn’t show up

    #!/bin/bash
    firefox &
    PID=$!
    insert iptable command lines to permit packets to go through for pid $PID
    wait $PID
    insert iptable command lines to remove rules that permit packets to go through
    exit 0<<<

    I think this should work but you need to make the script owner root, SUID so that an ordinary user can run it as root (required to change iptables rules), and replace the line

    firefox &

    with

    su $USERNAME -c ‘firefox &’

    so that you run firefox as an unpriveleged user.

    Having said this running programs (particularly shells) as SUID root and SGID root are generally frowned on for security reasons. This is because while not at Windows levels of insecurity, it is theoretically possible to use race conditions to gain an escalation in privilege to root.

    Another way of doing things is to have suspect activity logged in a file and put an inotify on the file as LB suggested and have a script inspect by PID and UID and dynamically filter accordingly. A number of off the shelf reactive network intrusion detection systems work this way.

  23. @SPM,

    Within limits, users can change gid, setgid, etc. But one of the things they *cannot* do (at least on my systems!) is to set the gid of a file to a *group they are not a member of*. I showed earlier, that an attemp to do this resulted in “Operation not permitted.” If this were not so, the setgid bit in permissions would be useless (or a gigantic security hole). So to make my suggestion work, create a group that *no normal user is a member of* and use this group to grant Internet access. Users can then copy/create files and set bits all they want to but it won’t get them Internet access.

  24. Re: blackhole

    That’s right, and it should work.

    The only problem is that you may have some security issues with regard to all users using the psuedo user getting access to each others pseudo user temporary files in /tmp, and depending on how the app behaves, users may also be able to affect other users settings, and possibly Firefox may refuse to start up more than one user profile etc. This depends on the application.

    Also you may need to set the X mit-cookie in the pseudo user’s xauthority file and copy it to the real users xauthority file in order to allow X to display the other user’s Firefox in the real users X session. If you can have more than one user running simultaneously as the same pseudo user, this might lead to security issues.

  25. # Marian Says:
    July 24th, 2007 at 20:19

    What about NuFW? (http://www.nufw.org/). I didn’t use it, but it seems that is exactly that – a packet filter that takes into account the application or the user.

    Looks like this uses iptables filter by PID or UID and does the grepping of ps right out of the box to link the application name to PID – which is exactly what the thread originator was looking for.

    Just one thing though, you need to specify the application allowed through by full pathname otherwise the user may create an path variable to another application with the same name.

  26. NuFW may be the solution liquidat was looking for. However, it appears to be intended as a solution for a gateway rather than for an indvidual host, which is what you would probably want in a corporate environment. For the home, less certain. It was not clear to me whether it could be used where both the client softare and the firewall were on the same machine. It sounds like it is still in the early stages of development.

    @SPM,

    In all honesty, I hadn’t thought about access to files. But this might not be a problem. Remember, this is the GID, not the UID that is being altered. I just looked at my .Xauthority and .ICEauthority files, and they both have permissions of 700, so they are just keying off of UID. I don’t know if any of these appliations actually use the /tmp directory, but even if they do, if umask was set to 700 prior to calling the application, I don’t think there would be an problem. But it is something to keep in mind. (As an aside, I borrowed this idea of using setgid from the way I have seen the “games” group used.)

  27. SPM said:
    Yes SELinux is a pain in the butt to configure, and is best left to the distro vendor. Also SELinux can be used to block access to certain hardware resources, but although I haven’t tried it, it is likely to be a crude allow or deny type permission rather than allow user access to LAN but deny Internet access which iproute/iptables allows.

    FYI, SELinux allows very granular specification of network permissions. You can specify access to network interfaces (e.g. eth0), nodes (e.g. 192.168.0.0/255.255.0.0), and ports (e.g. TCP 22) individually. Also, very recent kernels integrate SELinux with netfilter so you can be as granular as iptables.

  28. >>># Chad Sellers Says:
    July 27th, 2007 at 1:32

    FYI, SELinux allows very granular specification of network permissions. You can specify access to network interfaces (e.g. eth0), nodes (e.g. 192.168.0.0/255.255.0.0), and ports (e.g. TCP 22) individually. Also, very recent kernels integrate SELinux with netfilter so you can be as granular as iptables.<<<

    Thanks for that information. Maybe I should start learning SELinux configuration. I have resisted so far because of the issues involved – it is complicated to understand, lots of packages break it, and if you roll your own, distro bug updates may break it. On the latest FC6, FC7, Centos5 and SELinux is very usable on servers, but on the desktop it can a pain because many multi-media applications do things that SELinux blocks – presumably because they are ported from Windows where security is not a criterion. For this installing setroubleshooter is a must, and even though the blocks are easy to remove using setroubleshooter, you still have problems recurring if you install program updates.

    , and On a desktop

  29. It is a matter of privasy . even if the software can be trusted it should be made easy for a user to block it . many people dont like programs making connections even though it may not be a bad thing. i want to be able to say STOP disalow . please people develop a nice linux gui firewall thingy with both easy yes no questions but also extra options to configure port and protocol rules for an aplication.

    greets

  30. I’ll give you one more good reason for having good control over what is connecting and what is not: _save_precious_bandwidth_!
    I have this little project of mine (a hobby, really) to set up a computer in my summer house with a webcam & temperature sensors to be able to see “what is going on” during my absence. The house is very remote, but thank God has electricity and is within mobile access (mind you GPRS only). I want my “surveillance server for poor” to perform a simple task of periodically taking some snapshots every hour and then, say once a day, sending those in bulk to my ftp server throuh GPRS connection (a mobile connected by good old RS232).
    Need I say more? Yes, I need to be sure, that the ONLY application connecting to internet will be an ftp client launched by a script! I really wouldn’t appreciate some software connecting to the internet, even in good faith, to check whether there are any updates waiting. No sir! And guess what? It seems that linux won’t deliver and I’ll have to think about Win with some Tiny Personal Firewall or similar. At least I’ll know what is connecting and WHERE – down to destination IP!
    Regards,
    Tom

Comments are closed.