2012-11-08

Bash Script debugging and SELinux


OpenVPN can launch a script client-connect each time a client connect to the VPN.
The script used to work when OpenVPN is launched directly, but not when launched via /etc/init.d/openvpn start ...

A good way to debug is to put this at the beginning of the file:
#!/bin/sh
"client-connect
exec > /tmp/debug.$$ 2>&1; set -x
...

Reading the /tmp/debug.pid will give a first hint: "Permission denied" when trying to launch "/bin/mail" in the script.

I put a ME=$(whoami) in the script but both (working and non-working) returned the same: nobody. So, it leaves only one suspect: SELinux. (I didn't though about SELinux because I didn't see it in the services. But it is there, in the Kernel.)

Quick info about SELinux:
  • sestatus to get information
  • setenforce Permissive will give only warning (it creates less problems than disabling it).
  • /usr/sbin/selinuxenabled && SEL="SELinux ON" to use in scripts.

To be really sure, I did the following:
# ls -Z /etc/init.d/openvpn gives: system_u:object_r:openvpn_initrc_exec_t:s0
# ls -Z myTest               gives: unconfined_u:object_r:openvpn_etc_t:s0

My test script runs "unconfined". If I copy the openvpn script into my folder while preserving the context cp -c ..., I change the content to be the same as my old working script and re-launch. It doesn't work anymore.
Conclusion: the file's context will confine openvpn so that the script it launches will fail to uses /bin/mail.


Solution 1 :
The "hard way" is to try to patch the policy to workaround your case:
$ grep client-connect /var/log/audit/audit.log | audit2allow -M openvpn_cc
This will create two files: a .pp to be run and a .te for your reading pleasure.
install the module: semodule -i openvpn_cc.pp

It goes a little further, but still fails and if you look at the policy in the .te file, it is quite complicated.
(I didn't repeat the process audit2allow ... to get further, but I guess that ultimately it would have worked.)


Solution 2:
Create a policy to send mail:

$ vi openvpn_cc.te
policy_module(openvpn_cc, 1.0)
 
require {
        type openvpn_t;
};
 
mta_send_mail(openvpn_t)

Compile: make -f /usr/share/selinux/devel/Makefile openvpn_cc.pp
Install: semodule -i openvpn_cc.pp

Simple and it works.


References:

1 comment:

Unknown said...

Tried solution 2 in CentOS 7 and it works perfectly - thanks!

2023 summary

  Life is bigger than what you can imagine.  Still using Roam  http://www.roamresearch.com/  to take notes Still using Mastodon mainly, but ...