Връщането на адрес от скрипт client-connect изглежда, че трябва да зададе IP адреса на клиента. Но не го прави: единственият канал на куката към сървъра е временен файл, чийто път идва като последен аргумент на скрипта, и адресът трябва да се запише там в синтаксис ifconfig-push. Скрипт, който отпечатва адреса или излиза с нула, без да запише нищо, създава свързан клиент с адрес от пула, а сървърният журнал изглежда напълно здрав.

Объркването е разбираемо, защото няколко други куки наистина отговарят чрез кодове за изход или променливи на средата. Тази има свой собствен договор и договорът започва с име на файл.

Куката записва файл, а не връща стойност

Декларацията е два реда: script-security 2, за да разреши извикването, след това client-connect /etc/openvpn/server/assign-address.sh. Когато клиент се удостовери, сървърът изпълнява този скрипт, като добавя генерирания път до файла като последен аргумент, който е $1 само ако декларацията не подава собствени допълнителни аргументи. Всичко, приложено към този клиент, отива в този файл като обикновени директиви, по една на ред, точно както биха изглеждали в конфигурация. Обвивка, която добавя свои параметри, измества позицията и класическият симптом е скрипт, който пише в път, изглеждащ като --verbose.

Кодът за изход е другата половина на договора. Нула означава приеми и прочети файла; всичко друго отхвърля връзката и така некартирана идентичност бива отказана, вместо тихо да се върне към пула. Напишете пълната директива, преди да върнете успех, за да не се превърне наполовина записан файл в конфигурация на клиент.

Две директиви заслужават внимание, защото взаимодействат с всичко останало. ifconfig-push фиксира адреса, докато изпратеният route казва на клиента какво е достъпно през тунела; върнете първата и забравете втората и получавате клиент с адрес и без посока. Редът във файла няма значение, но пълнотата има. Кука, която изпраща маршрут за префикс, до който никой партньор не може да стигне, е същата грешка, видяна от другия край.

Входните данни пристигат чрез променливи на средата: common_name, trusted_ip, ifconfig_pool_remote_ip и останалите. Отнасяйте се към всички тях като към низове отвън сървъра, никога като към фрагменти от обвивка.

Съпоставянето на адреси е политика, не аритметика

Изкушаващо бързо решение е да се анализира името на сертификата и цифрите му да се използват като последен октет. Това не е разпределител и се проваля по обикновени начини: две имена с еднакъв суфикс се сблъскват, име, завършващо на 300, не е адрес, а сертификат, преименуван от администратор, тихо премества устройство. Проверявайте принадлежността към подмрежата, използваемия диапазон от хостове, резервираните адреси и уникалността при всяко извикване и дръжте съпоставянето в таблица, която човек може да прочете.

Който контролира името, контролира адреса, затова решете какво common_name всъщност представлява в това разгръщане. С включен username-as-common-name идентичността е логинът, а не субектът на сертификата. Никога не подавайте тази стойност към оценка на обвивка и никога не позволявайте на клиента да влияе на път до файл.

Разпределител, поддържан от регистър, трябва да устои на конкурентност. Резервирайте адреса атомарно, обработвайте неуспешен запис, без да допускате полуконфигуриран клиент, и маркирайте всяко разпределение с връзката, която го притежава, така че късно отпадане от по-стара сесия да не може да освободи адрес, който по-нова вече държи. Няколко сървърни екземпляра, споделящи един пул, правят това изискване по-остро, а не по избор.

Топологията определя какво означава ifconfig-push

С topology subnet в 10.77.0.0/24 ifconfig-push 10.77.0.20 255.255.255.0 е адрес плюс неговата мрежова маска. Под topology net30 вторият аргумент изобщо не е маска, а адресът на партньора, така че копирането на формата за подмрежа върху net30 сървър ви дава клиент, който се свързва и не може да пропуска трафик. Променяйте топологията умишлено, никога за да изглежда примерът последователен. Сървър, който вече работи с net30, има живи клиенти на старата адресация, така че превключването е миграция с прозорец за поддръжка, а не редакция на един ред.

Статичните адреси трябва да стоят извън динамичния пул и извън всяко друго статично назначение, включително тези, раздавани от обикновени файлове client-config-dir. Ако два механизма могат да произведат един и същ адрес за различни клиенти, един от тях в крайна сметка ще го направи.

Тествайте четири случая, преди да се доверите

Пуснете същите проверки срещу картана идентичност, некартана, повторно свързване и симулиран отказ на регистъра. openvpn --config client.ovpn --verb 4 показва назначения адрес в push отговора, а на сървъра grep -A2 PUSH_REPLY /var/log/openvpn/openvpn.log потвърждава какво всъщност е изпратено. За некартаната идентичност очакваният резултат е отхвърлена връзка, а не адрес от пула.

След това прегледайте директорията, в която демонът записва тези временни файлове. Скриптът работи в понижен контекст на услугата, така че път, достъпен за запис от root, но не и от демона, превръща всяка връзка в отказ с грешка за права, заровена няколко реда по-надолу в журнала.

Разпределянето не е оторизация: фиксиран адрес все още не дава достъп до всяка дестинация зад сървъра. Дръжте политиката за маршрутизиране и защитна стена в отделен слой и я проверявайте спрямо адреса, който току-що фиксирахте.

Подобни статии