9

I'm considering several options for sandboxing a Linux process. Using clone() with CLONE_NEWNET (etc.) is one of the options. CLONE_NEWNET ensures that the sandboxed process cannot make or accept real network connections. But I'd like to disable sockets entirely for that process, even bind()ing to any port on 0.0.0.0, and binding to a Unix doman socket (even anonymous). I'd like to do this to prevent the process from using too much kernel resources by binding to thousands of ports. How do I do that?

In general, I'm interested in many sandboxing approaches (i.e. those provided by the Linux kernel and those enforced by ptrace()), but in this question I'm only interested in the socket creation aspect of the sandboxing approaches (so if you suggest a sandboxing approach, please also explain how to prevent socket creation with it), and I'm not interested in approaches which need kernel patching or which involve loading a kernel module which is not part of the Ubuntu Lucid default binary kernel package, or which would affect every process on the system.

HoldOffHunger
  • 18,769
  • 10
  • 104
  • 133
pts
  • 80,836
  • 20
  • 110
  • 183
  • 2
    Similar Qs on sandboxing/jailing processes in Linux or Unix: * http://unix.stackexchange.com/q/6433/4319 * http://stackoverflow.com/q/3859710/94687 * http://stackoverflow.com/q/4249063/94687 * http://stackoverflow.com/q/1019707/94687 – imz -- Ivan Zakharyaschev Mar 13 '11 at 13:37

5 Answers5

8

ptrace seems to be the most obvious tool but aside from that…

util-linux[-ng] has a command unshare, which uses the kernel's clone/unshare interfaces. If you run the new process throughunshare -n (or clone(CLONE_NEWNET)), any network sockets it creates are in a different namespace. That doesn't solve the kernel resource issue but it does sandbox the process.

The Linux kernel also supports seccomp, a mode entered with prctl(PR_SET_SECCOMP, 1) which prevents the process (well, thread, really) from calling any syscalls other than read, write, exit, and sigreturn. It's a pretty effective sandbox but difficult to use with unmodified code.

You can define a SELinux domain which disallows socket/bind/etc. calls, and perform a dynamic transition into that type. This (obviously) requires a system with an actively enforcing SELinux policy. (Possibly similar things are possible with AppArmor and TOMOYO, but I'm not very familiar with any of them.)

ephemient
  • 198,619
  • 38
  • 280
  • 391
  • 1
    Thank you for composing such a comprehensive list. I've accepted your answer. I've tried AppArmor, and I can confirm that it can prevent socket creation. I have already mentioned `CLONE_NEWNET` in the question (and why it isn't a solution). seccomp is not a good answer to my question, because it restricts more (e.g. fork()) than what I want. – pts Dec 11 '10 at 17:34
4

Take a look at systrace - not limited to sockets, but a generic syscall policy generator/enforcer. Quote:

GNU/Linux port is finished and kernel patch is maintained actively by Marius Eriksen. Can be run without kernel changes using the ptrace backend.

Disclamer - I never tried it on Linux.

Community
  • 1
  • 1
Nikolai Fetissov
  • 82,306
  • 11
  • 110
  • 171
  • 1
    Thank you for mentioning systrace. I've just taken a look at it on Linux i386, and it looks powerful in terms of features: it can prevent socket creation, and much more. I had about five small problems compiling it, but once that was done, it seemed to work for sandboxing simple programs, but I couldn't sandbox GCC calling GNU as(1) with systrace: systrace got stuck indefinitely in a wait4 system call. Also, it's unmaintained for 2 years. So I've given up on it. since an earlier wait4 bugreport was unanswered: http://forum.soft32.com/linux/strace-wait4-pending-SIGALRM-ftopict484715.html – pts Dec 10 '10 at 18:34
  • FYI I've voted up your answer, but since systrace isn't stable for me, I can't accept this answer. – pts Dec 10 '10 at 18:36
2

Try seccomp (see the prctl man page), it can confine your process to only accessing the sockets that were left open at the time the prctl call was made.

Thomas M. DuBuisson
  • 64,245
  • 7
  • 109
  • 166
  • 1
    I know about seccomp, but that's not a good answer to my question, because it restricts more (e.g. fork()) than what I want. – pts Dec 11 '10 at 17:31
  • 1
    pts: I agree. Tangentially, this is why seccomp2 should have been accepted into mainline Linux instead of getting sneered at. – Thomas M. DuBuisson Dec 13 '10 at 20:00
  • Where is this seccomp2 you speak of? Link to mailing list archive having the post? – user562374 Jan 04 '11 at 23:34
  • 1
    "Adam Langley (also of Google) has posted a patch which does just that. The new 'mode 2' implementation accepts a bitmask describing which system calls are accessible." Found on [LWN](http://lwn.net/Articles/332974/) with lots of links. – Thomas M. DuBuisson Jan 04 '11 at 23:53
2

You might be interested with "sydbox" sandbox or "pinktrace" library :

http://www.diigo.com/user/wierzowiecki/sydbox

pts
  • 80,836
  • 20
  • 110
  • 183
Grzegorz Wierzowiecki
  • 10,545
  • 9
  • 50
  • 88
  • 1
    Thanks for mentioning these two. I discarded them early because they are horribly underdocumented. Maybe they will improve in the future. – pts Jan 01 '11 at 13:12
  • 1
    I had same feeling at beginning. Lucky, I decided to check out sources, and posts on mailing lists and I've found that this project looks interesting and finally, it's not as small that it feels on begging, and offers many ways of comfortable "filtering" of system calls - in flexible manner ! :) – Grzegorz Wierzowiecki Jan 01 '11 at 15:26
  • 2
    In my workload (running g++), sydbox was 50% slower than User-mode Linux, so I'm sticking to User-mode Linux now, because that gives me not only sandboxing, but limiting gross memory use. – pts Jan 06 '11 at 13:48
2

If your main goal is to limit the number of sockets that are opened by some benign process P applied to benign inputs, then setrlimit(RLIMIT_NOFILE, ...) will do approximately what you want.

However, if P is assumed be to malicious rather than benign or if you're looking for strong assurance about how P will behave in the face of potentially malicious inputs, then you're probably out of luck: i.e., at best, with the tools available today, you can create an obstacle course for attackers.

(That being said, if an obstacle course works for you, then you might get some more good ideas by poking around over here at sandboxing.org or by sending your questions to the friendly folks on sandboxing-talk@lists.sandboxing.org.)