以前自建代理,最折腾的不是买服务器,而是把它配通:问 ChatGPT 要一份 sing-box 配置,再对着官方文档把 inbound、outbound、route 一个个改,改完自己测。一个参数对不上,一晚上就没了。
这次我只做了两件事:在 AWS 控制台开一台机器、放行安全组。剩下的全部交给 Claude Code,用几句中文对话完成。
开始前先说明网络条件:Claude Code 默认连 Anthropic 官方的模型,需要能访问国际网络。如果你现在还没有可用的国际网络(这正是要搭代理的原因),可以先把 Claude Code 接到国产模型上,比如 DeepSeek、Kimi、GLM、Qwen 这类提供 Anthropic 兼容接口的服务,设好
ANTHROPIC_BASE_URL和对应的 API Key 就能用。本文这类 SSH 连服务器、改配置、排查报错的任务,国产模型也能完成。也可以直接换一个原生支持国产模型的 Agent 工具,比如 OpenCode 接 DeepSeek,或者 DeepSeek 官方的 DeepSeek Harness(dsh),把下文每一步“我说的话”原样发给它即可。代理搭好之后,再切回官方模型也可以。
这篇是视频的图文版,方便你照着做。每一步都写了三样东西:
- 我说的话:直接对 Agent 说的原话,你可以照抄
- 它做了什么:Agent 实际执行的操作
- 你可以核对的点:如果不用 Agent、想手动来,或者想检查它做得对不对,看这里
文中的 IP、UUID、Reality 密钥、short ID、Hysteria2 密码和证书指纹都是为本文单独生成的示范值,与录屏里的服务器无关。照着做时请全部换成你自己生成的,不要直接用文中的密钥和密码。
最终效果
- 服务端:一台 AWS EC2(Ubuntu,t3.micro),跑 sing-box,同时提供两个节点
- VLESS + Reality(TCP 443),不需要域名
- Hysteria2(UDP 443),自签证书
- 服务器加固:BBR 拥塞控制、fail2ban 防 SSH 爆破
- 客户端:Clash Verge,国内直连、广告拦截、其余走代理,两个节点可切换
整个过程中,我手动操作的只有 AWS 控制台里的开机器和改安全组。
想更进一步:这两步也可以交给 Agent。本地装好 AWS CLI,用
aws configure配好访问密钥,就可以直接对它说“帮我开一台 Ubuntu 的 t3.micro,安全组放行 TCP 22、TCP 443 和 UDP 443”,开实例、建密钥对、改安全组都由它用命令完成,全程不用打开控制台。但是配置IAM和密钥对于小白用户来说可能有点复杂,本期视频没有采用。
原理:客户端和服务端
一套代理有两个角色:
- 客户端跑在你的电脑或手机上,把应用发出的流量拦下来、加密后发出去
- 服务端是海外的一台服务器,解密请求,替你访问目标网站,再把结果加密传回来
客户端软件基本都开源免费。服务端有两种来源:买现成的商业节点,或者自己租 VPS 搭。
商业节点省心,但通常是一群人共用一个 IP,容易被各种服务风控,隐私也不在自己手里。自建是一个人独享 IP,协议、端口、分流规则全由自己定。自建过去最大的门槛是配置复杂,有了 Agent,这个门槛基本没了。
准备工作
需要两样东西:
- 一台海外云服务器。本文用 AWS EC2,其他 VPS 也一样
- 一个能执行命令的编码 Agent。本文用 Claude Code,本地终端里运行。其他codex,opencode,deepseek dsh 等Agent 智能体也可以。
技术栈:
| 组件 | 选择 | 说明 |
|---|---|---|
| 代理核心 | sing-box | 服务端 |
| 协议 1 | VLESS + Reality | 走 TCP,不需要域名,伪装成访问一个真实大站 |
| 协议 2 | Hysteria2 | 走 UDP(QUIC),某些网络下更快,和 VLESS 互为备份 |
| 客户端 | Clash Verge | 内核是 mihomo,macOS / Windows / Linux 都有 |
在 AWS 开一台 EC2
登录 AWS 控制台 → EC2 → 启动实例:
- 系统:Ubuntu
- 实例类型:
t3.micro(免费套餐档位,跑代理够用) - 密钥对:新建一个,类型选 ED25519,把
.pem私钥下载到本地(这就是等会儿交给 Agent 的钥匙) - 网络设置 / 安全组:勾选 允许 SSH 和 允许 HTTPS
第 4 步记住,HTTPS 放行的只是 TCP 443。后面加 Hysteria2 的时候,这里会埋一个雷。
启动后记下实例的公网 IP。
第一步:把钥匙交给 Agent
我说的话:
帮我配置连接我的 aws 服务器,key 在 download 下面,服务器 IP 是
203.0.113.10
它做了什么:
- 在
~/Downloads里找到.pem文件,挪到~/.ssh/,改成600权限 - 在
~/.ssh/config里给服务器起了个别名yt-demo - 自己连一次,确认能登录
你可以核对的点: ~/.ssh/config 里多了这样一段:
Host yt-demo
HostName 203.0.113.10
User ubuntu
IdentityFile ~/.ssh/yt-demo.pem
另开一个终端,ssh yt-demo 能直接登录进去,就说明这一步没问题。从这以后,后面的活基本只需要动嘴。
第二步:安装 sing-box
我说的话:
帮我在服务器安装 sing-box
它做了什么:
- 先用
uname -m、/etc/os-release探测系统和 CPU 架构 - 没有去 GitHub 手动下载安装包,而是接上了 sing-box 官方的 APT 软件源,以后
apt upgrade就能跟着系统一起升级 - 装完列出了下一步:写配置文件、设开机自启、在安全组放行端口
你可以核对的点: 官方 APT 源的安装方式(以 sing-box 官方文档 为准):
sudo mkdir -p /etc/apt/keyrings
sudo curl -fsSL https://sing-box.app/gpg.key -o /etc/apt/keyrings/sagernet.asc
sudo chmod a+r /etc/apt/keyrings/sagernet.asc
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/sagernet.asc] https://deb.sagernet.org/ * *" \
| sudo tee /etc/apt/sources.list.d/sagernet.list
sudo apt-get update
sudo apt-get install sing-box
sing-box version
第三步:服务端配置 VLESS Reality + 开启 BBR
配置 VLESS Reality
我说的话:
配置 VLESS-Reality,端口 443
VLESS Reality 需要准备四样东西:一个 UUID、一对 Reality 密钥、一个 short ID,以及一个伪装目标站点。以前挑伪装站点最麻烦,得自己一个个拿 curl 去试。
它做了什么:
- 挑伪装站点:在服务器上把微软、苹果、火狐插件站(
addons.mozilla.org)几个候选挨个测了一遍,看谁支持 TLS 1.3 和 HTTP/2、延迟又低,最后选中了addons.mozilla.org - 生成密钥:UUID、Reality 密钥对、short ID 全部用 sing-box 自带命令生成
- 写配置:写入
/etc/sing-box/config.json,先用sing-box check校验,再重启服务 - 外部探测:从本地探测 443 端口是否能连通
- 交付:给出一整张参数表,外加一条可以直接导入客户端的
vless://分享链接
你可以核对的点:
测伪装站点是否合格(要求:能协商 TLS 1.3,支持 HTTP/2,延迟低):
curl -so /dev/null --tlsv1.3 --http2 \
-w '%{http_version} connect=%{time_connect}s\n' \
https://addons.mozilla.org
生成需要的参数:
sing-box generate uuid # UUID
sing-box generate reality-keypair # PrivateKey 放服务端,PublicKey 给客户端
sing-box generate rand 8 --hex # short ID
服务端配置大致是这个结构(后面加 Hysteria2 时会再加一个 inbound):
{
"log": { "level": "warn" },
"inbounds": [
{
"type": "vless",
"tag": "vless-in",
"listen": "::",
"listen_port": 443,
"users": [
{ "uuid": "9bf3fe50-b240-4431-b355-52000d20c45e", "flow": "xtls-rprx-vision" }
],
"tls": {
"enabled": true,
"server_name": "addons.mozilla.org",
"reality": {
"enabled": true,
"handshake": { "server": "addons.mozilla.org", "server_port": 443 },
"private_key": "SKrVhmmC4Dl-IV0tVUQqND8vW8o7j0bmS59s8zuYBVI",
"short_id": ["d0902526d9e9ea13"]
}
}
}
],
"outbounds": [
{ "type": "direct", "tag": "direct" }
]
}
sudo sing-box check -c /etc/sing-box/config.json
sudo systemctl enable --now sing-box
sudo systemctl restart sing-box
开启 BBR
我说的话:
检查一下 bbr 是否开启,sing-box 设置一下开机自启
它做了什么:
- 发现服务器默认用的是老的
cubic拥塞控制算法,换成了 BBR,改善跨国线路丢包时的吞吐 - 确认 sing-box 已经设为开机自启
- 改完没有直接交差,而是主动重启了一次服务器,等机器重新上线后,再确认 BBR 仍然生效、sing-box 也自己起来了
你可以核对的点:
# 开启 BBR(写进 sysctl.d,重启后仍然有效)
echo -e "net.core.default_qdisc=fq\nnet.ipv4.tcp_congestion_control=bbr" \
| sudo tee /etc/sysctl.d/99-bbr.conf
sudo sysctl --system
# 验证
sysctl net.ipv4.tcp_congestion_control # 应输出 bbr
systemctl is-enabled sing-box # 应输出 enabled
第四步:选一个本地客户端
服务端就绪后,本地装一个图形化客户端。可以按自己习惯选:
- Clash Verge Rev(本文使用,在 GitHub Releases 下载)
- v2rayN
- sing-box 官方客户端(SFM / SFA / SFI)
第五步:让 Agent 写客户端配置,并在本地联调
我说的话:
我本地使用 clash verge,给我一个本地的配置
以前最常见的翻车点,是手抄公钥、UUID 的时候漏了一个字符。这次不会,因为服务端刚刚就是它配的,所有参数都还在它的上下文里。
它做了什么:
- 写好一份 Clash(mihomo)格式的
yt-demo-clash.yaml - 分流规则一并写好:局域网和国内直连,广告拦截,其余走代理,国内外 DNS 分开解析
- 写完先自己验证了一遍:用 Clash Verge 自带的 mihomo 内核直接把这份配置跑起来,测出口 IP 正是我们的服务器,访问 YouTube 约 1.3 秒返回 200
导入 Clash Verge:
订阅 → 新建 → 类型选 Local → 选中这个 yaml 文件 → 保存。代理组里就会多出 yt-demo 节点,延迟两百多毫秒。开启系统代理,打开浏览器搜一下 Google,秒开。
你可以核对的点: 配置的关键部分(最终版,已包含第七步加的 Hysteria2 节点):
mixed-port: 7897
mode: rule
ipv6: false
geodata-mode: true
geo-auto-update: true
dns:
enable: true
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
default-nameserver:
- 223.5.5.5
- 119.29.29.29
nameserver:
- https://dns.alidns.com/dns-query
- https://doh.pub/dns-query
nameserver-policy:
"geosite:geolocation-!cn":
- https://1.1.1.1/dns-query
- https://8.8.8.8/dns-query
proxies:
- name: yt-demo
type: vless
server: 203.0.113.10
port: 443
uuid: 9bf3fe50-b240-4431-b355-52000d20c45e
network: tcp
udp: true
tls: true
flow: xtls-rprx-vision
servername: addons.mozilla.org
client-fingerprint: chrome
reality-opts:
public-key: I1K-2DVvKABMnBwW-dnr6Y06f1m9spNipAoLhpqy3Ck
short-id: d0902526d9e9ea13
- name: yt-demo-hy2
type: hysteria2
server: 203.0.113.10
port: 443
password: ciVyTAZwk6qsexHDke4CcM0K
sni: addons.mozilla.org
alpn:
- h3
# 自签证书,用指纹锁定,不是无条件跳过校验
fingerprint: 0e64804c1e0bdfdc1630560a32f9fd255119e82772e97d55b92663af61672944
proxy-groups:
- name: Proxy
type: select
proxies:
- yt-demo
- yt-demo-hy2
- DIRECT
rules:
- GEOSITE,private,DIRECT
- GEOIP,private,DIRECT,no-resolve
- GEOSITE,category-ads-all,REJECT
- GEOSITE,cn,DIRECT
- GEOIP,CN,DIRECT
- MATCH,Proxy
几个值得注意的地方:
- 客户端用的是 Reality 的 公钥,私钥只留在服务器上
nameserver-policy让国外域名走 Cloudflare / Google 的 DoH,国内域名走阿里 / 腾讯的 DoH,避免 DNS 污染也避免国内站点解析到海外 CDNfake-ip模式下 DNS 响应更快,局域网、NTP 这类域名可以按需加进fake-ip-filter
第六步:配 fail2ban,并修掉一个默认配置的坑
节点一上公网,扫描器很快就会来尝试 SSH 爆破。
我说的话:
服务器做一下防护,配置一下 fail2ban
坑在这里: 新版 Ubuntu 附带的 OpenSSH 把登录认证拆到了单独的 sshd-session 进程里,SSH 登录失败的日志也改由它来写。但 fail2ban 自带的 sshd 过滤器在读 systemd journal 时,只匹配 _COMM=sshd,一条失败记录都抓不到。fail2ban 照常运行、status 也显示正常,实际上装了等于没装。
这个坑只在新版 Ubuntu 上出现,录视频时我用的是 AWS 默认的最新版26.04,所以踩到了。开机器时选低一点的版本,比如 Ubuntu 22.04 或 24.04,一般就能避开。
它做了什么:
- 装完 fail2ban 没急着交差,而是去查"到底是哪个进程在写 SSH 认证失败日志",发现了上面这个问题
- 改掉默认的匹配规则,再拿服务器上已有的失败记录试跑一遍,全部识别出来
- 定好封禁规则:10 分钟内输错 3 次封 1 小时,屡教不改的直接封一周
- 把我自己的公网 IP 加进白名单,免得把自己关在门外
你可以核对的点:
先确认你的系统是不是也有这个问题:
# 能看到失败记录,说明日志是 sshd-session 写的
sudo journalctl _COMM=sshd-session | grep -i "invalid user\|failed" | tail -5
# 这条如果几乎没有输出,就说明默认规则会漏掉它们
sudo journalctl _COMM=sshd | grep -i "invalid user\|failed" | tail -5
修正过滤器的 journal 匹配(.local 文件会覆盖同名 .conf,升级时不会被冲掉):
# /etc/fail2ban/filter.d/sshd.local
[Init]
journalmatch = _COMM=sshd + _COMM=sshd-session
封禁策略:
# /etc/fail2ban/jail.local
[DEFAULT]
ignoreip = 127.0.0.1/8 ::1 198.51.100.20
[sshd]
enabled = true
backend = systemd
findtime = 10m
maxretry = 3
bantime = 1h
# 一天内被封过多次的 IP,直接封一周
[recidive]
enabled = true
findtime = 1d
maxretry = 3
bantime = 1w
sudo systemctl restart fail2ban
sudo fail2ban-client status sshd # 看 Total failed 是否在增长
第七步:再加一个 Hysteria2 节点,以及 AWS 安全组的坑
VLESS 走 TCP,Hysteria2 走 UDP(基于 QUIC),在一些网络环境下更快,两个节点也能互为备份。它们都用 443 端口,但一个是 TCP、一个是 UDP,互不冲突。
我说的话:
再加一个 Hysteria2 节点
它做了什么:
- 生成一张自签证书,确认 sing-box 服务用户有权限读取
- 服务端加 Hysteria2 inbound,客户端 yaml 加
yt-demo-hy2节点,并用证书指纹锁定(而不是简单地跳过证书校验)
服务端新增的 inbound:
{
"type": "hysteria2",
"tag": "hy2-in",
"listen": "::",
"listen_port": 443,
"users": [
{ "password": "ciVyTAZwk6qsexHDke4CcM0K" }
],
"tls": {
"enabled": true,
"alpn": ["h3"],
"certificate_path": "/etc/sing-box/hy2.crt",
"key_path": "/etc/sing-box/hy2.key"
}
}
自签证书和指纹:
sudo openssl req -x509 -nodes -days 3650 \
-newkey ec -pkeyopt ec_paramgen_curve:prime256v1 \
-keyout /etc/sing-box/hy2.key -out /etc/sing-box/hy2.crt \
-subj "/CN=addons.mozilla.org"
# 客户端 fingerprint 字段要的 SHA-256 指纹(去掉冒号、转小写)
openssl x509 -in /etc/sing-box/hy2.crt -noout -fingerprint -sha256 \
| cut -d= -f2 | tr -d ':' | tr 'A-F' 'a-f'
连不上:包根本没进服务器
配置写完一测,超时。
这里 Agent 的处理方式值得说一下:它没有在服务器上乱改配置,而是一边从本地往服务器发 UDP 探测包,一边在服务器上抓包:
# 服务器上
sudo tcpdump -ni any udp port 443
# 本地
echo test | nc -u -w1 203.0.113.10 443
结果服务器一个包都没收到。包连服务器的网卡都没到,问题就不在 sing-box,而在云厂商那一层。
还记得开机器时安全组只勾了 SSH 和 HTTPS 吗?HTTPS 放行的只是 TCP 443,UDP 从来没有放行过。VLESS 走 TCP 所以一直能通,Hysteria2 走 UDP 就被安全组直接丢掉了。
它直接列出了要加的那条规则,这一步需要自己去控制台操作:
EC2 → 实例 → 安全 → 安全组 → 编辑入站规则 → 添加规则:
| 类型 | 协议 | 端口 | 来源 |
|---|---|---|---|
| 自定义 UDP | UDP | 443 | 0.0.0.0/0 |
放行之后:测速和 UDP 缓冲区
放行后再测,通了。它顺手给两个节点做了测速:
| 节点 | 下载速度 |
|---|---|
| VLESS Reality | 约 5.5 MB/s |
| Hysteria2(调整前) | 约 0.5 MB/s |
| Hysteria2(调大 UDP 缓冲区后) | 约 2.1 MB/s |
Hysteria2 一开始慢了十倍,它查出来是服务器的 UDP 接收缓冲区太小,QUIC 在高带宽下会被这个上限卡住,把上限从 4 MB 调到 16 MB 后提升到了 2.1 MB/s:
echo -e "net.core.rmem_max=16777216\nnet.core.wmem_max=16777216" \
| sudo tee /etc/sysctl.d/99-udp-buffer.conf
sudo sysctl --system
sudo systemctl restart sing-box
测速结果和线路、时段关系很大,这组数字只代表我录制时的那台 t3.micro,不代表两个协议的普遍差距。
一个小细节:Clash Verge 用的是副本
Clash Verge 导入本地配置时,会复制一份到它自己的配置目录,之后改原来的 yaml 文件是不会生效的。Agent 发现了这一点,顺手把新节点同步进了 Clash Verge 实际在用的那份副本。
最后在 Clash Verge 的代理组里,yt-demo 和 yt-demo-hy2 两个节点并排可选。
附:完整服务端配置(由客户端配置反推)
VLESS 和 Hysteria2 的两个 inbound 合在一起,就是服务器上 /etc/sing-box/config.json 的完整结构(示范)。客户端和服务端的参数是成对的,拿着上面那份 Clash 配置就能对出服务端每个字段:
| Clash 客户端字段 | sing-box 服务端字段 | 说明 |
|---|---|---|
port: 443 |
listen_port: 443 |
两个节点同端口,一个 TCP 一个 UDP |
uuid |
users[].uuid |
两边必须一致 |
flow: xtls-rprx-vision |
users[].flow |
两边必须一致 |
servername |
tls.server_name + reality.handshake.server |
伪装目标站点 |
reality-opts.short-id |
reality.short_id[] |
服务端可以放多个 |
reality-opts.public-key |
reality.private_key |
成对生成:私钥只放服务端,公钥给客户端。私钥无法从公钥反推,所以本文重新生成了一对示范密钥 |
password(hysteria2) |
users[].password |
两边必须一致 |
alpn: [h3] |
tls.alpn |
Hysteria2 固定用 h3 |
sni + fingerprint |
certificate_path / key_path |
客户端只锁定证书指纹,证书和私钥文件在服务器上 |
{
"log": { "level": "warn", "timestamp": true },
"inbounds": [
{
"type": "vless",
"tag": "vless-in",
"listen": "::",
"listen_port": 443,
"users": [
{ "name": "yt-demo", "uuid": "9bf3fe50-b240-4431-b355-52000d20c45e", "flow": "xtls-rprx-vision" }
],
"tls": {
"enabled": true,
"server_name": "addons.mozilla.org",
"reality": {
"enabled": true,
"handshake": { "server": "addons.mozilla.org", "server_port": 443 },
"private_key": "SKrVhmmC4Dl-IV0tVUQqND8vW8o7j0bmS59s8zuYBVI",
"short_id": ["d0902526d9e9ea13"]
}
}
},
{
"type": "hysteria2",
"tag": "hy2-in",
"listen": "::",
"listen_port": 443,
"users": [
{ "name": "yt-demo", "password": "ciVyTAZwk6qsexHDke4CcM0K" }
],
"tls": {
"enabled": true,
"server_name": "addons.mozilla.org",
"alpn": ["h3"],
"certificate_path": "/etc/sing-box/hy2.crt",
"key_path": "/etc/sing-box/hy2.key"
}
}
],
"outbounds": [
{ "type": "direct", "tag": "direct" }
]
}
改完配置后先校验再重启,并在 AWS 安全组里同时放行 TCP 443 和 UDP 443:
sudo sing-box check -c /etc/sing-box/config.json && sudo systemctl restart sing-box
sudo ss -tulnp | grep 443 # 应同时看到 tcp 和 udp 两行
总结
回头看整个流程:
| 步骤 | 我做的 | Agent 做的 |
|---|---|---|
| 开服务器 | AWS 控制台开 EC2 | — |
| SSH | 一句话 | 挪密钥、改权限、写 SSH config、验证登录 |
| 安装 | 一句话 | 探测系统、接官方 APT 源安装 |
| VLESS Reality | 一句话 | 测伪装站点、生成密钥、写配置、外部探测、给分享链接 |
| BBR | 一句话 | 开 BBR、设自启、重启验证 |
| 客户端 | 一句话 + 导入 | 写 Clash 配置和分流规则、用 mihomo 内核实测 |
| fail2ban | 一句话 | 发现 sshd-session 的坑、修规则、回放验证、加白名单 |
| Hysteria2 | 一句话 + 改安全组 | 自签证书、抓包定位安全组问题、调 UDP 缓冲区、同步客户端 |
除了在控制台开机器、改安全组,其余配置一行都没手敲。
比"省事"更值得说的是途中那两个坑:fail2ban 装了等于没装、UDP 被安全组丢掉。这两个都属于"表面上一切正常"的问题,以前自己配很可能根本发现不了。Agent 能发现,是因为它每做完一步都会去验证,而不是做完就交差。
几条使用建议:
- 给 Agent 的权限要心里有数。它能 SSH 到你的服务器执行任意命令,建议用一台专门的新机器,别拿跑着生产业务的服务器来试
- 关键结论自己核对一下。本文每一步的"你可以核对的点"就是为此准备的
- 密钥、UUID、密码别外泄。分享截图或配置时记得打码
如果你对这套配置模板或者 Agent 驱动的运维方式感兴趣,欢迎留言交流。
关于
关注我获取更多资讯