I want to limit connections to running Docker containers. I have a set of iptables
rules that do this effectively. However, the rule set hinges on applying my own rule chain ahead of the DOCKER
chain.
Basically, I want this result
Chain FORWARD (policy DROP)
target prot opt source destination
PRE_DOCKER all -- 0.0.0.0/0 0.0.0.0/0 /* Insert before Docker's filtering to apply our own */
DOCKER all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
Chain PRE_DOCKER (policy DROP)
target prot opt source destination
//My own rules go here targeting the DOCKER chain
I am having trouble getting these rules set at system startup. I have a systemd
file with the contents
[Unit]
Description=Restore iptables firewall rules
Before=iptables-store.service
Requires=docker.service
After=docker.service
Conflicts=shutdown.target
[Service]
Type=oneshot
ExecStart=/sbin/iptables-restore --noflush /var/lib/iptables/rules-save
[Install]
WantedBy=basic.target
But on startup, I get the error
iptables-restore v1.4.21: Couldn't load target `DOCKER':No such file or directory
which I assume means Docker service hasn't created its rules yet.
What is the correct way to structure my unit files or my iptables
rules so that I get the desired output.
For completeness, here are the contents of /var/lib/iptables/rules-save
that I have set up.
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
:PRE_DOCKER - [0:0]
-I FORWARD -o docker0 -j PRE_DOCKER -m comment --comment "Insert before Docker's filtering to apply our own"
-A PRE_DOCKER ! -i eth0 -o docker0 -j DOCKER -m comment --comment "Anything coming from something other than the public interface send to DOCKER chain"
-A PRE_DOCKER -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -m comment --comment "Allow connections from established connections"
-A PRE_DOCKER -j DROP -m comment --comment "Drop anything else"
-A INPUT ! -i eth0 -j ACCEPT -m comment --comment "Accept anything coming from something other than the public interface"
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -m comment --comment "Allow connections from established connections"
COMMIT
I really couldn't figure this out. I guess there's some timing issue with when docker.service creates the iptables DOCKER chain versus when systemd views it as finished started.
So I resorted to a polling method which checks to see if the chain is present and only then tries to restore the rules.