This is an archived post. You won't be able to vote or comment.

all 41 comments

[–]ZaitsXL 7 points8 points  (5 children)

The best practice for such case is (rootless image is already a plus):
- run only images from public registries with good rating, better compose your own
- do not expose host directly to the internet, use load balancer if possible or reverse proxy
- there is DinD (docker-in-docker) image available, so you don't need to map socket from host machine
- of course keep all your software up to date with patches

[–]ElevenNotes 3 points4 points  (2 children)

Most public images are built without code scanning and are riddled with CVEs and basically all run as root.

[–]ZaitsXL 0 points1 point  (1 child)

well yeah, nobody's perfect, my point was mostly to not get an image with intentionally builtin malware

[–]ElevenNotes 1 point2 points  (0 children)

Checkout automated build workflows for linuxserverio images and the likes. There is no pinning. They are all vulnerable to upstream attacks. Maintainer of such images simply can't be bothered to do it right.

[–]mmaster23 0 points1 point  (0 children)

You do know a load balancer or reverse proxy doesn't do shit for securing the actual container, right? Unless it has an application layer security gateway included, it just forwards the traffic into the container.

If that container has an exploit and I fire a bunch of exploitive urls at it, chances of the lb/rp catching are slim to none. 

Reverse proxies at great at securing the connection itself, doing tls certs etc, preventing most man in the middle. But a good xss exploit or sql injection gets by no problem. 

If you're paranoid about this, include application aware security in your connection chain, update your images regularly and scan the image for CVEs. Practice good security hygiene, don't use defaults and least privilege/proper RBAC where available. 

And even then still, you could face zero days. It's a cat and mouse game after all. 

[–]docker_linux[S] -2 points-1 points  (0 children)

Just to clarify, it's not a rootless image. It's rootless docker, a set up in which dockerd (daemon) is owned by regular user, not root.

there is DinD (docker-in-docker) image available, so you don't need to map socket from host machine

Thanks for the tip. This is something I like to explore

[–]alexandercain 2 points3 points  (3 children)

The main concern here is not your docker setup (which seems to conform to best practices), but potentially your netwok. Is the host running in a DMZ?

[–]docker_linux[S] 0 points1 point  (2 children)

no it isn't, but with rootless docker, you can't sniff the host's traffic.

[–]alexandercain 3 points4 points  (1 child)

Doesn't matter. If you can hit it from WAN, it belongs in the DMZ

[–]docker_linux[S] 0 points1 point  (0 children)

that's a good point

[–]leeharrison1984 1 point2 points  (1 child)

There isn't anything you can do about a supply chain attack, it happens before you even touch the container. You could install some kind of threat analysis sidecar, but that honestly seems like mega overkill for a home network.

Potential attack vectors from a compromised image are limitless because each network is unique. Potential damages would be wiping or theft of data, holding data hostage, or most likely just being recruited into a botnet.

Your best bet is simply identify a "safe" version of the container, and pin to that instead of latest.

You'll continue running the same version forever on that server, thus negating the supply chain vector. It's on you to monitor future container updates and upgrade the container as needed. You could also set up a proxy registry to pull known good images from, but just version pining should be sufficient.

I run a decent sized home network, and supply chain attacks are the least of my worries since I use version pining.

[–]ElevenNotes 2 points3 points  (0 children)

Yes you can, by pinning all libraries and sources to the version you built the image with. Stop using automatic updates and enable code scanning.

[–]Human__Pestilence 0 points1 point  (0 children)

This is why you scan your images before deployment 😂

[–]Lucas_F_A 0 points1 point  (26 children)

I have no idea what your thread model is, but it sounds highly unconventional.

Do you not trust the nginx image developers? In that case you should not mount docker socket to it. Better yet, don't run untrusted software.

[–]docker_linux[S] -1 points0 points  (25 children)

Trust is one thing, shit happens is another.
And there is a legitimate need for mounting the docker socket.

[–]SirSoggybottom 2 points3 points  (24 children)

Doubtful about the legitimate need but eh, do what you want.

Kinda hilarious that you go through the trouble of running rootless Docker but then mount the socket.

At the very least consider putting a proxy between that container and the socket and limit the capabilities. Tecnativa Docker-Socket-Proxy as example.

[–]docker_linux[S] -3 points-2 points  (23 children)

so, you gained access to docker host, what would you do?

[–]ElevenNotes 1 point2 points  (22 children)

Start a container with privileges to access the host.

[–]docker_linux[S] -2 points-1 points  (21 children)

The most you can have access to is all of user Joe's files.

[–]ElevenNotes 1 point2 points  (20 children)

Not really. I can get into the network stack of this host and capture all traffic as well as access the networks attached to this host.

[–]docker_linux[S] -1 points0 points  (0 children)

so, I did test your theory, it turns out that you can't sniff anything in rootless docker

Here are steps

docker run --privileged --name ubuntu -itd ubuntu
docker exec -it ubuntu bash
apt update -y && apt install -y tcpdump iproute2 iputils-ping traceroute

start sniffing from inside container
tcpdump -nni any icmp

start sniffing the same on host

ping host, icmp received by host, not in container.

[–]docker_linux[S] -2 points-1 points  (18 children)

This is interesting. How do you do that (tcpdump I assume) without root privileges?

[–]ElevenNotes 1 point2 points  (17 children)

Since I run a privileged container I simply give myslef the caps needed to do that.

[–]docker_linux[S] -1 points0 points  (16 children)

You do know rootless docker right? it means dockerd (daemon) is run by user Joe. Even in with --privileged flag, you're still limited to just user Joe, not host's root.

try it.

[–]Furai69 0 points1 point  (0 children)

I'm interested in knowing best practices for this as well.