ProtectHome mot ett TOTP-frö: varför VPN-inloggningen misslyckas
En korrekt kod hjälper inte en PAM-modul som inte kan öppna fröet. Välj mellan en drop-in och en skrivbar tillståndsväg och kontrollera sedan enheten.
Autentiseringsappen visar en ny sexsiffrig kod, VPN avvisar den, och samma kod verifieras fint när du testar den från ditt eget skal. Den klyftan är hela historien. En PAM-modul som inte kan öppna registreringshemligheten returnerar ett fel som ser identiskt ut med en felaktig kod, och tjänstemiljön som döljer hemkataloger är en vanlig orsak. Innan du läxar upp någon behörighet, avgör vilken av tre situationer du är i.
Vilket av tre fel är detta?
Det första är en hemlighet som modulen inte kan läsa alls. Det andra är en hemlighet som den kan läsa men inte uppdatera. Det tredje är en kod som verkligen är fel, oftast på grund av klockdrift eller ett återanvänt värde.
Skilj dem åt genom att läsa tjänsteloggen och systemets autentiseringslogg för ett misslyckat försök, och bekräfta sedan vilken PAM-tjänst insticksmodulen laddar och vilken modullinje den tjänsten använder. Ett allmänt autentiseringsfel skiljer dem inte, och ett lyckat manuellt test gör det inte heller, eftersom ditt skal inte är tjänstens miljö.
Enhetens filsystemsvy är den vanliga boven när bara tjänsten misslyckas.
systemctl show -p ProtectHome -p ProtectSystem -p ReadWritePaths [email protected]
ls -l /var/lib/vpn-otp/*/.google_authenticator 2>/dev/null | head -n 20Alternativ A: flytta hemligheten ut ur hemmet
När tjänsten döljer /home och du hellre behåller det skyddet, lagra hemligheten där den kan se den. Modulen accepterar en secret=-sökväg och ett user=-konto som utför filoperationerna, vilket låter ett centralt arkiv betjäna många identiteter.
Detta är det prydliga alternativet, och det är det som kräver mest omsorg, eftersom ett delat arkiv gör en enda katalog till säkerhetsgränsen för varje konto.
auth required pam_google_authenticator.so secret=/var/lib/vpn-otp/${USER}/.google_authenticator user=vpn-otpKontrollera tre saker innan du litar på det: kontot finns, modulens arbetsprocess kan byta till det, och filerna ägs av det med restriktiva lägen. Använd inte ~ eller en sökväg med hemvariabel tillsammans med user=, och stäng inte av modulens ägarskapskontroller för att få en sökväg att fungera. Håll lösenordssteget och resten av stacken intakta.
Alternativ B: lämna filen och öppna en sökväg
Om hemligheten måste stanna i användarens hemkatalog behöver enheten en vy som inkluderar den enda katalogen utan att exponera alla hemkataloger på värden. En drop-in kan lägga till en snävt avgränsad bind-mount under ett sandlådat hem.
Detta behåller ägarskap per användare som modell, till priset av en enhetsändring som måste granskas varje gång sandlådan ändras.
Två gränser är lätta att missa. En skrivskyddad sökväg som läggs till under en katalog som sandlådan döljer exponerar den inte, eftersom föräldern helt enkelt inte finns där. Och mounten måste vara skrivbar om modulen behöver uppdatera tillståndet, vilket för in nästa alternativ i spelet. Skriv drop-in som en separat fil i stället för att redigera det paketerade enheten under /usr/lib, så att en paketuppgradering inte tyst ångrar det.
Alternativ C: behåll sandlådan och fixa tillståndsskrivningar
Att läsa hemligheten är bara halva autentiseringen. Modulen kan skriva om information om tidsförskjutning, uppspelningsskydd eller en räknare, och en fil som klarar läskontrollen kan fortfarande misslyckas vid skrivning.
Det felet ser ut som en dålig kod vid nästa försök i stället för vid detta, och därför förväxlas det med klockdrift.
Ge den en egen skrivbar katalog och peka hemlighetens sökväg dit, i stället för att göra hela hemkatalogen skrivbar. Bekräfta katalogens ägare, filsystemets lediga utrymme och om enheten begränsar skrivningar någon annanstans. Testa sedan två på varandra följande inloggningar, eftersom den andra bevisar skrivvägen och den första bara läsningen.
Verifiera som tjänsten, inte som dig själv
Varje kontroll som spelar roll måste köras inuti enhetens sandlåda med enhetens identitet.
Ett kommando som lyckas som root berättar att filen finns och inget annat. En inloggning via den faktiska tjänsten berättar om modulen kan läsa hemligheten, använda den och skriva tillbaka det den behöver.
Till sist, håll kravet intakt. Att lägga till ett nollösenordsalternativ, acceptera skrivskyddade fel eller ta bort sandlådan skulle alla få symptomet att försvinna genom att ändra policyn. En användare som måste visa en kod ska fortfarande avvisas när hemligheten är oåtkomlig.