Wireguard安装
WireGuard是一种极其简单但快速且现代的 VPN,采用最先进的加密技术。它的目标是比 IPsec更快、更简单、更精简、更有用,同时避免令人头疼的问题。它的性能远高于 OpenVPN。WireGuard 被设计为通用 VPN,可在嵌入式接口和超级计算机上运行,适合许多不同的情况。它最初针对 Linux 内核发布,现在已跨平台(Windows、macOS、BSD、iOS、Android)且可广泛部署。
服务器安装
Linux内核必须>5.6
yum install wireguard-tools
Quick Start
-
密钥生成
umask 077
wg genkey | tee privatekey | wg pubkey > publickey -
生成配置文件
当客户端配置了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 -
启动wireguard
wg-quick up wg0
#设置开机自启
systemctl enable wg-quick@wg0 -
停止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