以非 root 用户身份运行 openvpn

以非 root 用户身份运行 openvpn

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

OpenVPN 需要能够管理网络接口(即创建 tun 接口、为其分配 IP 地址、启动它)。在我的系统(arch linux)上,openvpn-server.service我注意到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 上描述了该过程这里

相关内容