【发布时间】:2019-11-28 14:50:21
【问题描述】:
有这个Dockerfile:
FROM fedora:30
ENV LANG C.UTF-8
RUN dnf upgrade -y \
&& dnf install -y \
openssh-clients \
openvpn \
slirp4netns \
&& dnf clean all
CMD ["openvpn", "--config", "/vpn/ovpn.config", "--auth-user-pass", "/vpn/ovpn.auth"]
使用以下方法构建图像:
podman build -t peque/vpn .
如果我尝试使用它运行它(注意 $(pwd),VPN 配置和凭据的存储位置):
podman run -v $(pwd):/vpn:Z --cap-add=NET_ADMIN --device=/dev/net/tun -it peque/vpn
我收到以下错误:
ERROR: Cannot open TUN/TAP dev /dev/net/tun: Permission denied (errno=13)
关于如何解决此问题的任何想法?如果有帮助,我不介意更改基本图像(即:到 Alpine 或其他任何东西,只要它允许我使用 openvpn 进行连接)。
系统信息
使用 Podman 1.4.4(无根)和带有内核 5.1.19 的 Fedora 30 发行版。
/dev/net/tun 权限
运行容器:
podman run -v $(pwd):/vpn:Z --cap-add=NET_ADMIN --device=/dev/net/tun -it peque/vpn
然后,从容器中,我可以:
# ls -l /dev/ | grep net
drwxr-xr-x. 2 root root 60 Jul 23 07:31 net
我也可以列出/dev/net,但会得到“权限被拒绝错误”:
# ls -l /dev/net
ls: cannot access '/dev/net/tun': Permission denied
total 0
-????????? ? ? ? ? ? tun
正在尝试--privileged
如果我尝试使用--privileged:
podman run -v $(pwd):/vpn:Z --privileged --cap-add=NET_ADMIN --device=/dev/net/tun -it peque/vpn
然后我得到一个 no-such-file-or-directory 错误 (errno=2),而不是权限被拒绝错误 (errno=13):
ERROR: Cannot open TUN/TAP dev /dev/net/tun: No such file or directory (errno=2)
使用--privileged时可以有效验证不存在/dev/net/目录,即使我传递了--cap-add=NET_ADMIN --device=/dev/net/tun参数。
详细日志
这是我用verb 3配置客户端时得到的日志:
OpenVPN 2.4.7 x86_64-redhat-linux-gnu [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [PKCS11] [MH/PKTINFO] [AEAD] built on Feb 20 2019
library versions: OpenSSL 1.1.1c FIPS 28 May 2019, LZO 2.08
Outgoing Control Channel Authentication: Using 160 bit message hash 'SHA1' for HMAC authentication
Incoming Control Channel Authentication: Using 160 bit message hash 'SHA1' for HMAC authentication
TCP/UDP: Preserving recently used remote address: [AF_INET]xx.xx.xx.xx:1194
Socket Buffers: R=[212992->212992] S=[212992->212992]
UDP link local (bound): [AF_INET][undef]:0
UDP link remote: [AF_INET]xx.xx.xx.xx:1194
TLS: Initial packet from [AF_INET]xx.xx.xx.xx:1194, sid=3ebc16fc 8cb6d6b1
WARNING: this configuration may cache passwords in memory -- use the auth-nocache option to prevent this
VERIFY OK: depth=1, C=ES, ST=XXX, L=XXX, O=XXXXX, emailAddress=email@domain.com, CN=internal-ca
VERIFY KU OK
Validating certificate extended key usage
++ Certificate has EKU (str) TLS Web Server Authentication, expects TLS Web Server Authentication
VERIFY EKU OK
VERIFY OK: depth=0, C=ES, ST=XXX, L=XXX, O=XXXXX, emailAddress=email@domain.com, CN=ovpn.server.address
Control Channel: TLSv1.2, cipher TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 2048 bit RSA
[ovpn.server.address] Peer Connection Initiated with [AF_INET]xx.xx.xx.xx:1194
SENT CONTROL [ovpn.server.address]: 'PUSH_REQUEST' (status=1)
PUSH: Received control message: 'PUSH_REPLY,route xx.xx.xx.xx 255.255.255.0,route xx.xx.xx.0 255.255.255.0,dhcp-option DOMAIN server.net,dhcp-option DNS xx.xx.xx.254,dhcp-option DNS xx.xx.xx.1,dhcp-option DNS xx.xx.xx.1,route-gateway xx.xx.xx.1,topology subnet,ping 10,ping-restart 60,ifconfig xx.xx.xx.24 255.255.255.0,peer-id 1'
OPTIONS IMPORT: timers and/or timeouts modified
OPTIONS IMPORT: --ifconfig/up options modified
OPTIONS IMPORT: route options modified
OPTIONS IMPORT: route-related options modified
OPTIONS IMPORT: --ip-win32 and/or --dhcp-option options modified
OPTIONS IMPORT: peer-id set
OPTIONS IMPORT: adjusting link_mtu to 1624
Outgoing Data Channel: Cipher 'AES-128-CBC' initialized with 128 bit key
Outgoing Data Channel: Using 160 bit message hash 'SHA1' for HMAC authentication
Incoming Data Channel: Cipher 'AES-128-CBC' initialized with 128 bit key
Incoming Data Channel: Using 160 bit message hash 'SHA1' for HMAC authentication
ROUTE_GATEWAY xx.xx.xx.xx/255.255.255.0 IFACE=tap0 HWADDR=0a:38:ba:e6:4b:5f
ERROR: Cannot open TUN/TAP dev /dev/net/tun: No such file or directory (errno=2)
Exiting due to fatal error
错误编号可能会根据我是否使用--privileged 运行命令而改变。
【问题讨论】:
-
无法重现 - 客户端容器在
CAP_NET_ADMIN设置和/dev/net/tun允许的情况下运行良好。我使用了 podman1.4.4(无根)、内核5.2.1、来自官方 openvpn 示例的密钥和证书、配置 - 也来自示例,但删除了一些(可能)不需要的东西。 -
也许向问题添加更具体的信息是有意义的——版本、服务器/客户端的最小配置等。
-
@DanilaKiver 我在我的问题中附加了更多信息。更完整的日志,关于我如何从容器中看到
/dev/net/tun的信息以及尝试--privileged的结果(这没有帮助,或者因为/dev/net/不存在而变得更糟)。有什么想法吗? -
谢谢,这个更新现在更有意义了——Fedora 有 SELinux(在 VM 上检查——如果是非特权容器,SELinux 会阻止对
/dev/net/tun的访问)。此外,即使在 Fedora 和没有 SELinux 的情况下,似乎在特权容器的情况下缺少/dev/net/tun也是可以重现的——这很有趣。打算再深入一点。 -
我认为这里的好方法是扩展现有的 SELinux 策略,以允许此特定容器与
tun_tap_device_t一起工作 - 让我试验一下 :)
标签: dockerfile podman