PHP háčik v OpenVPN: trusted_ip verzus ifconfig_pool_remote_ip
Dve adresy s dvoma rôznymi významami, ktoré číta proces, ktorý ste nespustili. Čo sú premenné háčika a prečo prázdne $_ENV nič nedokazuje.
Prázdne pole $_ENV v skripte háčika vyzerá ako dôkaz, že OpenVPN nič neodovzdal. Zvyčajne dokazuje niečo úplne iné: PHP bolo nastavené tak, aby túto superglobálnu premennú neplnilo, a hodnoty celý čas sedeli v prostredí procesu. Druhý nesprávny záver je jemnejší, pretože dve adresové premenné v háčiku pripojenia znamenajú rozdielne veci a používajú sa zameniteľne. Obe chyby stoja popoludnie, ak začnete tou nesprávnou.
Dve adresy, dve rôzne tvrdenia
Vonkajší koncový bod je to, čo server pozoroval pri pripojení klienta, dostupný ako trusted_ip pre IPv4 a trusted_ip6 pre IPv6. Virtuálna adresa je to, čo fond pridelil pre túto reláciu, dostupná ako ifconfig_pool_remote_ip.
Odpovedajú na rôzne otázky a záznam zvyčajne potrebuje jednu z nich, nie obe. Prvá hovorí, odkiaľ spojenie prišlo, čo môže byť zdieľaná adresa NAT, ktorú používajú stovky ľudí. Druhá hovorí, kde táto relácia žije vnútri tunela, a neskôr sa môže prideliť inej relácii. Zámena oboch vytvára záznamy, ktoré vyzerajú vierohodne a sú nesprávne.
Minimálne čítanie vyzerá takto.
$outer4 = getenv('trusted_ip');
$outer6 = getenv('trusted_ip6');
$inner = getenv('ifconfig_pool_remote_ip');
$outer = $outer4 !== false ? $outer4 : $outer6;Ani jedna hodnota neidentifikuje osobu. Jedna je sieťové pozorovanie, druhá je nájom, a záznam, ktorý ktorúkoľvek z nich považuje za stabilný identifikátor zariadenia, bude nesprávny pri prvom opätovnom pripojení klienta z inej siete alebo pri pridelení inej adresy z fondu. Vyberte pole podľa otázky, na ktorú má záznam odpovedať, a potom tú otázku zapíšte vedľa stĺpca.
Skontrolujte, ako bolo PHP spustené, nie svoju shell
Háčik beží ako potomok démona VPN s prostredím, ktoré démon zostavuje. Váš interaktívny shell má iné a spúšťanie skriptu ručne testuje prostredie shellu, nie háčika.
Začnite tým, že potvrdíte, že háčik naozaj vystrelil v etape, ktorú ste očakávali. Skript pripojený k nesprávnej etape alebo taký, ktorý nikdy nebežal, pretože direktíva ukazuje na inú cestu, dáva presne ten istý príznak ako chýbajúca premenná. Pridajte zámernú značkovaciu riadku na začiatok skriptu a potvrďte, že sa objaví, skôr než skontrolujete čokoľvek iné. Jediný riadok s časovou značkou v logu oddeľuje „nikdy nebežal“ od „bežal bez hodnoty“.
Potom potvrďte, ktorý interpret a ktorý konfiguračný súbor to volanie používa. Úprava konfigurácie PHP pre webový server nič nemení na procese CLI spustenom OpenVPN a oba môžu načítať úplne odlišné súbory php.ini.
Prečo prázdne $_ENV nič nedokazuje
PHP referencia getenv dokumentuje priame čítanie prostredia procesu, ktoré vráti false, keď názov chýba. Superglobálna premenná $_ENV sa plní samostatne a direktíva variables_order rozhoduje, ktoré superglobálne sa naplnia.
Ak tá direktíva vynechá E, $_ENV zostane prázdne bez ohľadu na to, čo prostredie obsahuje. Kód, ktorý ju indexuje, potom hlási chýbajúcu premennú, ktorá v skutočnosti existuje, a vyšetrovanie ide smerom k OpenVPN, kým odpoveď je v php.ini. Skontrolujte direktívu konkrétne pre konfiguráciu CLI, nie pre webový server.
Čítanie pomocou getenv sa vyhne celej tejto zámene a obalový skript, ktorý pred volaním interpreta vyčistí prostredie, ju vráti v inej podobe.
Ukladajte asociáciu, nie aktualizáciu riadku
Pred zápisom rozhodnite, ktorú hodnotu záznam potrebuje. Ak je cieľom poznamenať, odkiaľ relácia prišla, uložte vonkajší koncový bod a označte ho ako pozorovanie. Ak je cieľom priradiť reláciu k adrese tunela na čas spojenia, uložte adresu z fondu a prepojte ju s reláciou.
Aktualizujte podľa overenej identity a aktuálnej relácie, nie podľa každého riadku zdieľajúceho adresu tunela, pretože adresy z fondu sa znovu používajú a neskorá udalosť odpojenia môže inak prepísať údaje novšieho spojenia. Spracujte IPv6 explicitne, namiesto tichého zápisu iba hodnoty IPv4. Riadok s NULL vonkajšou adresou je lepší ako riadok s nesprávnou, pretože prvý je viditeľne neúplný.
Prepojte zápis s identifikátorom relácie, ktorý poskytuje OpenVPN, aby opätovné pripojenie vytvorilo nový záznam a nie upravovalo starý. Používajte parametrizované príkazy a účet len s tými právami, ktoré operácia potrebuje. Háčik beží s právomocou démona, takže neopatrný dotaz je širší problém než nesprávny riadok logu.
Diagnostikujte bez vyhodenia prostredia
Zapisujte, ktoré názvy boli prítomné, ktorá etapa bežala a ktorý interpret sa použil. Nevypisujte celé prostredie, pretože proces háčika môže zdediť nesúvisiace hodnoty, ktoré by sa nemali dostať do logového súboru.
Overte jedno spojenie od začiatku do konca: prečítajte vonkajší koncový bod, prečítajte pridelenú adresu a obe potvrďte voči vlastnému pohľadu servera na tú reláciu. Keď je dvojica potvrdená pre jedného klienta, asociácii sa dá dôverovať aj inde.