Празна $_ENV низа во скрипта на кука изгледа како доказ дека OpenVPN не пренел ништо. Обично тоа докажува сосема друго: PHP бил конфигуриран да не ја пополнува таа суперглобална променлива, а вредностите цело време стоеле во околината на процесот. Вториот погрешен заклучок е посуптилен, бидејќи двете променливи за адреса во куката за поврзување значат различни работи и се користат како заменливи. Двете грешки чинат едно попладне ако се почне од погрешната.

Две адреси, две различни тврдења

Надворешната крајна точка е она што серверот го набљудувал кога клиентот се поврзал, достапна како trusted_ip за IPv4 и trusted_ip6 за IPv6. Виртуелната адреса е она што базенот ја доделил за оваа сесија, достапна како ifconfig_pool_remote_ip.

Тие одговараат на различни прашања, а записот обично бара една од нив, а не двете. Првата кажува од каде пристигнало поврзувањето, што може да биде заедничка NAT адреса што ја користат стотици луѓе. Втората кажува каде оваа сесија живее во тунелот, и таа може подоцна да се додели на друга сесија. Мешањето на двете дава записи што изгледаат веродостојно и се погрешни.

Минимално читање изгледа вака.

$outer4 = getenv('trusted_ip');
$outer6 = getenv('trusted_ip6');
$inner  = getenv('ifconfig_pool_remote_ip');
$outer  = $outer4 !== false ? $outer4 : $outer6;

Ниту една вредност не идентификува личност. Едната е мрежно набљудување, другата е закуп, а запис што некоја од нив ја третира како стабилен идентификатор на уред ќе биде погрешен првиот пат кога клиентот ќе се поврзе од друга мрежа или ќе добие друга адреса од базенот. Изберете го полето според прашањето на кое записот мора да одговори, потоа напишете го тоа прашање покрај колоната.

Проверете како е стартуван PHP, а не вашата обвивка

Куката работи како дете на VPN демонот со околина што демонот ја создава. Вашата интерактивна обвивка има друга, а рачното пуштање на скриптата ја тестира околината на обвивката, а не на куката.

Прво потврдете дека куката навистина се активирала во фазата што ја очекувавте. Скрипта прикачена на погрешна фаза, или таква што никогаш не се извршила зашто директивата покажува на друг пат, дава точно ист симптом како променлива што недостига. Додајте намерна линија-маркер на почетокот на скриптата и потврдете дека се појавува пред да проверите нешто друго. Една линија со временска ознака во дневникот го раздвојува „никогаш не се извршила“ од „се извршила без вредноста“.

Потоа потврдете кој интерпретер и која конфигурациска датотека ги користи тој повик. Менувањето на PHP конфигурацијата за веб-сервер не менува ништо за CLI процес стартуван од OpenVPN, и двете можат да вчитаат сосема различни php.ini датотеки.

Зошто празна $_ENV не докажува ништо

PHP референцата за getenv опишува директно читање на околината на процесот, кое враќа false кога името отсутствува. Суперглобалната $_ENV се пополнува одделно, а директивата variables_order одлучува кои суперглобални ќе се пополнат.

Ако таа директива го испушта E, $_ENV останува празна без оглед на тоа што содржи околината. Кодот што ја индексира тогаш пријавува променлива што недостига, а всушност е присутна, и истрагата оди кон OpenVPN кога одговорот е во php.ini. Проверете ја директивата конкретно за CLI конфигурацијата, не за веб-серверот.

Читањето со getenv ја избегнува целата оваа збунетост, а обвивка-скрипта што ја чисти околината пред да го повика интерпретерот ја воведува повторно во друга форма.

Складирајте поврзаност, не ажурирање на ред

Пред да пишувате, одлучете која вредност му е потребна на записот. Ако целта е да се забележи од каде дошла сесијата, складирајте ја надворешната крајна точка и означете ја како набљудување. Ако целта е да се преслика сесија на тунел-адреса за времетраењето на поврзувањето, складирајте ја адресата од базенот и поврзете ја со сесијата.

Ажурирајте по автентифицираниот идентитет и тековната сесија, а не по секој ред што дели тунел-адреса, бидејќи адресите од базенот се користат повторно и доцен настан за исклучување инаку може да ги пребрише податоците на поново поврзување. Ракувајте со IPv6 експлицитно наместо тивко да ја пишувате само вредноста за IPv4. Ред со NULL надворешна адреса е подобар од ред со погрешна, бидејќи првиот е видливо нецелосен.

Поврзете го пишувањето со идентификаторот на сесијата што го дава OpenVPN, за повторното поврзување да создаде нов запис наместо да го уредува стариот. Користете параметризирани изрази и сметка со само дозволите што и се потребни на операцијата. Куката работи со овластувањата на демонот, па невнимателно барање е поширок проблем од погрешен ред во дневникот.

Дијагностицирајте без да ја исфрлате околината

Забележете кои имиња биле присутни, која фаза се извршила и кој интерпретер се користел. Не ја печатете целата околина, бидејќи процесот на куката може да наследи неважни вредности што не треба да завршат во датотека на дневник.

Проверете едно поврзување од почеток до крај: прочитајте ја надворешната крајна точка, прочитајте ја доделената адреса и потврдете ги двете против сопственото видување на серверот за таа сесија. Откако парот е потврден за еден клиент, на поврзаноста може да ѝ се верува и на друго место.

Поврзани статии