配置自己的 VPN——内置 FreeBSD、Wireguard、IPv6 和广告拦截(基于 OpenBSD)

VPN 是连接到自己的服务器和设备的基本工具。许多人出于各种原因使用商业 VPN,从不信任其提供商(特别是在连接到公共热点时)到希望使用不同 IP 地址(也许是来自其他国家)在互联网上“出去”。

无论出于何种原因,解决方案都不会缺乏。我一直在设置管理 VPN,以允许服务器和/或客户端使用安全通道进行通信。最近,我在所有设备上(包括桌面/服务器和移动设备)启用了 IPv6 连接,我需要快速创建一个节点,集中一些网络并允许它们在 IPv6 网络上出站。我使用并将要描述的工具是:

  • VPS - 在这种情况下,我使用了基本的 Hetzner Cloud VPS(使用此链接,您将获得 20 欧元的云信用),但任何提供 IPv6 连接的提供商都可以 - 如果您需要 IPv6 的话。

  • OpenBSD - 一个干净、稳定且安全的操作系统。

  • Wireguard - 轻量级、安全,同时也不会“喋喋不休”,因此对移动设备电池也很友好。在没有流量时,它不会传输/接收任何内容。被所有主要的桌面和服务器操作系统以及 Android 和 iOS 设备广泛支持。

  • Unbound - 可以直接向根域名服务器发出 DNS 查询,而不是通过转发器。还允许插入阻止列表,类似于 Pi-Hole 的结果(即广告拦截)。

  • 列表 - 立即停止与黑名单用户之间的连接。

第一步是激活 VPS 并安装 OpenBSD。在 Hetzner 云控制台上,不会有预置的 OpenBSD 映像,只有 Linux 发行版可供选择。别担心,只需选择其中任何一个并创建 VPS。创建完成后,OpenBSD ISO 映像将出现在 "ISO 映像 "中。只需插入虚拟光驱,重启 VPS,OpenBSD 安装程序就会出现在控制台中。

我就不细说了,操作简单明了。唯一的注意事项(对于 Hetzner Cloud VPS)是使用 "autoconf "进行 IPv4 设置,但暂时不要配置 IPv6。稍后再配置。

使用 syspatch 命令安装所有 OpenBSD 更新并重新启动,内核将被重新链接。

在 OpenBSD 上,Wireguard 完全集成到基础系统中,不需要安装外部软件包。这是一个重大优势,因为随着时间的推移,与 Wireguard 相关的所有支持将由主要的 OpenBSD 开发团队直接管理。

第一步是在 VPS 上配置 IPv6。在 Hetzner 的情况下,不幸的是,他们只提供 /64 的地址,因此需要对分配的网络进行分段。在这个例子中,它将被划分为 /72 子网络 - 可以使用计算器来查找有效的子类。

/etc/hostname.vio0 文件应该看起来像这样:

inet autoconf
inet6 2a01:4f8:cafe:cafe::1 72 
!route add -net ::/0 fe80::1%vio0

简而言之,保留 Hetzner 分配的基地址,但将子网掩码改为/72 - 从而可以使用其他网络。

sh /etc/netstart vio0

它将重新配置网络接口并允许 IPv6 开始工作。要测试它:

ping6 google.com

如果一切配置正确,将执行 ping 命令并且 google.com 将会回复。

现在需要为 IPv4 和 IPv6 启用转发。在 /etc/sysctl.conf 文件中输入以下内容:

net.inet.ip.forwarding=1
net.inet6.ip6.forwarding=1

要应用这些更改,您可以重新启动或直接输入:

sysctl net.inet.ip.forwarding=1
sysctl net.inet6.ip6.forwarding=1

配置 Wireguard,需要进行一些步骤。首先,需要创建私钥:

openssl rand -base64 32

会出现类似以下内容:

YUkS6cNTyPbXmtVf/23ppVW3gX2hZIBzlHtXNFRp80w=

现在创建一个名为 /etc/hostname.wg0 的新文件:

172.14.0.1/24 wgport 51820 wgkey YUkS6cNTyPbXmtVf/23ppVW3gX2hZIBzlHtXNFRp80w=
inet6 2a01:4f8:cafe:cafe:100::1 72

正在创建一个新的 Wireguard 接口,名为 wg0。它将拥有 IPv4 地址“172.14.0.1”,Wireguard 将监听port 51820 端口,并使用稍后创建的私钥。它还将在供应商提供的子类别之一上拥有 IPv6 地址。

保存并激活该接口:

sh /etc/netstart wg0

如果所有内容都正确输入,它应该会启用接口。现在:

ifconfig wg0

将返回类似这样的内容:

wg0: flags=80c3<UP,BROADCAST,RUNNING,NOARP,MULTICAST> mtu 1420
	index 5 priority 0 llprio 3
	wgport 51820
	wgpubkey xxxxxxxxxxxxxxx=
	groups: wg
	inet 172.14.0.1 netmask 0xffffff00 broadcast 172.14.0.255
	inet6 2a01:4f8:cafe:cafe:100::1 prefixlen 72

记录下 wgpubkey - 它将用于配置客户端。

就防火墙而言,OpenBSD 带有基本的 pf 配置。在我的设置中,我倾向于阻止不需要的内容,并允许可能有用的内容。但是,我喜欢把“坏人”挡在门外,所以我使用黑名单。pf 允许在运行时向表中插入和移除元素,因此防火墙可以相应地进行配置。

要下载并应用 Spamhaus 列表,我使用在互联网上找到的一个简单而有效的脚本。

所以在/usr/local/sbin/spamhaus.sh 中创建脚本:

#!/bin/sh
#
# this is normally run once per day via /etc/daily.local.
#
echo updating Spamhaus DROP lists:
(
  { ftp -o - https://www.spamhaus.org/drop/drop.txt && \
    ftp -o - https://www.spamhaus.org/drop/dropv6.txt ; \
  } 2>/dev/null | sed "s/;/#/" > /var/db/drop.txt
)
pfctl -t spamhaus -T replace -f /var/db/drop.txt

使其可执行并运行:

chmod a+rx /usr/local/sbin/spamhaus.sh
/usr/local/sbin/spamhaus.sh

配置 pf 的可能性很多。一个相当简单的例子可能是这样的:

这是一个非常简单的配置:它阻止了来自 Spamhaus 下载列表中的所有内容,允许 Wireguard 网络到公共接口的 NAT,允许 IPv6 中的 icmp 流量(这对网络正常运行至关重要),同时阻止了针对 Wireguard IPv6 LAN 的传入流量(请记住,IP 地址将是公共的且可直接到达,因此我们不希望默认情况下公开我们的设备)。允许 Wireguard 接口上的所有流量通过。然后将阻止所有流量并指定异常,即允许 ssh 和 Wireguard 连接(当然)。还将授权允许流量从公共网络接口流出。

重新加载 pf 配置:

pfctl -f /etc/pf.conf

如果一切正常,防火墙应该已加载新的选项。

现在是配置 Unbound 来实现 DNS 查询缓存和相关广告拦截的时候了。一段时间前,我找到了一个脚本,稍作调整后使用。我记不清楚原始作者是谁了,所以我在这里贴出来。

创建一个脚本来更新 /usr/local/sbin/unbound-adhosts.sh 中的 unbound 广告拦截。

类似地,使脚本可执行并运行它:

chmod a+rx /usr/local/sbin/unbound-adhosts.sh
/usr/local/sbin/unbound-adhosts.sh

现在,可以修改位于 /var/unbound/etc/unbound.conf 的 Unbound 配置文件如下:

在启动 unbound 之前,必须给予适当的权限:

chown -R nobody:nobody /var/unbound

现在可以启用并启动 unbound。由于需要加载(长)阻止列表,这将需要几秒钟:

rcctl enable unbound
rcctl start unbound

如果一切都做得正确,unbound 将能够响应来自各自 LAN 的请求,位于 172.14.0.1 和 2a01:4f8:cafe:cafe:100::1 上。

现在可以配置 Wireguard 客户端了。每种实现都有其自己的过程(Android、iOS、MikroTik、Linux 等),但基本上只需在服务器和客户端上创建正确的配置即可。例如,在 OpenBSD 服务器上输入“ifconfig wg0”命令可查看服务器的公钥,应将其插入到客户端上将创建的“peer”配置中;而客户端的公钥则将在服务器上这样使用:

重新打开文件 /etc/hostname.wg0 并添加:

172.14.0.1/24 wgport 51820 wgkey YUkS6cNTyPbXmtVf/23ppVW3gX2hZIBzlHtXNFRp80w=
inet6 2a01:4f8:cafe:cafe:100::1 72
wgpeer *client's public key* wgaip 172.14.0.2/32 wgaip 2a01:4f8:cafe:cafe:100::2/128

重新加载配置:

sh /etc/netstart wg0

在客户端上,通过在本地 IP 地址中插入“172.14.0.2/32, 2a01:4f8:cafe:cafe:100::2/128”(在主机名为 wg0 的对等配置中输入的)创建一个新配置。将 DNS 服务器地址设置为“172.14.0.1”及/或其对应的 IPv6 地址(在本例中为 2a01:4f8:cafe:cafe:100::1 - 您的将会不同)。在对等端,插入服务器的数据,包括其公钥、IP 地址:port(在示例中,port是 51820),以及允许的地址(设置“0.0.0.0/0, ::0/0”意味着“所有连接将通过 Wireguard 发送” - 所有流量将通过 VPN 传输,无论是 IPv4 还是 IPv6)。

也可以将 VPN 仅用作广告拦截器,只通过其路由 DNS 流量。要实现此结果,只需配置客户端,使得唯一允许的地址是刚配置的 unbound 的地址(在本示例中,172.14.0.1 或 2a01:4f8:cafe:cafe:100::1) - DNS 解析将通过 VPN 进行,但浏览将继续通过主提供商运行。

如果您希望垃圾邮件和广告屏蔽列表能够自动更新,创建/etc/daily.local 文件并添加以下行:

#!/bin/ksh

/usr/local/sbin/unbound-adhosts.sh
/usr/local/sbin/spamhaus.sh

所有这些都可以通过简单安装 OpenBSD 来实现,无需安装任何额外的软件包。这既有助于更新管理,也有助于安全性。

最后更新于

FreeBSD 中文社区