通过 cronjob 在 SELinux 上重新启动 OpenVPN

通过 cronjob 在 SELinux 上重新启动 OpenVPN

我有一台服务器,其中有一些 OpenVPN 实例(一台服务器,多个客户端),在 Debian 上运行,并强制执行 SELinux。我的机器所连接的一些 VPN 服务器的连接有些不稳定,并且我机器上的 OpenVPN 实例时不时地崩溃,因此我设置了一个 cronjob 来在崩溃时重新启动它们。

现在的问题是,这个 cronjob 由于 SELinux 的问题而失败,我不太明白。使用相同的命令从命令行手动重新启动任何 OpenVPN 实例都可以正常工作。审计是这样说的:

type=AVC msg=audit(1422960005.730:3567927): avc:  denied  { sys_module } for  pid=14309 comm="ifconfig" capability=16  scontext=system_u:system_r:openvpn_t:s0 tcontext=system_u:system_r:openvpn_t:s0 tclass=capability
        Was caused by:
                Missing type enforcement (TE) allow rule.
                You can use audit2allow to generate a loadable module to allow this access.

type=AVC msg=audit(1422960005.722:3567921): avc:  denied  { relabelfrom } for  pid=14295 comm="openvpn" scontext=system_u:system_r:openvpn_t:s0 tcontext=unconfined_u:system_r:openvpn_t:s0-s0:c0.c1023 tclass=tun_socket
        Was caused by:

#Constraint rule:

        constrain tun_socket { create relabelfrom relabelto } ((u1 == u2 -Fail-)  or (t1 == { logrotate_t ldconfig_t initrc_t sysadm_t dpkg_t lvm_t mdadm_t unconfined_mount_t dpkg_script_t newrole_t local_login_t sysadm_passwd_t system_cronjob_t tmpreaper_t unconfined_execmem_t httpd_unconfined_script_t groupadd_t depmod_t insmod_t kernel_t passwd_t updpwd_t apmd_t apt_t chfn_t init_t sshd_t udev_t remote_login_t inetd_child_t restorecond_t setfiles_t unconfined_t systemd_tmpfiles_t sulogin_t useradd_t } -Fail-) ); Constraint DENIED

#       Possible cause is the source user (system_u) and target user (unconfined_u) are different.
#       Possible cause is the source level (s0) and target level (s0-s0:c0.c1023) are different.

我已经为 SELinux 设置了本地 openvpn 配置,以便让它运行。它看起来像这样:

module openvpn_local 1.0;

require {
        type openvpn_t;
        type kernel_t;
        type udev_t;
        type var_run_t;
        class system module_request;
        class file { read append };
        class capability sys_module;
        class tun_socket { relabelfrom relabelto };
}

#============= openvpn_t ==============
allow openvpn_t kernel_t:system module_request;
# allow openvpn_t self:capability sys_module;
allow openvpn_t self:tun_socket { relabelfrom relabelto };
allow udev_t var_run_t:file { read append };

在我必须对我的设置进行一些更改以在静态设备节点上运行 OpenVPN 实例之前,此设置已经有效。从那时起,授予的权利似乎不再足够了。

任何帮助,为此建立一个细粒度的解决方案,或者如何改进 OpenVPN 的本地 SELinux 模块将不胜感激!

答案1

第一个错误很明显;您注释掉的行给出了审计认为缺少的权限。

第二部分更有趣,但我怀疑问题是您正在修改的套接字的目标上下文(由 unconfined_u 拥有)。因为您已经转移到静态设备节点,所以您的接口不再由要修改它们的 openvpn 进程创建,所以我认为 self:tun_socket 不再足够了。您还可以通过将节点的上下文修改为由 system_u 拥有来解决此问题。

如果您所有的网络设置都在 initscript 中处理,并且一切都在启动时正常工作,那么您绝对可以run_init /etc/init.d/openvpn start在 root 的 crontab 中使用来完成此工作。run_init确保脚本在启动时的相同上下文中运行。

编辑:如果你希望它对崩溃敏感并且你的守护进程有 pid 文件,你可以inotify在 /proc/pid 上使用一些魔法来注意到它们何时消失,然后调用重新启动脚本。waitpid会更好,但仅适用于子进程。

答案2

我没有 SELinux,所以无法提供帮助。但是,如果您的问题是保持 OpenVPN 运行,您可以考虑如下代码:

while sleep 5; do
  /command/to/start/OpenVPN
done

这假设 OpenVPN 在前台运行。您可能需要更改 OpenVPN 命令行选项以使其停留在前台。该脚本休眠五秒钟,然后启动 OpenVPN。当 OpenVPN 退出时,它会休眠五秒钟并启动 OpenVPN。起泡沫,冲洗,重复。

这是一个丑陋的黑客,但如果你在屏幕会话中运行它,它可以完成工作。如果您愿意,您可以将其全部编写为在屏幕上运行的脚本。我无法强调这是一个丑陋的黑客......但从 cron 定期重新启动服务也是如此。

相关内容