H@H + nginx 4层代理设置教程
前言
最近购入了一个大盘鸡,除了作为离线下载工具外,还想挂着H@H赚点hath花花,遂有以下类似备忘录的教程。
由于本人对nginx最为熟悉,虽然也有haproxy等代理软件,但是同一台服务器上只要有nginx就足够了,布局简单也最好用;个人想法是不要重复搬轮子,这对自己身体并不是很好。
本文也是建立在前人的肩膀上罢了,提前谢谢观赏。

安装过程
nginx的4层(TCP)代理需要使用stream模块,需要注意。
本人使用debian 13系统,默认存储库即可用,若是其他系统需要注意默认模块是否包含以上提到的stream模块。
nginx -V
查看是否有 --with-stream即可。
本次教程用的是docker容器的hath-rust,也可以直接使用二进制文件,反正软件的参数都一样。
1. 安装nginx以及stream模块
sudo apt install nginx libnginx-mod-stream
碎碎念:国内好多教程只教如何编译nginx模块,明明存储库里有(apt search libnginx),根本不需要多此一举;而且目录规范,不需要额外配置。
即可。
2. nginx配置
打开 nginx.conf配置文件编辑。
vim /etc/nginx/nginx.conf
以下为配置文件示例:
user www-data;
worker_processes auto;
worker_cpu_affinity auto;
pid /run/nginx.pid;
error_log /var/log/nginx/error.log;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
# multi_accept on;
}
# 以上的不用修改
# 4层(tcp)代理
stream {
# SNI 识别,将域名映射成一个配置名
map $ssl_preread_server_name $backend_name {
hostnames; #加上这个能加快map识别分流速度
www.b2og.com www;
# ......
*.hath.network hath_proxy;
default default;
}
upstream www {
server 127.0.0.1:10101;
}
# ......
upstream hath_proxy {
server 127.0.0.1:10103;
}
upstream hath {
server 127.0.0.1:8585;
}
upstream default {
server 127.0.0.1:80; #默认请求
}
log_format basic '$proxy_protocol_addr '
'$protocol $status $bytes_sent $bytes_received '
'$session_time ';
# 监听 443 并开启 ssl_preread 用于识别sni
server {
listen 443 reuseport;
listen [::]:443 reuseport;
proxy_pass $backend_name;
proxy_protocol on; #使用proxy_protocol用于其他4层以及7层的真实ip识别
ssl_preread on;
}
# 由于h@h客户端不支持proxy_protocol,因此再转发一遍卸载掉proxy_protocol
server {
listen 10103 proxy_protocol;
proxy_pass hath;
}
}
# 7层(http)代理
http {
# ......
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
# 以上的无需修改,下面的server配置自行按需添加。
# 当然最好还是将server配置放在sites-available目录中,并软连接到sites-enabled目录中,这样看着不乱
# 用于切换ws连接
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
#www配置
server {
listen 10101 ssl reuseport proxy_protocol; # 这就是监听上面配置给4层(示例的www配置的10101端口);而且由于开启了proxy_protocol,这里也需要加上
listen [::]:10101 ssl reuseport proxy_protocol;
server_name www.b2og.com;
http2 on;
gzip_http_version 1.1;
gzip_vary on;
gzip_comp_level 6;
gzip_proxied any;
gzip_types text/plain text/css application/json application/javascript application/x-javascript text/javascript;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass http://localhost:8080/;
proxy_set_header HOST $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $proxy_protocol_addr; #通过proxy_protocol获取的ip
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# ws连接
location /ws {
proxy_pass http://localhost:8081/;
proxy_set_header HOST $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $proxy_protocol_addr; #通过proxy_protocol获取的ip
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 以下两个header用于切换ws
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
# ......其他server配置
}
这样的4层加7层代理转发就配置好了。4层代理由于是更底层的tcp/udp代理,因此不只是这个H@H,其他的例如mariadb,ftp,dns(udp)都可以通过4层转发,H@H只是例子。
而且这种先识别sni再转发流量的方式好处很多,不但可以全服务器端口包括ssh都可以通过一个端口转发;并且可以做到证书不泄露,也就是只输入ip是不可能通过不匹配的证书知道域名的,再配合使用cdn即可做到源站ip不泄露;这样共用一个端口也可以做到流量伪装,别人无法知道你后端究竟在运行什么服务...等等。
(可选)docker版hath-rust设置
由于我需要对hath限一下速,用docker容器是比较方便的,以下介绍一下方法。
这次使用的不是官方作者打包的hath-rust镜像,是我自己打包的镜像,这个镜像基本只包含hath-rust这个可执行文件,小于5MB。占用空间极小,欢迎使用,查看Dokcer镜像以及Dockerfile仓库。
最好是使用一个专用的用户来运行这个服务,防止你的服务器因为漏洞出现问题。
sudo useradd -m -d /home/hath -s /bin/bash hath
su - hath
其中: -m:创建用户的主目录。 -d:指定用户的主目录路径。 -s:指定用户的 shell;并且使用su命令切换用户。
使用以下命令开启容器即可启动hath-rust。
docker run -it \
--name hath \
-p 8585:8585 \
-v ./hath:/hath \
--user "$(id -u):$(id -g)" \
grandduke1106/hath-rust-docker \
--port 8585 --disable-ip-origin-check
其中:
-it: 开启交互模式并分配一个终端,在输入id和密码成功运行后即可去除这个参数改为-d用于后台运行。--name hath: 定义容器名字为hath。-p 8585:8585: 用于指定端口映射,刚刚的nginx示例使用8585端口,因此这里也是。-v ./hath:/hath: 将当前路径下的 hath 目录挂载到容器内的 /hath 工作目录,用于持久化存储数据。--user "$(id -u):$(id -g)": 由于容器默认用户为nonroot(id:65535),因此让容器内的进程以你当前主机的用户身份运行,从而解决挂载目录时的权限问题。--port 8585 --disable-ip-origin-check: 这是追加传递给 hath-rust 程序的所有命令行参数,其他参数请看官方的参数列表或者使用参数-h;其中追加--disable-ip-origin-check参数是因为通过nginx代理以及docker的ip只有本地ip,不加这个参数会出错。-
若要限速,请参考以下步骤:
基本就是使用tc命令,我在这里使用tcconfig,能够简化操作。
#尽量不要在全局环境中安装pip包
python3 -m venv tcconfig
tcconfig/bin/pip install tcconfig
使用以下命令限制上传速度
sudo tcconfig/bin/tcset hath --docker --rate 10mbps
其中:
sudo tcset hath:tcset是tcconfig中用于设置规则的命令,hath是目标容器的名称或ID。需要sudo权限来操作网络接口。--docker: 明确告诉tcconfig目标是一个Docker容器,它会自动处理找到对应网络接口的逻辑。--rate 10mbps: 这是核心的限速参数。它设置了出口带宽的上限。你可以使用不同的单位,常用的如下:kbps: 千比特每秒mbps: 兆比特每秒
使用以下命令检查规则,输出结果以json表示
sudo tcconfig/bin/tcshow hath --docker
注意:在运行这个命令后可能会出现以下错误
[ERROR] OperationalError: failed to execute query at /root/tcconfig/lib/python3.13/site-packages/simplesqlite/core.py(615) insert
- query: INSERT INTO if_index(host,ifindex,ifname,"peer_ifindex") VALUES ('vps3149731',48,'veth1ea42e7',2)
- msg: UNIQUE constraint failed: if_index.peer_ifindex
- db: :memory:
这是因为不同容器之间的 peer_ifindex 可以相同导致的错误(来源),进入tcconfig的安装目录进行修改
# 根据自己python版本进行修改
cd tcconfig/lib/python3.13/site-packages/tcconfig
# 编辑_docker.py文件
vim _docker.py
找到peer_ifindex = Integer(not_null=True, unique=True)这一行,目前版本应该在33行。vim可直接使用斜杠(/)搜索这一行。
将unique=True删掉,因此这一行修改为以下内容
peer_ifindex = Integer(not_null=True)
这样就不会出错了,能够正常施加限速。
本篇文章就是这样,欢迎多多评论,感谢指正。
咕咕咕~