spacehub

surshar / claude-code

Claude Code is an agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster by executing routine tasks, explaining complex code, and handling git workflows - all through natural language commands.

Built by Anthropic · github.com/anthropics

claude-code / .devcontainer / init-firewall.sh
135 lines · 4.8 KBRaw
1#!/bin/bash
2set -euo pipefail # Exit on error, undefined vars, and pipeline failures
3IFS=$'\n\t' # Stricter word splitting
4
5# Extract Docker DNS ports before cleanup (for protection)
6TCP_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 "")
7UDP_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 "")
8
9# Flush existing rules and delete existing ipsets
10iptables -F
11iptables -X
12iptables -t nat -F
13iptables -t nat -X
14iptables -t mangle -F
15iptables -t mangle -X
16ipset destroy allowed-domains 2>/dev/null || true
17
18# Restore Docker DNS NAT rules if they existed
19if [ -n "$TCP_PORT" ] && [ -n "$UDP_PORT" ]; then
20 echo "Restoring Docker DNS with TCP:$TCP_PORT, UDP:$UDP_PORT"
21 iptables -t nat -N DOCKER_OUTPUT
22 iptables -t nat -N DOCKER_POSTROUTING
23 iptables -t nat -A OUTPUT -d 127.0.0.11/32 -j DOCKER_OUTPUT
24 iptables -t nat -A POSTROUTING -d 127.0.0.11/32 -j DOCKER_POSTROUTING
25 iptables -t nat -A DOCKER_OUTPUT -d 127.0.0.11/32 -p tcp -j DNAT --to-destination 127.0.0.11:$TCP_PORT
26 iptables -t nat -A DOCKER_OUTPUT -d 127.0.0.11/32 -p udp -j DNAT --to-destination 127.0.0.11:$UDP_PORT
27 iptables -t nat -A DOCKER_POSTROUTING -s 127.0.0.11/32 -p tcp -j SNAT --to-source :53
28 iptables -t nat -A DOCKER_POSTROUTING -s 127.0.0.11/32 -p udp -j SNAT --to-source :53
29fi
30
31# First allow DNS and localhost before any restrictions
32# Allow outbound DNS
33iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
34# Allow inbound DNS responses
35iptables -A INPUT -p udp --sport 53 -j ACCEPT
36# Allow outbound SSH
37iptables -A OUTPUT -p tcp --dport 22 -j ACCEPT
38# Allow inbound SSH responses
39iptables -A INPUT -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
40# Allow localhost
41iptables -A INPUT -i lo -j ACCEPT
42iptables -A OUTPUT -o lo -j ACCEPT
43
44# Create ipset with CIDR support
45ipset create allowed-domains hash:net
46
47# Fetch GitHub meta information and aggregate + add their IP ranges
48echo "Fetching GitHub IP ranges..."
49gh_ranges=$(curl -s https://api.github.com/meta)
50if [ -z "$gh_ranges" ]; then
51 echo "ERROR: Failed to fetch GitHub IP ranges"
52 exit 1
53fi
54
55if ! echo "$gh_ranges" | jq -e '.web and .api and .git' >/dev/null; then
56 echo "ERROR: GitHub API response missing required fields"
57 exit 1
58fi
59
60echo "Processing GitHub IPs..."
61while read -r cidr; do
62 if [[ ! "$cidr" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/[0-9]{1,2}$ ]]; then
63 echo "ERROR: Invalid CIDR range from GitHub meta: $cidr"
64 exit 1
65 fi
66 echo "Adding GitHub range $cidr"
67 ipset add allowed-domains "$cidr"
68done < <(echo "$gh_ranges" | jq -r '(.web + .api + .git)[]' | aggregate -q)
69
70# Resolve and add other allowed domains
71for domain in \
72 "registry.npmjs.org" \
73 "api.anthropic.com" \
74 "sentry.io" \
75 "statsig.anthropic.com" \
76 "statsig.com"; do
77 echo "Resolving $domain..."
78 ips=$(dig +short A "$domain")
79 if [ -z "$ips" ]; then
80 echo "ERROR: Failed to resolve $domain"
81 exit 1
82 fi
83
84 while read -r ip; do
85 if [[ ! "$ip" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
86 echo "ERROR: Invalid IP from DNS for $domain: $ip"
87 exit 1
88 fi
89 echo "Adding $ip for $domain"
90 ipset add allowed-domains "$ip"
91 done < <(echo "$ips")
92done
93
94# Get host IP from default route
95HOST_IP=$(ip route | grep default | cut -d" " -f3)
96if [ -z "$HOST_IP" ]; then
97 echo "ERROR: Failed to detect host IP"
98 exit 1
99fi
100
101HOST_NETWORK=$(echo "$HOST_IP" | sed "s/\.[0-9]*$/.0\/24/")
102echo "Host network detected as: $HOST_NETWORK"
103
104# Set up remaining iptables rules
105iptables -A INPUT -s "$HOST_NETWORK" -j ACCEPT
106iptables -A OUTPUT -d "$HOST_NETWORK" -j ACCEPT
107
108# Set default policies to DROP first
109iptables -P INPUT DROP
110iptables -P FORWARD DROP
111iptables -P OUTPUT DROP
112
113# First allow established connections for already approved traffic
114iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
115iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
116
117# Then allow only specific outbound traffic to allowed domains
118iptables -A OUTPUT -m set --match-set allowed-domains dst -j ACCEPT
119
120echo "Firewall configuration complete"
121echo "Verifying firewall rules..."
122if curl --connect-timeout 5 https://example.com >/dev/null 2>&1; then
123 echo "ERROR: Firewall verification failed - was able to reach https://example.com"
124 exit 1
125else
126 echo "Firewall verification passed - unable to reach https://example.com as expected"
127fi
128
129# Verify GitHub API access
130if ! curl --connect-timeout 5 https://api.github.com/zen >/dev/null 2>&1; then
131 echo "ERROR: Firewall verification failed - unable to reach https://api.github.com"
132 exit 1
133else
134 echo "Firewall verification passed - able to reach https://api.github.com as expected"
135fi