DESCRIERE¶
Comanda unshare creează noi spații de nume
(așa cum se specifică în opțiunile liniei de
comandă descrise mai jos) și apoi execută
programul specificat. Dacă nu se indică
programul, atunci se execută "${SHELL}" (implicit:
/bin/sh).
În mod implicit, un nou spațiu de nume
persistă doar atât timp cât are procese membre. Un nou
spațiu de nume poate fi făcut persistent chiar și
atunci când nu are procese membre prin montarea „bind”
a fișierelor /proc/pid/ns/tip la o rută din
sistemul de fișiere. Un spațiu de nume care a fost
făcut persistent în acest mod poate fi introdus ulterior cu
nsenter(1) chiar și după ce programul se
termină (cu excepția spațiilor de nume PID, unde este
necesar un proces de init care rulează permanent). Odată ce un
spațiu de nume persistent nu mai este necesar, acesta poate fi scos
din persistență prin utilizarea umount(8) pentru a
elimina montarea „bind”. Pentru mai multe detalii,
consultați secțiunea EXEMPLE.
Deoarece unshare, util-linux versiunea 2.36
utilizează fișierele
/proc/[pid]/spațiu-nume/pid_pt_proces-copil și
/proc/[pid]/spațiu-nume/timp_pt_proces-copil pentru
spațiile de nume persistente PID și TIME. Această
modificare necesită nucleul Linux 4.17 sau o versiune mai
nouă.
Următoarele tipuri de spații de nume pot fi create
cu unshare:
mount namespace
Montarea și demontarea sistemelor de
fișiere nu va afecta restul sistemului, cu excepția sistemelor
de fișiere care sunt marcate în mod explicit ca fiind partajate
(cu
mount --make-shared; consultați
/proc/self/mountinfo
sau
findmnt -o+PROPAGATION pentru indicatoarele
shared). Pentru
mai multe detalii, consultați
mount_namespaces(7).
unshare, începând cu util-linux versiunea
2.27, stabilește automat propagarea la private într-un
nou spațiu de nume de montare pentru a se asigura că noul
spațiu de nume este într-adevăr nepartajat. Este
posibil să dezactivați această caracteristică cu
opțiunea --propagation unchanged. Rețineți
că private este valoarea implicită a nucleului.
UTS namespace
Stabilirea numelui de gazdă sau a numelui de
domeniu nu va afecta restul sistemului. Pentru mai multe detalii,
consultați
uts_namespaces(7).
IPC namespace
Procesul va avea un spațiu de nume independent
pentru cozile de mesaje POSIX, precum și pentru cozile de mesaje System
V, seturile de semafoare și segmentele de memorie partajată.
Pentru mai multe detalii, consultați
ipc_namespaces(7).
network namespace
Procesul va avea stive IPv4 și IPv6 independente,
tabele de direcționare IP, reguli de paravan de protecție,
arborii de directoare
/proc/net și
/sys/class/net,
socluri etc. Pentru mai multe detalii, consultați
network_namespaces(7).
PID namespace
Procesele-copii vor avea un set de corespondențe
PID-proces distincte de cele ale părintelui lor. Pentru mai multe
detalii, a se vedea
pid_namespaces(7).
cgroup namespace
Procesul va avea o vizualizare virtualizată a
/proc/self/cgroup, iar noile montări cgroup vor fi
înrădăcinate la rădăcina spațiului
de nume cgroup. Pentru mai multe detalii, consultați
cgroup_namespaces(7).
user namespace
Procesul va avea un set distinct de UID-uri, GID-uri
și capacități. Pentru mai multe detalii, a se vedea
user_namespaces(7).
time namespace
Procesul poate avea o viziune distinctă asupra
CLOCK_MONOTONIC și/sau
CLOCK_BOOTTIME, care poate fi
modificată cu ajutorul
/proc/self/timens_offsets. Pentru mai
multe detalii, a se vedea
time_namespaces(7).
OPȚIUNI¶
-i, --ipc[=fișier]
Creează un nou spațiu de nume IPC.
Dacă se specifică fișierul, atunci spațiul
de nume devine persistent prin crearea unei montări de
legătură la fișierul.
-m, --mount[=filșier]
Creează un nou spațiu de nume de montare.
Dacă se specifică fișier, spațiul de nume
devine persistent prin crearea unei montări de legătură
la fișier. Rețineți că fișier
trebuie să fie localizat pe o montare al cărei tip de propagare
nu este shared (în caz contrar, se produce o eroare).
Utilizați comanda findmnt -o+PROPAGATION atunci când nu
sunteți sigur de configurația curentă. Consultați
și exemplele de mai jos.
-n, --net[=fișier]
Creează un nou spațiu de nume de
rețea. Dacă se specifică fișierul, atunci
spațiul de nume devine persistent prin crearea unei montări de
legătură la fișierul.
-p, --pid[=fișier]
Creează un nou spațiu de nume PID.
Dacă se specifică
fișierul, atunci spațiul
de nume devine persistent prin crearea unei montări de
legătură la
fișierul. (Crearea unui spațiu
de nume PID persistent va eșua dacă nu este specificată
și opțiunea
--fork).
A se vedea, de asemenea, opțiunile --fork și
--mount-proc.
-u, --uts[=fișier]
Creează un nou spațiu de nume UTS.
Dacă se specifică fișierul, atunci spațiul
de nume devine persistent prin crearea unei montări de
legătură la fișierul.
-U, --user[=fișier]
Creează un nou spațiu de nume de
utilizator. Dacă se specifică fișierul, atunci
spațiul de nume devine persistent prin crearea unei montări de
legătură la fișierul.
-C, --cgroup[=fișier]
Creează un nou spațiu de nume cgroup.
Dacă se specifică fișierul, atunci spațiul
de nume devine persistent prin crearea unei montări de
legătură la fișierul.
-T, --time[=fișier]
Creează un nou spațiu de nume de timp.
Dacă este specificat fișier, spațiul de nume este
făcut persistent prin crearea unei montări de
legătură la fișier. Opțiunile
--monotonic și --boottime pot fi utilizate pentru a
specifica poziția corespunzătoare în spațiul de
nume de timp.
-f, --fork
Bifurcă programul specificat ca un
proces-copil al unshare, în loc să îl ruleze
direct. Acest lucru este util atunci când se creează un nou
spațiu de nume PID. Rețineți că, atunci
când unshare așteaptă procesul-copil,
ignoră SIGINT și SIGTERM și nu transmite
niciun semnal către procesul-copil. Este necesar să se
trimită semnale către procesul-copil.
--keep-caps
În cazul în care se oferă
opțiunea --user, se asigură că
capacitățile acordate în spațiul de nume al
utilizatorului sunt păstrate în procesul-copil.
--kill-child[=nume-semnal]
Când unshare se termină, se trimite
nume-semnal la procesul-copil bifurcat. În combinație cu
--pid, acest lucru permite o eliminare ușoară și
fiabilă a întregului arbore de procese de sub unshare.
Dacă nu este specificat, nume-semnal va fi SIGKILL.
Această opțiune implică --fork.
--mount-proc[=punct-montare]
Chiar înainte de a rula programul, montează
sistemul de fișiere proc la punct-montare (valoarea
implicită este /proc). Acest lucru este util atunci când
se creează un nou spațiu de nume PID. De asemenea,
implică crearea unui nou spațiu de nume de montare, deoarece,
în caz contrar, montarea /proc ar încurca programele
existente pe sistem. Noul sistem de fișiere proc este montat în
mod explicit ca fiind privat (cu MS_PRIVATE|MS_REC).
--mount-binfmt[=mountpoint]
Just before running the program, mount the binfmt_misc
filesystem at mountpoint (default is /proc/sys/fs/binfmt_misc). It also
implies creating a new mount namespace since the binfmt_misc mount would
otherwise mess up existing programs on the system. The new binfmt_misc
filesystem is explicitly mounted as private (with
MS_PRIVATE|MS_REC).
--map-user=uid|nume
Rulează programul numai după ce ID-ul de
utilizator efectiv curent a fost asociat cu uid. Dacă
această opțiune este specificată de mai multe ori, ultima
apariție are prioritate. Această opțiune implică
--user.
--map-users=uid-interior:uid-exterior:cantitate|auto|all
Rulează programul numai după ce blocul de
ID-uri de utilizator cu dimensiunea
cantitate care începe la
uid-exterior a fost cartografiat în blocul de ID-uri de
utilizator care începe la
uid-interior. Această
cartografiere este creată cu
newuidmap(1) dacă
unshare a fost rulat fără privilegii.. În cazul
în care intervalul de ID-uri de utilizator se suprapune cu
cartografierea specificată de
--map-user, atunci o
„gaură” va fi eliminată din cartografiere. Acest
lucru poate avea ca rezultat faptul că cel mai mare ID de utilizator
din cartografiere nu este cartografiat. Utilizați
--map-users de
mai multe ori pentru a cartografia mai mult de un bloc de ID-uri de
utilizator. Valoarea specială
auto va cartografia primul bloc de
ID-uri de utilizator deținut de utilizatorul efectiv din
/etc/subuid într-un bloc care începe cu ID-ul de
utilizator 0. Valoarea specială
all va crea o hartă
pasată către comandă pentru fiecare ID de utilizator
disponibil în spațiul de nume părinte. Această
opțiune implică
--user.
Înainte de util-linux versiunea 2.39, această
opțiune aștepta un argument separat prin virgulă de
forma uid-exterior,uid-interior,cantitate, dar acest format este acum
depreciat pentru coerență cu ordinea folosită în
/proc/[pid]/uid_map și opțiunea de montare
X-mount.idmap.
--map-group=gid|nume
Rulează programul numai după ce ID-ul de
grup efectiv curent a fost asociat cu gid. Dacă această
opțiune este specificată de mai multe ori, ultima
apariție are prioritate. Această opțiune implică
--setgroups=deny și --user.
--map-groups=gid-interior:gid-exterior:cantitate|auto|all
Rulează programul numai după ce blocul de
ID-uri de grup cu dimensiunea
cantitate care începe la
gid-exterior a fost cartografiat în blocul de ID-uri de grup
care începe la
gid-interior. Această cartografiere este
creată cu
newgidmap(1) dacă
unshare a fost rulat
fără privilegii. În cazul în care intervalul de
ID-uri de grup se suprapune cu cartografierea specificată de
--map-group, atunci o „gaură” va fi
eliminată din cartografiere. Acest lucru poate avea ca rezultat faptul
că cel mai mare ID de grup din cartografiere nu este cartografiat.
Utilizați
--map-groups de mai multe ori pentru a cartografia mai
mult de un bloc de ID-uri de grup. Valoarea specială
auto va
cartografia primul bloc de ID-uri de utilizator deținut de utilizatorul
efectiv din
/etc/subgid într-un bloc care începe cu ID-ul
de grup 0. Valoarea specială
all va crea o hartă
pasată către comandă pentru fiecare ID de grup disponibil
în spațiul de nume părinte. Această opțiune
implică
--user.
Înainte de util-linux versiunea 2.39, această
opțiune aștepta un argument separat prin virgulă de
forma gid-exterior,gid-interior,cantitate, dar acest format este acum
depreciat pentru coerență cu ordinea folosită în
/proc/[pid]/gid_map și opțiunea de montare
X-mount.idmap.
--map-auto
Cartografiază (asociază) primul bloc de
ID-uri de utilizator deținut de utilizatorul efectiv din
/etc/subuid într-un bloc care începe cu ID-ul de
utilizator 0. În același mod, se cartografiază, de
asemenea, primul bloc de ID-uri de grup deținute de grupul efectiv din
/etc/subgid într-un bloc care începe cu ID-ul de grup 0.
Această opțiune este menită să gestioneze cazul
obișnuit în care primul bloc de ID-uri de utilizator și
de grup subordonate poate cartografia întregul spațiu de ID-uri
de utilizator și de grup. Această opțiune este
echivalentă cu specificarea --map-users=auto și
--map-groups=auto.
-r, --map-root-user
Rulează programul numai după ce ID-urile de
utilizator și de grup efective actuale au fost puse în
corespondență cu UID și GID de superutilizator în
spațiul de nume de utilizator nou creat. Acest lucru face
posibilă obținerea în mod convenabil a
capacităților necesare pentru a gestiona diverse aspecte ale
spațiilor de nume nou create (cum ar fi configurarea
interfețelor în spațiul de nume de rețea sau
montarea sistemelor de fișiere în spațiul de nume de
montare), chiar și atunci când se execută
fără privilegii. Fiind o simplă caracteristică de
comoditate, nu acceptă cazuri de utilizare mai sofisticate, cum ar fi
cartografierea (asocierea) mai multor intervale de UID și GID.
Această opțiune implică --setgroups=deny și
--user. Această opțiune este echivalentă cu
--map-user=0 --map-group=0.
-c, --map-current-user
Rulează programul numai după ce ID-urile de
utilizator și de grup efective actuale au fost asociate cu
aceleași UID și GID în spațiul de nume de
utilizator nou creat. Această opțiune implică
--setgroups=deny și --user. Această opțiune
este echivalentă cu --map-user=$(id -ru) --map-group=$(id
-rg).
--propagation
private|shared|slave|unchanged
Activează în mod recurent fanionul de
propagare a montării în noul spațiu de nume de montare.
În mod implicit, propagarea este stabilită la private.
Este posibil să se dezactiveze această caracteristică cu
ajutorul argumentului unchanged. Opțiunea este ignorată
în mod silențios atunci când spațiul de nume de
montare (--mount) nu este solicitat.
--setgroups allow|deny
Permite sau refuză apelul de sistem
setgroups(2) într-un spațiu de nume de utilizator.
Pentru a putea apela setgroups(2), procesul care face
apelul trebuie să aibă cel puțin CAP_SETGID.
Dar, începând cu Linux 3.19, se aplică o
restricție suplimentară: nucleul oferă permisiunea de a
apela setgroups(2) numai după ce harta GID
(/proc/pid*/gid_map*) a fost stabilită. Harta GID poate
fi scrisă de root atunci când setgroups(2) este
activată (adică allow, valoarea implicită), iar
harta GID devine inscriptibilă de către procesele
neprivilegiate atunci când setgroups(2) este
dezactivată permanent (cu deny).
-R, --root=dir
rulează comanda cu directorul
rădăcină stabilit la dir.
-w, --wd=dir
schimbă directorul de lucru în
dir.
-S, --setuid uid
Stabilește ID-ul utilizatorului care va fi
utilizat în spațiul de nume introdus.
-G, --setgid gid
Stabilește ID-ul grupului care va fi utilizat
în spațiul de nume introdus și renunță la
grupurile suplimentare.
-l, --load-interp=string
Load binfmt_misc definition in the namespace (implies
--mount-binfmt). The
string argument is
:name:type:offset:magic:mask:interpreter:flags. For
more details about new binary type registration see
<
https://www.kernel.org/doc/Documentation/admin-guide/binfmt-misc.rst>.
To manage the F flag in
flags with
--root
parameter, binfmt_misc is mounted twice, once before the chroot to load the
interpreter from the caller filesystem and once after to make it available
from the chroot userspace.
--monotonic decalaj
Stabilește decalajul CLOCK_MONOTONIC care
va fi utilizat în spațiul de nume al timpului introdus.
Această opțiune necesită ne-partajarea unui spațiu
de nume de timp cu --time.
--boottime decalaj
Stabilește decalajul CLOCK_BOOTTIME care va
fi utilizat în spațiul de nume al timpului introdus.
Această opțiune necesită ne-partajarea unui spațiu
de nume de timp cu --time.
-h, --help
Afișează acest mesaj de ajutor și
iese.
-V, --version
Afișează informațiile despre
versiune și iese.
EXEMPLE¶
Următoarea comandă creează un spațiu
de nume PID, folosind --fork pentru a se asigura că
execuția comenzii este realizată într-un proces-copil
care (fiind primul proces din spațiul de nume) are PID 1.
Opțiunea --mount-proc asigură crearea simultană
a unui nou spațiu de nume de montare și montarea unui nou
sistem de fișiere proc(5) care conține
informații corespunzătoare noului spațiu de nume PID.
Când comanda readlink(1) se termină, noile
spații de nume sunt automat demontate.
# unshare --fork --pid --mount-proc readlink /proc/self
1
În calitate de utilizator neprivilegiat, creați un
nou spațiu de nume de utilizator în care acreditările
utilizatorului sunt puse în corespondență cu ID-urile
rădăcină din interiorul spațiului de nume:
$ id -u; id -g
1000
1000
$ unshare --user --map-root-user \
sh -c 'whoami; cat /proc/self/uid_map /proc/self/gid_map'
root
0 1000 1
0 1000 1
În calitate de utilizator neprivilegiat, creați un
spațiu de nume de utilizator în care primele 65536 ID-uri sunt
toate alocate, iar acreditările utilizatorului sunt alocate ID-urilor
rădăcină din interiorul spațiului de nume.
Corespondența este determinată de ID-urile subordonate
atribuite în subuid(5) și subgid(5).
Demonstrați această corespondență prin crearea
unui fișier cu ID-ul de utilizator 1 și ID-ul de grup 1. Din
motive de concizie, sunt prezentate doar corespondențele ID-ului
utilizatorului:
$ id -u
1000
$ cat /etc/subuid
1000:100000:65536
$ unshare --user --map-auto --map-root-user
# id -u
0
# cat /proc/self/uid_map
0 1000 1
1 100000 65535
# touch file; chown 1:1 file
# ls -ln --time-style=+ file
-rw-r--r-- 1 1 1 0 file
# exit
$ ls -ln --time-style=+ file
-rw-r--r-- 1 100000 100000 0 file
Prima dintre următoarele comenzi creează un nou
spațiu de nume UTS persistent și modifică numele de
gazdă așa cum este văzut în acel spațiu
de nume. Apoi se intră în spațiul de nume cu
nsenter(1) pentru a afișa numele de gazdă modificat;
acest pas demonstrează că spațiul de nume UTS
continuă să existe chiar dacă spațiul de nume nu
mai are procese membre după terminarea comenzii unshare.
Spațiul de nume este apoi distrus prin eliminarea montării
„bind”.
# touch /root/uts-ns
# unshare --uts=/root/uts-ns hostname FOO
# nsenter --uts=/root/uts-ns hostname
FOO
# umount /root/uts-ns
Următoarele comenzi stabilesc un spațiu de nume de
montare persistentă la care se face referire prin montarea
„bind” /root/namespaces/mnt. Pentru a se asigura de
succesul creării acestei montări „bind”,
directorul părinte (/root/namespaces) este transformat
într-o montare „bind” al cărei tip de propagare
nu este shared.
# mount --bind /root/namespaces /root/namespaces
# mount --make-private /root/namespaces
# touch /root/namespaces/mnt
# unshare --mount=/root/namespaces/mnt
Următoarele comenzi demonstrează utilizarea
opțiunii --kill-child atunci când se creează un
spațiu de nume PID, pentru a se asigura că atunci când
unshare este omorât, toate procesele din cadrul
spațiului de nume PID sunt omorâte.
# set +m # Nu afișează mesajele de stare a lucrării
# unshare --pid --fork --mount-proc --kill-child -- \
bash --norc -c '(sleep 555 &) && (ps a &) && sleep 999' &
[1] 53456
# PID TTY STAT TIME COMMAND
1 pts/3 S+ 0:00 sleep 999
3 pts/3 S+ 0:00 sleep 555
5 pts/3 R+ 0:00 ps a
# ps h -o 'comm' $! # Afișează că munca de fond este nepartajată unshare(1)
unshare
# kill $! # Omoară unshare(1)
# pidof sleep
Comanda pidof(1) nu afișează niciun rezultat,
deoarece procesele sleep au fost omorâte. Mai exact, atunci
când procesul sleep care are PID 1 în spațiul de
nume (adică procesul de init al spațiului de nume) a fost
omorât, această acțiune a dus la omorârea
tuturor celorlalte procese din spațiul de nume. În schimb, o
serie similară de comenzi în care nu se utilizează
opțiunea --kill-child arată că, atunci
când unshare se termină, procesele din spațiul
de nume cu PID nu sunt omorâte:
# unshare --pid --fork --mount-proc -- \
bash --norc -c '(sleep 555 &) && (ps a &) && sleep 999' &
[1] 53479
# PID TTY STAT TIME COMMAND
1 pts/3 S+ 0:00 sleep 999
3 pts/3 S+ 0:00 sleep 555
5 pts/3 R+ 0:00 ps a
# kill $!
# pidof sleep
53482 53480
Următorul exemplu demonstrează crearea unui
spațiu de nume de timp în care ceasul boottime (ora de
pornire) este fixat la un punct din trecut, cu câțiva ani
în urmă:
# uptime -p # Afișează timpul de funcționare în spațiul de nume al timpului inițial
up 21 hours, 30 minutes
# unshare --time --fork --boottime 300000000 uptime -p
up 9 years, 28 weeks, 1 day, 2 hours, 50 minutes
The following example execute a chroot into the directory
/chroot/powerpc/jessie and install the interpreter /bin/qemu-ppc-static to
execute the powerpc binaries.
$ unshare --map-root-user --fork --pid --load-interp=":qemu-ppc:M::\\x7fELF\x01\\x02\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x14:\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xfe\\xff\\xff:/bin/qemu-ppc-static:OCF" --root=/chroot/powerpc/jessie /bin/bash -l
The load-interp parameter can be read as
following
qemu-ppc
is the name of the new file created below
/proc/sys/fs/binfmt_misc to register the
interpreter
M
defines the interpreter for a given type of magic
number
\\x7fELF\x01\\x02\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x1
is the magic number to recognize the file to interpret
(in this case, the ELF header for PPC32)
\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xfe\\xff\\xff
the mask to apply to the magic number
/bin/qemu-ppc-static
the interpreter to use with the file
OCF
the file is open by the kernel with credential and
security tokens of the file itself and loaded as soon as we register it.