【Linux】HAProxy:结合 WG 实现内网 TCP 反代
本教程指导您通过 WireGuard 建立 VPN 隧道,并使用 HAProxy 在公网服务器上实现 TCP 反向代理,将公网请求转发到内网服务。教程目标是简单、直接、易于部署。
🧰 场景说明
角色 | 说明 |
---|---|
公网服务器 | 公网 IP:1.2.3.4 |
内网服务器 | 无公网 IP,但可访问外网 |
WireGuard IP | 公网服务器:10.0.0.1 内网服务器: 10.0.0.2 |
示例域名 | files.example.com (可选,非必须) |
目标:
- 通过公网服务器的
1.2.3.4:80
访问内网 HTTP 服务(如文件服务器)。 - 通过公网服务器的
1.2.3.4:2222
访问内网 SSH 服务。
一、安装 WireGuard
在 公网服务器 和 内网服务器 上执行以下命令安装 WireGuard:
sudo apt update
sudo apt install wireguard -y
二、配置 WireGuard
1. 生成密钥对
在 公网服务器 和 内网服务器 上分别生成 WireGuard 密钥对(密钥和私钥是唯一对应的):
# 生成私钥并保存到 /etc/wireguard/private.key,生成对应的公钥保存到 /etc/wireguard/public.key
wg genkey | tee /etc/wireguard/private.key | wg pubkey > /etc/wireguard/public.key
# 查看私钥内容(仅限本机使用,不可泄露)
cat /etc/wireguard/private.key
# 查看公钥内容(可提供给对端配置)
cat /etc/wireguard/public.key
记录两台服务器的私钥(private.key)和公钥(public.key)。
2. 配置公网服务器
在公网服务器上创建 /etc/wireguard/wg0.conf
:
# 公网服务器的本地接口配置
[Interface]
PrivateKey = <公网服务器私钥> # 本机私钥(只在本地使用,严禁泄露)
Address = 10.0.0.1/24 # 虚拟局域网内的 IP 地址
ListenPort = 51820 # 监听的 UDP 端口(客户端通过此端口连接)# 定义内网服务器为一个 Peer
[Peer]
PublicKey = <内网服务器公钥> # 对端(内网服务器)的公钥
AllowedIPs = 10.0.0.2/32 # 允许从该 IP 发来的数据包进入 WireGuard 网络
3. 配置内网服务器
在内网服务器上创建 /etc/wireguard/wg0.conf
:
# 内网服务器的本地接口配置
[Interface]
PrivateKey = <内网服务器私钥> # 本机私钥(只在本地使用,严禁泄露)
Address = 10.0.0.2/24 # 虚拟局域网内的 IP 地址# 定义公网服务器为一个 Peer
[Peer]
PublicKey = <公网服务器公钥> # 对端(公网服务器)的公钥
Endpoint = 1.2.3.4:51820 # 公网服务器的 IP 和监听端口
AllowedIPs = 10.0.0.0/24 # 允许通过 VPN 访问的地址范围(这里是整个虚拟网段)
PersistentKeepalive = 25 # 防止 NAT 断连,每 25 秒发送一次心跳包(适合内网)
4. 启动 WireGuard
在两台服务器上启动 WireGuard:
sudo systemctl enable wg-quick@wg0
sudo systemctl start wg-quick@wg0
5. 验证连通性
在任意服务器上测试 VPN 连接:
ping 10.0.0.1
ping 10.0.0.2
若能相互 ping 通,说明 WireGuard 配置成功。
三、通过公网服务器 SSH 访问内网服务器
1. 直接使用 ProxyJump
使用 OpenSSH 7.3+ 的 ProxyJump
选项,从本地机器通过公网服务器 SSH 登录内网服务器:
ssh -J user_public@1.2.3.4 user_internal@10.0.0.2
user_public
:公网服务器的用户名user_internal
:内网服务器的用户名
2. 使用 SSH 配置文件
为简化操作,可编辑本地机器的 ~/.ssh/config
:
Host public-serverHostName 1.2.3.4User user_publicHost internal-serverHostName 10.0.0.2User user_internalProxyJump public-server
保存后,直接运行:
ssh internal-server
即可自动通过公网服务器跳转登录内网服务器。
四、内网服务器运行服务
以下为内网服务器运行服务的示例,服务监听 WireGuard IP(10.0.0.2
)。
1. 运行 Python HTTP 文件服务器
在内网服务器上创建共享目录并启动 HTTP 服务:
mkdir -p ~/shared_files
echo "Hello World" > ~/shared_files/hello.txt
cd ~/shared_files
python3 -m http.server 8000 --bind 10.0.0.2
2. 运行 SSH 服务(可选)
修改内网服务器的 SSH 配置,监听 WireGuard IP 和自定义端口:
sudo vi /etc/ssh/sshd_config
添加或修改以下内容:
ListenAddress 10.0.0.2
Port 2222
重启 SSH 服务:
sudo systemctl restart ssh
五、公网服务器配置 HAProxy
1. 安装 HAProxy
在公网服务器上安装 HAProxy:
sudo apt install haproxy -y
2. 配置 HAProxy
编辑 /etc/haproxy/haproxy.cfg
,替换为以下内容:
# 全局配置:控制haproxy进程整体行为
globaldaemon # 以守护进程方式运行maxconn 256 # 最大并发连接数限制,防止资源过载# 默认配置:为所有proxy设置通用选项
defaultsmode tcp # 工作模式为TCP(适合SSH、非HTTP协议)timeout connect 5s # 连接后端服务器超时时间,避免长时间挂起timeout client 30s # 客户端连接超时,超过则断开timeout server 30s # 后端服务器响应超时,超过则断开# HTTP代理监听配置(监听80端口)
listen http_proxybind *:80 # 监听所有网卡80端口,确保端口未被占用server s1 10.0.0.2:8000 # 后端HTTP服务器地址及端口# SSH代理监听配置(监听2222端口)
listen ssh_proxybind *:2222 # 监听所有网卡2222端口,方便外部SSH连接server s2 10.0.0.2:22 # 后端SSH服务器地址及端口
http_proxy
:将公网服务器的1.2.3.4:80
转发到内网服务器的10.0.0.2:8000
(HTTP 服务)。ssh_proxy
:将公网服务器的1.2.3.4:2222
转发到内网服务器的10.0.0.2:2222
(SSH 服务)。
3. 重启 HAProxy
sudo systemctl restart haproxy
✅ 测试访问
从公网测试访问内网服务:
-
访问 HTTP 服务:
- 打开浏览器,访问
http://1.2.3.4/
,应看到内网 Python 文件服务器的内容(如hello.txt
)。
- 打开浏览器,访问
-
访问 SSH 服务:
-
使用 SSH 客户端连接:
ssh -p 2222 user_internal@1.2.3.4
-
若访问成功,说明配置正确。
六、清空配置
为了避免 HAProxy 或 WireGuard 的配置残留影响后续操作,或在调试时需要重置环境,可以按照以下步骤清空相关配置。
1. 清空 WireGuard 配置(公网服务器和内网服务器)
- 停止 WireGuard 服务
在两台服务器上停止并禁用 WireGuard:
sudo systemctl stop wg-quick@wg0
sudo systemctl disable wg-quick@wg0
- 删除 WireGuard 配置文件
移除 WireGuard 配置文件和密钥:
sudo rm /etc/wireguard/wg0.conf
sudo rm /etc/wireguard/private.key
sudo rm /etc/wireguard/public.key
- (可选)卸载 WireGuard
如果不再需要 WireGuard,可以完全卸载:
sudo apt remove wireguard -y
sudo apt autoremove -y
2. 清空 HAProxy 配置
公网服务器
- 停止 HAProxy 服务
sudo systemctl stop haproxy
sudo systemctl disable haproxy
- 备份并清空 HAProxy 配置
备份现有配置文件(以防需要恢复):
sudo mv /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak
创建空的默认配置文件:
sudo bash -c 'cat > /etc/haproxy/haproxy.cfg << EOL
globaldaemonmaxconn 256defaultsmode httptimeout connect 5stimeout client 30stimeout server 30s
EOL'
- (可选)卸载 HAProxy
如果不再需要 HAProxy,可以卸载:
sudo apt remove haproxy -y
sudo apt autoremove -y
七、拓展配置(可选)
1. 基于域名的 HTTP 转发
若需根据域名转发 HTTP 请求,修改 /etc/haproxy/haproxy.cfg
中的 http_proxy
部分:
listen http_proxybind *:80mode httpacl host_file hdr(host) -i files.example.comacl host_api hdr(host) -i api.example.comuse-server file1 if host_fileuse-server api1 if host_apiserver file1 10.0.0.2:8000 checkserver api1 10.0.0.3:8080 check
acl
:根据请求的Host
头匹配域名。use-server
:将匹配的请求转发到对应内网服务器。
2. 负载均衡
若有多个内网服务器提供相同服务,可配置 HAProxy 实现负载均衡:
listen http_balancerbind *:80mode httpserver web1 10.0.0.2:8000 checkserver web2 10.0.0.3:8000 check
HAProxy 默认使用轮询(round-robin)算法分配请求。
注意事项
-
防火墙设置:
- 确保公网服务器的
51820/UDP
(WireGuard)、80/TCP
(HTTP)、2222/TCP
(SSH)端口已开放。 - 内网服务器需允许
10.0.0.2
上的相应端口(如8000
、2222
)。
- 确保公网服务器的
-
域名解析(若使用域名):
- 将域名(如
files.example.com
)解析到公网服务器的 IP1.2.3.4
。
- 将域名(如
-
服务监听:
- 内网服务必须监听 WireGuard IP(
10.0.0.2
),否则 HAProxy 无法转发。
- 内网服务必须监听 WireGuard IP(
-
安全性:
- 本教程未配置 SSL,生产环境建议为 HTTP 服务启用 HTTPS(使用
certbot
或自签名证书)。 - 保护 WireGuard 私钥和 SSH 密钥,定期轮换。
- 本教程未配置 SSL,生产环境建议为 HTTP 服务启用 HTTPS(使用