我正在尝试通过 Fedora 25 上的 systemd 在网络命名空间上运行 OpenVPN。myns
看起来 SELinux 阻止了它的工作。
看着journalctl -xe
,我认为这是相关的部分:
-- Subject: Unit myvpn.service has begun start-up
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
-- Unit myvpn.service has begun starting up.
Jul 11 16:26:19 castiel audit[32456]: AVC avc: denied { mounton } for pid=32456 comm="ip" path="/etc/resolv.conf" dev="sda1" ino=1572869 scontext=system_u:system_r:ifconfig_t:s0 tcontext=system_u:o
bject_r:net_conf_t:s0 tclass=file permissive=0
Jul 11 16:26:19 castiel audit[32456]: AVC avc: denied { execute } for pid=32456 comm="ip" name="openvpn" dev="sda1" ino=1705174 scontext=system_u:system_r:ifconfig_t:s0 tcontext=system_u:object_r:o
penvpn_exec_t:s0 tclass=file permissive=0
Jul 11 16:26:19 castiel ip[32456]: Bind /etc/netns/myns/resolv.conf -> /etc/resolv.conf failed: Permission denied
Jul 11 16:26:19 castiel ip[32456]: exec of "/sbin/openvpn" failed: Permission denied
Jul 11 16:26:19 castiel systemd[1]: myvpn.service: Control process exited, code=exited status=1
Jul 11 16:26:19 castiel audit[1]: SERVICE_START pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 msg='unit=nordvpn comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? a
ddr=? terminal=? res=failed'
Jul 11 16:26:19 castiel systemd[1]: Failed to start OpenVPN connection to myvpn.
-- Subject: Unit myvpn.service has failed
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
-- Unit myvpn.service has failed.
/var/log/audit/audit.log
:
type=AVC msg=audit(1499799030.259:16264): avc: denied { mounton }
for pid=1419 comm="ip" path="/etc/resolv.conf" dev="sda1" ino=1572869
scontext=system_u:system_r:ifconfig_t:s0
tcontext=system_u:object_r:net_conf_t:s0
tclass=file permissive=0
type=AVC msg=audit(1499799030.259:16265): avc: denied { execute }
for pid=1419 comm="ip" name="openvpn" dev="sda1" ino=1705174
scontext=system_u:system_r:ifconfig_t:s0
tcontext=system_u:object_r:openvpn_exec_t:s0
tclass=file permissive=0
type=SERVICE_START msg=audit(1499799030.268:16266):
pid=1 uid=0 auid=4294967295 ses=4294967295
subj=system_u:system_r:init_t:s0 msg='unit=myvpn
comm="systemd" exe="/usr/lib/systemd/systemd"
hostname=? addr=? terminal=? res=failed'
type=SERVICE_START msg=audit(1499800402.528:16267):
pid=1 uid=0 auid=4294967295 ses=4294967295
subj=system_u:system_r:init_t:s0 msg='unit=dnf-makecache comm="systemd"
exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=success'
type=SERVICE_STOP msg=audit(1499800402.528:16268):
pid=1 uid=0 auid=4294967295 ses=4294967295
subj=system_u:system_r:init_t:s0 msg='unit=dnf-makecache comm="systemd"
exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=success'
# ll -Z /etc/resolv.conf
显示这个:
-rw-r--r--. 1 root root system_u:object_r:net_conf_t:s0 61 Jul 9 17:26 /etc/resolv.conf
服务文件如下所示:
[Unit]
[Service]
Type=forking
ExecStart=/sbin/ip netns exec myns /sbin/openvpn --config /etc/openvpn/profiles/myprofile.ovpn --auth-user-pass /etc/openvpn/credentials --daemon [email protected] --writepid /run/[email protected]
PIDFile=/run/[email protected]
[Install]
WantedBy=multi-user.target
如果我将 selinux 设置为 permissive ( setenforce 0
) ,它就可以正常工作。
如果我自己运行该命令,它可以在 selinux 强制下正常工作:
/sbin/ip netns exec myns /sbin/openvpn --config /etc/openvpn/profiles/myprofile.ovpn --auth-user-pass /etc/openvpn/credentials --daemon [email protected] --writepid /run/[email protected]
curl ifconfig.io
返回我的公共IP并
ip netns exec myns curl ifconfig.io
返回VPN服务器的IP。
我必须做什么才能让 SELinux 允许 systemd 脚本工作而不完全禁用 SELinux?
答案1
运行时setenforce 0
我能够使用以下命令获得以下允许规则audit2allow
:
#============= ifconfig_t ==============
allow ifconfig_t net_conf_t:file mounton;
allow ifconfig_t openvpn_etc_t:file { getattr open read };
allow ifconfig_t openvpn_exec_t:file { execute execute_no_trans open read };
allow ifconfig_t openvpn_tmp_t:dir { read write };
我也从相同的日志中得到了这条规则
#============= ifconfig_t ==============
#!!!! WARNING: 'tmp_t' is a base type.
allow ifconfig_t tmp_t:dir { read write };
为了不必允许这种情况,我创建了一个带有openvpn_tmp_t
标签的子文件夹,并 使用指向该目录的参数/tmp
运行。openvpn
--tmp-dir
此后我仍然无法启动该服务。查看journalctl -xe
,我发现加载配置文件时出现问题:
-- Unit myvpn.service has begun starting up.
Jul 17 06:19:56 castiel ip[22825]: Options error: In [CMD-LINE]:1: Error opening configuration file: /etc/openvpn/profiles/myprofile.ovpn
Jul 17 06:19:56 castiel ip[22825]: Use --help for more information.
Jul 17 06:19:56 castiel systemd[1]: myvpn.service: Control process exited, code=exited status=1
Jul 17 06:19:56 castiel systemd[1]: Failed to start OpenVPN connection to myprofile.ovpn.
我再次尝试setenforce 0
,它能够启动。令人惊讶的是有没有什么在审计日志中对此进行了说明。
我搜索并发现了一个Fedora selinux 邮件列表上的老问题。显然有一条dontaudit
规则阻止记录某些消息。可以使用 关闭此功能semodule -DB
(使用 重新启用semodule -B
)。
记录了其余的错误后,我得到了更多行,并将其转换为规则audit2allow
:
#============= ifconfig_t ==============
allow ifconfig_t openvpn_etc_t:dir search;
allow ifconfig_t openvpn_tmp_t:dir search;
#============= init_t ==============
allow init_t ifconfig_t:process noatsecure;
allow init_t kernel_t:unix_stream_socket { read write };
通过结合这些策略,我能够通过 systemd 在网络命名空间内运行 openvpn。
我仍然不确定这些规则有多安全,或者是否有更好的方法来解决这个问题。