【Linux】HAProxy:结合 WG 实现内网 TCP 反代

发布于:2025-06-10 ⋅ 阅读:(21) ⋅ 点赞:(0)

本教程指导您通过 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-server
    HostName 1.2.3.4
    User user_public

Host internal-server
    HostName 10.0.0.2
    User user_internal
    ProxyJump 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进程整体行为
global
    daemon                # 以守护进程方式运行
    maxconn 256           # 最大并发连接数限制,防止资源过载

# 默认配置:为所有proxy设置通用选项
defaults
    mode tcp              # 工作模式为TCP(适合SSH、非HTTP协议)
    timeout connect 5s    # 连接后端服务器超时时间,避免长时间挂起
    timeout client 30s    # 客户端连接超时,超过则断开
    timeout server 30s    # 后端服务器响应超时,超过则断开

# HTTP代理监听配置(监听80端口)
listen http_proxy
    bind *:80             # 监听所有网卡80端口,确保端口未被占用
    server s1 10.0.0.2:8000  # 后端HTTP服务器地址及端口

# SSH代理监听配置(监听2222端口)
listen ssh_proxy
    bind *: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

✅ 测试访问

从公网测试访问内网服务:

  1. 访问 HTTP 服务

    • 打开浏览器,访问 http://1.2.3.4/,应看到内网 Python 文件服务器的内容(如 hello.txt)。
  2. 访问 SSH 服务

    • 使用 SSH 客户端连接:

      ssh -p 2222 user_internal@1.2.3.4
      

若访问成功,说明配置正确。


六、清空配置

为了避免 HAProxy 或 WireGuard 的配置残留影响后续操作,或在调试时需要重置环境,可以按照以下步骤清空相关配置。

1. 清空 WireGuard 配置(公网服务器和内网服务器)

  1. 停止 WireGuard 服务

在两台服务器上停止并禁用 WireGuard:

sudo systemctl stop wg-quick@wg0
sudo systemctl disable wg-quick@wg0
  1. 删除 WireGuard 配置文件

移除 WireGuard 配置文件和密钥:

sudo rm /etc/wireguard/wg0.conf
sudo rm /etc/wireguard/private.key
sudo rm /etc/wireguard/public.key
  1. (可选)卸载 WireGuard

如果不再需要 WireGuard,可以完全卸载:

sudo apt remove wireguard -y
sudo apt autoremove -y

2. 清空 HAProxy 配置

公网服务器
  1. 停止 HAProxy 服务
sudo systemctl stop haproxy
sudo systemctl disable haproxy
  1. 备份并清空 HAProxy 配置

备份现有配置文件(以防需要恢复):

sudo mv /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak

创建空的默认配置文件:

sudo bash -c 'cat > /etc/haproxy/haproxy.cfg << EOL
global
    daemon
    maxconn 256

defaults
    mode http
    timeout connect 5s
    timeout client 30s
    timeout server 30s
EOL'
  1. (可选)卸载 HAProxy

如果不再需要 HAProxy,可以卸载:

sudo apt remove haproxy -y
sudo apt autoremove -y

七、拓展配置(可选)

1. 基于域名的 HTTP 转发

若需根据域名转发 HTTP 请求,修改 /etc/haproxy/haproxy.cfg 中的 http_proxy 部分:

listen http_proxy
    bind *:80
    mode http
    acl host_file hdr(host) -i files.example.com
    acl host_api hdr(host) -i api.example.com
    use-server file1 if host_file
    use-server api1 if host_api
    server file1 10.0.0.2:8000 check
    server api1 10.0.0.3:8080 check
  • acl:根据请求的 Host 头匹配域名。
  • use-server:将匹配的请求转发到对应内网服务器。

2. 负载均衡

若有多个内网服务器提供相同服务,可配置 HAProxy 实现负载均衡:

listen http_balancer
    bind *:80
    mode http
    server web1 10.0.0.2:8000 check
    server web2 10.0.0.3:8000 check

HAProxy 默认使用轮询(round-robin)算法分配请求。


注意事项

  1. 防火墙设置

    • 确保公网服务器的 51820/UDP(WireGuard)、80/TCP(HTTP)、2222/TCP(SSH)端口已开放。
    • 内网服务器需允许 10.0.0.2 上的相应端口(如 80002222)。
  2. 域名解析(若使用域名):

    • 将域名(如 files.example.com)解析到公网服务器的 IP 1.2.3.4
  3. 服务监听

    • 内网服务必须监听 WireGuard IP(10.0.0.2),否则 HAProxy 无法转发。
  4. 安全性

    • 本教程未配置 SSL,生产环境建议为 HTTP 服务启用 HTTPS(使用 certbot 或自签名证书)。
    • 保护 WireGuard 私钥和 SSH 密钥,定期轮换。

网站公告

今日签到

点亮在社区的每一天
去签到