Aveam o mașină de laborator care accepta un tunel de la un site aflat la distanță și, de asemenea, forma un apel către o rețea a unui furnizor. Profilul de ieșire funcționase săptămâni întregi. După ce serverul de intrare a fost adăugat, cel de ieșire s-a conectat și apoi a încetat să mai transmită trafic în câteva secunde, sau a refuzat să pornească cu o eroare că adresa este deja utilizată. Fișierele de configurare nu se schimbaseră; hostul pur și simplu dobândise un al doilea proces OpenVPN cu propria părere despre porturi și rute.

Defecțiunea nu este aleatorie și nu este o problemă de autentificare. Două demoni pe o singură mașină concurează pentru același socket local și pentru același tabel de rutare, iar cel care pornește sau se reconectează ultimul câștigă de obicei. Să știi care dintre aceste două coliziuni o ai decide unde să te uiți mai întâi.

Citește simptomul invers

Începe cu momentul în care tunelul moare. O eroare de bind la pornire indică spre partea care ascultă: ceva deține deja acel port, iar OpenVPN refuză să pornească în loc să îl partajeze. Un tunel care urcă și apoi tace indică spre rutare, pentru că o rută instalată de cealaltă instanță poate scoate pachetele conexiunii exterioare de pe calea lor.

Ambele cazuri produc aceeași plângere a utilizatorului, de aceea buclele de reîncercare și scripturile watchdog nu repară nimic. Ele reconectează clientul în același conflict. Prima întrebare utilă este dacă procesul încă rulează atunci când traficul se oprește.

Un socket și un dispozitiv pe instanță

Un server care ascultă își leagă portul; un client de ieșire are nevoie și el de un port local pentru traficul său încapsulat. Când ambele trăiesc pe același host, comportamentul implicit al clientului poate intra în coliziune cu portul serverului. Portul local al clientului poate fi fixat, iar legarea poate fi omisă acolo unde partenerul nu are nevoie de un port sursă fix:

lport 1195
nobind
dev tun1

Acele numere sunt exemple, nu o cerință. Important este ca clientul să nu mai concureze pentru portul serverului și ca fiecare instanță să primească un dispozitiv de tunel separat. Doi demoni care partajează tun0 își suprascriu starea dispozitivului unul altuia chiar și atunci când porturile lor diferă, așa că un dispozitiv pe tunel nu este opțional.

nobind aparține părții clientului. Un server trebuie în continuare să lege și să asculte, așa că nu copia linia în configurația serverului și nu dezactiva legarea pe un client al cărui partener filtrează pe un port sursă fix.

Alege un singur proprietar pentru ruta implicită

Doar o conexiune poate instala o rută implicită. Dacă ambele profiluri redirecționează tot traficul, a doua conexiune o înlocuiește în tăcere pe prima, iar prima pare că se strică. Fie păstrezi tunelul de ieșire împărțit și împingi doar prefixele furnizorului, fie îi dai un tabel de rutare separat.

ip rule add from 10.9.0.2 table 120
ip route add default dev tun1 table 120
ip route get 10.9.0.2

Adresele și numărul de tabel de mai sus sunt substituenți. Imediat după adăugarea regulii, confirmă că adresa serverului VPN însuși este încă rezolvată prin tabelul normal; un tabel care captează transportul exterior rupe tunelul pe care trebuia să îl protejeze, iar bucla de reconectare care urmează arată ca un furnizor nesigur.

Pentru o configurație care trebuie să supraviețuiască reconectărilor și repornirilor, un namespace de rețea este granița mai solidă. Al doilea client rulează în propriul namespace cu propriile interfețe și rute, iar doar serviciile care trebuie să traverseze sunt expuse. Hostul păstrează o rută implicită, iar o reconectare a namespace-ului nu o poate rescrie.

Verifică cu tabelul, nu cu linia de stare

Un client care raportează că este conectat își dovedește doar canalul de control. Capturează starea de rutare înainte și după fiecare conexiune, apoi întreabă kernelul ce dispozitiv ar folosi o destinație reală:

ip route show
ip route get 10.40.0.20
ss -lunp | grep 1194

Dacă dispozitivul selectat pentru adresa furnizorului se schimbă când pornește al doilea tunel, ai coliziunea de rute. Dacă ambele procese apar pe același port local, ai coliziunea de socketuri. Repararea primei fără a doua mută doar defecțiunea la următoarea reconectare.

Scrie porturile, dispozitivele, tabelele și proprietarul rutei în runbook-ul hostului. Altfel, următoarea persoană care adaugă un al treilea tunel va redescoperi aceeași coliziune, iar singura dovadă vizibilă va fi o conexiune care funcționează până când demonul altcuiva repornește.

Articole similare