Хук OpenVPN на PHP: trusted_ip супраць ifconfig_pool_remote_ip
Два адрасы з двума рознымі сэнсамі, якія чытае працэс, што запусцілі не вы. Што такое зменныя хука і чаму пусты $_ENV нічога не даказвае.
Пусты масіў $_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 нічога не даказвае
Дакументацыя getenv апісвае прамое чытанне асяроддзя працэса, якое вяртае false, калі імені няма. Суперглабал $_ENV запаўняецца асобна, і дырэктыва variables_order вырашае, якія суперглабалы будуць запоўненыя.
Калі гэтая дырэктыва не ўтрымлівае E, $_ENV застаецца пустым, што б ні было ў асяроддзі. Код, які індэксуе яго, тады паведамляе пра адсутную зменную, якая насамрэч ёсць, і расследаванне ідзе да OpenVPN, тады як адказ у php.ini. Праверце дырэктыву менавіта для канфігурацыі CLI, а не для вэб-сервера.
Чытанне праз getenv пазбягае ўсяго гэтага класа блытаніны, а скрыпт-абгортка, які ачышчае асяроддзе перад выклікам інтэрпрэтатара, вяртае яе ў іншай форме.
Захоўвайце сувязь, а не абнаўленне радка
Вырашыце, якое значэнне патрэбна запісу, перш чым яго пісаць. Калі мэта — адзначыць, адкуль прыйшла сесія, захоўвайце знешні канцавы пункт і пазначце яго як назіранне. Калі мэта — звязаць сесію з адрасам тунеля на час злучэння, захоўвайце адрас пула і прывязвайце яго да сесіі.
Абнаўляйце па аўтэнтыфікаванай асобе і бягучай сесіі, а не па кожным радку, што дзеліць адрас тунеля, бо адрасы пула выкарыстоўваюцца паўторна і позняя падзея адключэння інакш можа перазапісаць даныя больш новага злучэння. Апрацоўвайце IPv6 яўна, замест таго каб моўчкі пісаць толькі значэнне IPv4. Радок з NULL у знешнім адрасе лепш за радок з няправільным, бо першы бачна няпоўны.
Прывяжыце запіс да ідэнтыфікатара сесіі, які дае OpenVPN, каб перападключэнне стварала новы запіс, а не рэдагавала стары. Выкарыстоўвайце параметраваныя выразы і ўліковы запіс толькі з тымі правамі, якія патрэбныя аперацыі. Хук працуе з паўнамоцтвамі дэмана, таму няўважлівы запыт — гэта шырэйшая праблема, чым няправільны радок журнала.
Дыягнастуйце, не выгружаючы асяроддзе
Запішыце, якія імёны прысутнічалі, якая стадыя працавала і які інтэрпрэтатар выкарыстоўваўся. Не друкуйце ўсё асяроддзе, бо працэс хука можа атрымаць у спадчыну непатрэбныя значэнні, якія не павінны трапляць у файл журнала.
Праверце адно злучэнне ад пачатку да канца: прачытайце знешні канцавы пункт, прачытайце выдадзены адрас і пацвердзіце абодва з уласным поглядам сервера на гэтую сесію. Пасля таго як пара пацверджана для аднаго кліента, сувязі можна давяраць і ў іншых месцах.