返回

WireGuard应用-点对点连接

点对点连接:WireGuard 可用于在两台设备之间建立一个加密的网络隧道,所有传输的数据都通过这个隧道进行,适用于需要直接安全通信的场景。

  • 局域网环境下:在局域网内的两台设备上部署 wireguard 节点,这两台设备之间的通信数据全部走 WireGuard VPN 隧道

  • 公网环境下:在公网服务器和本地 Windows 计算机上部署 wireguard 节点,通过公网服务器将所有 IP 流量从本地 Windows 计算机路由到 Internet

前置准备

查看系统内核版本,若低于5.6版本则需要对内核进行升级:

1
uname -r

检查局域网内两台设备是否能互相 ping 通

安装

ubuntu

1
2
3
sudo apt update
sudo apt upgrade
sudo apt install wireguard

windows

官网下载windows客户端

配置

ubuntu

  1. 生成密钥对

WireGuard VPN 网络中的每个设备都需要有一个私钥和公钥

/etc下创建文件夹WireGuard,用于存放配置文件

1
2
3
4
5
6
sudo mkdir -p /etc/wireguard && sudo chmod 0777 /etc/wireguard
cd /etc/wireguard
# 设置新创建文件或目录的默认权限: 只能由拥有者读取和写入(不能执行),组和其他用户没有权限
umask 077
# 生成公私钥对
wg genkey | tee peerA_privatekey | wg pubkey > peerA_publickey
  • tee:将输出同时写入文件和标准输出(屏幕)
  • >:将输出重定向到文件中
  • |:管道,将前一个命令的输出传递给另一个命令作为输入
  1. 创建配置文件wg0.conf
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
[Interface]
    # 本机私钥
    PrivateKey = ...
    # 本机在 wireguard 隧道中的地址
    Address = 10.0.8.1/32
    # 监听端口
    ListenPort = 50820
    # 设置 DNS 服务器,确保连接时可以解析域名
    DNS = 8.8.8.8
    # 最大传输单元,单位是字节,指数据链路层的最大payload
    MTU = 1420

[Peer]
    # 对端公钥
    PublicKey = ...  
    # 对端在 wireguard 隧道中的地址
    AllowedIPs = 10.0.8.2/24
    # 指定对端 ip 地址
    Endpoint = 192.168.1.124:50820

windows

打开安装的 wireguard 软件,新建空隧道

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
[Interface]
    PrivateKey = ...
    ListenPort = 50820
    Address = 10.0.8.2/32
    DNS = 8.8.8.8
    MTU = 1420

[Peer]
    PublicKey = ...
    AllowedIPs = 10.0.8.1/24
    Endpoint = 192.168.2.135:50820
  • 可选是否拦截未经通道的流量

启动

ubuntu

  1. 使用配置文件启动
1
sudo wg-quick up wg0

该命令将隧道名称 wg0映射到 /etc/wireguard/wg0.conf 配置文件。这种命名方法意味着可以创建任意数量的单独 VPN 隧道。

例如,可以有一个隧道设备,名称为 prod,其配置文件为/etc/wireguard/prod.conf。 每个隧道配置可以包含不同的 IPv4、IPv6 和客户端防火墙设置。 通过这种方式,可以支持多个不同的对等连接,每个连接都有自己唯一的 IP 地址和路由规则

1
2
3
4
5
6
7
[#] ip link add wg0 type wireguard
[#] wg setconf wg0 /dev/fd/63
Warning: AllowedIP has nonzero host part: 10.0.8.2/24
[#] ip -4 address add 10.0.8.1/32 dev wg0
[#] ip link set mtu 1420 up dev wg0
[#] resolvconf -a wg0 -m 0 -x
[#] ip -4 route add 10.0.8.0/24 dev wg0
  1. 若未启动成功,查看日志,若报错/usr/bin/wg-quick: line 32: resolvconf: command not found,执行命令
1
sudo apt install openresolv

windows

点击连接即可

验证连接

  1. 检查连接:可以看到有流量产生
1
sudo wg
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
interface: wg0
  public key: 4yAkPBP7H9257pSN80ThYm7nLVWvfd+Hu+sJYUNE1Ag=
  private key: (hidden)
  listening port: 50820

peer: HYqSuxG7mo0yzPdkchr5LBuEHBeoUc6kGkVnsXsgIkQ=
  endpoint: 192.168.1.124:50820
  allowed ips: 10.0.8.0/24
  latest handshake: 7 minutes, 44 seconds ago
  transfer: 2.03 KiB received, 2.05 KiB sent
  1. 验证接口状态:
1
ip a show wg0
1
2
3
4
16: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000
    link/none 
    inet 10.0.8.1/32 scope global wg0
       valid_lft forever preferred_lft forever
  1. 互相 ping
1
2
3
4
# win -> ubuntu
ping 10.0.8.1 
# ubuntu -> win 无响应的话可以关闭win防火墙
ping 10.0.8.2 
  1. 检查两端都能连接到Internet,说明只有到对端的流量走隧道
  2. 关闭wg0接口
1
sudo wg-quick down wg0

流量抓包

  1. windows上安装wireshark,安装时选择包含 sshdump 功能
  2. 修改ubuntutcpdump权限,所有用户可使用
1
2
3
4
5
6
whereis tcpdump
cd /usr/bin
ll tcpdump
chmod u+s tcpdump
sudo chmod u+s tcpdump
ll tcpdump
  1. windows上使用wiresharksshdump 连接到虚拟机开启抓包
  2. 两端连接后,用 ubuntu ping windows,抓到的握手和密文数据包

  1. ubuntu中启动一个http服务,在windows上通过隧道ip地址:http服务的端口号10.8.0.1:8080)访问该web服务,抓包可以看到传输数据已被加密

流量分析

windows客户端发送的流量走向

  1. 应用层程序 chrome 创建网络包,并发送给对应的 socket
  2. 通过对应的 socket,该网络包到达了内核协议栈,在网络协议栈会判断路由,通过路由把流量发到 wg0 网卡;
  3. 到达 wg0 网卡的包,会通过字符驱动直接发送给应用层程序 wireguard
  4. wireguard 通过原始 IP 包的src ip10.0.8.1),在加密密钥路由表(上面的配置文件)中找到对端公钥,使用 ChaCha20Poly1305 算法加密签名该数据包,再在加密后的数据包前添加 wireguard header,然后加上 udp header,组合为 UDP 负载,最后在最外层再加上 IP header(对端公网 ip,也就是Endpoint),之后发送给对应的 socket
    • 内层 IP header:对端隧道 IP,即配置文件的 AllowedIPs
    • 外层 IP header:对端公网 IP,即配置文件的 Endpoint
    • 路由器等网络设备是通过外层 IP header 转发的。等网络包到达 wireguard 隧道的另外一端之后,内核中的网络协议栈会剥掉外层 IP header,然后交给 wireguard 协议栈
  5. socket 发出的包会通过内核网络协议栈,在内核网络协议栈会判断路由,通过路由把流量发到 eth0 网卡;
  6. 网络包通过 eth0 发送出去

ubuntu服务端接收的流量分析

  1. 网络包通过公网,到达 eth0 网卡

  2. 由于目标端口50820是被 wireguard 监听的,所以网络包发送到对应的 socket

  3. socket 将网络包发送给应用层程序 wireguard

  4. wireguard 对网络包进行解密、验证签名等操作后通过字符驱动发送给wg0wg0将解封装后的包发送到内核协议栈,之后分为两种情况,一种是作为中继服务器不做处理,直接转发(如上图1),另一种是交由应用层程序做处理(如上图2)

    • 直接转发:发送到网卡eth0
    • 交由应用层程序做处理:发送到对应应用层程序的 socket
  5. wg0 发出的包会通过内核网络协议栈,在内核网络协议栈会判断路由,通过路由把流量发到 eth0 网卡;

  6. 网络包通过 eth0 发送出去

参考

最后更新于 Mar 26, 2025 17:48 UTC
Built with Hugo
Theme Stack designed by Jimmy