32.1 企業網路配置
32.1.1 代理服务器配置
HTTP/HTTPS 代理
Claude Code 支援標準的環境變數來配置代理伺服器:
python
# HTTPS 代理(推荐)
export HTTPS_PROXY=<https://proxy.example.com:8080>
# HTTP 代理(如果 HTTPS 不可用)
export HTTP_PROXY=<http://proxy.example.com:8080>
# 代理白名单(不通过代理的地址)
export NO_PROXY="localhost 127.0.0.1 192.168.1.1 example.com .example.com"
### 代理配置管理器
bash
python
class ProxyConfigManager:
"""代理配置管理器"""
def __init__(self):
self.config = {
'https_proxy': None,
'http_proxy': None,
'no_proxy': [],
'proxy_auth': None
}
def configure(self, proxy_settings: Dict) -> ConfigResult:
"""配置代理"""
result = ConfigResult()
# 设置 HTTPS 代理
if 'https_proxy' in proxy_settings:
self.config['https_proxy'] = proxy_settings['https_proxy']
os.environ['HTTPS_PROXY'] = self.config['https_proxy']
result.add_setting('HTTPS_PROXY', self.config['https_proxy'])
# 设置 HTTP 代理
if 'http_proxy' in proxy_settings:
self.config['http_proxy'] = proxy_settings['http_proxy']
os.environ['HTTP_PROXY'] = self.config['http_proxy']
result.add_setting('HTTP_PROXY', self.config['http_proxy'])
# 设置白名单
if 'no_proxy' in proxy_settings:
no_proxy_list = ' '.join(proxy_settings['no_proxy'])
self.config['no_proxy'] = proxy_settings['no_proxy']
os.environ['NO_PROXY'] = no_proxy_list
result.add_setting('NO_PROXY', no_proxy_list)
# 验证配置
validation = self._validate_config()
result.validation = validation
return result
def _validate_config(self) -> ValidationResult:
"""验证配置"""
validation = ValidationResult()
# 检查代理 URL 格式
for proxy_type in ['https_proxy', 'http_proxy']:
proxy_url = self.config.get(proxy_type)
if proxy_url:
if not self._is_valid_url(proxy_url):
validation.add_error(
f"Invalid {proxy_type} URL: {proxy_url}"
)
# 测试代理连接
if self.config.get('https_proxy'):
if not self._test_proxy_connection(self.config['https_proxy']):
validation.add_error(
"Cannot connect to HTTPS proxy"
)
return validation
def _is_valid_url(self, url: str) -> bool:
"""验证 URL 格式"""
try:
result = urllib.parse.urlparse(url)
return all([result.scheme, result.netloc])
except Exception:
return False
def _test_proxy_connection(self, proxy_url: str) -> bool:
"""测试代理连接"""
try:
parsed = urllib.parse.urlparse(proxy_url)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(5)
result = sock.connect_ex((parsed.hostname, parsed.port or 8080))
sock.close()
return result == 0
except Exception:
return False
### 代理身份验证
#### 基本身份验证
# 在代理 URL 中包含凭据
export HTTPS_PROXY=http://username:password@proxy.example.com:8080
export HTTP_PROXY=http://username:password@proxy.example.com:8080
#### NTLM/Kerberos 认证對於需要高階身份驗證的代理,建議使用 LLM 閘道器:
python
bash
bash
# 配置 LLM 网关处理代理认证
export ANTHROPIC_BASE_URL=https://llm-gateway.company.com
export ANTHROPIC_AUTH_TOKEN=gateway-token
### 代理配置最佳实践
## 32.1.2 自定义 CA 证书
### 配置自定义 CA
企业环境通常使用自定义证书颁发机构(CA)来签发内部证书。Claude Code 需要配置以信任这些 CA:
# 配置自定义 CA 证书
export NODE_EXTRA_CA_CERTS=/path/to/ca-cert.pem
# 或使用多个证书
export NODE_EXTRA_CA_CERTS=/path/to/ca1.pem:/path/to/ca2.pem
### CA 证书管理器
bash
python
class CACertificateManager:
"""CA 证书管理器"""
def __init__(self):
self.certificates = []
self.certificate_store = '/etc/ssl/certs'
def add_certificate(self, cert_path: str) -> CertResult:
"""添加 CA 证书"""
result = CertResult()
# 验证证书
if not self._validate_certificate(cert_path):
result.success = False
result.error = "Invalid certificate"
return result
# 复制证书到存储
cert_name = os.path.basename(cert_path)
dest_path = os.path.join(self.certificate_store, cert_name)
shutil.copy(cert_path, dest_path)
self.certificates.append(dest_path)
# 更新环境变量
self._update_ca_bundle()
result.success = True
result.certificate_path = dest_path
return result
def _validate_certificate(self, cert_path: str) -> bool:
"""验证证书"""
try:
with open(cert_path, 'rb') as f:
cert_data = f.read()
# 使用 OpenSSL 验证
result = subprocess.run(
['openssl', 'x509', '-in', cert_path, '-noout'],
capture_output=True
)
return result.returncode == 0
except Exception:
return False
def _update_ca_bundle(self):
"""更新 CA 包"""
cert_paths = ':'.join(self.certificates)
os.environ['NODE_EXTRA_CA_CERTS'] = cert_paths
### 证书格式转换
# 将 DER 格式转换为 PEM 格式
openssl x509 -inform der -in certificate.cer -out certificate.pem
# 将 PKCS#12 格式转换为 PEM 格式
openssl pkcs12 -in certificate.p12 -out certificate.pem -nodes
# 提取证书链
openssl s_client -connect server:port -showcerts
## 32.1.3 mTLS 身份验证
### mTLS 配置對於需要客戶端證書身份驗證的企業環境:
python
bash
bash
# 客户端证书
export CLAUDE_CODE_CLIENT_CERT=/path/to/client-cert.pem
# 客户端私钥
export CLAUDE_CODE_CLIENT_KEY=/path/to/client-key.pem
# 私钥密码短语(如果加密)
export CLAUDE_CODE_CLIENT_KEY_PASSPHRASE="your-passphrase"
### mTLS 配置管理器
class MTLSConfigManager:
"""mTLS 配置管理器"""
def __init__(self):
self.config = {
'client_cert': None,
'client_key': None,
'key_passphrase': None
}
def configure(self, mtls_settings: Dict) -> ConfigResult:
"""配置 mTLS"""
result = ConfigResult()
# 设置客户端证书
if 'client_cert' in mtls_settings:
cert_path = mtls_settings['client_cert']
if self._validate_certificate(cert_path):
self.config['client_cert'] = cert_path
os.environ['CLAUDE_CODE_CLIENT_CERT'] = cert_path
result.add_setting('CLAUDE_CODE_CLIENT_CERT', cert_path)
else:
result.add_error("Invalid client certificate")
# 设置客户端密钥
if 'client_key' in mtls_settings:
key_path = mtls_settings['client_key']
if self._validate_key(key_path):
self.config['client_key'] = key_path
os.environ['CLAUDE_CODE_CLIENT_KEY'] = key_path
result.add_setting('CLAUDE_CODE_CLIENT_KEY', key_path)
else:
result.add_error("Invalid client key")
# 设置密钥密码短语
if 'key_passphrase' in mtls_settings:
self.config['key_passphrase'] = mtls_settings['key_passphrase']
os.environ['CLAUDE_CODE_CLIENT_KEY_PASSPHRASE'] = \
mtls_settings['key_passphrase']
result.add_setting('CLAUDE_CODE_CLIENT_KEY_PASSPHRASE', '***')
# 验证配置
validation = self._validate_mtls_config()
result.validation = validation
return result
def _validate_key(self, key_path: str) -> bool:
"""验证私钥"""
try:
result = subprocess.run(
['openssl', 'rsa', '-in', key_path, '-check', '-noout'],
capture_output=True
)
return result.returncode == 0
except Exception:
return False
def _validate_mtls_config(self) -> ValidationResult:
"""验证 mTLS 配置"""
validation = ValidationResult()
# 检查证书和密钥是否匹配
if (self.config['client_cert'] and
self.config['client_key']):
if not self._check_cert_key_match():
validation.add_error(
"Certificate and key do not match"
)
return validation
def _check_cert_key_match(self) -> bool:
"""检查证书和密钥是否匹配"""
try:
# 提取证书的公钥模数
cert_result = subprocess.run(
['openssl', 'x509', '-noout', '-modulus', '-in',
self.config['client_cert']],
capture_output=True,
text=True
)
# 提取密钥的公钥模数
key_result = subprocess.run(
['openssl', 'rsa', '-noout', '-modulus', '-in',
self.config['client_key']],
capture_output=True,
text=True
)
return cert_result.stdout == key_result.stdout
except Exception:
return False
## 32.1.4 网络访问要求
### 必需的 URLClaude Code 需要訪問以下 URL:
| URL | 用途 | 協議 |
|---|
api.anthropic.com| Claude API 端點| HTTPS claude.ai| WebFetch 保護措施| HTTPS statsig.anthropic.com| 遙測和指標| HTTPS sentry.io| 錯誤報告| HTTPS
python
### 防火墙配置
bash
python
class FirewallConfigurator:
"""防火墙配置器"""
def __init__(self):
self.required_urls = [
'api.anthropic.com',
'claude.ai',
'statsig.anthropic.com',
'sentry.io'
]
def generate_rules(self,
firewall_type: str = 'iptables') -> List[str]:
"""生成防火墙规则"""
rules = []
if firewall_type == 'iptables':
rules = self._generate_iptables_rules()
elif firewall_type == 'aws':
rules = self._generate_aws_rules()
elif firewall_type == 'gcp':
rules = self._generate_gcp_rules()
return rules
def _generate_iptables_rules(self) -> List[str]:
"""生成 iptables 规则"""
rules = []
for url in self.required_urls:
# 解析域名获取 IP
try:
ips = socket.gethostbyname_ex(url)[2]
for ip in ips:
rule = f"iptables -A OUTPUT -d {ip} -p tcp --dport 443 -j ACCEPT"
rules.append(rule)
except socket.gaierror:
pass
return rules
def _generate_aws_rules(self) -> List[str]:
"""生成 AWS 安全组规则"""
rules = []
for url in self.required_urls:
# AWS 需要使用 IP 范围
# 这里简化处理,实际需要查询 IP 范围
rule = {
'type': 'egress',
'protocol': 'tcp',
'port': 443,
'destination': url,
'action': 'allow'
}
rules.append(rule)
return rules
def _generate_gcp_rules(self) -> List[str]:
"""生成 GCP 防火墙规则"""
rules = []
for url in self.required_urls:
rule = {
'direction': 'EGRESS',
'action': 'ALLOW',
'rules': [{
'protocol': 'tcp',
'ports': ['443'],
'destinationRanges': [self._resolve_ip_range(url)]
}]
}
rules.append(rule)
return rules
def _resolve_ip_range(self, url: str) -> str:
"""解析 IP 范围"""
# 简化实现,实际需要查询 DNS 或 IP 范围
try:
ip = socket.gethostbyname(url)
return f"{ip}/32"
except socket.gaierror:
return "0.0.0.0/0"
### 网络连接测试
class NetworkTester:
"""网络测试器"""
def __init__(self):
self.required_urls = [
'https://api.anthropic.com',
'https://claude.ai',
'https://statsig.anthropic.com'
]
def test_all(self) -> NetworkTestResult:
"""测试所有网络连接"""
result = NetworkTestResult()
for url in self.required_urls:
test_result = self._test_url(url)
result.add_result(url, test_result)
# 生成报告
result.summary = self._generate_summary(result.results)
return result
def _test_url(self, url: str) -> URLTestResult:
"""测试单个 URL"""
result = URLTestResult(url=url)
try:
start_time = time.time()
response = requests.get(url, timeout=10)
end_time = time.time()
result.success = response.status_code == 200
result.latency = (end_time - start_time) * 1000 # ms
result.status_code = response.status_code
except requests.exceptions.Timeout:
result.success = False
result.error = "Timeout"
except requests.exceptions.ConnectionError:
result.success = False
result.error = "Connection error"
except Exception as e:
result.success = False
result.error = str(e)
return result
def _generate_summary(self,
results: Dict[str, URLTestResult]) -> str:
"""生成测试摘要"""
total = len(results)
successful = sum(1 for r in results.values() if r.success)
summary = f"Network Test Summary:\n"
summary += f"Total: {total}, Successful: {successful}, Failed: {total - successful}\n\n"
for url, result in results.items():
status = "✓" if result.success else "✗"
summary += f"{status} {url}: "
if result.success:
summary += f"OK ({result.latency:.0f}ms)\n"
else:
summary += f"FAILED ({result.error})\n"
return summary