Apache + appel script /bin/irsend –> Créer module de contexte de sécurité

Lien https://forums.fedoraforum.org/showthread.php?283129-selinux-to-allow-running-irsend-from-apache

lien : https://relativkreativ.at/articles/how-to-compile-a-selinux-policy-package

lien https://www.endpoint.com/blog/2013/11/20/selinux-fix-for-sudo-pam

 

Il n'est pas possible de manière simple d'autoriser le compte Apache à faire du SUDO.

Il faut dans un premier temps relever dans les logs le message qui interdit ce type d’action par SE LINUX :

 tail -f /var/log/messages | grep SELinux

Exemple de Résultat

May  2 15:49:05 vdi-nx setroubleshoot: SELinux is preventing sudo from using the setgid capability. For complete SELinux messages run: sealert -l b0707f8a-b189-44bd-99ee-51ad426cc3b0

rem : il est possible de voir avec plus de détails l’erreur dans le fichier /var/log/audit/audit.log

Pour voir le détail, executer la commande indiquée :

sealert -l b0707f8a-b189-44bd-99ee-51ad426cc3b0

Ce qui donne le résultat suivant :

SELinux is preventing sudo from using the setgid capability.

*****  Plugin catchall (100. confidence) suggests   **************************

If vous pensez que sudo devrait avoir des capacités setgid par défaut.
Then vous devriez rapporter ceci en tant qu'anomalie.
Vous pouvez générer un module de stratégie local pour autoriser cet accès.
Do
allow this access for now by executing:
# ausearch -c 'sudo' --raw | audit2allow -M my-sudo
# semodule -i my-sudo.pp


Additional Information:
Source Context                system_u:system_r:httpd_sys_script_t:s0
Target Context                system_u:system_r:httpd_sys_script_t:s0
Target Objects                Unknown [ capability ]
Source                        sudo
Source Path                   sudo
Port                          <Unknown>
Host                          vdi-nx
Source RPM Packages           sudo-1.8.19p2-11.el7_4.x86_64
Target RPM Packages
Policy RPM                    selinux-policy-3.13.1-166.el7_4.9.noarch
Selinux Enabled               True
Policy Type                   targeted
Enforcing Mode                Enforcing
Host Name                     vdi-nx
Platform                      Linux vdi-nx 3.10.0-693.21.1.el7.x86_64 #1 SMP Wed
                              Mar 7 19:03:37 UTC 2018 x86_64 x86_64
Alert Count                   80
First Seen                    2018-04-12 09:29:43 CEST
Last Seen                     2018-05-02 15:49:04 CEST
Local ID                      b0707f8a-b189-44bd-99ee-51ad426cc3b0

Raw Audit Messages
type=AVC msg=audit(1525268944.858:15678): avc:  denied  { setgid } for  pid=11884 comm="sudo" capability=6  scontext=system_u:system_r:httpd_sys_script_t:s0 tcontext=system_u:system_r:httpd_sys_script_t:s0 tclass=capability


type=SYSCALL msg=audit(1525268944.858:15678): arch=x86_64 syscall=setresgid success=no exit=EPERM a0=ffffffff a1=0 a2=ffffffff a3=7fa3525c0300 items=0 ppid=10046 pid=11884 auid=4294967295 uid=0 gid=48 euid=0 suid=0 fsuid=0 egid=48 sgid=48 fsgid=48 tty=(none) ses=4294967295 comm=sudo exe=/usr/bin/sudo subj=system_u:system_r:httpd_sys_script_t:s0 key=(null)

Hash: sudo,httpd_sys_script_t,httpd_sys_script_t,capability,setgid

rem : la partie RAW audit message est également présente dans /var/log/audit/audit.log

En lisant c’est bien notre cas. Le contexte de sécurité httpd_sys_script_t n’est pas autorisé à utiliser la commande sudo

On récupère les lignes comprennant type= AVC et type = “SYSCALL” puis on les envoie dans un générateur de module audit2allow

echo '
type=SYSCALL msg=audit(1525269643.375:15749): arch=c000003e syscall=119 success=no exit=-1 a0=ffffffff a1=0 a2=ffffffff a3=7f5ad39cd300 items=0 ppid=4974 pid=11974 auid=4294967295 uid=0 gid=48 euid=0 suid=0 fsuid=0 egid=48 sgid=48 fsgid=48 tty=(none) ses=4294967295 comm="sudo" exe="/usr/bin/sudo" subj=system_u:system_r:httpd_sys_script_t:s0 key=(null)
type=AVC msg=audit(1525269643.375:15749): avc:  denied  { setgid } for  pid=11974 comm="sudo" capability=6  scontext=system_u:system_r:httpd_sys_script_t:s0 tcontext=system_u:system_r:httpd_sys_script_t:s0 tclass=capability' | audit2allow -M  Module_httpd_sudo

Cela génère les fichiers suivants :

4 -rw-r--r--. 1 root   root    889  2 mai   16:08 Module_httpd_sudo.pp
4 -rw-r--r--. 1 root   root    187  2 mai   16:08 Module_httpd_sudo.te

Le fichier MonModule.pp est la version binaire qui faudra charger.

Le fichier MonModule.te est une version lisible du fichier binaire généré. Dans notre cas son contenu est le suivant :

module Module_httpd_sudo 1.0;

require {
        type httpd_sys_script_t;
        class capability setgid;
}

#============= httpd_sys_script_t ==============
allow httpd_sys_script_t self:capability setgid;

On remarque bien que le contexte “httpd_sys_script_t” peut utiliser la fonctionnalité “setgid”. Ce qui devrait permettre au compte Apache de pouvoir utiliser la commande “sudo”…

On intègre le module :

semodule -i MonModule.pp

A l’issue il existe toujours un refus d’accès. C’est normal car plusieurs ouvertures de “droits” sont nécessaires. Pour prendre en compte le premier lot d’ouverture de droits, une méthode plus rapide est à suivre. Il faut retirer des logs tous les messages liés à “sudo” puis prendre ce flux et l’envoyer à la commande “audit2allow” qui va générer les 2 fichiers de modules

# On enlève l'ancien module
semodule - R Module_httpd_sudo
# Recherche dans le journal des logs et construction du module de sécurité
ausearch -c 'sudo' --raw | audit2allow -M Module_httpd_sudo
# intégration du nouveau module
semodule -i Module_http_sudo

Mais l’ouverture de certains droits bloqués ouvre à d’autres interdiction qu’il faut lever…Il faut donc répéter l’opération tant que des messages d’interdiction apparaîssent.

Ainsi dans notre cas, le fichier de module (Module_httpd_sudo.te) va contenir les lignes suivantes :

module Module_httpd_sudo2 1.0;

require {
        type httpd_sys_script_t;
        class capability { setgid setuid sys_resource };
        class process setrlimit;
        class netlink_audit_socket create;
}

#============= httpd_sys_script_t ==============

#!!!! This avc is allowed in the current policy
allow httpd_sys_script_t self:capability { setgid setuid sys_resource };

#!!!! This avc is allowed in the current policy
allow httpd_sys_script_t self:netlink_audit_socket create;
allow httpd_sys_script_t self:process setrlimit;

Mais à ce stade ce n’est pas opérationnel.

En effet des erreurs apparaissent dans les fichiers /var/log/httpd/error_log

sudo: unable to send audit message: Permission denied
sudo: pam_open_session: System error
sudo: policy plugin failed session initialization

ou /var/log/secure

May  4 15:14:25 vdi-nx sudo: PAM audit_log_acct_message() failed: Permission denied
May  4 15:14:25 vdi-nx sudo:  apache : pam_open_session: System error ; TTY=unknown ; PWD=/var/www/html ; USER=root ; COMMAND=prive/donnees/iptables_co

Alors que que dans le fichier “/var/log/audit/audit” rien n’apparaît !

En effet, par défaut pas tous les accès SELinux refusés sont loggés. Il faut pour tous les voir activer la commande suivante :

semodule -DB

Ainsi de nouvelles erreurs apparaissent :

May  4 15:23:26 vdi-nx setroubleshoot: SELinux is preventing sudo from write access on the netlink_audit_socket Unknown. For complete SELinux messages run: sealert -l d33ac926-e867-4f11-b224-e3d0ad4d8388
May  4 15:23:26 vdi-nx python: SELinux is preventing sudo from write access on the netlink_audit_socket Unknown.#012#012*****  Plugin catchall (100. confidence) suggests   **************************#012#012If you believe that sudo should be allowed write access on the Unknown netlink_audit_socket by default.#012Then you should report this as a bug.#012You can generate a local policy module to allow this access.#012Do#012allow this access for now by executing:#012# ausearch -c 'sudo' --raw | audit2allow -M my-sudo#012# semodule -i my-sudo.pp#012


il faut recompiler le module SE en prenant en compte ces nouveaux refus :
<code>
ausearch -c 'sudo' --raw | audit2allow -M Module_httpd_sudo2

Maintenant le fichier Module_httpd_sudo2.te contenu de nouvelles directives :

module Module_httpd_sudo2 1.0;

require {
        type httpd_sys_script_t;
        class capability { setgid setuid sys_resource };
        class process setrlimit;
        class netlink_audit_socket { create write };
}

#============= httpd_sys_script_t ==============
#!!!! This avc is allowed in the current policy
allow httpd_sys_script_t self:capability { setgid setuid sys_resource };
#!!!! This avc is allowed in the current policy
allow httpd_sys_script_t self:netlink_audit_socket create;
allow httpd_sys_script_t self:netlink_audit_socket write;
#!!!! This avc is allowed in the current policy
allow httpd_sys_script_t self:process setrlimit;

Une fois le module rechargé, d’autres refus apparaissent. Refaire l’opération tant que des refus sont remontés.

Les remontées concernant “sudo” disparraissent. Mais d’autres d’apparaissent. Elles concernent les commandes :

  • sh
  • iptables
  • unix_chkpwd

Construire les modules SE pour chacun suivant le même processus que pour “sudo”. (c’est long, une quinzaine de passages est nécessaire).

Les règles obtenus sont :

Module_httpd_sudo2.te

module Module_httpd_sudo2 1.0;

require {
        type httpd_sys_script_t;
        type httpd_sys_rw_content_t;
        class capability { audit_write setgid setuid sys_resource };
        class process setrlimit;
        class file { execute execute_no_trans };
        class netlink_audit_socket { create nlmsg_relay read write };
}

#============= httpd_sys_script_t ==============

#!!!! This avc is allowed in the current policy
allow httpd_sys_script_t httpd_sys_rw_content_t:file { execute execute_no_trans };

#!!!! This avc is allowed in the current policy
allow httpd_sys_script_t self:capability { audit_write setgid setuid sys_resource };

#!!!! This avc is allowed in the current policy
allow httpd_sys_script_t self:netlink_audit_socket { create nlmsg_relay read write };

#!!!! This avc is allowed in the current policy
allow httpd_sys_script_t self:process setrlimit;

Module_httpd_sh.te :

 
module Module_httpd_sh 1.0;

require {
        type httpd_sys_script_t;
        type usermodehelper_t;
        type httpd_t;
        type sysctl_net_t;
        type setroubleshootd_t;
        type system_dbusd_t;
        class process { noatsecure rlimitinh siginh };
        class capability { dac_override dac_read_search net_admin };
        class dir search;
        class file { getattr open write };
}

#============= httpd_sys_script_t ==============

#!!!! This avc is allowed in the current policy
allow httpd_sys_script_t self:capability { dac_override dac_read_search net_admin };

#!!!! This avc is allowed in the current policy
allow httpd_sys_script_t sysctl_net_t:dir search;
allow httpd_sys_script_t sysctl_net_t:file getattr;

#!!!! This avc is allowed in the current policy
allow httpd_sys_script_t sysctl_net_t:file { open write };
#============= httpd_t ==============
#!!!! This avc is allowed in the current policy
allow httpd_t httpd_sys_script_t:process { noatsecure rlimitinh siginh };
#============= setroubleshootd_t ==============
#!!!! This avc is allowed in the current policy
allow setroubleshootd_t usermodehelper_t:file getattr;
#============= system_dbusd_t ==============
#!!!! This avc is allowed in the current policy
allow system_dbusd_t setroubleshootd_t:process { noatsecure rlimitinh siginh };

Module_httpd_iptables.te

module Module_httpd_iptables 1.0;

require {
        type proc_net_t;
        type iptables_var_run_t;
        type usermodehelper_t;
        type proc_t;
        type httpd_sys_script_t;
        class capability net_raw;
        class rawip_socket { create getopt setopt };
        class file { getattr lock open read };
        class filesystem getattr;
}

#============= httpd_sys_script_t ==============

#!!!! This avc is allowed in the current policy
allow httpd_sys_script_t iptables_var_run_t:file { lock open read };

#!!!! This avc is allowed in the current policy
allow httpd_sys_script_t proc_net_t:file getattr;

#!!!! This avc is allowed in the current policy
allow httpd_sys_script_t proc_t:filesystem getattr;

#!!!! This avc is allowed in the current policy
allow httpd_sys_script_t self:capability net_raw;
allow httpd_sys_script_t self:rawip_socket setopt;

#!!!! This avc is allowed in the current policy
allow httpd_sys_script_t self:rawip_socket { create getopt };

#!!!! This avc is allowed in the current policy
allow httpd_sys_script_t usermodehelper_t:file { open read };

Module_httpd_unix_chkpwd.te

module Module_httpd_unix_chkpwd 1.0;

require {
        type chkpwd_t;
        type sshd_t;
        class process { noatsecure rlimitinh siginh };
}

#============= sshd_t ==============
allow sshd_t chkpwd_t:process { noatsecure rlimitinh siginh };

Une fois tous ces modules SELinux chargés, les pages PHP peuvent executer un script bash en SUDO, script qui utilise la commande iptables

Enfin il faut désactiver dans l’audit les logs de type “dontaudit”

semodule -B
SE Linux

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *