2

If I want to run untrusted code inside a Docker container, or an untrusted Docker container for that matter, how can I restrict it?

I'd like to make sure it has no access to the host filesystem. Ideally I'd like it to have limited network access: listen on local ports only, nothing on WAN, nothing outbound even to LAN.

How can I enforce this?

Note: I found this What are the potential security problems running untrusted code in a Docker container as a non-root user? from 7 years ago, but it was written at a time when Docker was very new and immature

SRobertJames
  • 245
  • 1
  • 7

2 Answers2

4

There's a couple of different aspect to your question and different options for each. Using standard Docker tech, a container is just a process running on the host, with Linux features applied to restrict what it can do.

  • Filesystem Access - By default, a Docker container has no access to any filesystem outside of the container. You can mount folders inside the container (with the -v switch) but that's optional. The container filesystem is on the host though, so it always needs some level of accesss.
  • Network Access - If you want a container not to access the network at all, just use --net=none this will mean it has no network interface apart from lo for loopback traffic within the container.

There are some risks here. If a container is malicious and there is a vulnerability in the Linux kernel running on the host, the contained process might be able to break out to the underlying host (like any other software there is always the possibility of vulnerabilities).

If you want to run things like containers, with a smaller attack surface than the Linux kernel, there are a couple of options :-

  • gVisor - This is a container sandbox developed by Google. They use it for some of their own Container as a Service options. It's designed to isolate containers from the underlying host
  • firecracker - Firecracker from AWS essentially puts each container inside it's own virtual machine, making it less likely for a contained process to be able to affect the underlying host.
Rory McCune
  • 60,923
  • 14
  • 136
  • 217
  • firecracker looks fascinating, I hadn't heard of it. It seems, though, that you need to set up each instance with the kernel and various files. The benefit of containers over VMs is the simplicity and efficiency: just run it, it can use all the system binaries from the host. Is there a way to do something similar with firecracker, such that you can run a Docker container, or even a single binary, without having to create the whole VM? – SRobertJames Feb 03 '22 at 00:10
1

For people's reference, here are applications trying to solve similar problems:

  • gVisor (from Rory McCune's answer; uses user-mode kernel simulator written in Go, called runsc, which communicates to outside-the-container proxy for all system operations)
  • firecracker (from Rory McCune's answer; lightweight VMs; more info at https://systemadminspro.com/google-gvisor-amazon-firecracker-openstack-kata/ )
  • firejail (uses Linux's native capabilities, such as chroot, seccomp, etc.)
  • bubblewrap / flatpak (similar to firejail, but smaller binary, not suid)
  • nsjail (not sure how it operates)
SRobertJames
  • 245
  • 1
  • 7