Skip to content

Commit cfc79cc

Browse files
committed
firewall: make logging rules best-effort on limited kernels
1 parent eedfc3c commit cfc79cc

1 file changed

Lines changed: 55 additions & 40 deletions

File tree

bin/setup-firewall.sh

Lines changed: 55 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -33,22 +33,37 @@ if [ -z "$UID_BAUDBOT" ]; then
3333
fi
3434

3535
CHAIN="BAUDBOT_OUTPUT"
36+
IPTABLES_BIN="iptables"
37+
if command -v iptables-nft >/dev/null 2>&1 && iptables-nft -w -L OUTPUT -n >/dev/null 2>&1; then
38+
IPTABLES_BIN="iptables-nft"
39+
fi
40+
41+
fw() {
42+
"$IPTABLES_BIN" -w "$@"
43+
}
44+
45+
add_optional_rule() {
46+
if ! fw "$@"; then
47+
echo "⚠️ Optional firewall rule unsupported by kernel, skipping: $IPTABLES_BIN -w $*" >&2
48+
fi
49+
}
3650

3751
echo "🔒 Setting up firewall rules for $BAUDBOT_AGENT_USER (uid $UID_BAUDBOT)..."
52+
echo " backend: $IPTABLES_BIN"
3853

3954
# Clean up any existing rules first
40-
iptables -w -D OUTPUT -m owner --uid-owner "$UID_BAUDBOT" -j "$CHAIN" 2>/dev/null || true
41-
iptables -w -F "$CHAIN" 2>/dev/null || true
42-
iptables -w -X "$CHAIN" 2>/dev/null || true
55+
fw -D OUTPUT -m owner --uid-owner "$UID_BAUDBOT" -j "$CHAIN" 2>/dev/null || true
56+
fw -F "$CHAIN" 2>/dev/null || true
57+
fw -X "$CHAIN" 2>/dev/null || true
4358

4459
# Create a dedicated chain for baudbot_agent
45-
iptables -w -N "$CHAIN"
60+
fw -N "$CHAIN"
4661

4762
# ── Logging (SYN + DNS only — low volume) ────────────────────────────────────
48-
# Log all new outbound connections (SYN packets only to avoid flooding)
49-
iptables -w -A "$CHAIN" -p tcp --syn -j LOG --log-prefix "baudbot-out: " --log-level info
50-
# Log DNS queries
51-
iptables -w -A "$CHAIN" -p udp --dport 53 -j LOG --log-prefix "baudbot-dns: " --log-level info
63+
# Some kernels (notably certain cloud Arch images) lack optional LOG/tcp xtables
64+
# modules. Treat logging rules as best-effort; the allow/drop policy is mandatory.
65+
add_optional_rule -A "$CHAIN" -p tcp --syn -j LOG --log-prefix "baudbot-out: " --log-level info
66+
add_optional_rule -A "$CHAIN" -p udp --dport 53 -j LOG --log-prefix "baudbot-dns: " --log-level info
5267

5368
# ── Localhost: allow only specific services ──────────────────────────────────
5469

@@ -57,76 +72,76 @@ iptables -w -A "$CHAIN" -p udp --dport 53 -j LOG --log-prefix "baudbot-dns: " --
5772
# 4000-4999: Astro (4321), Remix (4200), Nuxt, etc.
5873
# 5000-5999: Vite (5173), Flask, generic dev servers
5974
# 6000-6099: Storybook (6006), Expo (6100 range is X11 — skip 6063+)
60-
iptables -w -A "$CHAIN" -o lo -p tcp --dport 3000:5999 -j ACCEPT
61-
iptables -w -A "$CHAIN" -o lo -p tcp --dport 6006 -j ACCEPT
75+
fw -A "$CHAIN" -o lo -p tcp --dport 3000:5999 -j ACCEPT
76+
fw -A "$CHAIN" -o lo -p tcp --dport 6006 -j ACCEPT
6277

6378
# ── Databases ────────────────────────────────────────────────────────────
6479
# 5432: PostgreSQL (native)
6580
# 6379: Redis
6681
# 27017: MongoDB
6782
# 54322: PostgreSQL (Docker-mapped)
68-
iptables -w -A "$CHAIN" -o lo -p tcp --dport 5432 -j ACCEPT
69-
iptables -w -A "$CHAIN" -o lo -p tcp --dport 6379 -j ACCEPT
70-
iptables -w -A "$CHAIN" -o lo -p tcp --dport 27017 -j ACCEPT
71-
iptables -w -A "$CHAIN" -o lo -p tcp --dport 54322 -j ACCEPT
83+
fw -A "$CHAIN" -o lo -p tcp --dport 5432 -j ACCEPT
84+
fw -A "$CHAIN" -o lo -p tcp --dport 6379 -j ACCEPT
85+
fw -A "$CHAIN" -o lo -p tcp --dport 27017 -j ACCEPT
86+
fw -A "$CHAIN" -o lo -p tcp --dport 54322 -j ACCEPT
7287

7388
# ── Infrastructure ───────────────────────────────────────────────────────
7489
# 7890: Slack bridge
7590
# 8000-9999: Wrangler (8787), Django/FastAPI (8000), inspector (9229+), MinIO (9000)
7691
# 11434: Ollama
7792
# 24678: Vite HMR websocket
78-
iptables -w -A "$CHAIN" -o lo -p tcp --dport 7890 -j ACCEPT
79-
iptables -w -A "$CHAIN" -o lo -p tcp --dport 8000:9999 -j ACCEPT
80-
iptables -w -A "$CHAIN" -o lo -p tcp --dport 11434 -j ACCEPT
81-
iptables -w -A "$CHAIN" -o lo -p tcp --dport 24678 -j ACCEPT
93+
fw -A "$CHAIN" -o lo -p tcp --dport 7890 -j ACCEPT
94+
fw -A "$CHAIN" -o lo -p tcp --dport 8000:9999 -j ACCEPT
95+
fw -A "$CHAIN" -o lo -p tcp --dport 11434 -j ACCEPT
96+
fw -A "$CHAIN" -o lo -p tcp --dport 24678 -j ACCEPT
8297

8398
# Allow DNS on localhost
84-
iptables -w -A "$CHAIN" -o lo -p udp --dport 53 -j ACCEPT
85-
iptables -w -A "$CHAIN" -o lo -p tcp --dport 53 -j ACCEPT
99+
fw -A "$CHAIN" -o lo -p udp --dport 53 -j ACCEPT
100+
fw -A "$CHAIN" -o lo -p tcp --dport 53 -j ACCEPT
86101

87102
# Allow localhost responses (established connections back to us)
88-
iptables -w -A "$CHAIN" -o lo -m state --state ESTABLISHED,RELATED -j ACCEPT
103+
fw -A "$CHAIN" -o lo -m state --state ESTABLISHED,RELATED -j ACCEPT
89104

90105
# Block everything else on localhost
91-
iptables -w -A "$CHAIN" -o lo -j LOG --log-prefix "BAUDBOT_LOCAL_BLOCKED: " --log-level 4
92-
iptables -w -A "$CHAIN" -o lo -j DROP
106+
add_optional_rule -A "$CHAIN" -o lo -j LOG --log-prefix "BAUDBOT_LOCAL_BLOCKED: " --log-level 4
107+
fw -A "$CHAIN" -o lo -j DROP
93108

94109
# ── Internet: allow standard + dev ports ─────────────────────────────────────
95110

96111
# DNS (UDP + TCP)
97-
iptables -w -A "$CHAIN" -p udp --dport 53 -j ACCEPT
98-
iptables -w -A "$CHAIN" -p tcp --dport 53 -j ACCEPT
112+
fw -A "$CHAIN" -p udp --dport 53 -j ACCEPT
113+
fw -A "$CHAIN" -p tcp --dport 53 -j ACCEPT
99114

100115
# HTTP/HTTPS (web, APIs, cloud services)
101-
iptables -w -A "$CHAIN" -p tcp --dport 80 -j ACCEPT
102-
iptables -w -A "$CHAIN" -p tcp --dport 443 -j ACCEPT
116+
fw -A "$CHAIN" -p tcp --dport 80 -j ACCEPT
117+
fw -A "$CHAIN" -p tcp --dport 443 -j ACCEPT
103118

104119
# SSH (git push/pull)
105-
iptables -w -A "$CHAIN" -p tcp --dport 22 -j ACCEPT
120+
fw -A "$CHAIN" -p tcp --dport 22 -j ACCEPT
106121

107122
# Cloud databases (Neon, Supabase, RDS, PlanetScale, Atlas, Upstash, etc.)
108-
iptables -w -A "$CHAIN" -p tcp --dport 3306 -j ACCEPT # MySQL / PlanetScale
109-
iptables -w -A "$CHAIN" -p tcp --dport 5432:5433 -j ACCEPT # PostgreSQL / Neon
110-
iptables -w -A "$CHAIN" -p tcp --dport 6543 -j ACCEPT # Supabase pooler
111-
iptables -w -A "$CHAIN" -p tcp --dport 6379 -j ACCEPT # Redis Cloud / Upstash
112-
iptables -w -A "$CHAIN" -p tcp --dport 27017 -j ACCEPT # MongoDB Atlas
123+
fw -A "$CHAIN" -p tcp --dport 3306 -j ACCEPT # MySQL / PlanetScale
124+
fw -A "$CHAIN" -p tcp --dport 5432:5433 -j ACCEPT # PostgreSQL / Neon
125+
fw -A "$CHAIN" -p tcp --dport 6543 -j ACCEPT # Supabase pooler
126+
fw -A "$CHAIN" -p tcp --dport 6379 -j ACCEPT # Redis Cloud / Upstash
127+
fw -A "$CHAIN" -p tcp --dport 27017 -j ACCEPT # MongoDB Atlas
113128

114129
# Observability (OpenTelemetry OTLP)
115-
iptables -w -A "$CHAIN" -p tcp --dport 4317:4318 -j ACCEPT
130+
fw -A "$CHAIN" -p tcp --dport 4317:4318 -j ACCEPT
116131

117132
# Allow established/related (responses to allowed outbound)
118-
iptables -w -A "$CHAIN" -m state --state ESTABLISHED,RELATED -j ACCEPT
133+
fw -A "$CHAIN" -m state --state ESTABLISHED,RELATED -j ACCEPT
119134

120135
# Log and drop everything else
121-
iptables -w -A "$CHAIN" -j LOG --log-prefix "BAUDBOT_BLOCKED: " --log-level 4
122-
iptables -w -A "$CHAIN" -j DROP
136+
add_optional_rule -A "$CHAIN" -j LOG --log-prefix "BAUDBOT_BLOCKED: " --log-level 4
137+
fw -A "$CHAIN" -j DROP
123138

124139
# Jump to our chain for all baudbot_agent traffic
125-
iptables -w -A OUTPUT -m owner --uid-owner "$UID_BAUDBOT" -j "$CHAIN"
140+
fw -A OUTPUT -m owner --uid-owner "$UID_BAUDBOT" -j "$CHAIN"
126141

127142
echo "✅ Firewall active. Rules:"
128143
echo ""
129-
iptables -w -L "$CHAIN" -n -v --line-numbers
144+
fw -L "$CHAIN" -n -v --line-numbers
130145
echo ""
131146
echo "Localhost allowed: 3000-5999 (dev servers), 5432 (pg), 6006 (storybook),"
132147
echo " 6379 (redis), 7890 (bridge), 8000-9999 (wrangler/inspector),"
@@ -137,6 +152,6 @@ echo " 3306 (mysql), 4317-4318 (otlp), 5432-5433 (pg),"
137152
echo " 6379 (redis), 6543 (supabase), 27017 (mongo)"
138153
echo "Everything else: BLOCKED + LOGGED"
139154
echo ""
140-
echo "To remove: sudo iptables -w -D OUTPUT -m owner --uid-owner $UID_BAUDBOT -j $CHAIN && sudo iptables -w -F $CHAIN && sudo iptables -w -X $CHAIN"
155+
echo "To remove: sudo $IPTABLES_BIN -w -D OUTPUT -m owner --uid-owner $UID_BAUDBOT -j $CHAIN && sudo $IPTABLES_BIN -w -F $CHAIN && sudo $IPTABLES_BIN -w -X $CHAIN"
141156
echo ""
142157
echo "Persistence: baudbot-firewall.service (systemd)"

0 commit comments

Comments
 (0)