Skip to content

Instantly share code, notes, and snippets.

@tehmoon
Last active January 13, 2024 09:21
Show Gist options
  • Save tehmoon/b1c3ae5e9a67d66186361d4728bed799 to your computer and use it in GitHub Desktop.
Save tehmoon/b1c3ae5e9a67d66186361d4728bed799 to your computer and use it in GitHub Desktop.
IPtables and docker reload!
#!/bin/sh
set -e
## SEE https://medium.com/@ebuschini/iptables-and-docker-95e2496f0b45
## You need to add rules in DOCKER-BLOCK AND INPUT for traffic that does not go to a container.
## You only need to add one rule if the traffic goes to the container
CWD=$(cd "$(dirname "${0}")"; pwd -P)
FILE="${CWD}/$(basename "${0}")"
chown root:root "${FILE}"
chmod o-rwx "${FILE}"
set -x
install_docker_block() {
## One time install rules for the DOCKER-BLOCK chain
/sbin/iptables -t nat -N DOCKER-BLOCK &&
## Deploy the new rules. After this, everything goes to DOCKER-BLOCK then to RETURN
/sbin/iptables -t nat -I PREROUTING -m addrtype --dst-type LOCAL -g DOCKER-BLOCK ||
true
}
## install the PREROUTING rules for the DOCKER chain in case docker starts after
/sbin/iptables -t nat -N DOCKER || true
## Block new connections while we restore the first PREROUTING RULES
/sbin/iptables -t nat -I PREROUTING -m addrtype --dst-type LOCAL -m state --state NEW -j RETURN
install_docker_block
## Delete installed rules, we need to ensure they always are at the top
## If rules were already installed, it would mean that the second and third rule
## are going to be deleted. We still have the RETURN on top.
while true; do
/sbin/iptables -t nat -D PREROUTING -m addrtype --dst-type LOCAL -j RETURN || break
done
while true; do
/sbin/iptables -t nat -D PREROUTING -m addrtype --dst-type LOCAL -j DOCKER-BLOCK || break
done
## Re-deploy the right rules on the top. After this, the flow is restored to DOCKER-BLOCK
/sbin/iptables -t nat -I PREROUTING -m addrtype --dst-type LOCAL -g DOCKER-BLOCK
## Remove the blocking rule, which should be unreachable after deploy_docker_block anyway
while true; do
/sbin/iptables -t nat -D PREROUTING -m addrtype --dst-type LOCAL -m state --state NEW -j RETURN || break
done
## Only let established connections go through while we flush the rules
/sbin/iptables -t nat -I PREROUTING -m addrtype --dst-type LOCAL -m state --state ESTABLISHED -j DOCKER
## Flush the rules of DOCKER-BLOCK, at this point new connections will be blocked
/sbin/iptables -t nat -F DOCKER-BLOCK
## Add your new rules below, allowing new connections
## Don't forget the NEW and ESTABLISHED states
#/sbin/iptables -t nat -A DOCKER-BLOCK -p tcp -m tcp --dport 8080 -m state --state NEW,ESTABLISHED -j DOCKER
## Restore the flow
## Loop trying to delete the rule in case the script failed above, we don't want to add more than one rule
while true; do
/sbin/iptables -t nat -D PREROUTING -m addrtype --dst-type LOCAL -m state --state ESTABLISHED -j DOCKER || break
done
## The INPUT chain is set to drop, then we flush it and reinstall the rules.
## Finally we restore the policy on the chain
## Remember that those rules don't apply to docker
/sbin/iptables -t filter -P INPUT DROP
/sbin/iptables -t filter -F INPUT
/sbin/iptables -t filter -A INPUT -i lo -j ACCEPT
# Add your non docker rules here
#/sbin/iptables -t filter -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
/sbin/iptables -t filter -A INPUT -m state --state ESTABLISHED -j ACCEPT
/sbin/iptables -t filter -A INPUT -j DROP
/sbin/iptables -t filter -P INPUT ACCEPT
@tl87
Copy link

tl87 commented Apr 19, 2022

That's one way to fix it and I would also recommend a proxy or firewall. One could also look into setting up a geofence to limit incoming traffic or a cloud firewall if the containers are hosted with a cloud provider.

@egberts
Copy link

egberts commented Jul 18, 2022

To get rid of that libvirt error, my permanent workaround in Debian 11 (as a host) with libvirtd daemon is to block the loading of iptables-related modules:

Create a file in /etc/modprobe.d/nft-only.conf:


#  Source: https://www.gaelanlloyd.com/blog/migrating-debian-buster-from-iptables-to-nftables/
#
blacklist x_tables
blacklist iptable_nat
blacklist iptable_raw
blacklist iptable_mangle
blacklist iptable_filter
blacklist ip_tables
blacklist ipt_MASQUERADE
blacklist ip6table_nat
blacklist ip6table_raw
blacklist ip6table_mangle
blacklist ip6table_filter
blacklist ip6_tables

libvirtd daemon now starts without any error.

Post-analysis: Apparently, I had iptables module loaded alongside with many nft-related modules; once iptables was gone, the pesky error message went away.

@tl87
Copy link

tl87 commented Jul 31, 2022

I found a more layered solution for my use case to this "issue":

  1. Layer: is having Cloudflare's firewall to stand in front and route traffic
  2. Layer: is my cloud providers firewall
  3. Layer: lastly on the hosts, im using this script

@Biepa
Copy link

Biepa commented Oct 21, 2022

You need to add rules in DOCKER-BLOCK AND INPUT for traffic that does not go to a container.

I only have this in my nat table
-A DOCKER-BLOCK -p tcp -m tcp --dport 80 -m state --state NEW,ESTABLISHED -j DOCKER
But still can access my SSH port.

Edit: Just curious. Why not use the mange or raw table instead?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment