From 8b2cbe3f867bb1ec9e6170eeff7c554791a704df Mon Sep 17 00:00:00 2001 From: shota-0129 Date: Tue, 29 Jul 2025 13:54:29 +0900 Subject: [PATCH 1/3] feat: Add Docker DNS protection to firewall script MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Extract Docker DNS NAT ports before iptables cleanup - Restore Docker DNS NAT rules after iptables reset - Maintains Docker container DNS functionality in network isolation - Fixes connection refused errors to 127.0.0.11 in Docker environments 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .devcontainer/init-firewall.sh | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/.devcontainer/init-firewall.sh b/.devcontainer/init-firewall.sh index 93ef9b60d..ed31583c0 100644 --- a/.devcontainer/init-firewall.sh +++ b/.devcontainer/init-firewall.sh @@ -2,6 +2,10 @@ set -euo pipefail # Exit on error, undefined vars, and pipeline failures IFS=$'\n\t' # Stricter word splitting +# Extract Docker DNS ports before cleanup (for protection) +TCP_PORT=$(iptables -t nat -L DOCKER_OUTPUT -n 2>/dev/null | grep 'tcp.*to:127.0.0.11:' | sed 's/.*127\.0\.0\.11://g' | cut -d' ' -f1 || echo "") +UDP_PORT=$(iptables -t nat -L DOCKER_OUTPUT -n 2>/dev/null | grep 'udp.*to:127.0.0.11:' | sed 's/.*127\.0\.0\.11://g' | cut -d' ' -f1 || echo "") + # Flush existing rules and delete existing ipsets iptables -F iptables -X @@ -11,6 +15,19 @@ iptables -t mangle -F iptables -t mangle -X ipset destroy allowed-domains 2>/dev/null || true +# Restore Docker DNS NAT rules if they existed +if [ -n "$TCP_PORT" ] && [ -n "$UDP_PORT" ]; then + echo "Restoring Docker DNS with TCP:$TCP_PORT, UDP:$UDP_PORT" + iptables -t nat -N DOCKER_OUTPUT + iptables -t nat -N DOCKER_POSTROUTING + iptables -t nat -A OUTPUT -d 127.0.0.11/32 -j DOCKER_OUTPUT + iptables -t nat -A POSTROUTING -d 127.0.0.11/32 -j DOCKER_POSTROUTING + iptables -t nat -A DOCKER_OUTPUT -d 127.0.0.11/32 -p tcp -j DNAT --to-destination 127.0.0.11:$TCP_PORT + iptables -t nat -A DOCKER_OUTPUT -d 127.0.0.11/32 -p udp -j DNAT --to-destination 127.0.0.11:$UDP_PORT + iptables -t nat -A DOCKER_POSTROUTING -s 127.0.0.11/32 -p tcp -j SNAT --to-source :53 + iptables -t nat -A DOCKER_POSTROUTING -s 127.0.0.11/32 -p udp -j SNAT --to-source :53 +fi + # First allow DNS and localhost before any restrictions # Allow outbound DNS iptables -A OUTPUT -p udp --dport 53 -j ACCEPT From 78e07859503d03277d2f1b01c491231252d962ee Mon Sep 17 00:00:00 2001 From: shota-0129 Date: Wed, 30 Jul 2025 14:22:15 +0900 Subject: [PATCH 2/3] simplify Docker DNS restoration using grep and xargs approach --- .devcontainer/init-firewall.sh | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/.devcontainer/init-firewall.sh b/.devcontainer/init-firewall.sh index ed31583c0..a410c5c71 100644 --- a/.devcontainer/init-firewall.sh +++ b/.devcontainer/init-firewall.sh @@ -2,9 +2,8 @@ set -euo pipefail # Exit on error, undefined vars, and pipeline failures IFS=$'\n\t' # Stricter word splitting -# Extract Docker DNS ports before cleanup (for protection) -TCP_PORT=$(iptables -t nat -L DOCKER_OUTPUT -n 2>/dev/null | grep 'tcp.*to:127.0.0.11:' | sed 's/.*127\.0\.0\.11://g' | cut -d' ' -f1 || echo "") -UDP_PORT=$(iptables -t nat -L DOCKER_OUTPUT -n 2>/dev/null | grep 'udp.*to:127.0.0.11:' | sed 's/.*127\.0\.0\.11://g' | cut -d' ' -f1 || echo "") +# 1. Extract Docker DNS info BEFORE any flushing +DOCKER_DNS_RULES=$(iptables-save -t nat | grep "127\.0\.0\.11") # Flush existing rules and delete existing ipsets iptables -F @@ -15,17 +14,14 @@ iptables -t mangle -F iptables -t mangle -X ipset destroy allowed-domains 2>/dev/null || true -# Restore Docker DNS NAT rules if they existed -if [ -n "$TCP_PORT" ] && [ -n "$UDP_PORT" ]; then - echo "Restoring Docker DNS with TCP:$TCP_PORT, UDP:$UDP_PORT" - iptables -t nat -N DOCKER_OUTPUT - iptables -t nat -N DOCKER_POSTROUTING - iptables -t nat -A OUTPUT -d 127.0.0.11/32 -j DOCKER_OUTPUT - iptables -t nat -A POSTROUTING -d 127.0.0.11/32 -j DOCKER_POSTROUTING - iptables -t nat -A DOCKER_OUTPUT -d 127.0.0.11/32 -p tcp -j DNAT --to-destination 127.0.0.11:$TCP_PORT - iptables -t nat -A DOCKER_OUTPUT -d 127.0.0.11/32 -p udp -j DNAT --to-destination 127.0.0.11:$UDP_PORT - iptables -t nat -A DOCKER_POSTROUTING -s 127.0.0.11/32 -p tcp -j SNAT --to-source :53 - iptables -t nat -A DOCKER_POSTROUTING -s 127.0.0.11/32 -p udp -j SNAT --to-source :53 +# 2. Selectively restore ONLY internal Docker DNS resolution +if [ -n "$DOCKER_DNS_RULES" ]; then + echo "Restoring Docker DNS rules..." + iptables -t nat -N DOCKER_OUTPUT 2>/dev/null || true + iptables -t nat -N DOCKER_POSTROUTING 2>/dev/null || true + echo "$DOCKER_DNS_RULES" | xargs -L 1 iptables -t nat +else + echo "No Docker DNS rules to restore" fi # First allow DNS and localhost before any restrictions From dde41f6225c5b5bf8320a87f0ee893e784a25b02 Mon Sep 17 00:00:00 2001 From: Kurt Carpenter Date: Wed, 30 Jul 2025 10:54:05 -0700 Subject: [PATCH 3/3] fix: Handle missing Docker DNS rules gracefully in firewall script MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add error handling for grep when no Docker DNS rules exist, preventing script failure on default Docker networks while still preserving DNS functionality on custom networks. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .devcontainer/init-firewall.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/init-firewall.sh b/.devcontainer/init-firewall.sh index a410c5c71..0b987171f 100644 --- a/.devcontainer/init-firewall.sh +++ b/.devcontainer/init-firewall.sh @@ -3,7 +3,7 @@ set -euo pipefail # Exit on error, undefined vars, and pipeline failures IFS=$'\n\t' # Stricter word splitting # 1. Extract Docker DNS info BEFORE any flushing -DOCKER_DNS_RULES=$(iptables-save -t nat | grep "127\.0\.0\.11") +DOCKER_DNS_RULES=$(iptables-save -t nat | grep "127\.0\.0\.11" || true) # Flush existing rules and delete existing ipsets iptables -F