Openvpn

以非root使用者身份執行openvpn

  • February 14, 2020

我正在嘗試在 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,而後者又會將它們進一步向下傳遞給 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

也許嘗試使用這樣的功能沒有意義?

我設法通過在容器內用總是返回 0 的 bash 腳本替換來讓 openvpn 工作。ip我認為 openvpn 嘗試做的唯一事情就是設置tun0然後為其分配 IP 地址並啟動它。我決定從容器外部(以 root 身份)手動執行此操作,因此 openvpn 不必這樣做。我在這裡描述了 openvpn wiki 上的過程

引用自:https://unix.stackexchange.com/questions/564556