-
-
Save tehmoon/b1c3ae5e9a67d66186361d4728bed799 to your computer and use it in GitHub Desktop.
| #!/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 |
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.
I found a more layered solution for my use case to this "issue":
- Layer: is having Cloudflare's firewall to stand in front and route traffic
- Layer: is my cloud providers firewall
- Layer: lastly on the hosts, im using this script
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?
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.