1

I'm trying to run OpenVPN on a network namespace myns through systemd on Fedora 25. It looks like SELinux is preventing it from working.

Looking at journalctl -xe, I think this is the relevant part:

-- 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 shows this:
-rw-r--r--. 1 root root system_u:object_r:net_conf_t:s0 61 Jul 9 17:26 /etc/resolv.conf


This is what the service file looks like:

[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 openvpn@myprofile.ovpn --writepid /run/openvpn@myprofile.ovpn.pid
PIDFile=/run/openvpn@myprofile.ovpn.pid

[Install]
WantedBy=multi-user.target

If I set selinux to permissive (setenforce 0) it works fine.


If I run the command my self it works fine with selinux enforcing:

/sbin/ip netns exec myns /sbin/openvpn --config /etc/openvpn/profiles/myprofile.ovpn --auth-user-pass /etc/openvpn/credentials --daemon openvpn@myprofile.ovpn --writepid /run/openvpn@myprofile.ovpn.pid

curl ifconfig.io returns my public IP and
ip netns exec myns curl ifconfig.io returns the IP of the VPN server.


What must I do to make SELinux allow the systemd script to work without disabling SELinux altogether?

  • audit2allow after running with setenforce 0, or setup the netns in systemd instead (but it will not be a "named" netns as used by ip netns) github.com/systemd/systemd/issues/2741#issuecomment-273745146 – sourcejedi Jul 15 '17 at 8:55
  • If you're curious about why you can run the command yourself - it's because normal user logins are simply unconfined by default. (See id -Z). A third alternative is to transition to unconfined for this service. Amusingly (to me) all you have to do is move your ExecStart command into a shell script, somewhere in a system directory like /usr/ or /etc/, and run the script instead. E.g. if a service is set as running a script which has defaulted to bin_t (see ls -Z after creation), it will transition to unconfined. – sourcejedi Jul 15 '17 at 9:02
  • Hopefully net_conf_t is trying to transition to openvpn_t, and the audit2allow rules would just 1) let it do that, after 2) allowing the bind mount. I guess that's not exactly perfect for net_conf_t, but it avoids opening things up completely. – sourcejedi Jul 15 '17 at 9:18
2

Running with setenforce 0 I was able to get the following allow rules using 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 };

I also got this rule from the same logs

#============= ifconfig_t ==============

#!!!! WARNING: 'tmp_t' is a base type.
allow ifconfig_t tmp_t:dir { read write };

To not have to allow this, I created a subfolder with the openvpn_tmp_t label under /tmp and ran openvpn with the --tmp-dir argument pointing to that directory.


After this I was still unable to start the service. Looking at journalctl -xe, I saw that there was a problem loading a configuration file:

-- 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.

I tried again with setenforce 0 and it was able to start up. Surprisingly there was nothing in the audit log about this.

I searched and came accross an old question on Fedora selinux mailing list. Apparently there is a dontaudit rule that blocks some messages from being logged. This could be turned off with semodule -DB (re-enabled with semodule -B).

With the rest of the errors logged, I got some more rows that I turned in to rules with 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 };

With these policies combined I was able to get openvpn running inside of the network namespace through systemd.

I'm still not sure how secure these rules are or if there is a better way to go about this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.