claude-code icon indicating copy to clipboard operation
claude-code copied to clipboard

[BUG] VPN conflict

Open trentmkelly opened this issue 9 months ago • 9 comments

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)

trentmkelly avatar Mar 16 '25 17:03 trentmkelly

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?

8enmann avatar Mar 17 '25 23:03 8enmann

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

  • https://registry.npmjs.org/
  • https://api.anthropic.com/
  • https://sentry.io/welcome/
  • https://statsig.anthropic.com/
  • https://statsig.com/

Thank you.

MPeli avatar Apr 09 '25 11:04 MPeli

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 [email protected]
2 info using [email protected]
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.

MPeli avatar Apr 10 '25 06:04 MPeli

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

netbrain avatar Apr 11 '25 06:04 netbrain

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 avatar May 05 '25 15:05 zhil

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 avatar May 06 '25 22:05 zhil

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

zhil avatar May 07 '25 15:05 zhil

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

knoel99 avatar Jun 02 '25 07:06 knoel99

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 /32" log " Emergency disable: sudo iptables -P OUTPUT ACCEPT"

log "🎉 Setup completed successfully!" exit 0

rename the script...

Claude_wsl_firewall_fixed.sh.txt

1ehden avatar Jun 16 '25 20:06 1ehden

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!

YCK1204 avatar Jul 06 '25 15:07 YCK1204

tried it, restarting doesn't work.

languor-daiduode avatar Jul 08 '25 02:07 languor-daiduode

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

  1. 关键的 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)

  1. 全面的 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

  1. 解决关键域名 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

  1. 添加主要 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

MaxwellEdisons avatar Jul 08 '25 06:07 MaxwellEdisons

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

MalekSmida avatar Jul 08 '25 13:07 MalekSmida

Likely duplicate of #1536 marked as duplicate of #2728

linas avatar Jul 28 '25 03:07 linas

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

rboyce-ant avatar Aug 22 '25 18:08 rboyce-ant

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.

github-actions[bot] avatar Aug 31 '25 14:08 github-actions[bot]