Nu suprapuneți hardeningul systemd peste coborârea user din OpenVPN
Două rețete cu privilegii minime împreună nu fac una mai strictă. Alegeți cine face schimbarea de identitate, apoi cartografiați autoritatea pe tot ciclul de viață.
Două rețete cu privilegii minime lipite împreună nu produc o implementare mai strictă. Un model lasă demonul să pornească cu privilegii și să coboare la un cont fără privilegii după inițializare; celălalt lasă managerul de servicii să îl lanseze sub o identitate restricționată încă de la prima instrucțiune. Fiecare funcționează singur, iar combinația produce adesea un serviciu care nu poate face curat niciuna dintre cele două sarcini. Restul parcurge decizia în ordine.
Două modele, un singur proprietar al comutării
Primul model aparține demonului. Opțiunile OpenVPN din versiunea comunitate user și group schimbă identitatea după ce tunelul și cheile sunt configurate, iar persist-key împreună cu persist-tun păstrează acele resurse utilizabile după aceea.
Al doilea model aparține managerului de servicii. O setare systemd User= sau Group= decide identitatea sub care pornește procesul, iar directivele de capabilități decid ce poate păstra. Alegerea între modele este o chestiune de ambalare înainte de a fi o chestiune de securitate, iar întreținătorul pachetului a răspuns deja. Sarcina dumneavoastră este să găsiți acel răspuns, nu să inventați o a treia opțiune.
Ambele sunt legitime. Greșeala este să le tratați ca straturi ale unui singur proiect, pentru că al doilea model poate face din schimbarea de identitate a primului o operație pe care procesul nu mai are voie să o execute.
Decideți unde se schimbă identitatea
Dacă unitatea pornește deja ca un cont dedicat, adăugarea unei instrucțiuni a demonului de a deveni alt cont cere o tranziție setuid pe care un serviciu întărit nu ar fi trebuit să o facă niciodată. Defecțiunea apare ca eroare de permisiune la pornire, nu ca mesaj clar de politică. Se citește ca o capabilitate lipsă, ceea ce împinge oamenii spre un set de limite mai larg în loc de întrebarea identității.
Citiți ce livrează de fapt pachetul instalat înainte de a edita ceva, inclusiv directorul lui drop-in. Unele unități omit intenționat coborârea proprie a demonului pentru că managerul se ocupă deja de ea, iar altele se bazează pe acele opțiuni pentru comutarea de după inițializare. Eliminarea oricăreia dintre ele fără să știți ce model ați moștenit este modul în care un serviciu funcțional nu mai pornește.
Scrieți modelul ales într-o singură linie: deținut de manager sau deținut de demon. Fiecare directivă ulterioară trebuie să fie consecventă cu acea propoziție, iar o unitate mixtă trebuie tratată ca defect, nu ca un compromis.
Capabilitățile sunt limite, nu acordări
Un set de limite de capabilități spune ce poate păstra un proces cel mult. Este un plafon, iar listarea unei capabilități acolo nu acordă nimic în sine, de aceea o unitate cu un set de limite generos poate totuși să nu reușească să creeze un tunel.
Ceea ce pune de fapt o capabilitate în setul ambiental al unui serviciu este AmbientCapabilities=. referința de execuție systemd documentează cele două directive separat, iar această distincție explică cea mai mare parte a sfaturilor confuze despre capabilități de pe internet.
Adăugați o capabilitate doar după ce operația care eșuează a identificat-o. Un set de limite mai larg ascunde cauza reală și lasă serviciul mai privilegiat decât a intenționat proiectul. Face și unitatea mai greu de revizuit, pentru că plafonul nu mai descrie munca. Eliminați capabilitatea suplimentară după ce defectul real este reparat.
Cartografiați autoritatea pe ciclul de viață
Enumerați ce trebuie să facă procesul în fiecare etapă: pornire, stare stabilă, reautentificare și demontare. Crearea interfeței, modificările de rută, citirea unei chei protejate și apelarea unui ajutor nu se întâmplă toate în același moment sau cu aceleași cerințe. Sortați lista după etapă înainte de a o sorta după capabilitate.
Opțiunile de persistență păstrează resurse peste renegocieri și nu acordă permisiuni care nu au fost niciodată deținute. O cheie pe care procesul nu o poate citi la pornire va rămâne ilizibilă și mai târziu, orice ar spune steagurile de persistență. Steagurile păstrează ceea ce funcționa deja.
Folosiți un cont dedicat, nu unul partajat. Dezvoltatorii OpenVPN avertizează împotriva obiceiului de a folosi nobody ca exemplu generic, pentru că alte servicii de pe gazdă s-ar putea să ruleze deja cu acel cont, iar izolarea pe care credeți că o aveți nu este acolo.
Funcțiile care schimbă sarcina locală, cum ar fi descărcarea canalului de date sau o compilare care se leagă diferit, pot deplasa ce operații sunt necesare. Revizuiți harta când se schimbă pachetul, nu doar când se strică ceva.
Scrieți planul și păstrați accesul de recuperare
Un registru de implementare ar trebui să numească managerul, identitatea de pornire, identitatea stabilă dorită și fiecare acordare împreună cu operația care o cere. Acel registru face următoarea schimbare revizuibilă în loc de experimentală.
Păstrați accesul la consolă disponibil în timp ce editați, pentru că o unitate care eșuează la pornire este greu de reparat de la distanță. Testați o repornire și o repornire completă înainte de a declara schimbarea încheiată. O unitate care supraviețuiește unei reporniri poate eșua totuși înainte ca rețeaua să fie sus.
Succesul este un ciclu de viață cu autoritate minimă înțeles, nu un proces care se întâmplă să ruleze sub un nume care nu este root.