Spårning av OpenVPN-kontrollpaket: tls-auth före TLS
tls-auth-HMAC:en sitter på kontrollkuvertet, inte inne i TLS-handskakningen. Stäm av nyckel, riktning och digest och verifiera sedan utan att ta bort skyddet.
Ett tls-auth-fel rapporteras vanligen som ett handskakningsproblem, och det har det aldrig varit. HMAC:en kontrolleras på kontrollpaketet innan någon TLS-behandling sker, så en felaktig nyckel eller riktning ger ett fel som ser ut som ett certifikatproblem och avgörs två lager tidigare. Behandlas kuvertet som ett eget objekt blir diagnosen kort: läs fälten, bekräfta att kontrollen slår till tidigt och jämför sedan de tre saker båda ändar måste vara överens om.
Läs kuvertet i den ordning det byggs
Ett kontrollpaket bär en sessionsidentifierare, den valfria tls-auth-HMAC:en, upprepnings- och kvitteringsinformation och en tillförlitlig meddelandeidentifierare, och därefter följer nyttolasten för meddelandetypen. När meddelandet är ett handskakningsmeddelande råkar nyttolasten vara TLS-chiffertext. Det är hela relationen: TLS-material färdas inuti ett meddelande som kuvertet redan skyddar. OpenVPN-referensen för nätverksprotokollet listar kontrollkanalens fält i den ordningen.
Tillförlitlighetslagret förväxlas lätt med kryptografi. Kvitteringar, omsändning och meddelandeidentifieraren finns för att kontrollmeddelanden ska anlända en gång och i rätt ordning över en opålitlig transport. De är inte autentisering, och en korrekt meddelandeidentifierare bevisar ingenting om vem som skickade paketet.
Håll denna gruppering konceptuell. Det är inte ett byte-ordningsdiagram och det räcker inte för att beräkna en tagg, eftersom fälten som går in i HMAC:en beror på implementering, version och läge.
Visa att kontrollen slår till före handskakningen
En mottagare med den delade nyckeln kan verifiera HMAC:en och kasta ett förfalskat paket direkt, utan att tilldela handskakningstillstånd eller utföra arbete med publik nyckel. Skyddet täcker även de första handskakningspaketen, och just därför visar sig en felaktig nyckel som en misslyckad anslutning i stället för som ett sent autentiseringsfel.
Höj daemonens utförlighet och följ kontrollkanalen i stället för tun-enheten:
openvpn --config /etc/openvpn/server.conf --verb 6
Det du letar efter är ett HMAC-verifieringsfel i kontrollkanalen som rapporteras på paketnivå, före någon TLS-varning. En TLS-varning i loggen betyder att kuvertet accepterades och att felet flyttade inåt, vilket är en annan undersökning med en annan åtgärd.
Riktningshantering finns också här. När en statisk nyckelfil används med tls-auth tar de två ändarna motsatta nyckelriktningar, och protokollet använder den uppdelningen så att ett fångat paket inte kan reflekteras tillbaka till sin avsändare. Att vända riktningen behåller nyckeln identisk och får ändå varje paket att misslyckas. Ändra en ände i taget och starta sedan om båda daemonerna så att paret laddas tillsammans.
Stäm av nyckel, riktning och digest i båda ändar
Tre värden måste stämma och bara ett av dem är filen. Innehållet i den statiska nyckeln måste vara identiskt i båda ändar, riktningen måste vara motsatt och digesten som används för HMAC:en måste stämma. Kontrollera konfigurationen innan du rör nyckelmaterialet, eftersom en enda omvänd riktning förklarar fler fel än en skadad fil:
grep -E 'tls-auth|tls-crypt|key-direction|auth ' /etc/openvpn/server.conf
Generera den delade hemligheten med verktyget i stället för med en editor, och håll behörigheterna strama:
openvpn --genkey secret /etc/openvpn/ta.key
chmod 600 /etc/openvpn/ta.key
Äldre utgåvor accepterade en något annan valordning för nyckelgenerering, och profiler skrivna för dessa utgåvor cirkulerar fortfarande. Den genererade filen är samma typ av objekt i båda fallen, så kontrollen är om båda ändar har identiska byte, inte vilken stavning som skapade dem.
Blanda inte ihop tls-auth med tls-crypt. Båda skyddar kontrollkanalen, men tls-crypt krypterar den också och döljer handskakningen för observatörer, och det ersätter riktningsuppdelningen med sin egen nyckelhantering. En profil med den ena kommer inte att samverka med en motpart konfigurerad för den andra, och ingen digest-justering stänger den luckan.
Återskapa en tagg endast från det verkliga formatet
Byte-exakt återskapande är en annan uppgift än att driva en VPN, och det fungerar bara med de verkliga indata: implementeringen och versionen som byggde paketet, den valda digesten, riktningen och de faktiska byten, inklusive sessionsidentifierare och kvitteringsarray. En textuell återgivning av fältlistan är inte dessa byte.
Taggens längd följer av digesten, så ett antagande om fast längd brister i samma stund någon ändrar den. Hasha paketet som implementeringen gör, inte som en tabell i ett blogginlägg presenterar det, och jämför med en inspelning tagen från samma motpart i stället för med en förväntan du härledde för hand.
Håll den övningen borta från produktionsprofiler. Ingenting i att återskapa en tagg säger dig om en driftsättning bör slå på skyddet.
Rulla tillbaka en avvikelse utan att ta bort skyddet
Det frestande testet är att radera tls-auth, se att anslutningen lyckas och dra slutsatsen att nyckeln var fel. Det svaret kostar dig skyddet och lär dig ingenting om vilket av de tre värdena som inte stämde. Hämta i stället den godkända matchande konfigurationen från serversidan och jämför med den.
Förbered ändringen så att den kan rullas tillbaka. Behåll föregående serverkonfiguration och nyckelfil, tillämpa det korrigerade paret, verifiera att en klient slutför handskakningen och ta först därefter bort säkerhetskopian. Om klienter misslyckas efter ändringen, återställ de föregående filerna i stället för att improvisera en tredje variant under ett avbrott. Återställningen bör vara ett enda kommando som du redan kan innan du börjar.
Kom slutligen ihåg vad en godkänd kontroll betyder. Den bevisar att motparten har den delade nyckeln, inte att dess certifikat eller konto är auktoriserat, och den säger ingenting om det förhandlade chiffert för datakanalen. Auktorisering och dataskydd upprättas senare, så en ren kuvertkontroll är en utgångspunkt och inte en dom.