Debian 13 生产级 Hysteria2 节点与 sing-box 客户端接入

在 Debian 13 stable 上部署 Hysteria2 服务端,使用 UDP 443、自签 TLS、Salamander 混淆、systemd 守护和 sing-box 分片客户端配置,适合简单高效的生产代理节点。

这篇记录一套简单、稳定、适合长期跑的 Hysteria2 节点部署方式。服务端使用 Debian 13 stable,Hysteria2 监听 443/udp,客户端继续使用既有 sing-box 结构:不改 TUN、不重写 DNS,只新增一个 outbound,并把节点域名和节点 IP 放到路由最前面直连,避免代理回环。

示例里使用占位符:

项目 示例值
服务端 IP 203.0.113.10
服务端域名 proxy.example.com
Hysteria2 端口 443/udp
节点 tag hy2-debian13
认证密码 HY2_AUTH_PASSWORD
混淆密码 HY2_OBFS_PASSWORD
sing-box 配置目录 /etc/sing-box/conf/

方案结构

LAN client
  -> 10.20.20.6 sing-box
  -> hysteria2 outbound: hy2-debian13
  -> proxy.example.com:443/udp
  -> Debian 13 hysteria-server.service

Hysteria2 基于 QUIC,适合 UDP 质量不错、希望速度更稳的线路。这里不套 Nginx,因为 Hysteria2 走 UDP,Nginx 的 HTTP/TCP 反代不参与这条链路。生产环境里最重要的是三件事:

  1. 域名真实解析到服务器公网 IP。
  2. 服务端只暴露需要的 UDP 443 和 SSH。
  3. 客户端把节点域名和节点 IP 直连,不能让它们再走代理。

1. 检查新系统

先确认系统版本、端口和异常服务:

cat /etc/os-release
uname -a
ip -brief addr
ss -lntup
systemctl --failed --no-pager

干净的新装 Debian 13 通常只会看到 SSH 监听:

tcp LISTEN 0 128 0.0.0.0:22
tcp LISTEN 0 128 [::]:22

再确认域名解析:

getent hosts proxy.example.com

应返回服务端公网 IP。Hysteria2 使用 UDP,云厂商安全组、机房防火墙和系统防火墙都要放行 443/udp

2. 安装 Hysteria2

安装最新版时先看官方 release,再替换版本号。下面以 v2.9.2 为例:

HY2_VERSION='v2.9.2'

curl -fsSL -o /tmp/hysteria \
  "https://github.com/apernet/hysteria/releases/download/app/${HY2_VERSION}/hysteria-linux-amd64"

install -m 755 /tmp/hysteria /usr/local/bin/hysteria
rm -f /tmp/hysteria

hysteria version

创建配置目录:

install -d -m 755 /usr/local/etc/hysteria /var/log/hysteria

3. 生成自签证书

如果只给 sing-box 客户端使用,自签证书足够。客户端配置里设置 tls.insecure: true,但 server_name 仍然要和证书 CN/SAN 保持一致。

DOMAIN='proxy.example.com'

openssl req -x509 -newkey rsa:2048 -sha256 -days 3650 -nodes \
  -keyout /usr/local/etc/hysteria/server.key \
  -out /usr/local/etc/hysteria/server.crt \
  -subj "/CN=${DOMAIN}" \
  -addext "subjectAltName=DNS:${DOMAIN}"

chmod 600 /usr/local/etc/hysteria/server.key
chmod 644 /usr/local/etc/hysteria/server.crt

检查证书:

openssl x509 -in /usr/local/etc/hysteria/server.crt -noout -subject -ext subjectAltName

应看到:

subject=CN=proxy.example.com
X509v3 Subject Alternative Name:
    DNS:proxy.example.com

4. 服务端配置

生成两组强随机密码:

openssl rand -base64 32
openssl rand -base64 32

编辑 /usr/local/etc/hysteria/config.yaml

listen: :443

tls:
  cert: /usr/local/etc/hysteria/server.crt
  key: /usr/local/etc/hysteria/server.key

auth:
  type: password
  password: HY2_AUTH_PASSWORD

obfs:
  type: salamander
  salamander:
    password: HY2_OBFS_PASSWORD

masquerade:
  type: proxy
  proxy:
    url: https://proxy.example.com/
    rewriteHost: true

ignoreClientBandwidth: false

acl:
  inline:
    - reject(all, udp/25)
    - reject(all, tcp/25)
    - reject(geoip:private)
    - direct(all)

resolver:
  type: udp
  udp:
    addr: 1.1.1.1:53
    timeout: 4s

说明:

  • listen: :443 是 UDP 443,不占用 TCP 443。
  • auth.password 是客户端连接密码。
  • obfs.salamander.password 是混淆密码,客户端必须一致。
  • acl 里拒绝 SMTP 25 端口和私网地址,避免节点被滥用或打内网。
  • masquerade 是认证失败时的伪装响应,不等同于 Nginx 反代。

5. 带宽参数怎么理解

Hysteria2 的带宽参数不是传统意义上“路由器限速规则”那么简单。它主要参与 Hy2 自己的拥塞控制,告诉协议当前链路大概能跑多快,从而决定发送节奏。如果值填得太低,速度上不去;如果值填得过高,也可能因为丢包、抖动和重传导致实际速度反而下降。

这里要分清三个位置:

配置项 所在位置 作用
up_mbps sing-box 客户端 outbound 客户端声明自己的上传能力
down_mbps sing-box 客户端 outbound 客户端声明自己的下载能力
ignoreClientBandwidth Hysteria2 服务端 服务端是否忽略客户端上报的带宽
bandwidth Hysteria2 服务端 服务端设置的每客户端带宽上限

本文服务端写的是:

ignoreClientBandwidth: false

意思是服务端接受客户端上报的 up_mbps / down_mbps。如果服务端没有额外写 bandwidth,就不会再从服务端侧卡一刀。

客户端示例里可以这样写:

{
  "type": "hysteria2",
  "tag": "hy2-debian13",
  "server": "proxy.example.com",
  "server_port": 443,
  "up_mbps": 60,
  "down_mbps": 360,
  "password": "HY2_AUTH_PASSWORD"
}

以家宽 300 Mbps 下行、50 Mbps 上行为例,客户端不一定要死板填写 50 / 300。实测中可以略高一点,例如 60 / 360,给 Hy2 拥塞控制留一些余量。是否更快要看线路质量;有时 80 / 400 这种填得更高的值反而更慢。

如果你想在服务端做硬限制,可以加:

bandwidth:
  up: 60 mbps
  down: 360 mbps

这表示服务端也给每个客户端设置上限。此时实际效果会受到客户端声明和服务端上限共同影响。简单理解:

客户端 服务端 实际倾向
up_mbps: 60 / down_mbps: 360 没有 bandwidth 按客户端声明跑
up_mbps: 80 / down_mbps: 400 bandwidth: 60 / 360 服务端最多按 60 / 360 控制
up_mbps: 40 / down_mbps: 240 bandwidth: 60 / 360 客户端自己报得更低,通常不会跑到服务端上限

如果你写:

ignoreClientBandwidth: true
bandwidth:
  up: 60 mbps
  down: 360 mbps

意思是服务端不信客户端上报值,只按服务端 bandwidth 来控制。这适合多人共用节点、你想统一限制每个用户速度的场景。

如果是自用节点,最简单的做法是本文这种:

ignoreClientBandwidth: false

服务端不写 bandwidth,只在客户端根据自己的家宽填写 up_mbps / down_mbps,然后用实际测速微调。比如家宽 300/50,可以从 50/30060/36070/380 这几组开始试,选速度高且延迟稳定的一组。

6. systemd 服务

写入 /etc/systemd/system/hysteria-server.service

[Unit]
Description=Hysteria2 Server
Documentation=https://v2.hysteria.network/
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
ExecStart=/usr/local/bin/hysteria server -c /usr/local/etc/hysteria/config.yaml
Restart=on-failure
RestartSec=5
LimitNOFILE=1048576
AmbientCapabilities=CAP_NET_BIND_SERVICE
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=full
ProtectHome=true
ReadWritePaths=/usr/local/etc/hysteria /var/log/hysteria

[Install]
WantedBy=multi-user.target

启动服务:

systemctl daemon-reload
systemctl enable --now hysteria-server
systemctl status hysteria-server --no-pager -l

确认监听:

ss -lunpt | grep ':443'

正常输出类似:

udp UNCONN 0 0 *:443 *:* users:(("hysteria",pid=1234,fd=3))

7. 内核参数

Debian 13 默认内核已经很新,可以开启 BBR,并适当提高 UDP 缓冲:

cat > /etc/sysctl.d/99-hysteria2.conf <<'EOF'
net.core.rmem_max = 67108864
net.core.wmem_max = 67108864
net.core.rmem_default = 1048576
net.core.wmem_default = 1048576
net.ipv4.udp_rmem_min = 8192
net.ipv4.udp_wmem_min = 8192
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
EOF

sysctl --system

虽然 Hysteria2 主要跑 UDP,BBR 仍然对服务器上的其它 TCP 出站有帮助。UDP 缓冲则能减少高吞吐场景下的抖动。

8. sing-box 客户端 outbound

客户端保持现有结构,只在 /etc/sing-box/conf/04_outbounds.json 添加新节点。示例:

{
  "type": "hysteria2",
  "tag": "hy2-debian13",
  "server": "proxy.example.com",
  "server_port": 443,
  "up_mbps": 60,
  "down_mbps": 360,
  "password": "HY2_AUTH_PASSWORD",
  "obfs": {
    "type": "salamander",
    "password": "HY2_OBFS_PASSWORD"
  },
  "tls": {
    "enabled": true,
    "server_name": "proxy.example.com",
    "insecure": true
  }
}

然后把 hy2-debian13 加入现有 selector 和 urltest 的 outbounds 数组。例如主选择器:

{
  "tag": "Proxy",
  "type": "selector",
  "outbounds": [
    "Auto",
    "old-node",
    "hy2-debian13"
  ]
}

如果你的配置里有 YouTube、Google、Telegram、GitHub、Netflix、Speedtest 等分流 selector,也可以把这个 tag 加进去,方便面板里手动切换。

这里的 60 / 360 是给 300/50 家宽预留余量的示例值。如果你的家宽是 1000/100,可以从 110/1100 附近开始试;如果只有 100/30,可以从 35/120 附近开始试。最终以实际测速和长时间稳定性为准。

9. 节点直连规则

编辑 /etc/sing-box/conf/05_route.json,把节点域名和 IP 的直连规则放在 route.rules 最前面:

{
  "domain": [
    "proxy.example.com"
  ],
  "ip_cidr": [
    "203.0.113.10/32"
  ],
  "outbound": "direct"
}

这一步很重要。sing-box 作为透明代理时,如果节点域名也被送进代理选择器,就会出现代理回环。常见现象是面板测速失败、节点时通时不通,或者 Hysteria2 日志完全没有客户端连接。

10. 校验和重启

客户端执行:

sing-box check -C /etc/sing-box/conf/
systemctl restart sing-box
systemctl is-active sing-box

服务端执行:

systemctl is-active hysteria-server
journalctl -u hysteria-server -n 60 --no-pager

看到 client connected 就说明客户端已经连上服务端。

如果启用了 Clash API,可以测新节点延迟:

curl -sS \
  'http://127.0.0.1:9090/proxies/hy2-debian13/delay?timeout=10000&url=https://www.gstatic.com/generate_204'

成功时会返回:

{"delay":377}

再走本机 SOCKS 入站做一次 HTTP 测试。这里假设 SOCKS 端口是 9666

curl --socks5-hostname 127.0.0.1:9666 -L -m 30 -o /dev/null \
  -w 'http_code=%{http_code} remote_ip=%{remote_ip} speed=%{speed_download} total=%{time_total}\n' \
  https://www.gstatic.com/generate_204

成功时通常是:

http_code=204 remote_ip=127.0.0.1 speed=0 total=0.414581

remote_ip=127.0.0.1 是因为 curl 连接的是本机 SOCKS 入站,不代表目标站点在本机。

11. 常见问题

面板测速失败

先看服务端有没有客户端日志:

journalctl -u hysteria-server -f

如果服务端完全没有连接,优先检查:

  • 域名是否解析到真实服务器 IP。
  • 443/udp 是否在安全组和系统防火墙里放行。
  • 客户端 passwordobfs.salamander.passwordserver_name 是否和服务端一致。
  • sing-box 路由最前面是否有节点域名/IP 的 direct 规则。

TCP 443 已经被 Nginx 占用

不冲突。Hysteria2 监听的是 443/udp,Nginx 通常监听 443/tcp。检查时要区分:

ss -lntp | grep ':443'
ss -lunp | grep ':443'

想换真实证书

可以用 ACME 申请真实证书,然后把 tls.certtls.key 指向真实证书路径。只给 sing-box 自用时,自签证书加 insecure: true 更简单,维护成本低。

是否一定要混淆

不是一定要,但生产节点建议开启 Salamander。开启后服务端和客户端必须同时配置同一个混淆密码;只改一边会直接连不上。

12. 升级

升级前备份二进制和配置:

cp /usr/local/bin/hysteria /usr/local/bin/hysteria.bak.$(date +%Y%m%d%H%M%S)
cp /usr/local/etc/hysteria/config.yaml /usr/local/etc/hysteria/config.yaml.bak.$(date +%Y%m%d%H%M%S)

下载新版替换:

HY2_VERSION='v2.9.2'

systemctl stop hysteria-server
curl -fsSL -o /tmp/hysteria \
  "https://github.com/apernet/hysteria/releases/download/app/${HY2_VERSION}/hysteria-linux-amd64"
install -m 755 /tmp/hysteria /usr/local/bin/hysteria
rm -f /tmp/hysteria
hysteria version
systemctl start hysteria-server
systemctl status hysteria-server --no-pager -l

如果新版启动失败,恢复旧二进制:

systemctl stop hysteria-server
cp /usr/local/bin/hysteria.bak.时间戳 /usr/local/bin/hysteria
systemctl start hysteria-server

13. 收尾检查

服务端:

systemctl is-active hysteria-server
ss -lunpt | grep ':443'
journalctl -u hysteria-server -n 30 --no-pager

客户端:

sing-box check -C /etc/sing-box/conf/
systemctl is-active sing-box
curl -sS 'http://127.0.0.1:9090/proxies/hy2-debian13/delay?timeout=10000&url=https://www.gstatic.com/generate_204'

到这里,一个 Debian 13 + Hysteria2 的生产节点就完成了。它的结构很轻:服务端一个二进制、一个配置文件、一个 systemd 服务;客户端只新增 outbound 和直连规则,不碰原来的 TUN、DNS 和分流框架。

参考