-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinit-firewall.sh
More file actions
executable file
·98 lines (82 loc) · 3.17 KB
/
init-firewall.sh
File metadata and controls
executable file
·98 lines (82 loc) · 3.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#!/bin/bash
set -euo pipefail
# Firewall: agent can talk to any container on its Docker networks,
# but the only path to the internet is through the proxy.
echo "Configuring firewall..."
# Detect iptables backend. Docker typically uses iptables-legacy,
# while modern Debian defaults to iptables (nft). We need to use
# whichever backend Docker set up its DNS NAT rules with.
if command -v iptables-legacy &>/dev/null && iptables-legacy-save -t nat 2>/dev/null | grep -q "127\.0\.0\.11"; then
IPT=iptables-legacy
IPT_SAVE=iptables-legacy-save
echo "Using iptables-legacy backend (matching Docker)"
else
IPT=iptables
IPT_SAVE=iptables-save
echo "Using iptables (nft) backend"
fi
# 1. Preserve Docker DNS NAT rules (127.0.0.11)
DOCKER_DNS_RULES=$($IPT_SAVE -t nat | grep "127\.0\.0\.11" || true)
# 2. Flush all existing rules
$IPT -F
$IPT -X
$IPT -t nat -F
$IPT -t nat -X
$IPT -t mangle -F
$IPT -t mangle -X
# 3. Restore Docker DNS NAT rules
if [ -n "$DOCKER_DNS_RULES" ]; then
echo "Restoring Docker DNS rules..."
$IPT -t nat -N DOCKER_OUTPUT 2>/dev/null || true
$IPT -t nat -N DOCKER_POSTROUTING 2>/dev/null || true
echo "$DOCKER_DNS_RULES" | grep -E '^-A (OUTPUT|POSTROUTING|DOCKER_OUTPUT|DOCKER_POSTROUTING) ' | while IFS= read -r rule; do
$IPT -t nat $rule 2>/dev/null || true
done
fi
# 4. Allow loopback
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT
# 5. Allow DNS (needed to resolve service names via Docker DNS)
$IPT -A OUTPUT -p udp --dport 53 -j ACCEPT
# 6. Allow traffic to all Docker bridge subnets the agent is attached to.
# This covers the proxy, any services from compose overrides, and external networks.
echo "Allowing Docker network subnets..."
for iface in $(ip -o -4 addr show | awk '{print $2}' | grep -v '^lo$' | sort -u); do
subnet=$(ip -o -4 addr show "$iface" | awk '{print $4}')
if [ -n "$subnet" ]; then
echo " Allowing subnet $subnet on $iface"
$IPT -A OUTPUT -d "$subnet" -j ACCEPT
fi
done
# 7. Allow established/related connections (for responses)
$IPT -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# 8. Reject everything else (with feedback, not silent drop)
$IPT -A OUTPUT -j REJECT --reject-with icmp-admin-prohibited
# 9. Set default policies to DROP (fallback)
$IPT -P INPUT DROP
$IPT -P FORWARD DROP
$IPT -P OUTPUT DROP
echo "Firewall configured. Verifying..."
# Verify: direct access should fail
if curl --connect-timeout 3 -s https://example.com >/dev/null 2>&1; then
echo "ERROR: Direct access to example.com should be blocked"
exit 1
fi
echo " Direct access blocked"
# Verify: proxy access should work (retry up to 3 times for startup race)
PROXY_IP=$(getent hosts proxy | awk '{print $1}')
PROXY_OK=false
for i in 1 2 3; do
if curl --connect-timeout 5 -s --proxy "http://${PROXY_IP}:3128" https://api.github.com/zen >/dev/null 2>&1; then
PROXY_OK=true
break
fi
[ "$i" -lt 3 ] && sleep 2
done
if [ "$PROXY_OK" = true ]; then
echo " Proxy access working"
else
echo " WARNING: Proxy access verification failed (proxy may still be starting)"
fi
echo "Firewall setup complete"