The problem with docker is it opens up ports in the firewall to the world, that’s fine if you want the app running in the container available to world + dog but in my case I didn’t, also this is on a hosted box elsewhere that sadly isn’t infront of a dedicated firewall, infant a dedicated firewall would probably cost more than the entire server itself as it was a very cheap server.


Because it’s running on a very low end box I couldn’t even run a KVM hypervisor and run a firewall infront of the docker host that way (Which is my preferred option if running on a dedi with no hardware f/w infront).

I could have disabled dockers tampering with iptables but it’s handy to have it do the NAT stuff automatically, instead this is a horrible hack that will inject a new forward rule above the docker rules after restart.

This assumes a few things here, that you are using SystemD, FirewallD is disabled the internet uplink is eth0.

You will also need the iptables-persistent package installed


I don’t claim this to be a secure setup, but it should be a bit more secure than the default I’d be wary of trusting it for anything with access to sensitive data,  ideally you’d want an external firewall infront of the Docker host if you plan to allow docker to have it’s way with the machines own firewall.

Below is a slightly modified version of my /etc/iptables/rules.v4 , Currently I’m only allowing access from certain IP’s although I expect to expand this later, it was a basic ruleset for testing





-A INPUT -i docker0 -j ACCEPT

-A INPUT -m conntrack –ctstate RELATED,ESTABLISHED -j ACCEPT

-A INPUT -p icmp –icmp-type echo-request -j ACCEPT

-A INPUT -s <My IP 1> -j ACCEPT

-A INPUT -s <My IP 2> -j ACCEPT





-A DOCKER-SEC -i eth0 -j DROP



What this does is setup an IPtables ruleset that allow my IP’s access to the server and drops everything else, it also creates a DOCKER-SEC chain that filters traffic from the internet into the docker containers…

Then I created the following script in /lib/systemd/system/docker-firewall-mod.service


Description=fix for docker opening the firewall to world and dog


ExecStart=/scripts/fix-firewall.sh &



The content of /scripts/fixfirewall.sh – hey I did say it was a horrible hackjob


# A Post docker start script to inject a new table to stop docker mess up the firewall, I’d disable dockers firewall mod support but I kinda want to to make the nat rules

# Ideally this should be done during the iptables laod but then this rule ends up below the docker created rules and everything is wired open, arrg.

# Begin injection

sleep 30

/sbin/iptables -I FORWARD 1 -o docker0 -j DOCKER-SEC

P.s I’ve actually cleaned up those comments in the description’s for the service/comments in the script the original wasn’t quite so polite about it 😉

Also note that there will be a brief window before this gets injected that containers will be exposed to the world.

Also using

iptables-restore < /etc/iptables/rules.v4

to add rules will remove the docker stuff from the firewall which seems to require a restart to docker to fix.



Pam_tally2 is an account locking module for unix that will lock out an account for to many logins, you can use programs like fail2ban/csf to block the IP if it’s a remote service and it’s supported but there are cases where you may just wish to lock out that user instead (E.g if you know the IP is shared, or part of a multi-layered approach)


http://ubuntuforums.org/showthread.php?t=2295409&page=2 — The post by Bembot is mostly correct other than the typo it’s pam_tally2.so not pal_tally2

I also adjusted the timeout and got rid of magicroot.


auth required pam_tally2.so deny=3 unlock_time=xxxx


account required pam_tally2.so deny=3 unlock_time=xxxx

Replace 3 with the desired threshold and xxxx with the time in seconds