Varför nc -uz inte kan bevisa att en OpenVPN-server är redo
En UDP-netcat-kontroll rapporterar framgång även när ingenting lyssnar, så den kan inte bevisa att en OpenVPN-server är redo. Kontrollera processen, loggen, lyssnaren och en riktig klient.
Att köra nc -uz mot en OpenVPN server mäter nästan ingenting, och OpenBSD-handboken säger det i sina förbehåll: UDP-skanningar i det läget rapporterar framgång oavsett om något lyssnar eller inte. Utgångsstatusen speglar den lokala sändningen, inte det avlägsna tillståndet, så en övervakare som litar på den håller en död server märkt som frisk så länge processtabellen ser rimlig ut. Att ersätta den börjar med att avgöra vilken fråga kontrollen ska svara på, eftersom process, lyssnare, autentisering och applikationens nåbarhet är fyra olika observationer. En kontroll som namnger en av dem är användbar; en kontroll som antyder alla fyra är en belastning.
Vad en UDP-kontroll kan och inte kan observera
nc -uz skickar ett datagram och avslutar, och statusen den returnerar beskriver den lokala sändningen. En stängd port kan svara med ICMP port unreachable, men det dokumenterade beteendet i detta skanningsläge gör inte det till ett fel, och en filtrerad port ger inget svar alls. Tystnad och framgång betyder därför samma sak för anroparen.
Det gör kontrollen till ett test av den lokala stacken, inte av servern. Den fastställer inte att värden är nåbar, att porten är bunden, att OpenVPN-processen körs eller att en klient skulle kunna autentisera sig. Ett TCP-anslutningstest är starkare eftersom handskakningen ger ett tydligt svar, men bara när driftsättningen faktiskt lyssnar på TCP. Att byta kontrollen till TCP på samma nummer testar en lyssnare som kanske inte finns, och mot en server med bara UDP kommer det att fälla en frisk tjänst.
Att anpassa kontrollen till den konfigurerade transporten kommer före tillit till något av de två resultaten. En UDP-driftsättning behöver en annan signal, inte ett annat protokoll.
Tre anropare, tre olika frågor
Beredskap beror på vem som frågar. En tjänstehanterare som startar om en kraschad process måste veta att instansen startade och band sin lyssnare. En lastbalanserare måste veta att en klient som kommer nu skulle accepteras. Ett övervakningssystem måste veta att vägen från ett riktigt nätverk fortfarande bär en session till en tillåten resurs.
Det här är inte samma kontroll, och en kontroll kan inte ärligt täcka alla tre. Välj först anroparen och sedan beviset.
Bygg kontrollen från den aktuella instansen
OpenVPN skriver en startrad när en instans har slutfört initieringen, och den raden är ett användbart bevis om den lokala starten. Läs den från den aktuella starten i stället för från slutet av en fil som fylls på, eftersom en framgång från förra veckan läses precis som en framgång för en minut sedan. En server kan också ha slutfört initieringen innan någon klient någonsin har anslutit, så raden säger ingenting om autentisering.
För en startkontroll, kombinera processtillståndet med aktuellt loggbevis och en lyssnare som matchar den konfigurerade transporten. Kontrollen bör misslyckas när processen körs men inte har slutfört initieringen, vilket betyder att loggfrågan måste begränsas till denna start och denna enhet.
systemctl is-active openvpn@server
sudo journalctl -u openvpn@server -b --no-pager | grep "Initialization Sequence Completed"
ss -lunp | grep 1194
Tre utdata, tre påståenden: enheten är aktiv, denna start producerade initieringsraden, och något håller UDP-porten. Ingen av dem säger att en klient kan ansluta. Håll dem åtskilda på statussidan så att en incident inte kollapsar till en enda grön prick.
Bryt det med avsikt och titta på kontrollen
En kontroll är bara pålitlig när du har sett den misslyckas. Stoppa servern, kör kontrollen och bekräfta det resultat du förväntar dig. Starta den sedan igen och bekräfta att kontrollen återhämtar sig utan någon annan ändring.
sudo systemctl stop openvpn@server
nc -uz 203.0.113.10 1194; echo "exit=$?"
ss -lunp | grep 1194
sudo systemctl start openvpn@server
ss -lunp | grep 1194
Läs blocket rad för rad. Netcat-kommandot skriver ut exit=0 , medan ingenting är bundet, och det är hela problemet på en rad. Den första ss skriver inte ut något, omstarten lyckas, och den andra ss visar lyssnaren igen. Om din kontroll passerar mot den stoppade servern mäter den den lokala stacken och ingenting annat.
Det motsatta felet spelar också roll. En kontroll som misslyckas mot en frisk server orsakar omstarter som aldrig var nödvändiga, och en omstartsloop är i sig ett avbrott. Testa båda riktningarna innan du kopplar kontrollen till något som kan agera på den.
Vad statusraden bör säga
Notera vilken gräns varje kontroll täcker: process, lyssnare, autentisering eller applikation. En kontroll täcker sällan mer än en, och en statussida som pressar ihop dem till “up” döljer skillnaden som spelar roll under en incident. För nätverksvägen, använd en riktig klient med en dedikerad identitet, låt den slutföra handskakningen och en ofarlig tillåten åtgärd och koppla sedan från. Det tränar styrkanalen, autentiseringspolicyn och lyssnaren i ett steg.
Håll den identiteten åtskild från riktiga användare och ge den de minimala behörigheter som kontrollen behöver. En beredskapskontroll med bred åtkomst är en ny attackyta som lagts till för bekvämlighetens skull. Rotera dess inloggningsuppgifter som för alla andra konton, eftersom en kontroll som slutar autentisera ser precis ut som en server som slutade acceptera klienter.
Namnge gränsen i larmtexten, så att den första som svarar vet om den ska titta på enheten, sockeln, certifikatet eller rutten. En kontroll som inte kan säga vad den har bevisat kommer att litas på av fel anledning, och det är hur netcat-kontrollen överlevde från början.