本文介绍如何设置 Linux_容器来运行多个带有“终止开关”的 VPN 协议,以实现安全/隐私的互联网使用。 与使用 VirtualBox 或者 QEMU 等全套的虚拟化相比, 这样做提供了更小的资源开销和在低功耗设备上运行等明显优势。
配置容器
需要对 Linux_容器进行基本配置和了解。 本文假设读者已经设置了可运行的基本LXC。
服务器模式的OpenVPN
本小节详细介绍了在容器中提供 OpenVPN 服务所需的一些额外设置。 想要使用给出的 OpenVPN 配置文件的用户无需阅读本小节。
主机设置
- 主机操作系统需要网桥设置才能允许容器运行。请参考 Linux_容器#宿主机网络配置。
- 需要启用数据包转发。请参考网络分享#启用包转发。
- 尽管不是必须的,但强烈建议使用防火墙。
客户端模式的 OpenVPN
需要修改容器的配置才能使用 OpenVPN,如下所示:
/var/lib/lxc/playtime/config
... ## for OpenVPN lxc.mount.entry = /dev/net dev/net none bind,create=dir lxc.cgroup2.devices.allow = c 10:200 rwm
安装 openvpn包. 如果使用容器连接到第三方 VPN 提供商,只需将配置文件 foo.conf
放在 /etc/openvpn/client/foo.conf
即可。 To v要验证容器内的 OpenVPN 功能,请启动 openvpn-client@foo.service
来开启OpenVPN。一旦对当前配置感到满意,启用服务来实现系统启动后自动开启。
有关其他用例和设置,请参阅 OpenVPN。
LimitNPROC...
WireGuard
安装wireguard-tools包。用户将拥有由第三方 VPN 服务提供的 WireGuard 配置,或者自己设置好的WireGuard 对应的配置。 如果使用容器连接到 VPN 提供商, 只需将配置文件 foo.conf
放入 /etc/wireguard/
。
要验证容器内的 WireGuard 功能,请通过启动 wg-quick@foo.service
来开启WireGuard。一旦对当前配置感到满意,启用服务来实现系统启动后自动开启。
有关其他用例和设置,请参阅 WireGuard。
容器内的防火墙配置
强烈建议在容器内运行正确配置的防火墙。容器内防火墙的作用有两个:
- 提供“终止开关”,以便在 VPN 连接失败时维护隐私。
- 把不想要东西拒之门外。
本指南使用易于配置的 ufw包,当然也可以使用其他防火墙。
ufw reset
.设置“终止开关”的方法是通过设置一个拒绝政策然后只允许VPN设备上的特定服务和流量。这样,如果该设备的连接中断时不会出现本地政策回退。
编辑 /etc/default/ufw
并将 DEFAULT_OUTPUT_POLICY 从 "ACCEPT" 更改为 "DROP":
/etc/default/ufw
DEFAULT_OUTPUT_POLICY="DROP"
ufw
需要以root用户执行; 按照 wiki 标准命令的前缀“#”符号已被省略,以允许干净地复制/粘贴到终端中。设置拒绝政策:
ufw default deny outgoing ufw default deny incoming
(可选)添加例如/etc/ufw/applications.d/custom
等文件中定义的任何预定义或自定义规则:
ufw allow ssh ufw allow from my-custom-app1 ufw allow from my-custom-app2
(可选)进一步限制来自内部 LAN IP 范围甚至单个 IP 地址的访问:
ufw allow from 192.168.1.0/24
WireGuard 用户将拥有一个与相应配置文件,比如/etc/wireguard/foo.conf
,同名的接口,而 OpenVPN 用户很可能使用tun0
. 在下面的命令中,将“foo”替换为 WireGuard 配置文件的名称(省略 .conf 后缀),或者如果使用 OpenVPN,则将“foo”替换为 tun0 或正在使用的任何设备:
ufw allow out on foo from any to any
最后,打开 VPN 提供商的 IP 地址和端口,并定义相对应的协议。在下面的行中,需要考虑三个变量:
- “xxx”代表 WireGuard 的 peer 或者 OpenVPN 的服务器的IP地址。它将在 VPN 提供商提供的相应配置文件中。
- “yyy”代表要进行通信的端口。同样,这将位于配置文件中。
- “zzz” 代表要使用的协议,可以从 udp 或 tcp 中选择。请注意,WireGuard 仅支持 udp,而 OpenVPN 两者都支持。
ufw allow out to xxx port yyy proto zzz
启动 ufw 并启用 ufw.service
以实现开机启动。
在配置文件中使用 VPN 域名的一个非正式方法
如果需要在 VPN 配置文件中使用域名,主机上的 shell 脚本可以将其预先解析为数字 IP,然后通过将该 IP 地址存储在写在容器中文件的一个变量来将该 IP 地址传递给容器。该文件又可以由修改后的 VPN systemd 服务读取。 它可以用, 但不正规。
编辑两个变量以匹配相对应的容器名称和服务器名称:
在主机上
安装 bind包 (dig 需要)并创建以下脚本:
/path/to/container-start.sh
#!/bin/bash # this script should be called as root container=foo server=www.myvpnserver.org if ! systemctl is-active lxc@"$container" &>/dev/null; then ToUse=$(dig +short "$server") [[ -d /var/lib/lxc/$container/rootfs/etc/conf.d ]] || mkdir -p /var/lib/lxc/$container/rootfs/etc/conf.d echo "SERVER=$ToUse" > /var/lib/lxc/$container/rootfs/etc/conf.d/server.hack.txt systemctl start lxc@"$container" fi
从现在开始,调用该脚本来启动容器。它将使用 dig 从域名中获取 IP 地址,然后启动容器。
从容器内部
修改启动 VPN 的 systemd 服务并创建一个框架配置文件,该配置文件可以使用我们刚刚创建的脚本创建的/var/lib/lxc/$container/rootfs/etc/conf.d/server.hack.txt
中定义的 IP 地址进行修改。
要制作框架配置文件,只需将使用的配置文件重命名为另一个名称即可。
例如使用 WireGuard:
mv /etc/wireguard/foo.conf /etc/wireguard/foo.skel
现在编辑 /etc/wireguard/foo.skel
以将 Endpoint = www.myvpnserver.org 替换为@@@,例如:
Endpoint = @@@:51820
或者如果使用 OpenVPN:
mv /etc/openvpn/client/foo.conf /etc/openvpn/client/foo.skel
编辑 /etc/openvpn/client/foo.skel
以将远程www.myvpnserver.org替换为@@@,例如:
remote @@@
最后,创建一个附加配置片段, 以读取 IP 并将其替换为实际配置文件。
使用 WireGuard 的示例:
/etc/systemd/system/wg-quick@foo.service.d/override.conf
[Service] EnvironmentFile=-/etc/conf.d/server.hack.txt ExecStartPre=/bin/bash -ac "sed s/@@@/$SERVER/ </etc/wireguard/foo.skel >/etc/wireguard/foo.conf"
使用 OpenVPN 的示例:
/etc/systemd/system/openvpn-client@foo.service.d/override.conf
[Service] EnvironmentFile=-/etc/conf.d/server.hack.txt ExecStartPre=/bin/bash -ac "sed s/@@@/$SERVER/ </etc/openvpn/client/foo.skel >/etc/openvpn/client/foo.conf"
测试服务
在正在运行的容器内 (通过 ssh 或者 lxc-attach -n playtime
) 通过将浏览器导出到主机的计算机 X server 来测试设置:
$ DISPLAY=:0 firefox
xhost +SI:localuser:yourusername
然后通过 ssh 连接到容器。结果应该是主机的 X server 中出现一个标题为"Mozilla Firefox (playtime)" 的 Firefox 窗口。许多网站可用于验证 IP 地址和 DNS 的状态,例如 ipleak dot net.
此时,仅应显示与配置文件中定义的条目相对应的 DNS 条目。