概述
有时候在公司或者在家里需要访问对方的私有网络, 这时候是无法访问的,通常在这种情况下我们会安装frp
等软件来进行代理, 但是这有两个问题:
- 只能点对点访问, 也就是说只能访问固定内网的特定主机
- 安全性较低,暴露内网的服务端口会引发安全问题
因此基于这类考虑,最终选择部署wireguard
服务, wireguard
服务是新一代vpn
技术, 目前已经合入linux
内核, 因此其具有极高的稳定性。
wireguard
服务需要满足所有节点中必须有一个节点具有公网ip(需要通过它进行流量转发), 通常情况下部署wireguard
有三种方案:
- 家里有公网ip的宽带, 在有公网ip的路由上部署
wireguard
服务, 其他节点连接该节点 - 没有公网ip, 但是路由器是拨号路由, 可以通过
ddns
映射到一个固定域名, 然后域名来访问服务 - 有公网的云服务器, 在其上部署代理节点, 其他节点连接到服务器节点
这些方案大家自己权衡, 由于客观环境因素, 我这里采用方案三。
部署环境
先简要说明一下我这里的环境
- 云服务器一台(公网ip)
- 公司n级路由器(已经刷了openwrt, 子网网段
192.168.115.x
) - 家庭n级路由器(已经刷了
openwrt
, 子网网段192.168.125.x
)
网络拓扑如下:
这里需要打通192.168.115.0/24
和192.168.125.0/24
两个网段。
服务端部署
服务端这里采用docker
部署, 网路上原本存在一个wg-easy
的方案, 地址见后面参考资料, 但是由于其不能指定AallowIP
地址, 因此这里没有采用, 而是自己手动构建docker
方案。Dockerfile
, 内容较简单如下:
1 2 3 4 5 6 7 8
| FROM ubuntu WORKDIR /
RUN apt update && apt install -y iproute2 iptables wireguard
CMD wg-quick up wg0 ; /bin/bash
|
然后执行如下命令:
1
| docker build -t wireguard-server .
|
成功构建后, 使用docker
部署:
1 2 3 4 5 6 7 8 9
| docker run -d -it \ --name=wg-server \ -v ~/.wg-easy:/etc/wireguard \ -p 51820:51820/udp \ --cap-add=NET_ADMIN \ --cap-add=SYS_MODULE \ --sysctl="net.ipv4.conf.all.src_valid_mark=1" \ --sysctl="net.ipv4.ip_forward=1" \ --restart=always wireguard-server
|
注意, 这里将宿主机~/.wg-easy
目录挂载到wireguard
默认配置目录下, 避免后期容器删除导致配置丢失。
由于我们是连通两个网段, 加上服务端代理节点一共需要三个节点, 因此在服务端生成三个密钥对用于后面加密传输(需要每个节点一个):
1
| wg genkey | tee /etc/wireguard/server.private.key | wg pubkey > /etc/wireguard/server.public.key
|
这样就生成了服务端密钥对, 如果这里报command not found: wg
, 需要安装如下工具:
1
| apt install wireguard-tools
|
类似的方法生成home.private.key, home.public.key, company.private.key, company.public.key
, 然后创建一个wg0.conf
文件, 这个文件就是wireguard
全局配置文件, 写入如下内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
[Interface] PrivateKey = 服务端私钥 Address = 10.8.0.1/24 ListenPort = 51820 PreUp = PostUp = iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE; iptables -A INPUT -p udp -m udp --dport 51820 -j ACCEPT; iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; PreDown = PostDown = iptables -t nat -D POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE; iptables -D INPUT -p udp -m udp --dport 51820 -j ACCEPT; iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT;
[Peer] PublicKey = 家庭网络的公钥 PresharedKey = 家庭网络的预共享密钥 AllowedIPs = 192.168.125.0/24,10.8.0.2/32
[Peer] PublicKey = 公司网络的公钥 PresharedKey =公司网络的预共享密钥 AllowedIPs = 192.168.115.0/24,10.8.0.3/32
|
这样就可以了, 然后重启一下docker
1
| docker restart wg-server
|
这样服务端就配好了。这里需要说明一下, AllowedIPs
表示服务器中继节点要不要向该端口转发这个ip
网段的流量, 如果你需要采用内网ip访问需要加上。
openwrt 客户端配置
openwrt
中默认是没有wireguard
插件的, 需要手动安装如下:
- luci-proto-wireguard: 用于支持 WireGuard 的核心包
- qrencode: 生成展示客户端的二维码。
安装可以通过命令行或者软件包中安装, 这里就不详述。安装完成后需要重启路由器, 不然无法进一步操作。重启完成后, 进入 网络 -> 接口, 添加新接口:
接下来设置如下:
注意:
- 对端设置中的允许ip新增后会新建一条代理路由, 如果没有包含相关网段,中继可能会出问题。新增的路由表如下:
1 2 3 4 5 6
| [root@KWrt:03:42 PM ~] Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 172.16.208.1 0.0.0.0 UG 0 0 0 wan 10.8.0.0 0.0.0.0 255.255.255.0 U 0 0 0 wg0 192.168.125.0 0.0.0.0 255.255.255.0 U 0 0 0 wg0
|
当然以上是通过手动添加客户端配置的方式, 还可以通过自动导入配置的方式来进行, 配置格式如下:
1 2 3 4 5 6 7 8 9 10 11
| [Interface] PrivateKey = wJ7fCp6+oHruJk4XVg0cTD7YauLza0Bmc46cDOE6nFg= Address = 10.8.0.x
[Peer] PublicKey = 服务端公钥 PresharedKey = 预共享密钥 AllowedIPs = 192.168.125.0/24, 10.8.0.0/24 Endpoint = 服务器代理地址:端口 PersistentKeepAlive = 25
|
保存并应用, 通过以上设置, 新建的接口就配置好了, 然后进入网络 - 防火墙,这里会自动新建一个vpn
区域。点击编辑:
保存,然后设置lan区域:
保存并应用, 设置好以后记得重启路由器,否则可能异常。至此, 192.168.125.0/24
网段的部署就完成了。这时候可以使用电脑连接到路由器, 然后ping一下中继节点, 这里是10.8.0.1
, 如下:
1 2 3 4 5 6 7 8 9 10 11
| C:\Users\EtcFly>ping 10.8.0.1
正在 Ping 10.8.0.1 具有 32 字节的数据: 来自 10.8.0.1 的回复: 字节=32 时间=30ms TTL=63 来自 10.8.0.1 的回复: 字节=32 时间=30ms TTL=63 来自 10.8.0.1 的回复: 字节=32 时间=30ms TTL=63
10.8.0.1 的 Ping 统计信息: 数据包: 已发送 = 3,已接收 = 3,丢失 = 0 (0% 丢失), 往返行程的估计时间(以毫秒为单位): 最短 = 30ms,最长 = 30ms,平均 = 30ms
|
说明这两个节点已经打通了, 进入服务端docker
ping一下该网络的私有网段:
1 2 3 4 5 6 7 8 9
| root@4c48dccf0de6:/ PING 192.168.125.1 (192.168.125.1) 56(84) bytes of data. 64 bytes from 192.168.125.1: icmp_seq=1 ttl=64 time=32.3 ms 64 bytes from 192.168.125.1: icmp_seq=2 ttl=64 time=31.3 ms 64 bytes from 192.168.125.1: icmp_seq=3 ttl=64 time=31.7 ms
--- 192.168.125.1 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2002ms rtt min/avg/max/mdev = 31.276/31.747/32.255/0.400 ms
|
如果通常表示该节点部署完全ok, 如果发现客户端ping不通服务端代理节点的虚拟ip, 那么可能有如下原因:
- wg0接口中对端允许ip没有配对
- 配置修改了但是没有重启路由器,配置未生效
- 云端代理节点中虚拟ip和本地没有对应上
具体按照上述操作自行检查
如果客户端节点可以ping通服务端代理节点, 但是反之不行, 那么请检查服务端代理节点中关于客户端节点的Allowip是否正确。如果互通都是ok,在windown下可以使用tracert
工具, linux下使用traceroute
工具跟踪一下转发是否按照预期,如果全部ok,那么恭喜你,该节点已经完全部署ok了,可以进行下一个节点的部署。
参考资料