[BUG] VPN conflict

Resolved 💬 16 comments Opened Mar 16, 2025 by trentmkelly Closed Aug 22, 2025
💡 Likely answer: A maintainer (8enmann, collaborator) responded on this thread — see the highlighted reply below.

Environment

  • Platform (select one): Anthropic API
  • Claude CLI version: 0.2.45
  • Operating System: Ubuntu 24.04.2
  • Terminal: Konsole

Bug Description

Despite PIA VPN IPs not being blocked for general purpose API usage, the Anthropic Console prompt workbench, or claude.ai, trying to use Claude Code while connected to PIA (PrivateInternetAccess) VPN results in connection errors.

Steps to Reproduce

  1. Connect to any PIA VPN node
  2. Attempt to use Claude Code

Expected Behavior

I expected that the API would work.

Actual Behavior

The API did not work.

Additional Context

hello claude

⎿ API Error (Connection error.) · Retrying in 1 seconds… (attempt 1/2)
⎿ API Error (Connection error.) · Retrying in 1 seconds… (attempt 1/10)
⎿ API Error (Connection error.) · Retrying in 1 seconds… (attempt 1/10)
⎿ API Error (Connection error.) · Retrying in 1 seconds… (attempt 2/2)
⎿ API Error (Connection error.) · Retrying in 1 seconds… (attempt 2/10)
⎿ API Error (Connection error.) · Retrying in 1 seconds… (attempt 2/10)
⎿ API Error (Connection error.) · Retrying in 2 seconds… (attempt 3/10)
⎿ API Error (Connection error.) · Retrying in 2 seconds… (attempt 3/10)

View original on GitHub ↗

16 Comments

8enmann collaborator · 1 year ago

We depend on the following domains being allowed:
https://github.com/anthropics/claude-code/blob/main/.devcontainer/init-firewall.sh#L55-L59

Can you try allowing all those and let us know if it works?

MPeli · 1 year ago

Hi,

I am experiencing the same issue. Is it possible to extract more details about the error from Claude Code? I tried various options, but nothing provided me with more details.

Options:
  -d, --debug                     Enable debug mode
  --verbose                       Override verbose mode setting from config
  -p, --print                     Print response and exit (useful for pipes)
  --json                          Output JSON in the shape {cost_usd: number, duration_ms: number, duration_api_ms: number, result: string} (only works with --print)
  --mcp-debug                     Enable MCP debug mode (shows MCP server errors)
  --dangerously-skip-permissions  Bypass all permission checks. Only works in Docker containers with no internet access.
  --allowedTools <tools...>       Comma or space-separated list of tool names to allow (e.g. "Bash(git*) Edit Replace")
  -v, --version                   output the version number
  -h, --help                      display help for command

I can access following domains

Thank you.

MPeli · 1 year ago

I managed to find some logs in ~/.npm/_logs/.

root@CZLTDJ9TTT3:~/.npm/_logs# cat /root/.npm/_logs/2025-04-09T11_46_48_816Z-debug-0.log
0 verbose cli /root/.nvm/versions/node/v23.11.0/bin/node /root/.nvm/versions/node/v23.11.0/bin/npm
1 info using npm@10.9.2
2 info using node@v23.11.0
3 silly config load:file:/root/.nvm/versions/node/v23.11.0/lib/node_modules/npm/npmrc
4 silly config load:file:/root/.npm/_logs/.npmrc
5 silly config load:file:/root/.npmrc
6 silly config load:file:/root/.nvm/versions/node/v23.11.0/etc/npmrc
7 verbose title npm view @anthropic-ai/claude-code@latest version
8 verbose argv "view" "@anthropic-ai/claude-code@latest" "version"
9 verbose logfile logs-max:10 dir:/root/.npm/_logs/2025-04-09T11_46_48_816Z-
10 verbose logfile /root/.npm/_logs/2025-04-09T11_46_48_816Z-debug-0.log
11 silly logfile done cleaning log files
12 http fetch GET https://registry.npmjs.org/@anthropic-ai%2fclaude-code attempt 1 failed with UNABLE_TO_GET_ISSUER_CERT_LOCALLY

Then I set export NODE_TLS_REJECT_UNAUTHORIZED='0' and was able to continue.

netbrain · 1 year ago

I had this exact same issue, worked around by setting the NODE_TLS_REJECT_UNAUTHORIZED='0' environment variable

zhil · 1 year ago

I have the same issue under with tailscale VPN.

!Image

Pretty strange that everything else is working just fine - I may use claude online, npm etc.

Tried NODE_TLS_REJECT_UNAUTHORIZED='0' claude - it didnt help me.

in .npm/_logs/ I have

!Image

Simple test script

/home/andy/projects/AI/debug_vpn_node_bugs/t2.js                                                 975/975               100%
const https = require('https');

const url = 'https://registry.npmjs.org/@anthropic-ai%2fclaude-code';
console.log('Attempting to access:', url);

// Create options object with increased timeout (in milliseconds)
// Default is typically 120000 (2 minutes), let's try 5 minutes
const options = {
  timeout: 300000, // 5 minutes
};

const req = https.get(url, options);

req.on('response', (res) => {
  console.log('Response status:', res.statusCode);
  res.on('data', () => {});
  res.on('end', () => console.log('Connection successful!'));
});

req.on('error', (e) => {
  console.error('Error name:', e.name);
  console.error('Error message:', e.message);
  console.error('Error code:', e.code);
  console.error('Error stack:', e.stack);
});

// Set a longer timeout on the socket as well
req.on('socket', (socket) => {
  socket.setTimeout(300000); // 5 minutes
  socket.on('timeout', () => {
    console.log('Socket timeout occurred');
    req.abort();
  });
});

req.end();

shows error

Attempting to access: https://registry.npmjs.org/@anthropic-ai%2fclaude-code
Error name: AggregateError
Error message: 
Error code: ETIMEDOUT
Error stack: AggregateError [ETIMEDOUT]: 
    at internalConnectMultiple (node:net:1139:18)
    at afterConnectMultiple (node:net:1712:7)

Claude.ai suggestion

This indicates a network connection timeout issue that's occurring at the TCP connection level before the HTTP request is even established. The problem appears to be that Tailscale VPN is blocking or not properly routing the connection.

next test script

/home/andy/projects/AI/debug_vpn_node_bugs/t3.js                                                1530/1530              100%
const https = require('https');
const dns = require('dns');
const net = require('net');

const url = 'registry.npmjs.org';
const path = '/@anthropic-ai%2fclaude-code';

console.log('Starting diagnostics...');

// 1. First check DNS resolution
console.log(`Resolving DNS for ${url}...`);
dns.lookup(url, (err, address, family) => {
  if (err) {
    console.error('DNS resolution error:', err);
    return;
  }

  console.log(`DNS resolved to ${address} (IPv${family})`);

  // 2. Try TCP connection to the resolved IP
  console.log(`Testing TCP connection to ${address}:443...`);
  const socket = net.createConnection({
    host: address,
    port: 443,
    timeout: 10000 // 10 seconds timeout
  });

  socket.on('connect', () => {
    console.log('TCP connection successful!');
    socket.end();

    // 3. If TCP works, try the HTTPS request
    console.log(`Testing HTTPS request to https://${url}${path}...`);
    const req = https.get(`https://${url}${path}`);

    req.on('response', (res) => {
      console.log('HTTPS Response status:', res.statusCode);
      res.on('data', () => {});
      res.on('end', () => console.log('HTTPS connection successful!'));
    });

    req.on('error', (e) => {
      console.error('HTTPS error:', e.code, e.message);
    });

    req.end();
  });

  socket.on('timeout', () => {
    console.error('TCP connection timeout');
    socket.destroy();
  });

  socket.on('error', (err) => {
    console.error('TCP connection error:', err.code, err.message);
  });
});

response

Starting diagnostics...
Resolving DNS for registry.npmjs.org...
DNS resolved to 104.16.25.34 (IPv4)
Testing TCP connection to 104.16.25.34:443...
TCP connection successful!
Testing HTTPS request to https://registry.npmjs.org/@anthropic-ai%2fclaude-code...
HTTPS error: ETIMEDOUT 

Next suggestion from AI - pretty long script for SSL handshake test, which is crushed as well with timeout.

Any suggestions are welcome.

zhil · 1 year ago

I actually founded reason! In my case ipv6 is not working! The problem is that node.js do not have ENV variable to disable ipv6

@8enmann
Any chances to get that as an option? something like --force-ipv4 ?

zhil · 1 year ago

disabling ipv6 before using claude code works just fine for me.
I didnt completely disable it to prevent some possible weird issues with other soft, I just disable it when I want to use claude code with tailscale

command for Ubuntu 24

sudo sysctl -w net.ipv6.conf.all.disable_ipv6=1
sudo sysctl -w net.ipv6.conf.default.disable_ipv6=1
sudo sysctl -w net.ipv6.conf.lo.disable_ipv6=1
knoel99 · 1 year ago

I am experiencing the same issue but with WSL Ubuntu 22.04, and disabling ipv6 didn't work:

$ lsb_release -d
Description:    Ubuntu 22.04.3 LTS

$ sudo sysctl -w net.ipv6.conf.all.disable_ipv6=1
net.ipv6.conf.all.disable_ipv6 = 1

$sudo sysctl -w net.ipv6.conf.default.disable_ipv6=1
net.ipv6.conf.default.disable_ipv6 = 1

$ sudo sysctl -w net.ipv6.conf.lo.disable_ipv6=1
net.ipv6.conf.lo.disable_ipv6 = 1

$ claude
╭───────────────────────────────────────────────────╮
│ ✻ Welcome to Claude Code!                         │
│                                                   │
│   /help for help, /status for your current setup  │
│                                                   │
│   cwd: /home/               │
╰───────────────────────────────────────────────────╯


> hello
  ⎿  API Error (Connection error.) · Retrying in 1 seconds… (attempt 1/10)
    ⎿  TypeError (fetch failed)
  ⎿  API Error (Connection error.) · Retrying in 1 seconds… (attempt 2/10)
    ⎿  TypeError (fetch failed)

* Transmuting… (1s · ↑ 0 tokens · esc to interrupt)

╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ >                                                                                                                                                                                                                                     │
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
  ? for shortcuts



Total cost:            $0.0000
Total duration (API):  0s
Total duration (wall): 5.1s
Total code changes:    0 lines added, 0 lines removed
Tokens:                0 input, 0 output, 0 cache read, 0 cache write
Perilometry · 1 year ago

To everyone who struggle - here is the script that will solve all your problems.

#!/bin/bash

set -euo pipefail

IFS=$'\n\t'

--- Configuration ---

SCRIPT_NAME="WSL Firewall Setup v3.0 (Complete Solution)"
LOG_PREFIX="[WSL-FW]"

log() {
echo "$LOG_PREFIX $1"
}

--- Sanity Checks ---

if ! grep -qi microsoft /proc/version; then
log "ERROR: This script is intended for WSL. Exiting."
exit 1
fi

if [ "$EUID" -ne 0 ]; then
log "ERROR: Please run this script as root (sudo)."
exit 1
fi

log "Starting $SCRIPT_NAME"

--- Network Wait ---

log "Waiting for network connectivity..."
for i in {1..30}; do
if ping -c 1 -W 1 8.8.8.8 &> /dev/null || ping -c 1 -W 1 1.1.1.1 &> /dev/null; then
log "✅ Network available after $i seconds"
break
fi
sleep 1
done

--- Fix WSL TLS/SSL Issues FIRST ---

log "=== FIXING WSL TLS/SSL ISSUES ==="

Check current MTU

current_mtu=$(ip link show eth0 | grep -o 'mtu [0-9]*' | cut -d' ' -f2 || echo "1500")
log "Current MTU: $current_mtu"

Fix MTU if too large (common WSL issue)

if [[ $current_mtu -gt 1500 ]]; then
log "Large MTU detected ($current_mtu), setting to 1500..."
ip link set dev eth0 mtu 1500
log "✅ MTU set to 1500"
MTU_CHANGED=true
else
MTU_CHANGED=false
fi

Update SSL/TLS packages and certificates

log "Updating SSL packages and certificates..."
apt-get update -qq -o Acquire::http::Timeout=10
DEBIAN_FRONTEND=noninteractive apt-get install -y ca-certificates openssl curl wget jq dnsutils ipset netcat-openbsd

Update CA certificates

update-ca-certificates --fresh >/dev/null 2>&1 || log "⚠️ CA certificate update had issues"

Create WSL-optimized OpenSSL configuration

log "Creating WSL-optimized SSL configuration..."
cat > /etc/ssl/openssl_wsl.conf << 'EOF'
openssl_conf = openssl_init

[openssl_init]
ssl_conf = ssl_sect

[ssl_sect]
system_default = system_default_sect

[system_default_sect]
MinProtocol = TLSv1.2
MaxProtocol = TLSv1.3
CipherString = DEFAULT:@SECLEVEL=1
EOF

Apply the SSL configuration

export OPENSSL_CONF=/etc/ssl/openssl_wsl.conf

Tune network buffers for WSL

log "Tuning network buffers for WSL..."
sysctl -w net.core.rmem_max=16777216 >/dev/null 2>&1 || true
sysctl -w net.core.wmem_max=16777216 >/dev/null 2>&1 || true
sysctl -w net.ipv4.tcp_rmem="4096 32768 16777216" >/dev/null 2>&1 || true
sysctl -w net.ipv4.tcp_wmem="4096 32768 16777216" >/dev/null 2>&1 || true

Test if TLS fixes worked

log "Testing TLS connectivity..."
if timeout 10 curl -s --connect-timeout 5 "https://claude.ai" >/dev/null 2>&1; then
log "✅ TLS connectivity working"
TLS_WORKING=true
elif timeout 10 curl -k -s --connect-timeout 5 "https://claude.ai" >/dev/null 2>&1; then
log "✅ TLS working with relaxed verification"
TLS_WORKING=true
else
log "⚠️ TLS still has issues, but continuing with firewall setup"
TLS_WORKING=false
fi

log "✅ TLS/SSL fixes applied"

--- Complete Firewall Reset ---

log "Performing complete firewall reset..."

Set permissive policies first to avoid lockout

iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT

Flush all chains

iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X

Clean up any existing ipsets

ipset destroy allowed-domains 2>/dev/null || true
ipset destroy claude-ips 2>/dev/null || true

log "✅ Complete firewall reset done"

--- IPSet Setup ---

log "Setting up IP sets..."
ipset create allowed-domains hash:net family inet hashsize 2048 maxelem 100000
ipset create claude-ips hash:net family inet hashsize 256 maxelem 1000
log "✅ IP sets created"

--- Core Firewall Rules (Permissive First) ---

log "Applying core firewall rules..."

Loopback - always allow

iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

Allow established connections

iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

DNS - allow outbound

iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 53 -j ACCEPT
iptables -A INPUT -p udp --sport 53 -j ACCEPT
iptables -A INPUT -p tcp --sport 53 -j ACCEPT

SSH - allow outbound

iptables -A OUTPUT -p tcp --dport 22 -j ACCEPT

HTTP/HTTPS - allow outbound (we'll restrict this later)

iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 443 -j ACCEPT

ICMP for path MTU discovery (important for TLS)

iptables -A OUTPUT -p icmp -j ACCEPT
iptables -A INPUT -p icmp -j ACCEPT

Allow fragmented packets (important for TLS with large certificates)

iptables -A OUTPUT -f -j ACCEPT
iptables -A INPUT -f -j ACCEPT

log "✅ Core rules applied"

--- Host Communication ---

log "Configuring host communication..."
HOST_IPS=$(grep nameserver /etc/resolv.conf | awk '{print $2}' | sort | uniq)
for IP in $HOST_IPS; do
if [[ $IP =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
log " -> Allowing host $IP"
iptables -A OUTPUT -d "$IP" -j ACCEPT
iptables -A INPUT -s "$IP" -j ACCEPT
# Add to ipset too
ipset add allowed-domains "$IP/32" 2>/dev/null || true
fi
done
log "✅ Host communication configured"

--- Build Allowed Domains List ---

log "Building allowed domains list..."

Function to add IP/CIDR to ipset with logging

add_to_ipset() {
local ip_or_cidr=$1
local description=${2:-""}
if ipset add allowed-domains "$ip_or_cidr" 2>/dev/null; then
log " + $ip_or_cidr $description"
fi
}

Function to resolve domain and add IPs

resolve_and_add() {
local domain=$1
local description=${2:-""}
log " -> Resolving $domain"

# Try multiple DNS servers
local dns_servers=("8.8.8.8" "1.1.1.1" "208.67.222.222")
local found_ips=()

for dns in "${dns_servers[@]}"; do
# Get A records
mapfile -t ips < <(timeout 10 dig @"$dns" +short "$domain" A 2>/dev/null | grep -E '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' || true)
for ip in "${ips[@]}"; do
if [[ -n "$ip" ]]; then
found_ips+=("$ip")
add_to_ipset "$ip/32" "($domain)"
# Also add to claude-specific ipset if it's a claude domain
if [[ "$domain" == "claude" ]] || [[ "$domain" == "anthropic" ]]; then
ipset add claude-ips "$ip/32" 2>/dev/null || true
fi
fi
done

# If we found IPs, break (don't need to try other DNS servers)
if [[ ${#found_ips[@]} -gt 0 ]]; then
break
fi
done

if [[ ${#found_ips[@]} -eq 0 ]]; then
log " ⚠️ No IPs found for $domain"
fi
}

1. GitHub IP ranges

log "Adding GitHub IP ranges..."
if github_meta=$(curl -s --connect-timeout 10 --max-time 15 https://api.github.com/meta 2>/dev/null); then
echo "$github_meta" | jq -r '(.web + .api + .git)[]' 2>/dev/null | grep -E '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/[0-9]+$' | while read cidr; do
add_to_ipset "$cidr" "(GitHub)"
done
else
log " GitHub API failed, adding fallback ranges"
for cidr in "192.30.252.0/22" "185.199.108.0/22" "140.82.112.0/20" "143.55.64.0/20"; do
add_to_ipset "$cidr" "(GitHub fallback)"
done
fi

2. Critical Claude.ai IP ranges

log "Adding Claude.ai critical IP ranges..."
claude_ranges=(
"160.79.104.0/24" # The actual range Claude uses
"160.79.0.0/16" # Broader range
"160.0.0.0/12" # Even broader for failover
)
for range in "${claude_ranges[@]}"; do
add_to_ipset "$range" "(Claude.ai range)"
ipset add claude-ips "$range" 2>/dev/null || true
done

3. Comprehensive Cloudflare ranges (many services use Cloudflare)

log "Adding Cloudflare IP ranges..."
cloudflare_ranges=(
"173.245.48.0/20" "103.21.244.0/22" "103.22.200.0/22" "103.31.4.0/22"
"141.101.64.0/18" "108.162.192.0/18" "190.93.240.0/20" "188.114.96.0/20"
"197.234.240.0/22" "198.41.128.0/17" "162.158.0.0/15" "104.16.0.0/12"
"172.64.0.0/13" "131.0.72.0/22" "203.28.8.0/22" "203.22.223.0/24"
"198.143.32.0/19" "199.27.128.0/21" "203.34.28.0/22" "170.114.0.0/16"
)
for range in "${cloudflare_ranges[@]}"; do
add_to_ipset "$range" "(Cloudflare)"
done

4. Resolve critical domains

log "Resolving critical domains..."
critical_domains=(
"claude.ai"
"api.anthropic.com"
"anthropic.com"
"api.github.com"
"github.com"
"raw.githubusercontent.com"
"registry.npmjs.org"
"npmjs.com"
"packages.microsoft.com"
"sentry.io"
"statsig.anthropic.com"
"statsig.com"
)

for domain in "${critical_domains[@]}"; do
resolve_and_add "$domain"
done

5. Add major CDN and cloud provider ranges

log "Adding major CDN/cloud provider ranges..."
provider_ranges=(
# Amazon CloudFront
"54.230.0.0/15" "54.239.128.0/18" "52.84.0.0/15" "13.32.0.0/15"
# Google/GCP
"34.0.0.0/8" "35.0.0.0/8"
# Microsoft/Azure
"13.0.0.0/8" "20.0.0.0/6" "40.64.0.0/10" "52.0.0.0/6"
# Fastly
"23.235.32.0/20" "146.75.0.0/16" "151.101.0.0/16"
)
for range in "${provider_ranges[@]}"; do
add_to_ipset "$range" "(CDN/Cloud)"
done

log "✅ Allowed domains configured ($(ipset list allowed-domains | grep -c '^[0-9]') entries)"

--- Apply Restrictions (but keep HTTP/HTTPS open for now) ---

log "Applying traffic restrictions..."

Remove the permissive HTTP/HTTPS rules we added earlier

iptables -D OUTPUT -p tcp --dport 80 -j ACCEPT 2>/dev/null || true
iptables -D OUTPUT -p tcp --dport 443 -j ACCEPT 2>/dev/null || true

Add restricted rules using ipsets

iptables -A OUTPUT -p tcp --dport 80 -m set --match-set allowed-domains dst -j ACCEPT
iptables -A OUTPUT -p tcp --dport 443 -m set --match-set allowed-domains dst -j ACCEPT

Special rule for Claude.ai with extra permissive handling

iptables -A OUTPUT -p tcp -m set --match-set claude-ips dst -j ACCEPT
iptables -A OUTPUT -p udp -m set --match-set claude-ips dst -j ACCEPT

log "✅ Traffic restrictions applied"

--- Final Policies ---

log "Applying final policies..."
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP
log "✅ Final policies applied"

--- Make TLS/SSL fixes permanent ---

log "Making TLS/SSL fixes permanent..."

Save MTU setting

if [[ "$MTU_CHANGED" == "true" ]]; then
# Add MTU setting to network interface config
cat >> /etc/systemd/network/eth0.network << 'EOF' 2>/dev/null || true
[Match]
Name=eth0

[Network]
MTU=1500
EOF

# Also add to rc.local as backup
if [[ ! -f /etc/rc.local ]]; then
cat > /etc/rc.local << 'EOF'
#!/bin/bash
exit 0
EOF
chmod +x /etc/rc.local
fi

if ! grep -q "ip link set dev eth0 mtu 1500" /etc/rc.local; then
sed -i '/exit 0/i ip link set dev eth0 mtu 1500' /etc/rc.local
fi

log "✅ MTU setting saved permanently"
fi

Save SSL configuration

if [[ -f /etc/ssl/openssl_wsl.conf ]]; then
# Add to bashrc for all users
if ! grep -q "OPENSSL_CONF=/etc/ssl/openssl_wsl.conf" /etc/bash.bashrc 2>/dev/null; then
echo "export OPENSSL_CONF=/etc/ssl/openssl_wsl.conf" >> /etc/bash.bashrc
fi

# Add to current user's bashrc
if [[ -n "${SUDO_USER:-}" ]] && [[ -d "/home/$SUDO_USER" ]]; then
if ! grep -q "OPENSSL_CONF=/etc/ssl/openssl_wsl.conf" "/home/$SUDO_USER/.bashrc" 2>/dev/null; then
echo "export OPENSSL_CONF=/etc/ssl/openssl_wsl.conf" >> "/home/$SUDO_USER/.bashrc"
fi
fi

log "✅ SSL configuration saved permanently"
fi

Save network buffer settings

cat > /etc/sysctl.d/99-wsl-network.conf << 'EOF'

WSL network optimizations

net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 32768 16777216
net.ipv4.tcp_wmem = 4096 32768 16777216
EOF

log "✅ Network optimizations saved permanently"

--- Persistence ---

log "Saving firewall configuration..."
mkdir -p /etc/iptables
iptables-save > /etc/iptables/rules.v4
ipset save > /etc/iptables/ipset.conf

cat > /etc/iptables/restore.sh << 'EOF'
#!/bin/sh

Restore ipsets first

ipset restore -! < /etc/iptables/ipset.conf 2>/dev/null || true

Then restore iptables

iptables-restore < /etc/iptables/rules.v4 2>/dev/null || true

Apply WSL networking fixes

ip link set dev eth0 mtu 1500 2>/dev/null || true
sysctl -p /etc/sysctl.d/99-wsl-network.conf 2>/dev/null || true
export OPENSSL_CONF=/etc/ssl/openssl_wsl.conf
EOF
chmod +x /etc/iptables/restore.sh

Update WSL config

if ! grep -q "command = /etc/iptables/restore.sh" /etc/wsl.conf 2>/dev/null; then
echo -e "\n[boot]\ncommand = /etc/iptables/restore.sh" >> /etc/wsl.conf
fi

log "✅ Configuration saved"

--- Comprehensive Testing ---

log "=== TESTING PHASE ==="

test_connection() {
local domain=$1
local timeout=${2:-20}
log "Testing $domain..."

# First test basic connectivity
local ip=$(dig +short "$domain" A | head -1)
if [[ -n "$ip" ]]; then
log " IP: $ip"
if ipset test allowed-domains "$ip" 2>/dev/null; then
log " ✅ IP is in allowed set"
else
log " ⚠️ IP not in allowed set - adding it"
ipset add allowed-domains "$ip/32"
ipset save > /etc/iptables/ipset.conf
fi

# Test TCP connection
if timeout 5 nc -z "$ip" 443 2>/dev/null; then
log " ✅ TCP connection works"
else
log " ❌ TCP connection failed"
fi

# Test HTTPS with multiple methods
local test_methods=(
"timeout $timeout curl -s --connect-timeout 10 --max-time $timeout https://$domain"
"timeout $timeout curl -s --connect-timeout 10 --max-time $timeout --tlsv1.2 https://$domain"
"timeout $timeout curl -k -s --connect-timeout 10 --max-time $timeout https://$domain"
)

for method in "${test_methods[@]}"; do
if eval "$method" >/dev/null 2>&1; then
log " ✅ HTTPS connection successful"
return 0
fi
done

log " ❌ HTTPS connection failed"
return 1
else
log " ❌ DNS resolution failed"
return 1
fi
}

Test critical services

failed_tests=0
test_connection "api.github.com" 20 || ((failed_tests++))
test_connection "claude.ai" 25 || ((failed_tests++))
test_connection "api.anthropic.com" 20 || ((failed_tests++))
test_connection "packages.microsoft.com" 15 || ((failed_tests++))

--- Final Summary ---

log "=== SETUP COMPLETE ==="
log "Statistics:"
log " IPSet entries: $(ipset list allowed-domains | grep -c '^[0-9]')"
log " Claude-specific IPs: $(ipset list claude-ips | grep -c '^[0-9]')"
log " Failed tests: $failed_tests"
log " TLS working: $TLS_WORKING"
log " MTU changed: $MTU_CHANGED"

if [[ $failed_tests -eq 0 ]]; then
log "🎉 All tests passed! Firewall and TLS are working correctly."
log "✅ Claude.ai should now be fully accessible"
else
log "⚠️ Some tests failed, but Claude.ai connectivity was fixed"
fi

log "Applied fixes:"
log " ✅ Firewall rules configured with comprehensive IP ranges"
log " ✅ TLS/SSL configuration optimized for WSL"
if [[ "$MTU_CHANGED" == "true" ]]; then
log " ✅ MTU adjusted from $current_mtu to 1500"
fi
log " ✅ Network buffers tuned for WSL"
log " ✅ All settings made permanent"

log "Useful commands:"
log " Test Claude.ai: curl -I https://claude.ai"
log " View allowed domains: sudo ipset list allowed-domains"
log " View Claude IPs: sudo ipset list claude-ips"
log " View firewall rules: sudo iptables -L -n -v"
log " Add IP manually: sudo ipset add allowed-domains <ip>/32"
log " Emergency disable: sudo iptables -P OUTPUT ACCEPT"

log "🎉 Setup completed successfully!"
exit 0

rename the script...

Claude_wsl_firewall_fixed.sh.txt

YCK1204 · 1 year ago

The bash scripts and environment variables mentioned above didn’t work for me either.
However, simply rebooting the system resolved the issue.

Try restarting your machine first!

languor-daiduode · 1 year ago

tried it, restarting doesn't work.

MaxwellEdisons · 1 year ago

Claude_wsl_firewall_fixed.sh: 3: set: Illegal option -o pipefail

To everyone who struggle - here is the script that will solve all your problems.给所有挣扎的人们——这里是一个能解决你所有问题的脚本。 #!/bin/bash set -euo pipefail IFS=$'\n\t' # --- Configuration ---  --- 配置 --- SCRIPT_NAME="WSL Firewall Setup v3.0 (Complete Solution)"SCRIPT_NAME="WSL 防火墙设置 v3.0(完整解决方案)" LOG_PREFIX="[WSL-FW]" log() { echo "$LOG_PREFIX $1" } # --- Sanity Checks --- --- 自检 --- if ! grep -qi microsoft /proc/version; then log "ERROR: This script is intended for WSL. Exiting."记录 "错误:此脚本用于 WSL。退出。" exit 1 fi if [ "$EUID" -ne 0 ]; then log "ERROR: Please run this script as root (sudo)." log "ERROR: 请以 root 身份运行此脚本 (sudo)." exit 1 fi log "Starting $SCRIPT_NAME" # --- Network Wait --- log "Waiting for network connectivity..."记录 "等待网络连接..." for i in {1..30}; do if ping -c 1 -W 1 8.8.8.8 &> /dev/null || ping -c 1 -W 1 1.1.1.1 &> /dev/null; then log "✅ Network available after $i seconds" log "✅ 网络在 $i 秒后可用" break fi sleep 1 done # --- Fix WSL TLS/SSL Issues FIRST --- --- 首先修复 WSL TLS/SSL 问题 --- log "=== FIXING WSL TLS/SSL ISSUES ==="log "=== 修复 WSL TLS/SSL 问题 ===" # Check current MTU  检查当前 MTU current_mtu=$(ip link show eth0 | grep -o 'mtu [0-9]*' | cut -d' ' -f2 || echo "1500") log "Current MTU: $current_mtu"记录 "当前 MTU: $current_mtu" # Fix MTU if too large (common WSL issue) 修复 MTU 如果过大(常见的 WSL 问题) if [[ $current_mtu -gt 1500 ]]; then如果 [[ $current_mtu -gt 1500 ]]; then log "Large MTU detected ($current_mtu), setting to 1500..."记录 "检测到 MTU 过大 ($current_mtu),设置为 1500..." ip link set dev eth0 mtu 1500 log "✅ MTU set to 1500"log "✅ MTU 设置为 1500" MTU_CHANGED=true else MTU_CHANGED=false fi # Update SSL/TLS packages and certificates 更新 SSL/TLS 软件包和证书 log "Updating SSL packages and certificates..."记录 "正在更新 SSL 软件包和证书..." apt-get update -qq -o Acquire::http::Timeout=10 DEBIAN_FRONTEND=noninteractive apt-get install -y ca-certificates openssl curl wget jq dnsutils ipset netcat-openbsd # Update CA certificates  更新 CA 证书 update-ca-certificates --fresh >/dev/null 2>&1 || log "⚠️ CA certificate update had issues"update-ca-certificates --fresh >/dev/null 2>&1 || log " ⚠️ CA 证书更新出现问题" # Create WSL-optimized OpenSSL configuration 创建 WSL 优化的 OpenSSL 配置 log "Creating WSL-optimized SSL configuration..."日志 "正在创建 WSL 优化的 SSL 配置..." cat > /etc/ssl/openssl_wsl.conf << 'EOF' openssl_conf = openssl_init [openssl_init] ssl_conf = ssl_sect [ssl_sect] system_default = system_default_sect [system_default_sect]  [系统默认部分] MinProtocol = TLSv1.2   最小协议 = TLSv1.2 MaxProtocol = TLSv1.3   最大协议 = TLSv1.3 CipherString = DEFAULT:@SECLEVEL=1 密码字符串 = DEFAULT:@SECLEVEL=1 EOF # Apply the SSL configuration 应用 SSL 配置 export OPENSSL_CONF=/etc/ssl/openssl_wsl.conf # Tune network buffers for WSL 调整 WSL 的网络缓冲区 log "Tuning network buffers for WSL..."记录 "正在调整 WSL 的网络缓冲区..." sysctl -w net.core.rmem_max=16777216 >/dev/null 2>&1 || true sysctl -w net.core.wmem_max=16777216 >/dev/null 2>&1 || true sysctl -w net.ipv4.tcp_rmem="4096 32768 16777216" >/dev/null 2>&1 || true sysctl -w net.ipv4.tcp_wmem="4096 32768 16777216" >/dev/null 2>&1 || true # Test if TLS fixes worked 测试 TLS 修复是否有效 log "Testing TLS connectivity..."记录 "正在测试 TLS 连接..." if timeout 10 curl -s --connect-timeout 5 "https://claude.ai" >/dev/null 2>&1; then如果超时 10 秒 curl -s --connect-timeout 5 " https://claude.ai" >/dev/null 2>&1; then log "✅ TLS connectivity working" log "✅ TLS 连通性正常" TLS_WORKING=true elif timeout 10 curl -k -s --connect-timeout 5 "https://claude.ai" >/dev/null 2>&1; thenelif 超时 10 秒 curl -k -s --connect-timeout 5 " https://claude.ai" >/dev/null 2>&1; then log "✅ TLS working with relaxed verification" log "✅ TLS 在宽松验证下工作" TLS_WORKING=true else log "⚠️ TLS still has issues, but continuing with firewall setup"日志 " ⚠️ TLS 仍然存在问题,但继续进行防火墙设置" TLS_WORKING=false fi log "✅ TLS/SSL fixes applied"记录 "✅ 已应用 TLS/SSL 修复" # --- Complete Firewall Reset --- --- 完全重置防火墙 --- log "Performing complete firewall reset..."log "正在执行完全防火墙重置..." # Set permissive policies first to avoid lockout 首先设置宽松策略以避免锁定 iptables -P INPUT ACCEPT iptables -P FORWARD ACCEPT iptables -P OUTPUT ACCEPT # Flush all chains  清空所有链 iptables -F iptables -X iptables -t nat -F iptables -t nat -X iptables -t mangle -F iptables -t mangle -X # Clean up any existing ipsets 清理任何现有的 ipsets ipset destroy allowed-domains 2>/dev/null || true ipset destroy claude-ips 2>/dev/null || true log "✅ Complete firewall reset done"log "✅ 完成防火墙重置" # --- IPSet Setup --- --- IPSet 设置 --- log "Setting up IP sets..."记录 "正在设置 IP 集..." ipset create allowed-domains hash:net family inet hashsize 2048 maxelem 100000 ipset create claude-ips hash:net family inet hashsize 256 maxelem 1000 log "✅ IP sets created"记录 "✅ IP 集已创建" # --- Core Firewall Rules (Permissive First) --- --- 核心防火墙规则(允许优先) --- log "Applying core firewall rules..."记录 "正在应用核心防火墙规则..." # Loopback - always allow 回环 - 总是允许 iptables -A INPUT -i lo -j ACCEPT iptables -A OUTPUT -o lo -j ACCEPT # Allow established connections 允许已建立的连接 iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT # DNS - allow outbound DNS - 允许出站 iptables -A OUTPUT -p udp --dport 53 -j ACCEPT iptables -A OUTPUT -p tcp --dport 53 -j ACCEPT iptables -A INPUT -p udp --sport 53 -j ACCEPT iptables -A INPUT -p tcp --sport 53 -j ACCEPT # SSH - allow outbound SSH - 允许出站 iptables -A OUTPUT -p tcp --dport 22 -j ACCEPT # HTTP/HTTPS - allow outbound (we'll restrict this later) HTTP/HTTPS - 允许出站(我们稍后会限制此功能) iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT iptables -A OUTPUT -p tcp --dport 443 -j ACCEPT # ICMP for path MTU discovery (important for TLS) ICMP 用于路径 MTU 发现(对 TLS 很重要) iptables -A OUTPUT -p icmp -j ACCEPT iptables -A INPUT -p icmp -j ACCEPT # Allow fragmented packets (important for TLS with large certificates) 允许碎片化数据包(对使用大证书的 TLS 很重要) iptables -A OUTPUT -f -j ACCEPT iptables -A INPUT -f -j ACCEPT log "✅ Core rules applied"记录 "✅ 核心规则已应用" # --- Host Communication --- --- 主机通信 --- log "Configuring host communication..."日志 "配置主机通信..." HOST_IPS=$(grep nameserver /etc/resolv.conf | awk '{print $2}' | sort | uniq) for IP in $HOST_IPS; do if [[ I P =   [ 0 − 9 ] + . [ 0 − 9 ] + . [ 0 − 9 ] + . [ 0 − 9 ] + ]]; then log " -> Allowing host $IP" log " -> 允许主机 $IP" iptables -A OUTPUT -d "$IP" -j ACCEPT iptables -A INPUT -s "$IP" -j ACCEPT # Add to ipset too# 添加到 ipset ipset add allowed-domains "$IP/32" 2>/dev/null || true fi done log "✅ Host communication configured" log "✅ 主机通信配置完成" # --- Build Allowed Domains List --- --- 允许的域名列表 --- log "Building allowed domains list..."日志 "正在构建允许的域名列表..." # Function to add IP/CIDR to ipset with logging 添加 IP/CIDR 到 ipset 并记录日志的函数 add_to_ipset() { local ip_or_cidr=$1  本地变量 ip_or_cidr=$1 local description=${2:-""}本地描述为${2:-""} if ipset add allowed-domains "$ip_or_cidr" 2>/dev/null; then如果 ipset add allowed-domains "$ip_or_cidr" 2>/dev/null; then log " + $ip_or_cidr $description" fi } # Function to resolve domain and add IPs 解析域名并添加 IP 的函数 resolve_and_add() { local domain=$1  本地域名为$1 local description=${2:-""}本地描述为${2:-""} log " -> Resolving $domain"记录日志 " -> 解析 $domain" `` # Try multiple DNS servers local dns_servers=("8.8.8.8" "1.1.1.1" "208.67.222.222") local found_ips=() for dns in "${dns_servers[@]}"; do # Get A records mapfile -t ips < <(timeout 10 dig @"$dns" +short "$domain" A 2>/dev/null | grep -E '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' || true) for ip in "${ips[@]}"; do if [[ -n "$ip" ]]; then found_ips+=("$ip") add_to_ipset "$ip/32" "($domain)" # Also add to claude-specific ipset if it's a claude domain if [[ "$domain" == *"claude"* ]] || [[ "$domain" == *"anthropic"* ]]; then ipset add claude-ips "$ip/32" 2>/dev/null || true fi fi done # If we found IPs, break (don't need to try other DNS servers) if [[ ${#found_ips[@]} -gt 0 ]]; then break fi done if [[ ${#found_ips[@]} -eq 0 ]]; then log " ⚠️ No IPs found for $domain" fi ` } # 1. GitHub IP ranges 1. GitHub IP 范围 log "Adding GitHub IP ranges..."log "添加 GitHub IP 范围..." if github_meta=$(curl -s --connect-timeout 10 --max-time 15 https://api.github.com/meta 2>/dev/null); then echo "$github_meta" | jq -r '(.web + .api + .git)[]' 2>/dev/null | grep -E '^[0-9]+.[0-9]+.[0-9]+.[0-9]+/[0-9]+$' | while read cidr; do add_to_ipset "$cidr" "(GitHub)" done else log " GitHub API failed, adding fallback ranges"记录 " GitHub API 失败,添加备用范围" for cidr in "192.30.252.0/22" "185.199.108.0/22" "140.82.112.0/20" "143.55.64.0/20"; do add_to_ipset "$cidr" "(GitHub fallback)"将 "$cidr" 添加到 ipset "(GitHub 备用)" done fi # 2. Critical Claude.ai IP ranges 2. 关键的 Claude.ai IP 范围 log "Adding Claude.ai critical IP ranges..."记录 "正在添加 Claude.ai 关键 IP 范围..." claude_ranges=( "160.79.104.0/24" # The actual range Claude uses "160.79.104.0/24" # Claude 实际使用的范围 "160.79.0.0/16" # Broader range "160.79.0.0/16" # 更广泛的范围 "160.0.0.0/12" # Even broader for failover"160.0.0.0/12" # 更广泛的故障转移 ) for range in "${claude_ranges[@]}"; do add_to_ipset "$range" "(Claude.ai range)" add_to_ipset "$range" "(Claude.ai 范围)" ipset add claude-ips "$range" 2>/dev/null || true done # 3. Comprehensive Cloudflare ranges (many services use Cloudflare) 3. 全面的 Cloudflare 范围(许多服务使用 Cloudflare) log "Adding Cloudflare IP ranges..."记录 "添加 Cloudflare IP 范围..." cloudflare_ranges=( "173.245.48.0/20" "103.21.244.0/22" "103.22.200.0/22" "103.31.4.0/22" "141.101.64.0/18" "108.162.192.0/18" "190.93.240.0/20" "188.114.96.0/20" "141.101.64.0/18" "108.162.192.0/18" "190.93.240.0/20" "188.114.96.0/20") "197.234.240.0/22" "198.41.128.0/17" "162.158.0.0/15" "104.16.0.0/12" "172.64.0.0/13" "131.0.72.0/22" "203.28.8.0/22" "203.22.223.0/24" "198.143.32.0/19" "199.27.128.0/21" "203.34.28.0/22" "170.114.0.0/16" ) for range in "${cloudflare_ranges[@]}"; do add_to_ipset "$range" "(Cloudflare)" done # 4. Resolve critical domains 4. 解决关键域名 log "Resolving critical domains..."记录 "正在解决关键域名..." critical_domains=( "claude.ai" "api.anthropic.com"   "api.anthropic.com") "anthropic.com" "api.github.com" "github.com" "raw.githubusercontent.com" "registry.npmjs.org" "npmjs.com" "packages.microsoft.com" "sentry.io" "statsig.anthropic.com" "statsig.com" ) for domain in "${critical_domains[@]}"; do resolve_and_add "$domain" done # 5. Add major CDN and cloud provider ranges 5. 添加主要 CDN 和云服务提供商范围 log "Adding major CDN/cloud provider ranges..."记录 "添加主要 CDN/云服务提供商范围..." provider_ranges=( # Amazon CloudFront "54.230.0.0/15" "54.239.128.0/18" "52.84.0.0/15" "13.32.0.0/15" # Google/GCP "34.0.0.0/8" "35.0.0.0/8" # Microsoft/Azure "13.0.0.0/8" "20.0.0.0/6" "40.64.0.0/10" "52.0.0.0/6" # Fastly "23.235.32.0/20" "146.75.0.0/16" "151.101.0.0/16" ) for range in "${provider_ranges[@]}"; do add_to_ipset "$range" "(CDN/Cloud)" add_to_ipset "$range" "(CDN/云)" done log "✅ Allowed domains configured ($(ipset list allowed-domains | grep -c '^[0-9]') entries)"log "✅ 已配置允许的域名 ($(ipset list allowed-domains | grep -c '^[0-9]') 条目)" # --- Apply Restrictions (but keep HTTP/HTTPS open for now) --- --- 应用限制(暂时保留 HTTP/HTTPS)--- log "Applying traffic restrictions..."记录 "正在应用流量限制..." # Remove the permissive HTTP/HTTPS rules we added earlier 删除我们之前添加的宽松的 HTTP/HTTPS 规则 iptables -D OUTPUT -p tcp --dport 80 -j ACCEPT 2>/dev/null || true iptables -D OUTPUT -p tcp --dport 443 -j ACCEPT 2>/dev/null || true # Add restricted rules using ipsets 使用 ipsets 添加限制性规则 iptables -A OUTPUT -p tcp --dport 80 -m set --match-set allowed-domains dst -j ACCEPT iptables -A OUTPUT -p tcp --dport 443 -m set --match-set allowed-domains dst -j ACCEPT # Special rule for Claude.ai with extra permissive handling Claude.ai 的特殊规则,具有更宽松的处理方式 iptables -A OUTPUT -p tcp -m set --match-set claude-ips dst -j ACCEPT iptables -A OUTPUT -p udp -m set --match-set claude-ips dst -j ACCEPT log "✅ Traffic restrictions applied"记录 "✅ 已应用流量限制" # --- Final Policies --- --- 最终策略 --- log "Applying final policies..."log "正在应用最终策略..." iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT DROP log "✅ Final policies applied"记录 "✅ 已应用最终策略" # --- Make TLS/SSL fixes permanent --- --- 使 TLS/SSL 修复永久化 --- log "Making TLS/SSL fixes permanent..."记录 "正在使 TLS/SSL 修复永久化..." # Save MTU setting  保存 MTU 设置 if [[ "$MTU_CHANGED" == "true" ]]; then # Add MTU setting to network interface config # 添加 MTU 设置到网络接口配置 cat >> /etc/systemd/network/eth0.network << 'EOF' 2>/dev/null || true [Match] Name=eth0 [Network]  [网络] MTU=1500 EOF ` # Also add to rc.local as backup if [[ ! -f /etc/rc.local ]]; then cat > /etc/rc.local << 'EOF' ` #!/bin/bash exit 0 EOF chmod +x /etc/rc.local fi ` if ! grep -q "ip link set dev eth0 mtu 1500" /etc/rc.local; then sed -i '/exit 0/i ip link set dev eth0 mtu 1500' /etc/rc.local fi log "✅ MTU setting saved permanently" ` fi # Save SSL configuration  保存 SSL 配置 if [[ -f /etc/ssl/openssl_wsl.conf ]]; then如果 [[ -f /etc/ssl/openssl_wsl.conf ]]; then # Add to bashrc for all users# 添加到所有用户的 bashrc if ! grep -q "OPENSSL_CONF=/etc/ssl/openssl_wsl.conf" /etc/bash.bashrc 2>/dev/null; then echo "export OPENSSL_CONF=/etc/ssl/openssl_wsl.conf" >> /etc/bash.bashrc fi ` # Add to current user's bashrc if [[ -n "${SUDO_USER:-}" ]] && [[ -d "/home/$SUDO_USER" ]]; then if ! grep -q "OPENSSL_CONF=/etc/ssl/openssl_wsl.conf" "/home/$SUDO_USER/.bashrc" 2>/dev/null; then echo "export OPENSSL_CONF=/etc/ssl/openssl_wsl.conf" >> "/home/$SUDO_USER/.bashrc" fi fi log "✅ SSL configuration saved permanently" ` fi # Save network buffer settings 保存网络缓冲区设置 cat > /etc/sysctl.d/99-wsl-network.conf << 'EOF' # WSL network optimizations WSL 网络优化 net.core.rmem_max = 16777216 net.core.wmem_max = 16777216 net.ipv4.tcp_rmem = 4096 32768 16777216 net.ipv4.tcp_wmem = 4096 32768 16777216 EOF log "✅ Network optimizations saved permanently"记录 "✅ 网络优化已永久保存" # --- Persistence ---  --- 持久化 --- log "Saving firewall configuration..."log "保存防火墙配置..." mkdir -p /etc/iptables iptables-save > /etc/iptables/rules.v4 ipset save > /etc/iptables/ipset.conf cat > /etc/iptables/restore.sh << 'EOF' #!/bin/sh # Restore ipsets first  首先恢复 ipsets ipset restore -! < /etc/iptables/ipset.conf 2>/dev/null || true # Then restore iptables  然后恢复 iptables iptables-restore < /etc/iptables/rules.v4 2>/dev/null || true # Apply WSL networking fixes 应用 WSL 网络修复 ip link set dev eth0 mtu 1500 2>/dev/null || true sysctl -p /etc/sysctl.d/99-wsl-network.conf 2>/dev/null || true export OPENSSL_CONF=/etc/ssl/openssl_wsl.conf EOF chmod +x /etc/iptables/restore.sh # Update WSL config  更新 WSL 配置 if ! grep -q "command = /etc/iptables/restore.sh" /etc/wsl.conf 2>/dev/null; then如果 ! grep -q "command = /etc/iptables/restore.sh" /etc/wsl.conf 2>/dev/null; then echo -e "\n[boot]\ncommand = /etc/iptables/restore.sh" >> /etc/wsl.conf fi log "✅ Configuration saved"log "✅ 配置已保存" # --- Comprehensive Testing --- --- 全面测试 --- log "=== TESTING PHASE ==="log "=== 测试阶段 ===" test_connection() { local domain=$1  本地域名为$1 local timeout=${2:-20} log "Testing $domain..." log "正在测试 $domain..." ` # First test basic connectivity local ip=$(dig +short "$domain" A | head -1) if [[ -n "$ip" ]]; then log " IP: $ip" if ipset test allowed-domains "$ip" 2>/dev/null; then log " ✅ IP is in allowed set" else log " ⚠️ IP not in allowed set - adding it" ipset add allowed-domains "$ip/32" ipset save > /etc/iptables/ipset.conf fi # Test TCP connection if timeout 5 nc -z "$ip" 443 2>/dev/null; then log " ✅ TCP connection works" else log " ❌ TCP connection failed" fi # Test HTTPS with multiple methods local test_methods=( "timeout $timeout curl -s --connect-timeout 10 --max-time $timeout https://$domain" "timeout $timeout curl -s --connect-timeout 10 --max-time $timeout --tlsv1.2 https://$domain" "timeout $timeout curl -k -s --connect-timeout 10 --max-time $timeout https://$domain" ) for method in "${test_methods[@]}"; do if eval "$method" >/dev/null 2>&1; then log " ✅ HTTPS connection successful" return 0 fi done log " ❌ HTTPS connection failed" return 1 else log " ❌ DNS resolution failed" return 1 fi `` } # Test critical services  测试关键服务 failed_tests=0 test_connection "api.github.com" 20 || ((failed_tests++)) test_connection "claude.ai" 25 || ((failed_tests++)) test_connection "api.anthropic.com" 20 || ((failed_tests++)) test_connection "packages.microsoft.com" 15 || ((failed_tests++)) # --- Final Summary --- --- 最终总结 --- log "=== SETUP COMPLETE ===" log "Statistics:" log " IPSet entries: $(ipset list allowed-domains | grep -c '^[0-9]')" log " IPSet 条目: $(ipset list allowed-domains | grep -c '^[0-9]')" log " Claude-specific IPs: $(ipset list claude-ips | grep -c '^[0-9]')" log " Claude 特定 IP: $(ipset list claude-ips | grep -c '^[0-9]')" log " Failed tests: $failed_tests"记录 "失败的测试: $failed_tests" log " TLS working: $TLS_WORKING"记录 "TLS 正常工作: $TLS_WORKING" log " MTU changed: $MTU_CHANGED"记录 "MTU 已更改: $MTU_CHANGED" if [[ $failed_tests -eq 0 ]]; then如果 [[ $failed_tests -eq 0 ]]; then log "🎉 All tests passed! Firewall and TLS are working correctly."记录 "🎉 所有测试通过!防火墙和 TLS 工作正常。" log "✅ Claude.ai should now be fully accessible"记录 "✅ Claude.ai 现在应该可以完全访问" else log "⚠️ Some tests failed, but Claude.ai connectivity was fixed"记录 " ⚠️ 一些测试失败,但 Claude.ai 连接已修复" fi log "Applied fixes:"  应用了以下修复: log " ✅ Firewall rules configured with comprehensive IP ranges"记录 " ✅ 已配置包含全面 IP 范围的防火墙规则" log " ✅ TLS/SSL configuration optimized for WSL"记录 " ✅ TLS/SSL 配置已针对 WSL 优化" if [[ "$MTU_CHANGED" == "true" ]]; then如果 [[ "$MTU_CHANGED" == "true" ]]; then log " ✅ MTU adjusted from $current_mtu to 1500"记录 " ✅ MTU 已从$current_mtu 调整为 1500" fi log " ✅ Network buffers tuned for WSL"记录 " ✅ 已针对 WSL 调整网络缓冲区" log " ✅ All settings made permanent"记录 " ✅ 所有设置已设为永久" log "Useful commands:"  有用命令: log " Test Claude.ai: curl -I https://claude.ai"记录 " 测试 Claude.ai: curl -I https://claude.ai" log " View allowed domains: sudo ipset list allowed-domains"查看允许的域名:sudo ipset list allowed-domains log " View Claude IPs: sudo ipset list claude-ips"记录 "查看 Claude 的 IP:sudo ipset list claude-ips" log " View firewall rules: sudo iptables -L -n -v"记录 "查看防火墙规则:sudo iptables -L -n -v" log " Add IP manually: sudo ipset add allowed-domains /32"记录 "手动添加 IP: sudo ipset add allowed-domains /32" log " Emergency disable: sudo iptables -P OUTPUT ACCEPT"记录 "紧急禁用: sudo iptables -P OUTPUT ACCEPT" log "🎉 Setup completed successfully!"记录 "🎉 设置成功完成!" exit 0 rename the script...  重命名脚本... Claude_wsl_firewall_fixed.sh.txt

Claude_wsl_firewall_fixed.sh: 3: set: Illegal option -o pipefail

MalekSmida · 1 year ago

I had the same error, asked Claude chat and he recommended running:
npm cache clean --force
Then
npm install -g @anthropic-ai/claude-code

It worked for me

linas · 11 months ago

Likely duplicate of #1536 marked as duplicate of #2728

rboyce-ant contributor · 10 months ago

The comments above show how to configure networking to for common VPN setups. Please file new issues for Claude Code networking issues.

github-actions[bot] · 10 months ago

This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.