Restricting the network access of Docker container

Solution 1:

It still makes sense to put some ingress rules inside your docker instance to help ward off attacks, but you will have to limit outbound (Internet) access from whatever upstream router the docker image connects with. The reason for this is, if you try to block outbound access with the firewall rules inside your instance, then if the instance is compromised those rules could be removed by the attacker. By blocking egress via the instance's router, you block outbound access even in the event of a compromise - the attacker would have to compromise the router as well.


Ok, so after receiving some commentary that explains that the filtering was intended for the container's host, it's a little clearer what is trying to be accomplished. In which case, on the host, you would add some rules similar to this:

iptables -A FORWARD -s lo.cal.sub.net -d con.tai.ner.ip -j ACCEPT
iptables -A FORWARD -s con.tai.ner.ip -d lo.cal.sub.net -j ACCEPT
iptables -A FORWARD -s ! lo.cal.sub.net -d con.tai.ner.ip -p tcp --dport sftp -j ACCEPT
iptables -A FORWARD -s con.tai.ner.ip -d ! lo.cal.sub.net -p tcp --sport sftp -j ACCEPT
iptables -A FORWARD -s con.tai.ner.ip -m state --state related,established -j ACCEPT
iptables -A FORWARD -s con.tai.ner.ip -j DROP

The first two rules are for access between the host and the container. The third rule says (roughly) that anything that isn't the host's subnet headed for SFTP is just OK by us; the fourth is the outbound rule that is basically a twin to the third; the fifth rule is a catch-all (in case there are other related ports that are used), although it shouldn't be needed, you could probably remove it; the last rule is the magic on that prevents access to anything other than the host subnet. Because access is given in the first few rules, it will never trigger unless none of the preceding rules apply, in which case we are saying "we don't care what you want, you didn't match anything you're approved for, so you can't get there from here". Inbound traffic from the outside will be satisfied by the 3rd and 4th rules.

Solution 2:

This isn't really a docker specific problem. There are a couple of ways you could solve this.

  1. Use stateful iptables rules to allow connections inbound and related/established traffic then block everything else.

  2. Use an sftp only service such as ProFTPD that is incapable of running a shell.

In general, if you don't allow your users to get a shell and don't allow them to run programs from within the container, you don't need to worry about it.