Questo articolo si basa sui miei precedenti articoli sugli spazi dei nomi, sui 7 spazi dei nomi Linux più utilizzati e sulla mia serie sulla creazione manuale di un contenitore Linux utilizzando gli spazi dei nomi, utilizzando lo spazio dei nomi di montaggio e utilizzando lo spazio dei nomi PID. Questo articolo illustra lo spazio dei nomi UTS e la sua relazione con i contenitori.
L'osservatore occasionale spesso fraintende lo spazio dei nomi Unix Timesharing System (UTS), soprattutto perché il suo nome non corrisponde più al suo scopo. Nonostante il nome, lo spazio dei nomi UTS controlla effettivamente il nome host e il dominio NIS. Ecco come la pagina man descrive lo spazio dei nomi UTS:
Questi identificatori vengono impostati utilizzando sethostname(2)
e setdomainname(2)
e possono essere recuperati utilizzando uname(2)
, gethostname(2)
e getdomainname(2)
. Le modifiche apportate a questi identificatori sono visibili a tutti gli altri processi nello stesso spazio dei nomi UTS, ma non sono visibili ai processi in altri spazi dei nomi UTS.
Ciò significa che alcuni strumenti moderni (systemd e altri) potrebbero non causare le modifiche previste.
Come puoi immaginare, potrebbero esserci diversi casi d'uso in cui potresti volere che i processi abbiano nomi host diversi. I server Web, ad esempio, tendono a generare un avviso se il nome host non corrisponde al certificato SSL che stanno servendo. D'altra parte, alcuni processi potrebbero associare il nome host a un processo di rete. Un nome host errato può causare connessioni non riuscite o negate o una miriade di altri problemi.
Detto questo, entriamo in alcuni esempi.
Esplora lo spazio dei nomi UTS
Puoi richiamare lo spazio dei nomi UTS con:
$ unshare --uts /bin/bash
Tuttavia, potresti notare che una volta che sei nel nuovo spazio dei nomi, usando hostnamectl set-hostname
non cambia il nome host nel nuovo spazio dei nomi.
# unshare --uts
# hostname
bastion.stratus.lab
# hostnamectl set-hostname tux
# hostname
bastion.stratus.lab
Se apri una nuova shell, però, il nome host è effettivamente cambiato:
[user@host ~]$ ssh root@bastion
Last login: Tue Dec 7 08:17:48 2021 from 192.168.99.198
[root@tux ~]# hostname
tux
Perchè è questo? Systemd non esegue il sethostname
chiamata di sistema. Invece, systemd completa l'attività connettendosi a un socket. Poiché il socket è associato al vecchio spazio dei nomi, il vecchio nome host dello spazio dei nomi viene modificato ma non il nuovo spazio dei nomi.
Utilizzo degli spazi dei nomi radice
Nel mio articolo sullo spazio dei nomi di montaggio, scrivo:
Ora che sei all'interno del nuovo spazio dei nomi, potresti non aspettarti di vedere nessuno dei punti di montaggio originali dall'host. Tuttavia, questo non è il caso. La ragione di ciò è che per impostazione predefinita systemd condivide ricorsivamente i punti di montaggio con tutti i nuovi spazi dei nomi.
A quanto pare, systemd ricava molte delle sue informazioni da /run
, che è condiviso nello spazio dei nomi che ho creato qui.
Nell'articolo dello spazio dei nomi di montaggio, monto tmpfs
nel nuovo spazio dei nomi su una directory che non voglio condividere con il vecchio spazio dei nomi.
Posso disabilitare la maggior parte delle chiamate systemd montando il nuovo spazio dei nomi con le seguenti opzioni:
$ unshare --mount --uts /bin/bash
Quindi rimonta /run
:
$ mount -t tmpfs tmpfs /run
L'intero processo si presenta così:
# unshare --fork --mount --uts /bin/bash
# mount -t tmpfs tmpfs /run
# hostnamectl set-hostname bastion.stratus.lab
System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down
# hostname tux
# hostname
tux
Posso confermarlo aprendo una nuova shell nella scatola:
[user@host ~]$ ssh root@bastion
Last login: Tue Dec 7 08:33:04 2021 from 192.168.99.198
[root@bastion ~]# hostname
bastion.stratus.lab
Posso trovare lo spazio dei nomi appropriato usando lsns
comando:
[root@bastion ~]# lsns |grep uts
4026531838 uts 133 1 root /usr/lib/systemd/systemd --switched-root --system --deserialize 31
4026532250 uts 1 645 root /usr/lib/systemd/systemd-udevd
4026532405 uts 1 743 root /usr/lib/systemd/systemd-logind
4026532479 mnt 2 11507 root unshare --fork --mount --uts /bin/bash
4026532480 uts 2 11507 root unshare --fork --mount --uts /bin/bash
Posso quindi inserire lo spazio dei nomi con nsenter
comando:
[root@bastion ~]# nsenter -t 11507 -a
[root@tux /]#
Utilizzo di uno spazio dei nomi utente
Nel mio articolo sullo spazio dei nomi utente, menziono alcune considerazioni aggiuntive durante la creazione di spazi dei nomi come utente non privilegiato:
Quando crei un nuovo spazio dei nomi utente, il tuo attuale utente verrà mappato all'utente nessuno . Questo perché, per impostazione predefinita, non è in corso alcuna mappatura dell'ID utente. Quando non viene definita alcuna mappatura, lo spazio dei nomi utilizza semplicemente le regole del tuo sistema per determinare come gestire un utente non definito.
Fare riferimento a quell'articolo per ulteriori informazioni sulla mappatura degli utenti. In questo caso, voglio avere il root utente mappato automaticamente. In questo modo, ho "root" nel nuovo spazio dei nomi. (Anche in questo caso, consulta l'articolo sullo spazio dei nomi utente per una discussione su spazi dei nomi e autorizzazioni).
Se metto in pratica le mie lezioni combinate su un host CentOS Stream 9, osservo:
ocp@bastion ~ $ unshare --map-root-user --user --mount --uts --fork /bin/bash
root@bastion ~ $ hostnamectl set-hostname tux
Could not set static hostname: Interactive authentication required.
Ciò è dovuto al modo in cui polkit
è configurato sulla famiglia di distribuzioni RHEL. Altre distribuzioni non generano necessariamente questo errore. Arch Linux (senza polkit
speciali configurazione), ad esempio, consente comunque al contenitore di modificare il nome host. Pertanto, indipendentemente dalla tua distribuzione, è comunque una buona pratica di sicurezza rimontare /run
.
È importante notare che l'output di lsns
potrebbe essere più facile da leggere usando --fork
durante la creazione di spazi dei nomi.
Ecco come appare senza il --fork
bandiera:
[root@bastion ~]# lsns |grep uts
4026531838 uts 135 1 root /usr/lib/systemd/systemd --switched-root --system --deserialize 31
4026532250 uts 1 645 root /usr/lib/systemd/systemd-udevd
4026532405 uts 1 743 root /usr/lib/systemd/systemd-logind
4026532414 uts 1 11962 ocp /bin/bash
E con il --fork
bandiera:
[root@bastion ~]# lsns |grep uts
4026531838 uts 134 1 root /usr/lib/systemd/systemd --switched-root --system --deserialize 31
4026532250 uts 1 645 root /usr/lib/systemd/systemd-udevd
4026532405 uts 1 743 root /usr/lib/systemd/systemd-logind
4026532412 user 2 11939 ocp unshare --map-root-user --user --mount --uts --fork /bin/bash
Mentre --fork
non è strettamente necessario in questo scenario, può essere utile o addirittura necessario se è richiesto un nuovo spazio dei nomi PID (consultare l'articolo sul mio spazio dei nomi PID per ulteriori informazioni).
Conclusione
Lo spazio dei nomi UTS non è lo spazio dei nomi Linux più complicato. È, tuttavia, abbastanza utile, soprattutto nel contesto dei contenitori.
Per ottenere il massimo dallo spazio dei nomi UTS, combinalo almeno con lo spazio dei nomi di montaggio quando utilizzi lo spazio dei nomi root e gli spazi dei nomi di montaggio e utente quando si genera da un utente senza privilegi.
[ Scarica il cheat sheet di Linux intermedio per avere i comandi chiave a portata di mano. ]
Nel prossimo articolo parlerò dello spazio dei nomi di rete e di come utilizzarlo per consentire agli spazi dei nomi di avere il proprio IP e spazio delle porte.