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.
Sandboxing involves providing a safe environment for a program or software so that you can play around with it without hurting your system. It actually keeps your program isolated from the rest of the system, by using any one of the different methods available in the Linux kernel.
We use different sandboxing techniques on Linux and Chrome OS, in combination, to achieve a good level of sandboxing. You can see which sandboxes are currently engaged by looking at chrome://sandbox (renderer processes) and chrome://gpu (gpu process).
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.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With