В macOS превключвателят за сигурност е толкова добър, колкото е политиката на пакетния филтър зад него, а pf е частта, която налага тази политика. Политиката трябва да прави две противоположни неща едновременно: да позволи на клиента да стигне до своя сървър, за да може да съществува тунел, и да спре всичко останало да излиза директно. Повечето публикувани набори от правила се справят с второто и забравят първото, затова машината губи свързаност вместо да спечели защита. Версията, която работи, назовава крайната точка, резолвера и тунела и нищо повече.

Какво може да реши пакетният филтър и какво не

pf гледа интерфейси, адреси, номера на протоколи и портове и спира дотук. Той никога не научава кой процес е отворил сокет, затова разрешение, написано за една програма, става разрешение за всяка програма, която може да стигне до същия порт. Така щедро изключение за UDP превръща превключвателя за сигурност обратно в обикновена мрежа. Блокирането със знание за приложението принадлежи на клиента или на системно разширение, не на този файл.

Филтърът не създава и маршрути. Когато клиентът падне, маршрутът по подразбиране може все още да сочи към мъртъв тунел и pf превръща това в блокирани пакети, а не в тихо връщане към Wi-Fi. Блокирането е желаният резултат, а не дефект, който да се заобикаля.

Редът решава изхода по-често от текста на правилото. Без quick pf продължава да оценява след съвпадение и печели последното съвпадащо правило, затова широк пропуск близо до дъното отменя внимателните изключения над него. Отбелязването на пропуските като quick прави първото съвпадение окончателно, което авторът на политика обикновено има предвид.

Прочетете първо фактите за интерфейса и крайната точка

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

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

route -n get default
ifconfig -l
scutil --nc list

Първата команда назовава интерфейса, който в момента печели, втората изброява всяко устройство, което ядрото познава, а третата показва VPN конфигурациите, които системата може да стартира. Запишете тези отговори, после прочетете адреса и порта на сървъра от собствената конфигурация на клиента.

Напишете набора от правила около пътя на тунела

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

set skip on lo0
block all
pass out quick on utun0
# maintain this line when the server address changes
pass out quick on en1 inet proto udp to 203.0.113.10 port 1194
# only the resolver the client uses before the tunnel exists
pass out quick on en1 inet proto udp to 192.0.2.53 port 53
pass out quick on en1 inet proto udp from any port 68 to any port 67
pass out quick on en1 inet proto udp to 224.0.0.251 port 5353

Редът за DHCP съществува, защото Mac иска адрес, преди да има такъв, затова заявката излиза от порт 68 към порт 67 без използваем адрес на източника. Редът за multicast позволява на системата да прецени дали безжичната връзка си струва, а премахването му създава машина, която съобщава липса на връзка в работеща мрежа. Редът за крайната точка е това, което позволява на OpenVPN изобщо да стигне до своя сървър; без него block all изпуска външния ръкостиск и тунелът никога не се вдига. Редът за резолвера е по-тесен от общо разрешение за DNS, защото назовава един адрес и един порт вместо всяка заявка, която машината прави.

Тези две изключения — за крайната точка и за резолвера — са тези, които трябва да съществуват; всичко останало остава блокирано. Ако клиентът набира буквален адрес, премахнете реда за резолвера и запазете реда за крайната точка. Ако адресът на сървъра се промени, актуализирайте реда преди следващата връзка или напълнете таблица на pf от собствения hook на клиента и съпоставяйте вместо това таблицата.

Спуснете тунела, после рестартирайте

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

sudo pfctl -n -v -f /etc/pf.conf
sudo pfctl -f /etc/pf.conf
sudo pfctl -e
sudo pfctl -s rules
sudo pfctl -s Anchors
sudo pfctl -a <anchor> -s rules
sudo pfctl -s info

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

Рестартирането е частта, която хората пропускат. macOS чете /etc/pf.conf при зареждане, но четенето на файла не е същото като включване на филтъра, затова набор от правила, който работи сега, може да е неактивен след рестарт. Пуснете после sudo pfctl -s info и потвърдете, че редът за състоянието съобщава филтъра като включен.

Пазете изхода и пътя за рестарт честни

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

sudo pfctl -d
sudo pfctl -f /etc/pf.conf.previous
sudo pfctl -s rules

Устойчивостта изисква launch daemon, който пуска pfctl -e и зарежда вашия файл при стартиране. Отнасяйте се към него като към всяка друга привилегирована задача: абсолютни пътища, дневник, който можете да прочетете после, и тест на машина, до която можете физически да се доберете. Демон, който се проваля тихо, оставя машината незащитена и изглеждаща нормално.

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

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