I certificati possono trovarsi nella directory corretta con un modo leggibile e la proprietà di root, e il servizio può comunque segnalare che non riesce ad aprire il file. Su un sistema SELinux quella combinazione indica un meccanismo preciso e non i permessi. L’etichetta ha viaggiato con il file, perché una rinomina non crea un nuovo oggetto. L’inode ha conservato il contesto di sicurezza che aveva sul vecchio percorso, e la policy del nuovo percorso non ha mai avuto l’occasione di assegnare il proprio.

Cosa fa realmente una rinomina a un’etichetta

Un file porta il proprio contesto SELinux come dati di attributo collegati all’inode. Una rinomina all’interno di un solo filesystem cambia la voce di directory e nient’altro, il che è rapido e atomico, ed è il motivo per cui il contesto sopravvive allo spostamento. Nessuna policy viene interrogata, nessun valore predefinito viene applicato e nessun avviso viene stampato.

La copia si comporta diversamente. Una copia crea un nuovo inode nella directory di destinazione, e la policy assegna un contesto in base al tipo di quella directory, quindi un certificato copiato di solito finisce con l’etichetta corretta mentre uno spostato resta sbagliato. Proprio questa unica differenza spiega la maggior parte della confusione in questa classe di ticket.

Gli spostamenti tra filesystem ricadono nella semantica della copia, quindi lo stesso comando può comportarsi diversamente su due macchine a seconda che /etc viva su un volume proprio. Verificatelo prima di concludere che lo strumento non sia affidabile. Uno sguardo alla tabella dei mount vi dice quale tipo di spostamento avete eseguito.

Leggete l’etichetta attuale rispetto a quella attesa

Tre comandi di sola lettura rispondono alla domanda senza cambiare nulla. Il primo mostra cosa ha ora il file, il secondo riferisce cosa la policy si aspetta per quel percorso esatto, e il terzo elenca ogni file sotto la directory la cui etichetta differisce.

ls -lZ /etc/openvpn/client/office-ca.crt
matchpathcon /etc/openvpn/client/office-ca.crt
restorecon -Rn -v /etc/openvpn/client

È l’esecuzione a secco quella di cui fidarsi, perché nomina ogni file il cui contesto si discosta dalla policy e lascia comunque il sistema intatto. Se il certificato compare in quell’elenco, avete trovato la discrepanza tra ciò che il percorso significa e ciò che il file afferma. Se non compare, l’etichetta è già quella che la policy vuole e il vostro tempo appartiene altrove.

Correlate poi la differenza con un rifiuto reale. Una discordanza è prova di un’etichetta errata, non la prova che il servizio abbia fallito per causa sua, e una correzione applicata senza un rifiuto corrispondente nel registro è una congettura con passaggi extra.

Ripristinate la mappatura invece di inventare un’eccezione

Per una posizione standard la policy mappa già il percorso, quindi restorecon la applica e il lavoro è fatto. Mantenete l’ambito sulla directory che state riparando; rietichettare l’intero filesystem è lento, invasivo e seppellisce l’errore originale sotto un cambiamento molto grande.

Per una directory personalizzata l’ordine conta, e invertirlo produce un comando che segnala successo senza cambiare nulla. La mappatura appartiene alla policy, la rietichettatura appartiene alla fine, e l’esecuzione a secco appartiene prima di entrambe. Saltare quest’ultima parte è il modo in cui un percorso che non è mai stato sbagliato viene rietichettato comunque.

semanage fcontext -a -t openvpn_etc_t '/etc/openvpn/custom(/.*)?'
restorecon -Rv /etc/openvpn/custom

restorecon applica una mappatura; non può inventarne una. Se nessuna regola descrive il percorso, non c’è nulla da ripristinare, ed è per questo che la mappatura persistente deve esistere prima della rietichettatura. Annotate quale configurazione possiede quella mappatura, perché altrimenti uno spostamento successivo, un aggiornamento di pacchetto o una rietichettatura ricreano il guasto e la persona successiva riparte da zero.

Perché chcon non è la soluzione

chcon scrive un contesto direttamente sul file. Ha effetto immediato ed è l’opzione meno durevole disponibile, perché una rietichettatura del filesystem riapplica la policy e scarta le modifiche manuali senza chiedere. Il file sembra riparato e la riparazione ha una data di scadenza che nessuno ha scritto. Quello che volete invece è una regola che descriva il percorso, così che ogni file che vi arriva riceva automaticamente lo stesso trattamento.

Peggio, insegna la lezione sbagliata: la mappatura sottostante manca ancora, quindi il guasto ritorna settimane dopo senza un innesco evidente e senza memoria del raggiro. Usate chcon solo come esperimento temporaneo per confermare un’ipotesi, poi sostituitelo con una mappatura che sopravviva alla rietichettatura successiva, e verificate che la sostituzione sia davvero in posizione.

Quando l’etichetta è corretta e l’accesso fallisce comunque

Cominciate dalle directory superiori. Il permesso di attraversamento viene verificato su ogni componente del percorso, quindi un certificato etichettato correttamente dentro una directory in cui il servizio non può entrare resta illeggibile. Sia SELinux sia il permesso ordinario devono consentire ogni passo, e correggere l’uno non corregge l’altro.

Poi verificate l’identità del processo e la sandbox del servizio stesso. Un’unità con una sandbox restrittiva può negare l’accesso a un file che la policy permetterebbe volentieri, e dalla riga di registro le due cause sembrano identiche. Confermate quale processo sta realmente chiedendo, non quale supponete stia chiedendo.

Ricordate che le regole dontaudit possono sopprimere i messaggi di rifiuto, quindi un registro di audit vuoto è una prova debole e non una dimostrazione. Se la policy sembra corretta e l’accesso fallisce comunque, indagate prima di generare un modulo di autorizzazione ampio, e non disabilitate SELinux per far sparire il sintomo. Entrambe le scorciatoie producono un sistema che sembra funzionare e una postura di sicurezza che nessuno sa descrivere. Un’indagine breve è meglio di entrambe.

Articoli correlati