Efter privilegiefallet: vilka OpenVPN-filer fungerar fortfarande?
Deskriptorer som öppnades före fallet fungerar fortfarande; sökvägar som öppnas igen senare gör det inte. Avgör vilken av de tre körtidsfilerna din konfiguration måste öppna igen.
Lång drifttid bevisar bara att starten lyckades med de privilegier som daemonen hade i det ögonblicket. De fel som spelar roll här kommer senare: en ny klient ansluter, en återkallningslista ersätts, ett hjälpskript måste skriva en fil. Var och en av dem är en ny öppning som utförs av kontot utan privilegier, med sin egen behörighetsfråga och sitt eget felmeddelande. Tre beslut skiljer en konfiguration som fortsätter att fungera från en som fallerar vid nästa händelse.
Skilj det som laddades tidigt från det som öppnas senare
En deskriptor är ett handtag på en öppen filbeskrivning, och åtkomstläget fastställdes när beskrivningen skapades. Att byta procesanvändare senare stänger inte handtaget, vilket är varför en nyckelfil som lästes som root fortsätter att fungera efter fallet. Läget ändras inte heller: ett handtag som öppnats för läsning blir inte skrivbart, och ett skrivbart handtag återkallas inte bara för att kontot förlorade sina rättigheter på sökvägen. Dessa två fakta förklarar det mesta av det överraskande beteendet i de här rapporterna.
Den andra halvan är minne. En daemon kan tolka ett certifikat, behålla det tolkade materialet och stänga filen; det som är i bruk är data, inte en öppen fil. Fortsatt trafik bevisar därför varken att en deskriptor är öppen eller att sökvägsnamnet är nåbart. Det bevisar bara att materialet som behövs för den aktuella sessionen hämtades tidigare.
En senare öppning är en annan transaktion. Den körs under nuvarande autentiseringsuppgifter, nuvarande säkerhetskontext och nuvarande monteringsvy, så en sökväg som var läsbar vid start kan avvisas vid nästa anslutning. Rotation lägger till en fälla: att skriva en ny fil över samma sökvägsnamn lämnar en befintlig deskriptor fäst vid det gamla objektet, så en omladdning kan verka lyckad medan daemonen fortfarande använder det föregående innehållet. Jämför inoden som processen håller med den på disken innan du tror på en rotation.
Namnge de tre körtidsläsningarna och när var och en sker
Tre resurser öppnas vanligen långt efter initieringen, och de fallerar vid olika tidpunkter. En klientspecifik konfigurationsfil läses när just den klienten ansluter, så den kan gå sönder för en användare medan alla andra fortsätter. Återkallningsdata konsulteras under peer-autentisering och igen när filen ersätts. En tillfällig katalog berörs bara när ett skript eller ett plugin skriver något.
Ingen av de tre hör till startvägen, vilket är varför en server som varit frisk i veckor kan fallera vid nästa anslutning. Kategorin namnger också ägaren till rättelsen: de två första är läsrättigheter på konfigurationen under daemonkontot, och den tredje är en skrivbar plats med ett smalt syfte.
| Path reopened later | What triggers the open | First sign when it fails |
|---|---|---|
| Client configuration file | A connection for that client identity | One client rejected while others connect |
| Revocation data | Peer authentication, including after replacement | Revoked and valid peers both refused |
| Script or plugin temporary directory | A helper needs to create a file | The helper exits with a path error |
persist-key svarar på en smalare fråga än de flesta antar. Det håller nyckelfilen öppen genom de dokumenterade SIGUSR1- och ping-restart-återställningarna, och det gör ingenting för CCD-filer, återkallningsdata, hjälpprogram eller en fullständig omstart av processen. De följer fortfarande sina egna öppningsvägar, under vilket konto som helst som körs då.
Bekräfta kontot och den vy det faktiskt har
Fråga den körande daemonen vilket konto den använder i stället för att lita på unit-filen, och jämför sedan svaret med det uniten ställer in. En avvikelse är det första att lösa, eftersom varje senare behörighetskontroll körs som den processen faktiskt är. Gå sedan igenom sökvägen komponent för komponent; genomgång utvärderas på varje nivå, så en läsbar fil i en katalog som inte går att ta sig igenom förblir oläsbar. Det slutliga filläget är den sista frågan, inte den första.
Namnrymder och tjänstens sandlådor lägger till gränser som ägarskap och lägesbitar inte beskriver. En sökväg som syns i ditt skal kan saknas eller vara skrivskyddad inuti en chroot, en monteringsnamnrymd eller en unit som döljer hemkataloger. Säkerhetsmoduler lägger till ett lager till, så en fil som ser läsbar ut kan ändå avvisas när den öppnas.
ps -o user:12,pid,args -C openvpn
systemctl show -p User -p Group -p ProtectHome -p RootDirectory [email protected]
sudo -u openvpn namei -l /etc/openvpn/ccd/aliceEn lyckad läsning i administratörens skal testar ingen av dessa kombinerade villkor. Kör kontrollen som daemonkontot, med samma namnrymd och sandlåda, eller acceptera att resultatet beskriver ditt skal och inte servern. Det tredje kommandot är den billiga versionen av det testet: det skriver ut läget för varje komponent och fallerar på den första som daemonkontot inte kan ta sig igenom.
Ge körtidsskrivningen en egen katalog
Läsning är bara halva inventeringen. Ett hjälpskript kan behöva skapa en statusfil, ett plugin kan behöva skriva tillstånd bredvid sin konfiguration, och de skrivningarna täcks inte av att göra konfigurationsträdet skrivbart. Ge den specifika katalogen den skrivbehörighet som dess funktion kräver, med en ägare och ett läge som du kan förklara. Föredra skrivskyddad åtkomst för allt som bara läses.
Håll den privata nyckelns behörigheter åtskilda från policyfilerna. En nyckel som måste läsas om efter en återställning har ett annat krav än en klientfil som läses vid varje anslutning, och ett enda eftergivligt läge för båda ger mer åtkomst än problemet begär. Ett dedikerat daemonkonto med smalt ägarskap är lättare att granska än en bred grupp. När nyckeln måste överleva återställningar, persist-key tar det bort omläsningen i stället för att vidga katalogen.
Avgör utifrån händelsen du kan återskapa
En levande tunnel bevisar en enda väg genom koden. Händelsen som behöver filen är det enda testet som täcker den öppning du bryr dig om, vare sig det är en ny klientanslutning, en ersatt återkallningsfil, en tillåten mjuk återställning eller en planerad omstart. Välj händelsen, kör den och behåll det första felet i stället för det sista.
Vid en mjuk återställning visar en signal och unitens logg om nyckeln lästes om. Skicka signalen och läs sedan de sista raderna som uniten skrev:
systemctl kill -s SIGUSR1 [email protected]
journalctl -u [email protected] -n 40 --no-pagerSlut inte att en komprometterad daemon inte längre kan ändra filer bara för att privilegierna sänktes. Vad den fortfarande kan beror på kvarvarande autentiseringsuppgifter, dess förmågor, katalogerna den kan skriva i och varje skrivbar deskriptor den fortfarande håller. Privilegiereduktion snävar in auktoriteten, och inventeringen av körtidsöppningar visar hur mycket. Skriv den gränsen bredvid konfigurationen så att nästa person inte behöver upptäcka den igen.