这篇文章讲的是, 使用 mihomo 的入站 listener 来搭建 Hysteria2 服务器端, 并在不跳过证书校验的情况下 (skip-cert-verify: false), 服务器客户端双端自签名证书校验 + 固定指纹 + ECH. 步骤很多, 尤其是自签很多个证书, 容易乱, 乱了删掉重新来就行.
域名自选, 我用惯了 VLESS xtls-rprx-vision 偷来的域名, 下面生成证书的命令中, 替换 "偷来的域名", 不要直接粘贴运行.
解决两个问题,
error: CRYPTO_ERROR 0x12a (local): tls: failed to verify certificate: x509: certificate signed by unknown authority
error: listen udp context deadline exceeded
error: authentication failed, status code: 404
生成自签名证书, 除了客户端配置外, 其它所有内容都在 Linux 服务器上操作.
生成 CA 私钥:
openssl ecparam -name prime256v1 -genkey -noout -out ca.key
生成 CA 公钥:
openssl req -x509 \
-new \
-key ca.key \
-sha256 \
-days 3650 \
-out ca.crt \
-subj "/CN=Hysteria2 Root CA" \
-addext "basicConstraints=critical,CA:TRUE,pathlen:0" \
-addext "keyUsage=critical,keyCertSign,cRLSign" \
-addext "subjectKeyIdentifier=hash"
生成服务器私钥:
openssl ecparam -name prime256v1 \
-genkey -noout -out server.key
生成证书签名请求 CSR:
openssl req -new \
-key server.key \
-out server.csr \
-subj "/CN=偷来的域名"
创建服务器证书扩展 server.ext:
cat > server.ext <<'EOF'
basicConstraints=critical,CA:FALSE
keyUsage=critical,digitalSignature
extendedKeyUsage=serverAuth
subjectAltName=DNS:偷来的域名
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
EOF
生成服务器公钥:
openssl x509 -req \
-in server.csr \
-CA ca.crt \
-CAkey ca.key \
-CAcreateserial \
-out server.crt \
-days 825 \
-sha256 \
-extfile server.ext
生成客户端私钥:
openssl ecparam -name prime256v1 \
-genkey -noout -out client.key
生成客户端签名请求 CSR (这个 CN 不用管它, 不校验):
openssl req -new \
-key client.key \
-out client.csr \
-subj "/CN=hy2-client-3"
创建客户端证书扩展 client.ext:
cat > client.ext <<'EOF'
basicConstraints=critical,CA:FALSE
keyUsage=critical,digitalSignature
extendedKeyUsage=clientAuth
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
EOF
生成客户端公钥:
openssl x509 -req \
-in client.csr \
-CA ca.crt \
-CAkey ca.key \
-CAcreateserial \
-out client.crt \
-days 825 \
-sha256 \
-extfile client.ext
校验:
openssl verify \
-CAfile ca.crt \
-purpose sslserver \
server.crt
↑server.crt: OK
openssl verify \
-CAfile ca.crt \
-purpose sslclient \
client.crt
↑client.crt: OK
openssl x509 -in server.crt -noout -text
↑CA:FALSE
TLS Web Server Authentication
DNS:偷来的域名
openssl x509 -in client.crt -noout -text
↑CA:FALSE
TLS Web Client Authentication
获取指纹:
openssl x509 \
-in server.crt \
-noout \
-fingerprint \
-sha256
记下指纹, AA:BB..EE:FF, 等会要写到客户端配置 fingerprint 中.
* 以上 OpenSSL 命令由 ChatGPT 生成, 测试可用.
生成 Encrypted Client Hello 密钥:
mihomo generate ech-keypair 偷来的域名
KEYS: ----- 格式的写到客户端中, config 格式的等会写到客户端中.
服务端模板:
listeners:
- name: 节点名
type: hysteria2
port: 443 # 只开 udp 端口
listen: 0.0.0.0
users:
3: "密码, 机场会把密码设置成 uuid, 这里只要是字符串就行"
up: 0 # 0 为不限制
down: 0
ignore-client-bandwidth: false #打开后客户端会连不上, 认证失败, 日志 404, 文章开头那个报错
alpn:
- h3
# 服务端自己的证书
certificate: server.crt 的内容或文件路径, 如果是内容, 写成 certificate: | 然后另起一行写 ----begin, 注意这一行要缩进对齐, 可以参考下面 ech-key 的写法
private-key: server.key 的内容或文件路径
# 强制客户端提供证书,并验证签发者
client-auth-type: require-and-verify
client-auth-cert: ca.crt 的内容或文件路径
# ECH 服务端密钥
ech-key: |
-----BEGIN ECH KEYS-----
在这里粘贴 mihomo generate ech-keypair 输出的 ECH KEYS
-----END ECH KEYS-----
客户端模板:
proxies:
- name: 节点名
type: hysteria2
server: IP
port: 端口
password: 密码
sni: 偷来的域名
alpn:
- h3
skip-cert-verify: false #费这么大劲就是为了不像那些傻逼机场一样把它打开
name-cert-verify: 偷来的域名
udp: true
# 服务端证书 SHA256 指纹
fingerprint: "刚获取的 server.crt 公钥指纹"
# 客户端自己的证书和私钥
certificate: client.crt 的内容或文件路径
private-key: client.key 的内容或文件路径, 这两个缺一不可程序会直接退出
# ECH 客户端配置
ech-opts:
enable: true
config: "刚获取的 ECH Config 的内容"
dialer-proxy: zerotier #此 hy2 节点外面套了一层 zerotier, 可选, 我自己组网用的, 相当于 udp in udp, 也就是说, hy2 的流量由 zerotier 承载
没开 masquerade 伪装, 因为两台设备都是外网而且是私网里的, 没必要了. 如果你搭这个 hysteria2 节点是从国内到国外, 请研究 masquerade 伪装.
skip-cert-verify false + 服务器客户端双端自签名证书校验 + 固定指纹 + ECH, 珍爱生命, 远离跳过证书校验的傻逼机场.
有问题欢迎留言指出.
0 条评论:
发表评论