Linux 容器/使用 VPN
本文介绍如何设置 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 条目。