返回
Featured image of post 使用 WiregGuard 更安全的访问内网

使用 WiregGuard 更安全的访问内网

搭建 WireGuard 隧道以达到访问内网服务的目的

了解 WireGuard

WireGuard 的白皮书中说到:

WireGuard: Next Generation Kernel Network Tunnel
谷歌翻译: WireGuard: 下一代网络内核隧道

你可以把它理解为 VPN (Virtual Private Network,虚拟专用网络)
这里并不是指科学上网,而是让员工更安全的访问公司内网数据的手段,常见于高校的教务系统登录当中。

但于传统 VPN 隧道不同的是,WireGuard 采用点对点连接,无服务端于客户端,谁先发起连接谁就是客户端。不仅如此,在 Linux 5.6 之后 WireGuard 被并入内核当中,其吞吐能力也是其他软件无法比拟的。还有就是,WireGuard 采用 UDP 连接,连接速度要更快,延迟更低,能够在网络故障恢复之后自动重连。

前置知识

需要一点点的计算机网络知识,比如:

  • IP 地址与子网划分
  • CIDR 表示法
  • NAT 网络地址转换
  • DNS 域名解析服务
  • TCP/UDP 网络协议
  • 路由配置

WireGuard 的应用

  • 访问内网服务,eg:NAS 直接暴露在公网不安全,SMB 不能跨网段,使用 WireGuard 访问内网的 NAS。
  • 多设备异地组网,eg:Minecraft 联机。

WireGuard 配置的格式

WireGuard 配置的默认路径为 /etc/wireguard/,配置文件名为 <网口名>.conf 如:wg0.conf

WireGuard 的配置格式为 ini 且由两部分组成: [Interface][Peer]

Interface 为本地的接口配置,有以下几个参数:

  • Address = 本机在 VPN 网络中的地址
  • ListenPort = 服务监听地址,默认 51820
  • PrivateKey = 私钥(注意保密)
  • DNS = 通过 DHCP 向客户端宣告 DNS 服务器。客户端将会使用这里指定的 DNS 服务器来处理 VPN 子网中的 DNS 请求。
  • Table = 定义 VPN 子网使用的路由表,off 表示禁止,默认 auto
  • MTU = Maximum Transmission Unit,最大传输单元
  • PreUp = 启动接口前所运行的操作
  • PostUp = 启动接口后所运行的操作
  • PreDown = 关闭接口前所运行的操作
  • PostDown = 关闭接口后所运行的操作

Peer 为对等节点配置:

  • Endpoint = 对端,若节点为 NAT 后无公网地址可不填写
  • AllowedIPs = 路由的 IP 地址(段)
  • PublicKey = 公钥
  • PersistentKeepalive = 连接保活间隔,一般用于 NAT 后的节点,确定连接是否被 NAT 阻断。格式为数字,单位:秒。

开始实践

让树莓派作为 WireGuard 服务器,实现从外部通过 WireGuard 访问内网 NAS

环境

树莓派具有公网 IP,NAS 与树莓派在同一网段

安装 WireGuard

因为我的树莓派 3B+出现了更新系统无法启动的问题,所以用了 Ubuntu 20.04.2 LTS 系统,Debian 系统也可以使用

完全更新并重启:

sudo apt update && sudo apt full-upgrade
sudo reboot

安装 WireGuard:

官方安装文档

使用 apt 进行安装,下列指令二选一即可:

sudo apt install wireguard
# 也可以作为 动态内核模块 安装
sudo apt install wireguard-dkms

配置启用一些相关功能:

# 启用内核转发
echo 'net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1' | \
sudo tee /etc/sysctl.d/wireguard.conf > /dev/null
# 自动加载内核模块
echo 'wireguard' | \
sudo tee /etc/modules-load.d/wireguard.conf > /dev/null
# 立即生效
sudo sysctl -p /etc/sysctl.d/wireguard.conf
# 重启
sudo reboot

生成密钥对

wg genkey | tee server.key | wg pubkey > server.pub #生成服务端密钥对
wg genkey | tee client.key | wg pubkey > client.pub #生成客户端密钥对

创建配置

树莓派(服务端):

# /etc/wireguard/wg0.conf
[Interface]
ListenPort = 51820
PrivateKey = <填写server.key>
# 服务器在 VPN 局域网中的地址
Address = 172.27.0.1/24
# 设置一个 NAT ,不然数据包到达内网后无法返回
# 注意将 eth0 替换为对应的网卡设备名字
PostUp = iptables -A FORWARD -i %i -j ACCEPT
PostUp = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT
PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer] # 客户端 1,依次类推
PublicKey = <填写client.pub>
AllowedIPs = 172.27.0.0/24
PersistentKeepalive = 15

客户端:

# Client
[Interface]
Address = 172.27.0.2/32
PrivateKey = <填写client.key>
# 可选项
DNS = <任意DNS服务器,可以是内网路由器>

[Peer]
# 这里可以填上树莓派所在的内网地址实现转发,我的为10.0.0.0/16,一般家庭为192.168.1.0/24
AllowedIPs = 172.27.0.0/24, 10.0.0.0/16
Endpoint = <IP>:[PORT] # 服务器地址及端口
PublicKey = <填写server.pub>

启动与关闭隧道

# 启动隧道
sudo wg-quick up wg0
# 关闭隧道
sudo wg-quick down wg0
# 查看隧道信息
sudo wg

使外部可连接

进入路由器的管理界面,打开端口映射界面,添加规则,内外端口均为 51820 IP 为树莓派的 IP

部分路由器将此功能叫做 虚拟服务器

OpenWRT 的设置位于 网络 -> 防火墙 -> 端口转发,同时需要在 通信规则 页面添加放行规则

隧道开机自启动

wg0 改为你自己的网口

sudo systemctl enable wg-quick@wg0

附: 创建 IPv6 隧道

自行参照上下模板进行更改

树莓派(服务端):

# /etc/wireguard/wg0.conf
[Interface]
ListenPort = 51820
PrivateKey = <填写server.key>
Address = fe80:32::1/64
PostUp = ip6tables -A FORWARD -i %i -j ACCEPT
PostUp = ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = ip6tables -D FORWARD -i %i -j ACCEPT
PostDown = ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
PublicKey = <填写client.pub>
AllowedIPs = fd23:32::0/64
PersistentKeepalive = 15

客户端:

# Client
[Interface]
Address = fd23:32::2/64
DNS = <任意DNS服务器,可以是内网路由器>
PrivateKey = <填写client.key>

[Peer]
AllowedIPs = fd23:32::0/64
Endpoint = <IP>:[PORT] # 服务器地址及端口
PublicKey = <填写server.pub>

注意

  • 预共享密钥需要两端都填写,否则会导致无法连接
  • 使用 DDNS 时请注意,WireGuard 只会在启动时解析域名对应的 IP 地址,如果 IP 发生变动需要重启 WireGuard 或者改用 IP 连接
Licensed under CC BY-NC-SA 4.0
最后更新于 Aug 22, 2021 21:09 +0800
Built with Hugo
Theme Stack designed by Jimmy