I thought I'd written down the solution before, but it turned out I'd just asked about it on StackOverflow and then "solved" it by starting a new server and failing to tell docker not to wipe my iptables rules. The problem was I could either
- use docker with my own iptables rules and
"iptables": false
and have those containers not able to access the internet or - allow docker to wreck my iptables rules and allow the whole big nasty internet access to all of my containers with exposed ports.
Apparently there's an easy way to address this now, using the DOCKER-USER chain.
I set iptables=true
and append to my iptables configuration
iptables -A DOCKER-USER -i eth0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -A DOCKER-USER -i eth0 -p tcp -m tcp --dport 80 -j ACCEPT
iptables -A DOCKER-USER -i eth0 -p tcp -m tcp --dport 443 -j ACCEPT
iptables -A DOCKER-USER -i eth0 -j DROP
which says "accept established, accept input HTTP(S), drop everything else."
Containers can connect out, can't be connected into, except on 80 and 443. 👍