Reiniciando o OpenVPN no SELinux por um cronjob

1

Eu tenho um servidor com algumas instâncias do OpenVPN (um servidor, vários clientes) rodando no Debian com a aplicação do SELinux. As conexões com alguns dos servidores VPN com os quais minha máquina está se conectando são um pouco instáveis, e as instâncias do OpenVPN em minha máquina falham de vez em quando, então eu configurei um cronjob para reiniciá-las em caso de falha.

Agora o problema é que esse cronjob falha devido a problemas com o SELinux, o que eu realmente não entendo. Reiniciar qualquer instância do OpenVPN manualmente a partir da linha de comando, usando o mesmo comando, funciona bem. Isto é o que a auditoria diz:

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.

Eu já tinha configurado uma configuração openvpn local para o SELinux, para que tudo funcionasse. Parece assim:

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 };

Essa configuração funcionou, antes de eu ter que fazer algumas alterações na minha configuração, para executar as instâncias do OpenVPN em nós de dispositivos estáticos. Desde então, os direitos concedidos não parecem mais suficientes.

Qualquer ajuda, para configurar uma solução refinada para isso, ou como melhorar o módulo local do SELinux para o OpenVPN seria muito apreciada!

    
por Michael 03.02.2015 / 12:13

2 respostas

1

O primeiro erro é claro; a linha que você comentou dá a permissão que a auditoria diz que está faltando.

A segunda parte é mais interessante, mas o que eu suspeito é que o problema é o contexto de destino do socket que você está modificando (de propriedade de unconfined_u). Como você mudou para nós de dispositivos estáticos, suas interfaces não são mais criadas pelo processo openvpn que irá modificá-las, então não acho que o self: tun_socket seja mais suficiente. Você também pode consertar isso modificando os contextos de seus nós para serem de propriedade de system_u.

Se toda a sua configuração de rede é tratada em um script e tudo funciona no boot, você pode definitivamente usar run_init /etc/init.d/openvpn start no crontab do root para fazer este trabalho. run_init garante que o script seja executado no mesmo contexto que teria sido na inicialização.

EDIT: Se você quer que o sensitve falhe e seus daemons possuam pidfiles, você pode usar alguns inotify magic em / proc / pid para notar quando eles desaparecem e então chamar o script de reinicialização. waitpid seria melhor, mas só funciona em processos filhos.

    
por 12.02.2015 / 20:44
0

Eu não faço o SELinux, então não posso ajudar com isso. No entanto, se o seu problema estiver mantendo o OpenVPN em execução, você poderá considerar um código como este:

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

Isso pressupõe que o OpenVPN esteja sendo executado em primeiro plano. Você pode precisar alterar suas opções de linha de comando do OpenVPN para que ele fique em primeiro plano. Este script aguenta cinco segundos e inicia o OpenVPN. Quando o OpenVPN sai, ele dorme por cinco segundos e inicia o OpenVPN. Espuma, enxaguar, repita.

Este é um hack feio, mas se você executá-lo em uma sessão de tela, ele pode fazer o trabalho. Você pode roteirizar tudo para rodar na tela, se quiser. Eu não posso enfatizar o suficiente que é um hack feio .... mas está reiniciando o serviço periodicamente do cron.

    
por 11.02.2015 / 23:52