以非 root 用户身份运行 openvpn

以非 root 用户身份运行 openvpn

我正在尝试在 podman 非特权容器内运行 openvpn 服务器。

Openvpn 需要能够管理网络接口(即创建 tun 接口、为其分配 IP 地址、启动它)。openvpn-server.service我在我的系统(arch linux)中注意到了CapabilityBoundingSet这一点,这让我开始尝试并创建自己的服务,而不是运行 openvpn podman run

首先我创建了我的 openvpn 容器,下面是 Dockerfile(为了方便,我使用 archlinux 作为基础):

FROM archlinux
RUN pacman -Sy --noconfirm openvpn

然后我构建了这个容器(以 身份登录my_unprivileged_user

podman build \
--force-rm \
--no-cache \
--rm \
--device=/dev/net/tun \
-t openvpn .

然后我创建my_custom_openvpn.service

Description=OpenVPN in Podman container
After=syslog.target network-online.target
Wants=network-online.target

[Service]
User=my_unprivileged_user
Group=my_unprivileged_group
WorkingDirectory=/etc/openvpn
ExecStart=/usr/bin/podman run --rm --name openvpn -v ./server:/server --device /dev/net/tun --network "host" --cap-add CAP_IPC_LOCK,CAP_NET_ADMIN,CAP_NET_BIND_SERVICE,CAP_NET_RAW,CAP_SETGID,CAP_SETUID,CAP_SYS_CHROOT,CAP_DAC_OVERRIDE,CAP_AUDIT_WRITE localhost/openvpn:latest /usr/bin/openvpn --config /server/my_config.conf
ExecStop=/usr/bin/podman stop -t 0 openvpn
Capabilities=CAP_IPC_LOCK CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_RAW CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_DAC_OVERRIDE CAP_AUDIT_WRITE
DeviceAllow=/dev/null rw
DeviceAllow=/dev/net/tun rw
#ProtectSystem=true
#ProtectHome=true
RestartSec=5s
Restart=on-failure
TimeoutSec=5s

[Install]
WantedBy=multi-user.target

所以我认为 systemd 会将功能传递给 podman,然后 podman 会将它们进一步传递给 openvpn。

但是 openvpn 无法启动,提示无法创建 tun0 接口。即使我像这样自己创建 tun0,openvpn --mktun --dev tun0我还是会收到另一个错误,即 openvpn 无法设置此 tun0 接口。

我想也许我需要setcap在容器内执行此操作,因此我将podman exec其放入容器中并执行如下操作:

setcap CAP_IPC_LOCK,CAP_NET_ADMIN,CAP_NET_BIND_SERVICE,CAP_NET_RAW,CAP_SETGID,CAP_SETUID,CAP_SYS_CHROOT,CAP_DAC_OVERRIDE,CAP_AUDIT_WRITE=+ep /usr/bin/openvpn

但这没有帮助。我一直收到此错误:

Tue Jan 28 13:34:31 2020 /usr/bin/ip link set dev tun0 up mtu 1500
RTNETLINK answers: Operation not permitted

也许尝试使用这样的功能是没有意义的?

答案1

ip我设法通过在容器内用始终返回 0 的 bash 脚本替换来使 openvpn 正常工作。我认为 openvpn 尝试做的唯一事情就是设置tun0然后为其分配 IP 地址并启动它。我决定从容器外部手动执行此操作(以 root 身份),这样 openvpn 就不必这样做了。我在 openvpn wiki 上描述了该过程这里

相关内容