简介
Wireguard是一款快速现代的VPN,旨在提供易用性和高性能。其协议开源且相对简单,使得代码便于开发和审查。
wireguard简单来说是一个三层p2p安全隧道,底层传输使用udp;用编程语言将该协议写成软件叫做实现,常见的有Linux内核中的实现,或者其他用户空间的实现,比如wireguard-go或者wireguard-rs。
配置
wireguard协议的配置方式
使用get
和set
操作获取或者传递“键值对”的方式通信。wireguard配置过程大体分两个角色,manger和tunnel;tunnel负责数据传输和加解密等,manger主要负责向tunnel下发配置和查询状态;wireguard协议规定,wireguard的实现需要支持两个操作“set”和“get”,set用于向tunnel下发配置,get获取tunnel各种状态,set和get的内容均为一系列键值对,具体如下:
在此之前先看两个术语,便于后续描述方便。
- peer:直译为对等体,代表一个wireguard节点。wireguard主要逻辑概念就是interface和peer;interface代表本地隧道接口,peer指该interface逻辑连接的wireguard节点。
- endpoint:对端,指peer的真实ip和端口号,endpoint概念隶属于属于peer,一个peer同一时刻只能有一个endpoint。
注意! 这里展示的是"配置协议"中的操作,和wireguard软件的配置文件还是有区别的,不过配置文件参数大都是来自于这些配置协议参数,后面关于配置文件参数的解释。
Key | 描述 | 可选 | set | get | 归属 | 数据格式 |
---|---|---|---|---|---|---|
private_key | 私钥;为全0代表删除该接口的密钥 | 否 | V | V | 接口 | 小写16进制 |
listen_port | 监听端口,漫游模式可以不设置 | 是 | V | V | 接口 | 十进制字符串整数 |
fwmark | firewall mark,接口的fwmark,可以类比iptable的fwmark,全0表示删除fwmark。 | 是 | V | V | 接口 | 十进制字符串整数 |
replace_peers=true | 开关值;接口级配置,使用用本次配置中的peer(可以为空)覆盖当前配置中的peer,无此设置则应追加 | 是 | V | X | 接口 | 开关值 |
public_key | 公钥;单次set 操作中可以有多个但不能重复;在set 操作中,public_key作为一个peer的起始配置,可以认为一条public_key配置就声明了一个peer |
否 | V | V | peer | 小写16进制 |
remove=true | 开关值;删除该peer | 是 | V | X | peer | 开关值 |
update_only=true | 开关值;用于更新已经存在的peer配置 | 是 | V | X | peer | 开关值 |
preshared_key | 预共享密钥;全0代表删除共享密钥 | 是 | V | V | peer | 小写16进制 |
endpoint | 指定peer的ipv4/ipv6地址和端口号 | 是 | V | V | peer | IPv4:port或[IPv6]:port |
persistent_keepalive_interval | peer的保活时间(秒);为0表明禁用保活 | 是 | V | V | peer | 十进制字符串整数 |
replace_allowed_ips=true | 开关值;用本次配置中的allowed_ips(可以为空)覆盖当前的allowed_ips配置,无此设置则应该追加本次allowed_ips配置到所属peer中 | 是 | V | X | peer | 开关值 |
allowed_ip | peer可转发的ip段,即路由,表明指定的网段应该发往哪个peer。如果相同的网段已经存在于其他peer中,那么后配置的将会覆盖之前的配置,即将该网段从之前peer中删除,保留本次配置。 | 否 | V | V | peer | IP/cidr |
rx_bytes/tx_bytes | peer的收发字节数 | 是 | X | V | peer | 十进制字符串整数 |
last_handshake_time_sec/ last_handshake_time_nsec | 上次握手距现在时间-秒/纳秒 | 是 | X | V | peer | 十进制字符串整数 |
protocol_version | 协议版本号,一般不使用该配置,当不指定时应当使用协议的最新版本;设置必须置为"1" | 是 | V | V | peer | 1 |
示例
get操作
get=1
{empty line}
get的返回值
private_key=e84b5a6d2717c1003a13b431570353dbaca9146cf150c5f8575680feba52027a
listen_port=12912
public_key=b85996fecc9c7f1fc6d2572a76eda11d59bcd20be8e543b15ce4bd85a8e75a33
preshared_key=188515093e952f5f22e865cef3012e72f8b5f0b598ac0309d5dacce3b70fcf52
allowed_ip=192.168.4.4/32
endpoint=[abcd:23::33%2]:51820
public_key=58402e695ba1772b1cc9309755f043251ea77fdcf10fbe63989ceb7e19321376
tx_bytes=38333
rx_bytes=2224
allowed_ip=192.168.4.6/32
persistent_keepalive_interval=111
endpoint=182.122.22.19:3233
public_key=662e14fd594556f522604703340351258903b64f35553763f19426ab2a515c58
endpoint=5.152.198.39:51820
allowed_ip=192.168.4.10/32
allowed_ip=192.168.4.11/32
tx_bytes=1212111
rx_bytes=1929999999
protocol_version=1
errno=0
{empty line}
set操作
set=1
private_key=e84b5a6d2717c1003a13b431570353dbaca9146cf150c5f8575680feba52027a
fwmark=0
listen_port=12912
replace_peers=true
public_key=b85996fecc9c7f1fc6d2572a76eda11d59bcd20be8e543b15ce4bd85a8e75a33
preshared_key=188515093e952f5f22e865cef3012e72f8b5f0b598ac0309d5dacce3b70fcf52
replace_allowed_ips=true
allowed_ip=192.168.4.4/32
endpoint=[abcd:23::33%2]:51820
public_key=58402e695ba1772b1cc9309755f043251ea77fdcf10fbe63989ceb7e19321376
replace_allowed_ips=true
allowed_ip=192.168.4.6/32
persistent_keepalive_interval=111
endpoint=182.122.22.19:3233
public_key=662e14fd594556f522604703340351258903b64f35553763f19426ab2a515c58
endpoint=5.152.198.39:51820
replace_allowed_ips=true
allowed_ip=192.168.4.10/32
allowed_ip=192.168.4.11/32
public_key=e818b58db5274087fcc1be5dc728cf53d3b5726b4cef6b9bab8f8f8c2452c25c
remove=true
{empty line}
set操作也是有返回值的,返回的为错误编号,0代表无错误。
errno=0
{empty line}
配置文件示例
Wiresguard隧道两端技术上是对等的,也就是说没有真正意义上的server,架构是p2p,不是cs;各种终端尤其是移动终端,几乎不可能有固定的公网IP地址,一端处于nat之后的情况非常常见,所以作为终端远程接入内网使用的时候,Endpoint不是必须的,此种peer视为漫游模式(多次上线的地址和端口可能不一样),漫游模式的终端只能主动连接有固定地址的peer(当然如果通过STUN等协议打洞NAT也可以),连接成功后一般使用保活机制确保一直在线不会被NAT设备注销连接导致回访失败。
下面是一个配置实例,参数的功能参见备注。
#wireguard配置文件
#接口只能有一个
[Interface]
# 此处为注释
Address = 192.0.2.3/32 #接口地址,可以配置多个IP(v4或者v6都可以),wireguard隧道为P2P隧道,IP掩码其实不重要,不过不建议用/32掩码,windows系统可能会有问题。
ListenPort = 51820 #监听端口,可以不写,漫游模式不需要
PrivateKey = localPrivateKeyAbcAbcAbc= #接口私钥,必要
DNS = 1.1.1.1,8.8.8.8 #dns,可选项
DNSSearch = abc.com #接口dns域,可选
Table = 12345 #路由表id,linux系统专用,windows无此配置。
Fwmark = 0x01 #linux专用,iptable中的fwmark,用于给隧道流量打标记用于ip rule等,可选
MTU = 1500 #mtu,wireguard属于隧道封装协议,mtu取决于底层网络,一般建议设置为1420,如果底层是pppoe网络建议使用1400
SaveConfig = true #关闭Wireguard接口时,将当前状态保存到配置文件中,可选,可能会导致漫游终端接入时失败。
PreUp = /bin/example arg1 arg2 %i #下面四项linux专用,用于接口up/down时执行一些命令,比如iptable策略等等
PostUp = /bin/example arg1 arg2 %i
PreDown = /bin/example arg1 arg2 %i
PostDown = /bin/example arg1 arg2 %i
#peer可以有多个
[Peer]
# Name = 注释
AllowedIPs = 192.0.2.1/24 #peer可以转发的地址,可以是对方隧道接口地址,也可以是对方能够转发的地址,可以配置多段。在系统上体现出来就是指向该隧道的路由。设置为0.0.0.0/0时隧道会劫持除endpoint ip外的全部流量。
Endpoint = node1.example.tld:51820 #对端公网地址和端口,对端为漫游模式时候可以不用,但此时只能对方主动发起连接。
PublicKey = remotePublicKeyAbcAbcAbc= #公钥,必要
PresharedKey = 123456789 #预共享口令,官方说是为了抵抗量子攻击,不懂,可选。
PersistentKeepalive = 25 #保活时间,单位为秒,漫游模式建议配置。
参考
https://www.wireguard.com/xplatform/
https://github.com/pirate/wireguard-docs?tab=readme-ov-file#-Name