Alpine Linux 生产级 Hysteria2 节点与 sing-box 客户端接入

在 Alpine Linux 上部署 Hysteria2 生产节点,使用 OpenRC、自签 TLS、Salamander 混淆和 sing-box 客户端接入,适合长期稳定运行。

这篇是 Alpine 版的保姆教程。目标很简单:

  • 服务端只跑 Hysteria2,监听 443/udp
  • 证书、自启动、日志、内核参数一次配好
  • 客户端只补一个 outbound,不改现有 TUN 结构
  • 节点域名和节点 IP 永远走直连,避免回环

本文以自建单节点为例。你可以把它当成后面重装后直接复用的标准模板。

先说结论

Alpine 很适合这类节点:

  • 系统轻
  • OpenRC 简单
  • 重装干净
  • 资源占用小

Hysteria2 适合 UDP 质量还可以、想要速度和稳定性兼顾的线路。它不是传统 TCP 代理,核心是 QUIC,所以你要盯住的是:

  1. 443/udp 是否真放通
  2. 域名是否正确解析到服务器公网 IP
  3. 客户端的带宽参数是否和实际家宽大致匹配

1. 检查新系统

先确认系统和基础状态:

cat /etc/os-release
uname -a
cat /etc/alpine-release
ps -ef | grep -i '[h]ysteria' || true
ss -lntup 2>/dev/null | grep -E ':443|hysteria|hy2' || true
apk --version

干净的新机一般不会有 Hysteria2 进程,也不会有 443/udp 监听。

再看一下防火墙和解析:

getent hosts proxy.example.com

proxy.example.com 这里只是示例。正式环境里换成你的真实域名。

2. 安装依赖

apk add --no-cache curl ca-certificates openssl

如果你打算长期维护,建议顺手也把常用工具装上:

apk add --no-cache bash vim jq iproute2

3. 安装 Hysteria2

直接下载官方 Linux amd64 二进制即可。

curl -fsSL -o /usr/local/bin/hysteria \
  https://download.hysteria.network/app/latest/hysteria-linux-amd64

chmod 755 /usr/local/bin/hysteria
/usr/local/bin/hysteria version

如果你想固定版本,也可以改成某个 release。

4. 生成证书

Hysteria2 自用节点通常直接上自签证书就够了。客户端保持 insecure: true,但 server_name 仍然要和证书 CN/SAN 保持一致。

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

DOMAIN='proxy.example.com'

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

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

检查一下:

openssl x509 -in /etc/hysteria/server.crt -noout -subject -issuer -dates

5. 服务端配置

编辑 /etc/hysteria/config.yaml

listen: :443

tls:
  cert: /etc/hysteria/server.crt
  key: /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://www.cloudflarestatus.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
  • auth.password 是客户端连接密码
  • obfs.salamander.password 是混淆密码
  • ignoreClientBandwidth: false 表示接受客户端上报的带宽
  • acl 里直接拒绝私网和 SMTP,少给自己惹麻烦

6. 带宽怎么填

Hysteria2 的 up_mbps / down_mbps 不是普通意义上的硬限速按钮。它更像是告诉协议“这条链路大概有多快”,让它自己调整节奏。

对于家宽 300/50,我会先从这些值开始试:

  • 50/300
  • 60/360
  • 70/380

我这次实测更偏向 60/360。太低速度上不去,太高有时反而抖。

如果你想在服务端强行统一上限,再加:

bandwidth:
  up: 60 mbps
  down: 360 mbps

两者关系可以这样理解:

  • ignoreClientBandwidth: false 时,服务端接受客户端声明
  • ignoreClientBandwidth: true 时,服务端只看自己的 bandwidth

自用节点一般先别加 bandwidth,先把客户端值调顺。

7. OpenRC 服务

Alpine 用 OpenRC,不是 systemd。

创建 /etc/init.d/hysteria

#!/sbin/openrc-run

name="hysteria"
description="Hysteria2 server"
command="/usr/local/bin/hysteria"
command_args="server -c /etc/hysteria/config.yaml"
command_background="yes"
pidfile="/run/${RC_SVCNAME}.pid"
output_log="/var/log/hysteria.log"
error_log="/var/log/hysteria.err"
start_stop_daemon_args="--make-pidfile --pidfile ${pidfile}"

depend() {
  need net
}

然后:

chmod 755 /etc/init.d/hysteria
rc-update add hysteria default
rc-service hysteria start
rc-service hysteria status

查看日志:

tail -f /var/log/hysteria.log

8. 内核参数

可以先把 UDP 缓冲和通用 TCP 参数配上:

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

sysctl -p /etc/sysctl.d/99-hysteria2.conf

这段不是玄学加速。Hysteria2 主链路是 QUIC over UDP,所以真正和它关系更近的是:

net.core.rmem_max
net.core.wmem_max
net.core.rmem_default
net.core.wmem_default
net.ipv4.udp_rmem_min
net.ipv4.udp_wmem_min

这些参数提高 socket 收发缓冲,在高延迟、高吞吐或者瞬时突发时更稳一些。

下面两项则主要是通用 Linux TCP 优化:

net.core.default_qdisc=fq
net.ipv4.tcp_congestion_control=bbr

它们对 Hysteria2 的 UDP 主链路不是决定性因素,但对系统更新、普通 HTTPS 出站、测速下载等 TCP 流量有帮助。生产节点保留没问题,但不要期待它们把 HY2 延迟直接打下来。

9. 客户端接入

客户端保持原有 sing-box 结构,只新增节点。

/etc/sing-box/conf/04_outbounds.json 里加:

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

然后把这个 tag 加进主 selector 和需要的分组 selector。

10. 路由里先直连节点

/etc/sing-box/conf/05_route.json 的规则最前面加节点域名和 IP 直连:

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

这步不能省。否则节点本身也会被代理,轻则测速失败,重则自己绕自己。

11. 校验

客户端:

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

服务端:

rc-service hysteria status
tail -n 40 /var/log/hysteria.log

如果正常,会看到类似:

server up and running
client connected

面板里也可以测延迟:

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

12. 常见坑

证书不对

server_name、证书 CN/SAN、域名三者最好一致。

只开了 TCP 443

Hysteria2 需要的是 443/udp,不是 TCP 443。

带宽填太大

速度不一定更快,尤其是家宽和跨境线。先从保守值开始。

客户端选了节点但游戏不走

这通常不是节点坏了,而是前面的 DNS 分流把域名先处理掉了。要让游戏稳定,必须把 Riot/LoL 域名从 fake-ip 链路里拿出来,走 real-ip。

13. 我这次的落地经验

这台 Alpine 232 机器最后跑起来了,面板 API 延迟看起来仍然比 146 / 209 高一些,但实际 YouTube 业务测速能稳定到 118 Mbps 左右,4K60 播放没有问题。对家宽和这条代理线路来说,这基本已经接近可用上限。

这说明两件事:

  • API delay 只能看连通性和大致延迟,不能单独代表真实吞吐。
  • 生产节点最终还是要看真实业务,比如 YouTube Stats、下载速度、长时间播放和掉帧情况。

所以这台 Alpine 232 不是“延迟数字不好就不能用”。它更适合作为高吞吐流媒体节点;如果是游戏、语音这类延迟敏感场景,再优先选延迟更低的 146 / 209。

14. 收尾

当你完成部署后,建议保留这些东西:

  • /etc/hysteria/config.yaml
  • /etc/hysteria/server.crt
  • /etc/hysteria/server.key
  • /etc/init.d/hysteria
  • 客户端 04_outbounds.json
  • 客户端 05_route.json

以后重装 Alpine,照着这份教程重新铺一遍就行。