最近有连接两个内网的小需求,想起了之前写过的 WireGuard 搭建和使用折腾小记,决定尝试着使用 WireGuard 来实现。因为两个内网都在 NAT 后,自己也没有固定的公网 IP,所以只能借助一台 VPS 作为中继服务器,用来分别连接两个内网并进行流量转发。以下内容为自己的一点记录,其实大体上和之前的文章区别不大,不过这次主要以手动命令配置为主,方便自己进一步理解。

拓扑环境

  1. NAT-A (192.168.0.0/24) --- Gateway (VPS) --- NAT-B (10.180.0.0/16)
  2. wg 隧道接口 IP 我这里采用的是 10.10.10.0/24 网段的 IP,如下:
  3. NAT-A10.10.10.2/24
  4. GW10.10.10.1/24
  5. NAT-B10.10.10.3/24

安装与配置

环境依赖

  1. NAT-A、NAT-B、VPS 均采用一台 Linux PC 作为 WireGuard endpoint;
  2. WireGuard 安装过程不再赘述,见官方文档
  3. iptables、iproute2

    配置过程

    GW 端

    1. # 1. 生成密钥对
    2. wg genkey | tee privatekey | wg pubkey > publickey
    3. # 2. 创建 WireGuard tunnel 接口
    4. ip link add dev wg0 type wireguard
    5. # 3. 为 wg 接口配置 IP 地址
    6. ip address add dev wg0 10.10.10.1/24
    7. # 4. 指定 gw 端 wg0 接口私钥及接听端口
    8. wg set wg0 private-key $(cat privatekey) listen-port 60000
    9. # 5. 启用 wg0 接口
    10. ip link set up dev wg0
    11. # 6. 开启流量转发
    12. echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
    13. sysctl -p
    14. # > filter 表转发链中允许 wg0 接口的出入流量
    15. iptables -A FORWARD -i wg0 -j ACCEPT
    16. iptables -A FORWARD -o wg0 -j ACCEPT
    17. # > nat 表动态伪装 snat
    18. iptables -t nat -A POSTROUTING -o $OUTBOUND_INTERFACE -j MASQUERADE

    NAT-A 端

    1. # 1. 生成密钥对
    2. wg genkey | tee privatekey | wg pubkey > publickey
    3. # 2. 创建 WireGuard tunnel 接口
    4. ip link add dev wg0 type wireguard
    5. # 3. 为 WireGuard 接口配置 IP 地址
    6. ip address add dev wg0 10.10.10.2/24
    7. # 4. 指定 NAT-A 端接口密钥及 peer 信息(注意替换字段内容)
    8. # > allowed-ips: 指定需要经隧道的 IP 段,即指定相应 IP 段的静态路由;这里除了添加 WireGuard 网段,还需添加 NAT-B 网段地址,即相当于添加路由 ip route add 10.180.0.0/16 dev wg0
    9. # > endpoint: 指定 gw 端的地址和监听端口
    10. # > persistent-keepalive:用于保持长连接
    11. wg set wg0 private-key $(cat privatekey) peer $GW_PUBKEY allowed-ips 10.10.10.0/24,10.180.0.0/16 endpoint $GW_IP:60000 persistent-keepalive 10
    12. # 5. 启用 wg0 接口
    13. ip link set up dev wg0
    14. # 6. 开启流量转发
    15. echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
    16. sysctl -p
    17. # > filter 表转发链中允许 wg0 接口的出入流量
    18. iptables -A FORWARD -i wg0 -j ACCEPT
    19. iptables -A FORWARD -o wg0 -j ACCEPT
    20. # > nat 表动态伪装 snat
    21. iptables -t nat -A POSTROUTING -o $OUTBOUNG_INTERFACE -j MASQUERADE

    NAT-B 端

    1. # 1. 生成密钥对
    2. wg genkey | tee privatekey | wg pubkey > publickey
    3. # 2. 创建 WireGuard tunnel 接口
    4. ip link add dev wg0 type wireguard
    5. # 3. 为 WireGuard 接口配置 IP 地址
    6. ip address add dev wg0 10.10.10.3/24
    7. # 4. 指定 NAT-B 端接口密钥及 peer 信息(注意替换字段内容)
    8. # > allowed-ips: 指定需要经隧道的 IP 段,相当于指定了相应 IP 段的静态路由;这里除了指定 WireGuard 网段,还添加了 NAT-A 网段地址,即相当于添加路由 ip route add 192.168.0.0/24 dev wg0
    9. # > endpoint: 指定 gw 端的地址和监听端口
    10. # > persistent-keepalive:用于保持长连接;设置为 0 代表不打开
    11. wg set wg0 private-key $(cat privatekey) peer $GW_PUBKEY allowed-ips 10.10.10.0/24,192.168.0.0/24 endpoint $GW_IP:60000 persistent-keepalive 10
    12. # 5. 启用 wg0 接口
    13. ip link set up dev wg0
    14. # 6. 开启流量转发
    15. echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
    16. sysctl -p
    17. # > filter 表转发链中允许 wg0 接口的出入流量
    18. iptables -A FORWARD -i wg0 -j ACCEPT
    19. iptables -A FORWARD -o wg0 -j ACCEPT
    20. # > nat 表动态伪装 snat
    21. iptables -t nat -A POSTROUTING -o $OUTBOUNG_INTERFACE -j MASQUERADE

    GW 端添加 peer

    1. # 1. 添加 peer NAT-A,注意 allowed-ips 添加 NAT-A 网段,相当于添加到 NAT
    2. wg set wg0 peer $NAT_A_PUBKEY allowed-ips 10.10.10.2/32,192.168.0.0/24
    3. # 2. 添加 peer NAT-B,注意 allowed-ips 添加 NAT-B 网段
    4. wg set wg0 peer $NAT_B_PUBKEY allowed-ips 10.10.10.3/32,10.180.0.0/16
    至此,就全部配置完成了,NAT-A (192.168.0.0/24) 与 NAT-B (10.180.0.0/16) 两个 LAN 可以通过 GW 进行通信了。如需添加更多 NAT 网络,同样操作即可,主要就是 allowed-ips 即路由的设置。

    配置文件

    上述过程可以编写成配置文件(默认保存位置 /etc/wireguard)通过 wg-quick 命令快速运行,这里不再赘述(可参考 WireGuard 搭建和使用折腾小记),各端配置文件示例如下:
    1. # GW
    2. [Interface]
    3. ListenPort = 60000
    4. Address = 10.10.10.1/24
    5. PrivateKey = $GW_PRIVATE_KEY
    6. PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o $OUTBOUND_INTF -j MASQUERADE
    7. PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o $OUTBOUND_INTF -j MASQUERADE
    8. [Peer]
    9. PublicKey = $NAT_A_PUBKEY
    10. AllowedIPs = 10.10.10.2/32, 192.168.0.0/24
    11. [Peer]
    12. PublicKey = $NAT_B_PUBKEY
    13. AllowedIPs = 10.10.10.3/32, 10.180.0.0/16
    14. # NAT-A
    15. [Interface]
    16. Address = 10.10.10.2/24
    17. PrivateKey = $NAT_A_PRIVATEKEY
    18. [Peer]
    19. PublicKey = $GW_PUBKEY
    20. AllowedIPs = 10.10.10.0/24,10.180.0.0/16
    21. Endpoint = $GW_IP:60000
    22. PersistentKeepalive = 10
    23. # NAT-B
    24. [Interface]
    25. Address = 10.10.10.3/24
    26. PrivateKey = $NAT_B_PRIVATEKEY
    27. [Peer]
    28. PublicKey = $GW_PUBKEY
    29. AllowedIPs = 10.10.10.0/24,192.168.0.0/24
    30. Endpoint = $GW_IP:60000
    31. PersistentKeepalive = 10

    参考