The filter table is best place to drop packets, agreed.
But, out of the box, Docker bypasses INPUT filter rules with PREROUTING to its own FORWARD rules making Docker containers world-accessible. Inserting DOCKER-named filter INPUT/FORWARD rules fails because when Docker is restarted they are deleted then inserted (not appended).
My best attempt is to insert another PREROUTING chain before Docker's and send unwanted packets from eth0 (WAN) to a black hole - 0.0.0.1 - because you cannot DROP/REJECT in a nat table anymore.
# Route anything but TCP 80,443 and ICMP to an IPv4 black hole iptables -t nat -N BLACKHOLE iptables -t nat -A BLACKHOLE ! -i eth0 -j RETURN iptables -t nat -A BLACKHOLE -m conntrack --ctstate ESTABLISHED,RELATED -j RETURN iptables -t nat -A BLACKHOLE -p tcp --dport 80 -j RETURN iptables -t nat -A BLACKHOLE -p tcp --dport 443 -j RETURN iptables -t nat -A BLACKHOLE -p icmp -j RETURN iptables -t nat -A BLACKHOLE -p all -j DNAT --to 0.0.0.1 iptables -t nat -I PREROUTING -m addrtype --dst-type LOCAL -j BLACKHOLE
Here are what the NAT chains looks like with Docker and one container running:
This seems to work well, though, is there a way to explicitly reject packets before reaching the other pre-routing rule?
(Alpine Linux 3.6.2, Docker v17.05.0-ce)