WireGuard 安装与双机隧道组网(公网机 ↔ 内网机)
2026-07-23
安装搭建
00

目录

WireGuard 安装与双机隧道组网(公网机 ↔ 内网机)
一、背景与准备
二、方案选型:WireGuard 还是 frp / Tailscale
三、两端安装
Ubuntu / Debian
CentOS / RHEL 8+ / Rocky / Alma
CentOS 7(内核老,走 DKMS)
四、生成密钥对
五、配置公网机(守门方)
六、配置内网机(主动连接方)
七、放行防火墙
八、启动与开机自启
九、验证连通
十、让内网服务可被公网访问(可选)
十一、排错速查
十二、小结与参考资料

WireGuard 安装与双机隧道组网(公网机 ↔ 内网机)

本文记录在两台 Linux 之间用 WireGuard 打通一条加密隧道的最简做法:一台有公网 IP(公网机),一台只有内网、藏在 NAT 后面(内网机)。目标是让内网机主动连上公网机之后,两端互访,并顺带把内网机身后网段的服务也暴露出来。照着做基本能一次通。

一、背景与准备

WireGuard 是内核态的轻量 VPN,配置比 OpenVPN 简单太多,一个 .conf 就搞定。本文场景:

  • 公网机:有公网 IP(下文记 <公网IP>),比如一台云服务器,负责"守门",监听 UDP 51820。
  • 内网机:没有公网 IP,在公司或家里内网,藏在路由器 NAT 后面,主动去连公网机。

连接方向只能是内网机 → 公网机(因为内网机没有公网地址可被回连),所以内网机的配置里要写 Endpoint = <公网IP>:51820 加上 PersistentKeepalive,让 NAT 映射一直保活,公网机才能"反打"回来。

需要准备的:

  • 两台机都是 Linux(Ubuntu/Debian 或 CentOS/RHEL 系都行,本文都覆盖)。
  • 内核 ≥ 5.6 自带 wireguard 模块;老内核(如 CentOS 7)要走 DKMS 装 wireguard-dkms
  • 公网机的防火墙要放行 UDP 51820(云厂商安全组也要放)。
  • 规划一个隧道内网段,本文用 10.0.0.0/24:公网机 10.0.0.1,内网机 10.0.0.2

改 IP、配网络这些前置,可参考同系列的静态 IP 配置和 SSH 公钥登录文档。

二、方案选型:WireGuard 还是 frp / Tailscale

动手装之前,先想清楚用哪种——WireGuard 不是内网穿透的唯一解。下面这张对比表,是结合 IMA 知识库「Linux运维」里《内网穿透方案对比:frp、WireGuard、Tailscale 实测体验》(作者:马哥Linux运维)的实测经验整理的,帮你少走弯路。

维度WireGuardfrpTailscale
转发原理内核态 VPN,节点间 P2P 直连(不经第三方)流量经过你自己的中转服务器基于 WireGuard,自动组网 + 中继兜底
是否需要公网 IP至少一端要(本文就是公网机这端)需要一台中转服务器有公网 IP不需要(官方中继,或自建 Headscale)
性能极高,内核态 + 直连受中转带宽瓶颈,有额外延迟能直连时同 WireGuard,否则走中继
部署难度中:写一份 wg0.conf中:服务端 + 客户端都要配极低:装客户端、登录账号即可
维护成本低,纯配置文件中,要长期维护中转机低(官方托管控制面,或自建 Headscale)
典型用途多台服务器组私有网络把本地服务暴露到公网不想折腾、个人/小团队互联

那篇实测环境是:客户端在 NAT 后、服务端在阿里云华南(广州)节点,对"家庭宽带 + 云服务器"的组合也成立。

三个方案的取舍(经验之谈)

  • WireGuard:适合"机器和机器之间组一张私有网"。加密隧道、直连、性能炸裂。但它有三个现实痛点:① 需要固定公网 IP(动态公网 IP 得配 DDNS,本文排错表也提到了);② NAT 穿透能力弱——只有一端有公网地址时只能那端被动等连,所以本文场景里内网机必须主动连 + PersistentKeepalive,两端都在对称型 NAT 后可能直接连不上;③ 加新设备要重配所有节点:每加一个 Peer,所有节点的 wg0.conf 都得补一段 [Peer] 再重载,规模一大就烦。
  • frp:完全可控、不依赖第三方、数据经你自己的中转服务器。缺点是流量都压在中转机上,有带宽瓶颈和延迟;中转服务器也得你自己养。
  • Tailscale:最省心,5 分钟能用起来,免费版对个人和小团队够用。它底层也是 WireGuard,只是帮你把"找 IP、打洞、中继"这些脏活干了。代价是要信它的控制面(或自己搭 Headscale 摆脱依赖)。

怎么选(库文作者的场景建议,我认同)

  • 只想把家里/公司的 Web、SSH、RDP 暴露到公网 → Tailscale 免费版最省心。
  • 文件传输、数据库连接、机器间 SSH 这类"互联"需求 → WireGuard + Tailscale 混合,或纯 WireGuard。
  • 想要全场景、且完全自建掌控 → Headscale 自建 + WireGuard

本文选 WireGuard,是因为它最能讲清"隧道到底怎么搭",而且不依赖任何第三方服务,适合当作基础来学。如果你只是想快速连上,Tailscale 可能更合适——按需取用即可。

三、两端安装

Ubuntu / Debian

bash
sudo apt update sudo apt install -y wireguard # 含 wireguard-tools sudo modprobe wireguard && echo "模块已加载" # 验证内核支持

CentOS / RHEL 8+ / Rocky / Alma

bash
sudo dnf install -y epel-release sudo dnf install -y wireguard-tools # 内核 ≥ 5.6 自带模块;更老的内核需额外装 kmod-wireguard(来自 elrepo) sudo modprobe wireguard && echo "模块已加载"

CentOS 7(内核老,走 DKMS)

bash
sudo yum install -y epel-release sudo yum install -y wireguard-dkms wireguard-tools sudo modprobe wireguard && echo "模块已加载"

确认 wg 命令可用:wg --version

四、生成密钥对

每台机各自生成私钥/公钥,私钥只留在本机,公钥发给对端

bash
cd /etc/wireguard umask 077 # 密钥文件权限收紧 wg genkey | tee privatekey | wg pubkey > publickey # 一次性生成私钥和对应公钥
  • /etc/wireguard/privatekey:本机私钥,填到自己配置的 [Interface] 里。
  • /etc/wireguard/publickey:本机公钥,发给对端填到它的 [Peer] 里。

两端各生成一次。记一下:公网机公钥 <公网机公钥>,内网机公钥 <内网机公钥>

五、配置公网机(守门方)

/etc/wireguard/wg0.conf

ini
[Interface] Address = 10.0.0.1/24 ListenPort = 51820 PrivateKey = <公网机私钥> # 如果要把内网机身后的网段也转发出来,放开下面两行(eth0 换成公网机出口网卡) # PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE # PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE [Peer] PublicKey = <内网机公钥> AllowedIPs = 10.0.0.2/32

AllowedIPs = 10.0.0.2/32 表示只有这个隧道地址的流量走公网机的 wg0。

如果还想让公网机能访问内网机后面的整个内网(比如 192.168.1.0/24),把那行改成 AllowedIPs = 10.0.0.2/32, 192.168.1.0/24,同时放开上面的 PostUp/PostDown 做 NAT 转发,并在内网机侧把对应网段也写进它的 Peer AllowedIPs。

六、配置内网机(主动连接方)

/etc/wireguard/wg0.conf

ini
[Interface] Address = 10.0.0.2/24 PrivateKey = <内网机私钥> [Peer] PublicKey = <公网机公钥> Endpoint = <公网IP>:51820 # 公网机地址,内网机主动连这里 AllowedIPs = 10.0.0.0/24 # 只走隧道访问对端网段;要全局代理改成 0.0.0.0/0 PersistentKeepalive = 25 # NAT 保活,关键!否则公网机无法主动回连

PersistentKeepalive = 25 是 NAT 场景的命脉:内网机每 25 秒发个保活包,让路由器端口映射不超时,公网机才能随时找到它。

七、放行防火墙

公网机要放行 UDP 51820:

bash
# Debian/Ubuntu(ufw) sudo ufw allow 51820/udp # CentOS/RHEL(firewalld) sudo firewall-cmd --add-port=51820/udp --permanent sudo firewall-cmd --reload

云服务器还要在安全组里放 UDP 51820,这是最常见被漏掉的一步。

八、启动与开机自启

两端都执行:

bash
sudo wg-quick up wg0 # 拉起隧道 sudo systemctl enable wg-quick@wg0 # 开机自启 sudo wg show # 看接口状态和握手情况

九、验证连通

内网机 ping 公网机隧道地址:

bash
ping 10.0.0.1

公网机 ping 内网机:

bash
ping 10.0.0.2

wg showlatest handshake 有最近时间戳、且 transfer 有数据,就说明隧道通了。从没握手过,基本就是防火墙 / Endpoint / 密钥三选一错了。

十、让内网服务可被公网访问(可选)

典型需求:内网机上有个 192.168.1.100:8080 的服务,想从外面通过公网机访问。

  1. 公网机 wg0.conf 放开第五节注释的 PostUp/PostDown 两行,并 sysctl -w net.ipv4.ip_forward=1(持久化写进 /etc/sysctl.d/99-wireguard.conf)。
  2. 公网机加端口转发,把公网流量引到隧道:
    bash
    sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8080 -j DNAT --to-destination 10.0.0.2:8080
  3. 内网机 [Peer]AllowedIPs 保持 10.0.0.0/24 即可(服务流量从公网机经 wg0 进隧道)。

十一、排错速查

现象原因处理
wg show 一直无 handshake防火墙/安全组没放 UDP 51820公网机 ufw/firewalld 放行,云安全组也放
内网机连不上Endpoint 写错或公网 IP 变了核对 <公网IP>:51820;动态公网 IP 要上 DDNS
能握手但 ping 不通AllowedIPs 写错 / 没开转发确认两端网段;网关场景开 net.ipv4.ip_forward
公网机无法主动访问内网机PersistentKeepalive内网机 Peer 加 PersistentKeepalive = 25
RTNETLINK answers: Operation not permitted没 root / 模块没加载sudo 执行,确认 modprobe wireguard 成功
MTU 导致部分网站打不开默认 MTU 偏大[Interface]MTU = 1380

十二、小结与参考资料

WireGuard 把"两台 Linux 打通加密隧道"压到了一个配置文件。记住三个关键点:内网机写 Endpoint + PersistentKeepalive(因为只能它主动连)、公网机防火墙和安全组放 UDP 51820要转发就开 ip_forward 和 NAT。选型上,纯互联、想完全自建就选 WireGuard;只想快速把服务暴露公网、不想折腾,Tailscale 更省力——第二篇「方案选型」一节有完整的对比和取舍。

参考资料:

  • WireGuard 官方文档:https://www.wireguard.com/
  • man wg / man wg-quick
  • 马哥Linux运维《内网穿透方案对比:frp、WireGuard、Tailscale 实测体验》(IMA 知识库「Linux运维」)

ai协作,人工编辑

本文作者:张老板

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!