跳到主要内容

Wireguard安装

· 阅读需 6 分钟
GavinTan
DevOps Engineer

WireGuard是一种极其简单但快速且现代的 VPN,采用最先进的加密技术。它的目标是比 IPsec更快、更简单、更精简、更有用,同时避免令人头疼的问题。它的性能远高于 OpenVPN。WireGuard 被设计为通用 VPN,可在嵌入式接口和超级计算机上运行,适合许多不同的情况。它最初针对 Linux 内核发布,现在已跨平台(Windows、macOS、BSD、iOS、Android)且可广泛部署。

服务器安装

前往官方安装文档

Linux内核必须>5.6

yum install wireguard-tools

Quick Start

前往配置文档

  1. 密钥生成

    umask 077
    wg genkey | tee privatekey | wg pubkey > publickey
  2. 生成配置文件

    当客户端配置了AllowedIPs = 0.0.0.0/0代理所有流量,服务器端必须添加PostUp的iptables来转发流量客户端才能正常使用,是支持多个Peer的也就是能同时配置多个远程端点。

    AllowedIPs通俗的来说就是本地需要经过wireguard的ip网段都要配置上

    umask 077
    cat <<EOF > /etc/wireguard/wg0.conf
    [Interface]
    PrivateKey = `cat privatekey`
    Address = 172.16.100.1/24 #地址须唯一
    ListenPort = 51820 #udp端口
    PostUp = sysctl -w net.ipv4.ip_forward=1
    PostUp = iptables -A FORWARD -i %i -j ACCEPT
    PostUp = iptables -A FORWARD -o %i -j ACCEPT
    PostUp = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
    PostDown = sysctl -w net.ipv4.ip_forward=0
    PostDown = iptables -D FORWARD -i %i -j ACCEPT
    PostDown = iptables -D FORWARD -o %i -j ACCEPT
    PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

    [Peer]
    PublicKey = <客户端的publickey>
    AllowedIPs = 172.16.100.2/32
    EOF
  3. 启动wireguard

    wg-quick up wg0

    #设置开机自启
    systemctl enable wg-quick@wg0
  4. 停止wireguard

    wg-quick down wg0

    #删除开机自启
    systemctl disable wg-quick@wg0

客户端安装

客户端需要全局流量走wireguard需要添加AllowedIPs = 0.0.0.0/0配置,不行全局流量都走wireguard只需要在AllowedIPs 配置需要经过vpn的网段或ip即可

如果是在windows上客户端打通隧道需要在连接局域网的网卡上设置Internet连接共享允许本地wireguard Tunnel创建的网卡

[Interface]
PrivateKey = <客户端的privatekey>
Address = 172.16.100.2/24 #地址须唯一且同服务器为同一网段
DNS = 8.8.8.8,1.1.1.1

[Peer]
PublicKey = <服务器的publickey>
AllowedIPs = 0.0.0.0/0,::/0
Endpoint = <server>:51820
PersistentKeepalive = 25 #当服务器位于NAT或防火墙后面时需要配置keepalive

疑难解答

使用动态域名之类的ip发生变化不会自动重连

git clone https://git.zx2c4.com/wireguard-tools /usr/share/wireguard-tools


cat <<EOF > /etc/systemd/system/wireguard_reresolve-dns.timer
[Unit]
Description=Periodically reresolve DNS of all WireGuard endpoints

[Timer]
OnCalendar=*:*:0/30

[Install]
WantedBy=timers.target
EOF



cat <<EOF > /etc/systemd/system/wireguard_reresolve-dns.service
[Unit]
Description=Reresolve DNS of all WireGuard endpoints
Wants=network-online.target
After=network-online.target

[Service]
Type=oneshot
ExecStart=/bin/sh -c 'for i in /etc/wireguard/*.conf; do /usr/share/wireguard-tools/contrib/reresolve-dns/reresolve-dns.sh "$i"; done'
EOF



systemctl enable wireguard_reresolve-dns.timer --now

遇到运营商UDP限速(QOS)

WireGuard 在国内网络环境下会遇到一个致命的问题:UDP 封锁/限速。虽然通过 WireGuard 可以在隧道内传输任何基于 IP 的协议(TCP、UDP、ICMP、SCTP、IPIP、GRE 等),但 WireGuard 隧道本身是通过 UDP 协议进行通信的,而国内运营商几乎全部采取一刀切的手段:对 UDP 进行限速甚至封锁。

解决方法:使用Phantun将UDP伪装成TCP连接。

服务端:

假设服务端的公网 IP 地址是 121.36.134.95,WireGuard 监听端口是 51822。首先修改配置文件 /etc/wireguard/wg0.conf,在 [Interface] 中添加以下配置:

如果你使用 ping 或者 dig 等工具(小数据包)测试 WireGuard 隧道能够正常工作,但浏览器或者远程桌面(大数据包)却无法正常访问,很有可能是 MTU 的问题,你需要将 MTU 的值调小一点。

Phantun 官方建议将 MTU 的值设为 1428(假设物理网卡的 MTU 是 1500),但经我测试是有问题的。建议直接将 MTU 设置为最低值 1280,然后渐渐增加,直到无法正常工作为止,此时你的 MTU 就是最佳值。

MTU = 1300
PreUp = iptables -t nat -A PREROUTING -p tcp -i eth0 --dport 4567 -j DNAT --to-destination 192.168.201.2
PreUp = RUST_LOG=info phantun_server --local 4567 --remote 127.0.0.1:51822 &> /var/log/phantun_server.log &
PostDown = iptables -t nat -D PREROUTING -p tcp -i eth0 --dport 4567 -j DNAT --to-destination 192.168.201.2
PostDown = killall phantun_server || true

你需要将 eth0 替换为你服务端的物理网卡名。MTU 值先不管,后面再告诉大家调试方法。

PreUp = iptables -t nat -A PREROUTING -p tcp -i eth0 --dport 4567 -j DNAT --to-destination 192.168.201.2

这条 iptables 规则表示将 4567 端口的入站流量 DNAT 为 TUN 网卡的 IP 地址。

PreUp = RUST_LOG=info phantun_server --local 4567 --remote 127.0.0.1:51822 &> /var/log/phantun_server.log &

这里会启动 phantun_server,监听在 4567 端口,并将 UDP 数据包转发到 WireGuard。

服务端完整的 WireGuard 配置:

# local settings for Endpoint B
[Interface]
PrivateKey = QH1BJzIZcGo89ZTykxls4i2DKgvByUkHIBy3BES2gX8=
Address = 10.0.0.2/32
ListenPort = 51822
MTU = 1300
PreUp = iptables -t nat -A PREROUTING -p tcp -i eth0 --dport 4567 -j DNAT --to-destination 192.168.201.2
PreUp = RUST_LOG=info phantun_server --local 4567 --remote 127.0.0.1:51822 &> /var/log/phantun_server.log &
PostDown = iptables -t nat -D PREROUTING -p tcp -i eth0 --dport 4567 -j DNAT --to-destination 192.168.201.2
PostDown = killall phantun_server || true

# remote settings for Endpoint A
[Peer]
PublicKey = wXtD/VrRo92JHc66q4Ypmnd4JpMk7b1Sb0AcT+pJfwY=
AllowedIPs = 10.0.0.1/32

最后重启 WireGuard 即可:

$ systemctl restart wg-quick@wg0
客户端:

假设客户端的 WireGuard 监听端口是 51821。首先修改配置文件 /etc/wireguard/wg0.conf,在 [Interface] 中添加以下配置:

MTU = 1300
PreUp = iptables -t nat -A POSTROUTING -o eth0 -s 192.168.200.2 -j MASQUERADE
PreUp = RUST_LOG=info phantun_client --local 127.0.0.1:4567 --remote 121.36.134.95:4567 &> /var/log/phantun_client.log &
PostDown = iptables -t nat -D POSTROUTING -o eth0 -s 192.168.200.2 -j MASQUERADE
PostDown = killall phantun_client || true

你需要将 eth0 替换为你服务端的物理网卡名。

PreUp = iptables -t nat -A POSTROUTING -o eth0 -s 192.168.200.2 -j MASQUERADE

这条 iptables 规则表示对来自 192.168.200.2(TUN 网卡) 的出站流量进行 MASQUERADE。

PreUp = RUST_LOG=info phantun_client --local 127.0.0.1:4567 --remote 121.36.134.95:4567 &> /var/log/phantun_client.log &

这里会启动 phantun_client,监听在 4567 端口,并与服务端建立连接,将伪装的 TCP 数据包传送给服务端。

除此之外还需要修改 WireGuard peer 的 Endpoint,将其修改为 127.0.0.1:4567。

Endpoint = 127.0.0.1:4567

客户端完整的 WireGuard 配置:

# local settings for Endpoint A
[Interface]
PrivateKey = 0Pyz3cIg2gRt+KxZ0Vm1PvSIU+0FGufPIzv92jTyGWk=
Address = 10.0.0.1/32
ListenPort = 51821
MTU = 1300
PreUp = iptables -t nat -A POSTROUTING -o eth0 -s 192.168.200.2 -j MASQUERADE
PreUp = RUST_LOG=info phantun_client --local 127.0.0.1:4567 --remote 121.36.134.95:4567 &> /var/log/phantun_client.log &
PostDown = iptables -t nat -D POSTROUTING -o eth0 -s 192.168.200.2 -j MASQUERADE
PostDown = killall phantun_client || true

# remote settings for Endpoint B
[Peer]
PublicKey = m40NDb5Cqtb78b1DVwY1+kxbG2yEcRhxlrLm/DlPpz8=
Endpoint = 127.0.0.1:4567
AllowedIPs = 10.0.0.2/32
PersistentKeepalive = 25

最后重启 WireGuard 即可:

$ systemctl restart wg-quick@wg0
客户端(多服务端):

如果客户端想和多个服务端建立连接,则新增的服务端配置如下:

PreUp = RUST_LOG=info phantun_client --local 127.0.0.1:4568 --remote xxxx:4567 --tun-local=192.168.202.1 --tun-peer=192.168.202.2 &> /var/log/phantun_client.log &
PostDown = iptables -t nat -D POSTROUTING -o eth0 -s 192.168.202.2 -j MASQUERADE

本地监听端口需要选择一个与之前不同的端口,同理,TUN 网卡的地址也需要修改。最终的配置如下:

# local settings for Endpoint A
[Interface]
PrivateKey = 0Pyz3cIg2gRt+KxZ0Vm1PvSIU+0FGufPIzv92jTyGWk=
Address = 10.0.0.1/32
ListenPort = 51821
MTU = 1300
PreUp = iptables -t nat -A POSTROUTING -o eth0 -s 192.168.200.2 -j MASQUERADE
PreUp = RUST_LOG=info phantun_client --local 127.0.0.1:4567 --remote 121.36.134.95:4567 &> /var/log/phantun_client.log &
PreUp = RUST_LOG=info phantun_client --local 127.0.0.1:4568 --remote xxxx:4567 --tun-local=192.168.202.1 --tun-peer=192.168.202.2 &> /var/log/phantun_client.log &
PostDown = iptables -t nat -D POSTROUTING -o eth0 -s 192.168.200.2 -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -o eth0 -s 192.168.202.2 -j MASQUERADE
PostDown = killall phantun_client || true

# remote settings for Endpoint B
[Peer]
PublicKey = m40NDb5Cqtb78b1DVwY1+kxbG2yEcRhxlrLm/DlPpz8=
Endpoint = 127.0.0.1:4567
AllowedIPs = 10.0.0.2/32
PersistentKeepalive = 25