零信任内网远程访问:基于WireGuard部署私有网络远程接入,并实现远程访问内网设备
前言
WireGuard是一种实现加密虚拟专用网络(VPN) 的通信协议和免费开源软件,其设计目标是易于使用、高速性能和低攻击面。它旨在比IPsec和OpenVPN这两种常见的隧道协议具有更好的性能和更强大的功能。
家中服务器已经获取公网IPv6地址,并配置DDNS动态域名解析。受限于IPv6不兼容IPv4,导致部分服务无法远程访问。并且家庭内网直接暴露在公网环境上过于不安全。
通过已经配置DDNS的域名连接WireGuard服务,建立VPN连接,在VPN内通过IPv4来访问服务。这样既解决了IPv6不兼容的问题,也避免了将家庭设备直接暴露到公网的危险。
服务器配置
安装 WireGuard
WireGuard是一个开源项目,在主流Linux系统上都可以通过包管理器进行安装
目前WireGuard代码已经进入Linux主线内核(Linux 5.6+),所以部分主流Linux发行版只需要安装WireGuard-tool工具即可
Fedora/RHEL
sudo dnf install wireguard-toolsDebian/Ubuntu
sudo apt install wireguard其他发行版 可以参考官方指南
编写配置文件
在开始配置前,需要先完成公私钥的准备和服务器网段的规划
生成公私钥
wg genkey | tee privatekey | wg pubkey > publickey这将在当前目录下生成存有公钥和私钥的publickey和privatekey文件,可以通过cat来查看。
cat privatekey && cat privatekey规划网段
出于避免冲突和兼容性的考虑,VPN应当选择IPv4内网网段来配置。
为了避免和家庭网络中的ip冲突,故放弃使用192.168.0.0/16网段,选择使用10.10.0.0/24网段。
所以设置家庭服务器VPN内IP为10.10.0.1/32, 笔记本VPN内IP为10.10.0.2/32。
将规划写入配置文件
在/etc/wireguard/wg0.conf下创建配置文件
sudo vim /etc/wireguard/wg0.conf示例配置文件如下所示:
[Interface]Address = 10.10.0.1/24ListenPort = 51820PrivateKey = XXX(填入刚刚生成的私钥)参数说明
- [Interface] 下为本机 WireGuard 网卡配置
- Address: WireGuard 虚拟网卡的 IP 地址
- ListenPort: 服务器监听端口
- PrivateKey:当前机器自己的私钥(填入刚刚生成的私钥)
运行服务
使用 wg-quick 服务配置 WireGuard 服务器
systemctl enable --now wg-quick@wg0验证
使用wg查看服务状态来确认是否成功运行
sudo wg配置防火墙
在服务器放行WireGuard的udp端口
firewall-cmd --permanent --add-port=51820/udp --zone=public可以将WireGuard网络加入trust区域,以此来实现在vpn内不受限制访问服务器所有端口。添加指令如下: sudo firewall-cmd —permanent —zone=trusted —add-interface=wg0
到此WireGuard已经正常运行,如果没有远程访问内网其他设备的需求,可以直接跳转到客户端配置。
配置远程内网访问
目前WireGuard只是做到可以访问在vpn内的设备,但如果我们想访问家庭网络内(192.168.xxx.xxx)中的其他设备,是无法建立连接的。 这时我们就需要以家庭服务器为跳板,来帮我们转发发向192.168.xxx.xxx网段的网络包
开启内核转发并持久化
首先要开启内核相关的配置
sudo sysctl -w net.ipv4.ip_forward=1但上面的指令在重启后失效,我们需要进行持久化配置。
linux系统会按照文件名加载/etc/sysctl.d/目下的文件作为内核参数,所以要持久化内核参数需要在该目录下建立配置文件
sudo vim /etc/sysctl.d/99-wireguard.confsysctl会按文件名前数字,从小到大进行加载。后加载的会覆盖先加载的参数,所以越靠后优先级越高,最大为99
在99-wireguard.conf文件里面填写如下内容来持久化开启内核转发
net.ipv4.ip_forward=1开启地址伪装
在开启内核转发后,我们发向内网网段的数据包已经可以被服务器中转到192.168.xxx.xxx网段了。但由于我们是从VPN内发的数据包,经家庭服务器转发到达内网。所以数据包的发送地址为我们在VPN内的地址。但我们VPN的IP在内网中是不能被除了家庭服务器外的设备访问到的,所以因为内网的设备无法回包导致无法访问。
而解决方法也很简单,让家庭服务器在转发数据包时把数据包源IP也一起修改,由自己进行路由。
而开启伪装的方法也很简单,只需要一行指令
iptables -t nat -A POSTROUTING -j MASQUERADE但这里更推荐使用firewall来开启,可以更精确伪装的范围,并且持久化。
sudo firewall-cmd --permanent --add-masquerade客户端配置
下载客户端
建议使用带有gui的客户端,便于使用。
Windows可以点击此处下载。
macOS上需要从App Store上下载,可自行注册美区账号后下载。
Windows上exe格式安装程序会自动下载目前最新版本安装,如果上网环境不好建议下载msi格式。
添加客户端隧道配置
打开WireGuard的GUI客户端,点击右下角加号选择新建空隧道。 之后会自动生成公钥和私钥,并显示如下配置文件内容:
[Interface]PrivateKey = xxxxx之后根据之前的规划将配置文件补全
[Interface]PrivateKey = xxxxxAddress = 10.0.0.2/32MTU = 1420
[Peer]PublicKey = xxxAllowedIPs = 10.0.0.0/24, 192.168.1.0/24Endpoint = 服务器IP:端口PersistentKeepalive = 25参数说明
-
[Interface] 下为本机 WireGuard 网卡配置
- PrivateKey:当前机器自己的私钥(使用自动生成的,不需要改动)
- Address: 客户端VPN内的 IP 地址
- MTU:最大传输单元
-
[Peer] 下为对端节点配置
- PublicKey: 对端节点的公钥(填入服务器公钥)
- AllowedIPs: 需要通过VPN访问的IP(填入的IP再被访问时会自动转发到VPN上)
- Endpoint: 接入点,填入之前配置的服务器地址和端口
- PersistentKeepalive: 发送心跳包的时间,用于在多层NAT环境下保活隧道连接
将客户端信息写入服务器配置文件
在服务器WireGuard配置文件/etc/wireguard/wg0.conf中添加客户端信息
[Interface]Address = 10.10.0.1/24ListenPort = 51820PrivateKey = XXX
#添加下面内容[Peer]PublicKey = XXX #填写刚刚客户端生成的公钥AllowedIPs = 10.10.0.2/32 #填写为客户端规划的IP保存后重启WireGuard服务
sudo wg-quick down wg0sudo wg-quick up wg0到此大功告成,点击客户端点击连接即可接入VPN
参考资料
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!