Archivi giornalieri: 22 Dicembre 2022

Samba, SSSD e SELinux su Red Hat

Di recente ho dovuto installare un server Red Hat Enterprise Linux 7, si tratta di una macchina che ospita un database Oracle, ma mi è stato chiesto di attivare anche alcune condivisioni tramite samba. Ho fatto tutti i passaggi consueti per l’installazione e configurazione, ma non funzionava nulla. Dopo due giorni di lavoro ho sistemato la macchina, superando vari ostacoli. Elenco qui i problemi più grossi e le relative soluzioni.

Autenticazione

La macchina è stata messa in dominio Windows per poter accettare connessioni dai computer aziendali. Per farlo è stato installato il server SSSD che permette l’integrazione con il dominio Windows e la mappatura di utenze e gruppi di dominio. Samba è stato configurato copiando il tutto da un’altra macchina, SunOS, che ospitava precedentemente le cartelle di rete. Quel samba usava Winbind per l’integrazione con il dominio, sicché anche qui è stato usato winbind.
Nelle utenze sul dominio Windows non sono presenti userid e groupid come su Linux, sicché tutti i programmi di interfaccia con il dominio fanno una mappatura che parte dal SID dell’utenza Windows e arrivare a userid e groupid di Linux. Ovviamente per un determinato utente la mappatatura deve essere sempre eguale, sicché questa associazione viene memorizzata in un file. Il file è diverso se si usa SSSD o se si usa Winbind. Ma la cosa che non sapevo è che anche l’algoritmo di mappatura è diverso, quindi quando samba riceve una richiesta di connessione, effettua l’autenticazione con Kerberos e poi mappa il SID dell’utenza Windows su una utenza locale, che però qui non veniva trovata. L’errore era:

[2022/12/22 10:37:04.668145, 1] ../../source3/auth/token_util.c:561(add_local_groups)
SID S-1-5-21-990198401-320236572-313593124-1040 -> getpwuid(11040) failed

in effetti l’utenza in questione aveva un uid diverso: 1092201040 anziché 11040

[linux]# id 'azienda\nome.utente'
uid=1092201040(nome.utente@azienda.dom) gid=1092200513(domain users@azienda.dom) gruppi=1092200513(domain users@azienda.dom)

mentre sul vecchio server era proprio 11040:

[SunOS] # id 'azienda\nome.utente'
uid=11040(AZIENDA\nome.utente) gid=10513(AZIENDA\domain users)

Per sistemare questa cosa ci sono due diverse possibilità. La più diffusa, ma secondo me peggiore, è di fare usare winbind anche a NSS, cambiando le tre righe nel file /etc/nssswitch.conf da

passwd: files sss
group: files sss
shadow: files sss

a

passwd: files winbind
group: files winbind
shadow: files winbind

la seconda è di cambiare l’algoritmo usato da SSSD per generare userid e groupid. Questo si fa nel file /etc/sssd/sssd.conf, dove, per il dominio in questione, ci sarà scritto che il backend è proprio il dominio tramite la configurazione id_provider=ad. Questo vuol dire che si possono usare anche le configurazioni di sssd-ad come quella che ci interessa: ldap_idmap_autorid_compat. Il valore predefinito è false, ma se viene aggiunta al file di configurazione e impostata a true, risolve il problema.

Una volta fatto questo, l’autenticazione dovrebbe cominciare a funzionare.

Accesso al file system

Quando si accede tramite samba, l’utenza sulla quale si viene mappati deve avere l’accesso alle directory e ai file da utilizzare. Se, ad esempio, la condivisione utilizza la directory /s6/work1/samba, allora sarà necessario che l’utente possa arrivarci. Per farlo è necessario che la directory e quelle padre, cioè /s6, /s6/work1 e /s6/work1/samba abbiano tutte i bit “r” e “x” accesi, cioè che siano leggibili (“r”) e che ci si possa spostare in quella directory (“x”).

Una volta fatto questo, si ottiene ancora l’errore:

[2022/12/22 12:23:30.517028, 0] ../../source3/smbd/service.c:784(make_connection_snum)
make_connection_snum: canonicalize_connect_path failed for service CARTELLA, path /s6/work1/samba

Questo perché è attivo SELinux. Quando samba lavora su un sistema con SELinux è necessario fare alcune operazioni in più:

indicare che la directory in questione deve essere accessibile a samba per una condivisione. Questo si fa con la policy samba_share_t. Il comando da usare per fare una prova è;

[linux]# chcon --recursive --type samba_share_t /s6/work1/samba

mentre quelli per rendere il tutto permanente sono;

[linux]# semanage fcontext --add --type samba_share_t "/s6/work1/samba(/.*)?"
[linux]# restorecon -R -v /s6/work1/samba/

Per verificare che il tutto abbia funzionato, date il comando:

[linux]# ls -ldZ /s6/work1/samba/ /s6/work1/ /s6/
drwxr-xr-x. root root unconfined_u:object_r:default_t:s0 /s6/
drwxr-xr-x. root root unconfined_u:object_r:default_t:s0 /s6/work1/
drwxrwxrwx+ root root unconfined_u:object_r:samba_share_t:s0 /s6/work1/samba/

A questo punto samba potrà accedere a quella directory e ai file ivi contenuti senza che SELinux la blocchi. Ma, se cercate di collegarvi ottenete ancora lo stesso errore:

[2022/12/22 14:05:14.602571, 0] ../../source3/smbd/service.c:784(make_connection_snum)
make_connection_snum: canonicalize_connect_path failed for service CARTELLA, path /s6/work1/samba

Ora però il problema è un altro, sempre legato a SELinux: ci sono delle attività che sono completamente inibite in samba a meno di attivare tramite la configurazione di SELinux. Perché sia possibile condividere una qualsiasi directory in lettura va usato il parametro samba_export_all_ro, perché sia possibile farlo anche in scrittura va usato il parametro samba_export_all_rw. I due si attivano in questo modo:

[linux]# setsebool -P samba_export_all_ro=1 samba_export_all_rw=1
[linux]# getsebool -a| grep samba
samba_create_home_dirs --> off
samba_domain_controller --> off
samba_enable_home_dirs --> off
samba_export_all_ro --> on
samba_export_all_rw --> on
samba_load_libgfapi --> off
samba_portmapper --> off
samba_run_unconfined --> off
samba_share_fusefs --> off
samba_share_nfs --> off
sanlock_use_samba --> off
tmpreaper_use_samba --> off
use_samba_home_dirs --> off
virt_use_samba --> off
[linux]# systemctl restart smb nmb winbind

A questo punto tutto dovrebbe funzionare.