Hysteria2 部署指南(sing-box)

Hysteria2 基于 QUIC,服务端监听 UDP 端口。证书两种方案任选其一:ACME 自动申请(推荐,需域名)或自签名证书。ACME 使用 certificate_providers 写法,需要 sing-box 1.14.0+。入站是 UDP 443,TCP 443 空着,因此挑战可用 HTTP-01(TCP 80)或 TLS-ALPN(TCP 443)。用 IP 申请会自动套用 Let's Encrypt shortlived 短期证书(约 6 天有效期、续期频繁),故推荐域名。自签名方案不要把 insecure 当默认。字段说明见 Hysteria2 inboundoutbound

一、部署前准备

  • 一台使用 systemd 的 Linux VPS,具备 root 或 sudo 权限;官方安装脚本覆盖 deb / rpm / Arch / OpenWrt
  • 一个已解析到该 VPS 公网 IP 的域名,以及可接收邮件的邮箱(ACME 申请用);
  • 云安全组和本机防火墙放行 UDP 443,且未被其他服务占用;启用端口跳跃时还需放行整个 UDP 范围(如 20000–40000),不是只放行 443 或 9443——只改安全组不够;
  • 使用 ACME 时按挑战方式放行对应 TCP 端口(HTTP-01 为 80,TLS-ALPN 为 443);
  • 准备一个较长、随机的认证密码。

二、安装 sing-box

bash
curl -fsSL https://sing-box.app/install.sh | sh
sing-box version

输出中的版本号必须 ≥ 1.14.0,否则不认识 certificate_providers / gecko / bbr_profile。若要钉死版本:

bash
curl -fsSL https://sing-box.app/install.sh | sh -s -- --version 1.14.0

脚本会下载 sing-box、安装 systemd 服务(以 sing-box 用户运行)并创建 /etc/sing-box/

三、生成证书(二选一)

方案 A:ACME 自动申请(推荐,使用域名)

配置见第四章;把域名解析到该 VPS 后自动完成证书签发与续期。HTTP-01 与 TLS-ALPN 都可以(后者走 TCP 443,与 UDP 443 不冲突)。

方案 B:自签名证书

bash
sudo openssl ecparam -name prime256v1 -genkey -noout \
  -out /etc/sing-box/server.key

sudo openssl req -x509 -nodes \
  -key /etc/sing-box/server.key \
  -out /etc/sing-box/server.crt \
  -subj "/CN=bing.com" \
  -addext "subjectAltName=DNS:bing.com" \
  -days 825

sudo chmod 600 /etc/sing-box/server.key
sudo chmod 644 /etc/sing-box/server.crt

CN=bing.com 只是示例伪装名,不代表证书由 Bing 签发。-addext 给证书附加 SAN——导入客户端信任列表并严格校验时,SAN 必须与 server_name 一致。有效期用 825 天,避免部分客户端拒绝过长有效期。密钥必须是 P-256(或 RSA);不要用 Ed25519——sing-box 1.14 客户端默认鹦鹉 Chrome QUIC,Chrome 不声明 Ed25519,握手会失败(ACME 证书不受影响)。

使用此方案时删除 certificate_providers 段,tls 段改为:

json
"tls": {
  "enabled": true,
  "certificate_path": "/etc/sing-box/server.crt",
  "key_path": "/etc/sing-box/server.key"
}

客户端应导入该证书并保持 insecure 为关闭。"insecure": true 等于放弃证书校验,只适合临时排障。server_name 填证书中的伪装域名(如 bing.com)。

四、写入服务端配置

将以下配置写入 /etc/sing-box/config.json

json
{
  "log": {
    "level": "info",
    "timestamp": true
  },
  "certificate_providers": [
    {
      "type": "acme",
      "tag": "acme_cert",
      "domain": [
        "YOUR_DOMAIN"
      ],
      "email": "YOUR_EMAIL@example.com",
      "data_directory": "/var/lib/sing-box/certmagic"
    }
  ],
  "inbounds": [
    {
      "type": "hysteria2",
      "listen": "::",
      "listen_port": 443,
      "users": [
        {
          "password": "CHANGE_THIS_TO_A_STRONG_PASSWORD"
        }
      ],
      "tls": {
        "enabled": true,
        "server_name": "YOUR_DOMAIN",
        "certificate_provider": "acme_cert"
      }
    }
  ],
  "outbounds": [
    {
      "type": "direct"
    }
  ]
}

data_directory 必须落在官方服务的 StateDirectory/var/lib/sing-box)下。省略时 ACME 数据跟 sing-box 用户的 HOME 走,重启后可能丢证书或写不进去。

必须修改的字段

配置项 说明
certificate_providers[0].domain[0] 你的域名(需解析到该 VPS)
certificate_providers[0].email 你的邮箱地址
users[0].password 客户端连接时使用的密码,必须修改
tls.server_name domain[0] 保持一致
listen 默认 ::。机器禁用 IPv6 时改为 0.0.0.0

YOUR_DOMAIN 必须在 domain[0]tls.server_name 两处保持一致,且已解析到当前 VPS;密码不要继续使用示例值。

可选字段说明

  • up_mbps / down_mbps服务端向客户端下发 Brutal 速率上限;留空则不限速。与 ignore_client_bandwidth 互斥;
  • ignore_client_bandwidth:仅服务端。未设置带宽时命令客户端改用 BBR;已设置带宽时禁止客户端用 BBR;
  • bbr_profile(1.14+):BBR 档位,可选 conservativestandardaggressive,默认 standard
  • obfs:QUIC 流量混淆,支持 salamandergecko(1.14+),见下方示例;
  • masquerade:认证失败时的 HTTP3 伪装响应,见下方示例;未配置时返回 404;
  • users:密码认证;官方程序的 userpass 写法在 sing-box 中需将 username:password 整体作为密码。

客户端出站自己的 up_mbps / down_mbps该客户端的带宽声明:留空则该客户端使用 BBR,与服务端是否限速是两件事。

可选:obfs 混淆示例

在入站中加入 obfs 段(服务端与客户端的类型、密码必须完全一致):

json
"obfs": {
  "type": "salamander",
  "password": "OBFS_PASSWORD"
}

使用 gecko(1.14+)时把 type 改为 gecko,还可调整 min_packet_size(默认 512)与 max_packet_size(默认 1200)。

可选:masquerade 伪装示例

对象写法(认证失败时反向代理到真实网站):

json
"masquerade": {
  "type": "proxy",
  "url": "https://www.bing.com/",
  "rewrite_host": true
}

也可以用字符串简写 "masquerade": "https://www.bing.com/",或改用 file 类型将 directory 指向本地站点目录作为文件服务器。

生成随机密码并设置配置文件权限:

bash
openssl rand -base64 32
sudo chmod 600 /etc/sing-box/config.json

五、检查并启动

bash
sudo sing-box check -c /etc/sing-box/config.json
sudo systemctl enable sing-box
sudo systemctl restart sing-box
sudo systemctl status sing-box --no-pager

check 没有输出且退出码为 0 表示配置通过。status 应为 active (running);否则查看日志:

bash
sudo journalctl -u sing-box --output cat -e

六、服务管理

操作 命令
查看状态 sudo systemctl status sing-box --no-pager
启动 sudo systemctl start sing-box
停止 sudo systemctl stop sing-box
重启 sudo systemctl restart sing-box
禁用开机自启 sudo systemctl disable sing-box
查看最近日志 sudo journalctl -u sing-box --output cat -e
实时查看日志 sudo journalctl -u sing-box --output cat -f

七、客户端配置参考

下面是一份可直接 sing-box check 的最小客户端配置:本地 mixed 入站 + 一个出站。出站必须放在 outbounds 数组里,不能把出站对象单独当成完整配置文件。

json
{
  "log": {
    "level": "info",
    "timestamp": true
  },
  "inbounds": [
    {
      "type": "mixed",
      "listen": "127.0.0.1",
      "listen_port": 1080
    }
  ],
  "outbounds": [
    {
      "type": "hysteria2",
      "tag": "hy2-out",
      "server": "YOUR_SERVER_IP",
      "server_port": 443,
      "password": "CHANGE_THIS_TO_A_STRONG_PASSWORD",
      "tls": {
        "enabled": true,
        "server_name": "YOUR_DOMAIN"
      }
    }
  ]
}

本机 SOCKS / HTTP 代理为 127.0.0.1:1080

要点:

客户端字段 说明
server VPS 公网 IP
server_port 与服务端 listen_port 一致;启用端口跳跃时改用 server_ports,此时不要写 server_port
password 与服务端 users[0].password 完全一致
tls.server_name 与服务端 tls.server_name 一致,即证书申请所用的域名

ACME 公网受信证书不要加 insecure。自签名(方案 B)应导入服务端证书;server_name 填证书中的伪装域名(如 bing.com)。

服务端启用 obfs 时,客户端需配置类型与密码一致的 obfs 段。1.14 客户端默认鹦鹉 Chrome QUIC;服务端若误用 Ed25519 证书会握手失败,可在客户端设 "disable_chrome_parrot": true 做对比测试,生产环境应换 ECDSA/RSA 证书而不是关鹦鹉。

八、配置端口跳跃(可选)

客户端用一个 UDP 端口范围连接,由 iptables 转发到实际服务端口。示例:跳跃端口 20000:40000,实际监听 9443,网卡 eth0

安全组 / 防火墙必须放行 UDP 20000–40000。DNAT 之后数据包打到本机 9443,公网不必再放行 443 或 9443。

1. 修改监听端口

"listen_port": 443 改为 9443,并重启服务:

bash
sudo systemctl restart sing-box

2. 添加转发规则

安装持久化工具并添加 IPv4 / IPv6 转发规则:

bash
sudo apt update
sudo apt install -y iptables-persistent

sudo iptables -t nat -A PREROUTING -i eth0 -p udp --dport 20000:40000 -j DNAT --to-destination :9443
sudo ip6tables -t nat -A PREROUTING -i eth0 -p udp --dport 20000:40000 -j DNAT --to-destination :9443
sudo netfilter-persistent save

网卡不是 eth0 时替换为实际接口名(ip route get 1.1.1.1 可查看);规则中的网卡、端口范围、目标端口须与实际配置一致,添加前建议先备份现有规则。

3. 客户端(端口跳跃)

server_portsserver_port 冲突,只保留范围。单元素时官方允许省略数组括号,写成字符串也可以:

json
{
  "log": {
    "level": "info",
    "timestamp": true
  },
  "inbounds": [
    {
      "type": "mixed",
      "listen": "127.0.0.1",
      "listen_port": 1080
    }
  ],
  "outbounds": [
    {
      "type": "hysteria2",
      "tag": "hy2-out",
      "server": "YOUR_SERVER_IP",
      "server_ports": [
        "20000:40000"
      ],
      "hop_interval": "30s",
      "password": "CHANGE_THIS_TO_A_STRONG_PASSWORD",
      "tls": {
        "enabled": true,
        "server_name": "YOUR_DOMAIN"
      }
    }
  ]
}

hop_interval 默认 30s;1.14+ 可用 hop_interval_max 做随机间隔。

4. 删除转发规则

停用端口跳跃前删除对应规则:

bash
sudo iptables -t nat -D PREROUTING -i eth0 -p udp --dport 20000:40000 -j DNAT --to-destination :9443
sudo ip6tables -t nat -D PREROUTING -i eth0 -p udp --dport 20000:40000 -j DNAT --to-destination :9443
sudo netfilter-persistent save

九、故障排查

1. 服务启动失败

bash
sudo sing-box check -c /etc/sing-box/config.json
sudo journalctl -u sing-box -n 100 --no-pager

重点排查:

  • sing-box version 是否 ≥ 1.14.0;
  • 证书路径是否正确,密钥文件权限是否可读;
  • data_directory 是否可被 sing-box 用户写入;
  • up_mbps / down_mbps 是否与 ignore_client_bandwidth 同时设置;
  • UDP 端口是否被占用(sudo ss -lunp | grep -E ':443|:9443');
  • 禁用 IPv6 的机器是否仍在听 ::

2. 服务启动但客户端无法连接

依次检查:

  • 服务端口是否按 UDP 放行(只放行 TCP 不够);
  • 云安全组是否放行对应 UDP 端口;
  • 客户端密码是否完全一致;
  • 自签名证书是否已导入、server_name 是否与证书中的伪装域名一致;不要靠长期 insecure
  • 服务端是否误用了 Ed25519 证书;
  • 服务端日志是否有认证失败或 QUIC 错误。

3. 端口跳跃不生效

重点检查:

  • 服务端是否监听 9443
  • 客户端是否用了 server_ports没有同时写 server_port
  • DNAT 规则是否使用 UDP、网卡是否为公网接口;
  • 防火墙是否放行整个跳跃端口范围(UDP 20000–40000);
  • IPv4 和 IPv6 是否分别添加了规则。

查看 NAT 规则:

bash
sudo iptables -t nat -L PREROUTING -n -v
sudo ip6tables -t nat -L PREROUTING -n -v

4. 带宽参数怎么填写

up_mbpsdown_mbps 应接近 VPS 实际带宽,填写过大可能导致拥塞、丢包或速度不稳。

  • 服务端不想限速:删除这两个字段(不限速,不是「强制 BBR」);
  • 要客户端改用 BBR:在入站设 "ignore_client_bandwidth": true(此时不要同时写带宽字段);
  • 客户端自己的 up_mbps / down_mbps 留空,该客户端使用 BBR。

十、安全建议

  • 密码用长随机值,不要示例字符串;
  • config.jsonserver.key 权限 600
  • 优先 ACME 公网证书;自签要导入证书,不要长期开 insecure
  • 自签 / 手写证书用 P-256 或 RSA,不要 Ed25519;
  • 定期升级 sing-box,升级后重新执行 sing-box check