前言
作为一个出差在外时间长过待在家时间的人,远程访问对我来说是不可获取的一部分。
在之前,zerotier基本能够覆盖99%的需求。但随着每次出差距离的加长,经常要在奇奇怪怪的酒店网络环境跨过半个甚至是一个中国访问设备,p2p打洞就不显得那么可靠了。但众所周知,zerotier的中继服务器基本都在国外,国内使用官方中继简直就是折磨,再加上手机使用的ios键位封闭,因此我决定再部署一套方案作为保底,双重保险更为有效。
选择wireguard的理由
先说说为什么我会选择wireguard而不是经常跟zerotier对比的tailscale。
- wireguard作为几乎是最为基础、现在基本是个内网穿透服务软件都会带的协议,它几乎在任何平台都能找到相对应的软件。
- wireguard已经并入到linux主线,也就是说主要linux版本不是很旧,那就是自带一个wireguard,兼容性非常完美,开箱即用。
- 相对于tailscale,它的自由度更大,能够自部署且任自己随意搭配。
- 相对于tailscale的自部署版本——headscale:,wireguard自部署简单,而且不会在什么平台有莫名其妙的访问失败问题,
说的就是你,iphone!
当然,tailscale也是有胜过它的优点,比如:
- tailscale可以借助官方的服务器,不需要在服务器上花钱和精力。wireguard的缺点便是需要一台公网服务器和没有自动p2p的功能,所有wireguard的流量都必须走服务器中继。
- tailscale跟zerotier一样,会优先进行p2p链接,提供最快的连接途径;当无法p2p直连时会自动切换到中继服务,可以说即有速度优先又有保底保障。
因此我个人推荐,如果使用的是移动端使用安卓平台,或者压根不需要在移动端使用内网穿透服务的,优先tailscale,无论是自部署还是使用官方的服务器。
话扯远了,最后让我选择wireguard的理由还是平台限制。app store上下载的tailscale虽然有提供了连接自部署服务器的选择,但不知为何,是死活无法成功登录自部署的服务器,更别说连接;使用安卓备用机测试则是一下子就连接成功。
wireguard部署
本次要讲的是我自己的wireguard配置,而我又有一台openwrt作为旁路由,因此接下来会分为以下几个部分来叙述:
- wireguard的搭建
- wireguard服务端配置
- openwrt上的wireguard客户端配置
- 在openwrt上为wireguard开启路由转发
wireguard的搭建
由于自身经常习惯到处搬迁服务器,因此我非常喜欢使用docker,wireguard虽然在我的服务器中自带,但我还是选择docker部署wireguard:
services:
wireguard:
image: lscr.io/linuxserver/wireguard:latest # wireguard本体
container_name: wireguard
cap_add:
- NET_ADMIN
- SYS_MODULE
ports:
- 51820:51820/udp # wireguard流量传输端口
environment:
- PUID=1000
- PGID=1000
- TZ=Asia/Shanghai
- SERVERPORT=51820
- INTERNAL_SUBNET=10.0.8.0 # wireguard网段,不要带“/24”
- LOG_CONFS=true
sysctls:
- net.ipv4.conf.all.src_valid_mark=1
volumes:
- ./config:/config
- /lib/modules:/lib/modules
restart: unless-stopped
wireguard-ui:
image: ngoduykhanh/wireguard-ui:latest # wireguard-ui容器,方便管理client
container_name: wireguard-ui
ports:
- 51821:5000 # wireguard-ui端口
depends_on:
- wireguard
cap_add:
- NET_ADMIN
environment:
- WGUI_USERNAME=your_username
- WGUI_PASSWORD=your_password
- WGUI_MANAGE_START=false
- WGUI_MANAGE_RESTART=true
logging:
driver: json-file
options:
max-size: 50m
volumes:
- ./db:/app/db
- ./config/wg_confs:/etc/wireguard
- /var/run/docker.sock:/var/run/docker.sock
其中ngoduykhanh/wireguard-ui是为了方便管理wireguard而增加的,属于可选,wireguard本身就是用命令来对管理的。接下来的配置均在wireguard-ui中进行,官方的用法可以查看官方文档:快速入门 - WireGuard
wireguard服务端配置
基础配置
进入wireguard-ui后,我们首先需要完成一些基础设定。
进入Global Settings,在Endpoint Address栏填写服务器的公网ip。DNS Servers写1.1.1.1和255.5.5.5。
进入Wireguard Server,在Server Interface Addresses栏填写自己想要的wireguard网段,也就是上面compose中INTERNAL_SUBNET栏所填写的网段,例如:10.0.8.0/24。
Post Up Script栏填入iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE.
Post Down Script烂填入 iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE.
添加clinet
在wireguard clients页面中,点击右上角的new client,在出现的弹窗中填写信息。
name:可以随意填写,仅作作为备注。
IP Allocation:代表该client被分配到的节点,自动配分配的到的节点会在事先设置好的网段内;可随意修改ip地址,只需要该ip在之前设定的网段内即可,例如:10.0.8.45/32。
Allowed IPs:表示可以通过wireguard的流量,这里的流量指的是client,也就是客户端所发出的流量。当客户端发出的流量符合Allowed IPs的设定,那么改流量变回自动被wireguard截取并发送到wireguard服务端进行分配。例如填写了192.168.1.0/24和10.0.8.0/24,那么该设备所有发往192.168.1.0/24和10.0.8.0/24都会被截取并发往wireguard服务器中进行下一步分配。
Extra Allowed IPs:表示一个client所额外负责的流量。本质上跟IP Allocation是一回事,代表该client所声明负责的流量。
如果对上面的配置还是感到一头雾水,那也继续往下看,后面会对这些参数进行详细的说明。
点击右上角的apply config,并重启wireguard容器后,wireguard服务端的配置就结束了。我们可以点击每一个client左上角的download下载配置文件并导入到客户端,或者是点击QR code,让设备扫二维码导入client配置。
wireguard-ui参数说明
想要理解这些参数,还需要回到源头,也就是wireguard本身的配置文件才行。
点击打开config/wg_confs/wg0.conf,在这里可以看到所有的wireguard服务端的所有配置
。
将wg0.conf、下载下来的client配置文件跟对照wireguard-ui的配置进行三者对照,不难发现wireguard-ui的IP Allocation和Extra Allowed IPs其实都是对wg0.conf中的Allowed IPs进行修改。
在wireguard中,Allowed IPs其实是对流量进行声明、再分配的参数,无论是客户端配置还是服务端配置都是如此。在客户端中,凡是符合clinet配置文件中Allowed IPs的流量都会被wireguard客户端声明所负责,然后被wireguard客户端所截取并发往wireguard服务端进行分配;在服务端,wireguard会根据wg0.conf中每个client中Allowed IPs的参数,对客户端上传上来的流量进行分配转发。
例如:客户端的client配置文件的Allowed IPs设置为192.168.1.1/32、10.0.8.0/24和101.1.1.0/24,服务端设置该client的Allowed IPs是10.0.8.45/32和192.168.1.0/24。那么在该客户端所在设备所有发往192.168.1.1、10.0.8.0/24和101.1.1.0/24的流量都会上传到服务端,而服务端再根据服务端中client的Allowed IPs对流量进行分配:
- 客户端发出的
192.168.1.1在服务端设置的192.168.1.0/24网段内,流量会转发到该client上。 - 客户端发出的
10.0.8.45符合服务端设置的10.0.8.45/32,流量会转发到该client上。 - 客户端发出的
10.0.8.78不符合服务端设置的10.0.8.45/32,也不在该client的Allowed IPs中任何一个网段内,流量不会转发到该client上。 - 客户端发出的
101.1.1.80不在该client的Allowed IPs中任何一个网段内,流量不会转发到该client上。
因此,只需要对wireguard-ui的参数配置进行以下理解就行:
- wireguard-ui中的
Allowed IPs对应的是客户端配置文件中的Allowed IPs。 - wireguard-ui中的
IP Allocation和Extra Allowed IPs都是修改wireguard服务端配置文件中的Allowed IPs。 - 客户端和服务端的
Allowed IPs都是一样的,都是对特定流量进行声明、转发。客户端的Allowed IPs是将符合要求的流量发往服务端;服务端是将被上传的流量,对应各个client中Allowed IPs进行分配转发。
openwrt上的wireguard客户端配置
openwrt启动wireguard是一件非常简单的事情,甚至不需要打开shell,全程只用webui就能进行。
打开网络>接口,点击添加新接口,名称随意,协议选择wireguard vpn。在新弹窗中将页面拉到最后,点击加载配置,随后打开之前那下载的client的配置文件,并将里面的内容全部复制粘贴进去,再点击导入设置。
随机点击防火墙选项卡,在创建/分配防火墙区域新建一个防火墙,名称可以随意命名。做完这一切后再点击保存并应用该配置。
点击网络>防火墙,对刚刚新增的防火墙进行编辑,将区域内转发、入站数据、出站数据都改成和lan防火墙一样,并再点击保存并应用。
在openwrt上为wireguard开启路由转发
正如之前所说的,wireguard可以指定client处理特定流量,从而变成一个网关。而在openwrt上实现也非常简单。
打开网络>接口,对wireguard接口进行编辑,点击对端,并将路由运行的ip勾选上。
打开网络>防火墙,编辑lan防火墙。将允许转发到目标区域和允许来自源区域的转发都添加上wireguard接口的防火墙,并将IP 动态伪装勾选上。最后再点击保存并应用。
至此,这台openwrt变作为一个网关,在外地设备连接wireguard后直接输入局域网(并非wireguard ip)就能连接到其他未安装wireguard的设备了。
其实根据这种玩法,可以轻松的将多个局域网连接在一起,只需要注意网段(无论是wireguard ip网段还是真实局域网网段)不能是同一个就行。
结尾
wireguard对我而言还是一个底线的保底手段,在ipv6越来越普及的今天,直连也是越来越方便了。希望有一天我能彻底淘汰这一套东西吧。