Блокиране на един OpenVPN клиент от LAN, без да спирате тунела
Закачете тунелния адрес на клиента към сертификата му, изхвърлете LAN трафика му в началото на FORWARD, после проверете IPv6, проследените сесии и оцеляването след рестарт.
Един клиент на вашия OpenVPN сървър трябва да загуби достъп до LAN, докато всички други тунели остават активни. Потърсете това и най-добрият отговор обикновено казва, че демонът не може, което е само наполовина вярно: OpenVPN няма защитна стена за отделен клиент, но хостът, който прекратява тунела, вече филтрира пакети. Двете решения, които имат значение, са идентичността, която блокирате, и позицията на правилото. Направете ги правилно и промяната става един ред, който можете да тествате и премахнете.
Закачете клиента, преди да напишете правилото
OpenVPN отдава тунелни адреси от пул, така че 10.8.0.6 е място, а не човек. Когато сесията приключи, наемът се връща и може да бъде даден на следващата връзка, което означава, че правило, написано срещу този адрес, следва мястото, а не потребителя. Затова решете първо какво всъщност блокирате: адрес за кратък експеримент или сертификат за някого, когото искате да държите навън.
За да свържете адреса със сертификата, създайте файл в директорията, посочена от client-config-dir, и дайте на файла точно common name на сертификата. Поставете в него една директива, ifconfig-push 10.8.0.6 255.255.255.0, и този клиент запазва същия тунелен адрес при повторни връзки. За да се приложи това, трябва да съществуват две настройки: client-config-dir трябва да е декларирана в конфигурацията на сървъра, а изпращаният адрес трябва да е в подмрежа, която сървърът може да маршрутизира. Пропуснете едното и файлът се игнорира без грешка, което прави следващия тест на защитната стена подвеждащ.
Временна блокада може да използва адрес от пула, стига тикетът да записва коя сесия го е държала по това време.
Редът определя дали изхвърлянето ще се изпълни
На Linux шлюз, който препраща между тунела и LAN, пакетите преминават през веригата FORWARD. Прочетете командата по-долу като изречение: вмъкни в началото на FORWARD, съпостави трафик, влизащ от tun0, от този единствен хост, насочен към подмрежата на LAN, и го изхвърли.
iptables -I FORWARD -i tun0 -s 10.8.0.6/32 -d 192.168.1.0/24 -j DROP-I е това, което кара правилото да работи. Добавено с -A, то попада под всяко широко разрешение за тунелната подмрежа и никога не вижда пакет. Проверете позицията с iptables -vnL FORWARD --line-numbers и прочетете и броячите: изхвърляне в началото, което не отчита нищо, означава, че трафикът пристига по друг път.
Собственият LAN адрес на шлюза е друг път. Пакетите, изпратени до самата кутия, отиват в INPUT, а не в FORWARD, така че клиент може да загуби LAN хост и все пак да отвори администраторската страница на рутера. Добавете съответното правило INPUT, когато това има значение.
Какво филтърът не може да види
Филтрирането се случва, когато пакетът се оценява, така че установена TCP сесия може да продължи, докато не се затвори или нулира. Ако блокадата трябва да действа веднага, изчистете проследените потоци за този източник с conntrack -D -s 10.8.0.6 след вмъкването на правилото. Ако няколко секунди припокриване са приемливи, запишете този избор, вместо да го оставяте неявен. Във всеки случай следващият човек трябва да знае дали правилото спира живия трафик, или само новите връзки.
Трафикът между партньори никога не докосва защитната стена на хоста. С включено client-to-client OpenVPN препраща тези пакети вътре в демона, така че нито FORWARD, нито INPUT ги вижда. Единствените решения са да изключите client-to-client или да приемете, че партньорите могат да се достигат; правило на iptables няма да види този трафик.
IPv6, фърмуер и оцеляване след рестарт
Правило за IPv4 не казва нищо за IPv6. Ако тунелът и LAN носят и двете семейства, еквивалентното правило трябва да съществува в ip6tables или в набора от правила nftables, който притежава политиката на този хост. Фърмуерът на рутера често скрива netfilter зад собствената си абстракция, така че синтаксис и имена на таблици, копирани от форум, може да не се прилагат.
На OpenWrt документираният път е запис в конфигурацията на защитната стена, а не ръчно написан ред на iptables, и ръчно написаният ред може да изчезне при презареждане на защитната стена. Други дистрибуции възстановяват правилата чрез netfilter-persistent, зареждащ модул или хранилище на доставчика, и тези механизми не са взаимозаменяеми. Докажете избрания с рестарт, защото презареждането минава по различен път.
Проверете по път, после върнете чисто
Тествайте всеки път отделно, защото една успешна проверка скрива останалите. Блокираният клиент трябва да достига интернет през тунела, но да се проваля срещу LAN хост; втори клиент трябва да достига същия хост; адресът на шлюза и пътят към партньор се нуждаят от собствени наблюдения. Запишете резултатите до правилото, за да има следващата промяна базова линия. Таблицата по-долу е наборът, който си струва да остане в тикета.
| Път | Очаквано с правилото | Когато се провали |
|---|---|---|
| Блокиран клиент към LAN хост | Няма отговор | Правилото е под разрешение или източникът не съвпада |
| Блокиран клиент към интернет | Работи през tun0 | Правилото е твърде широко, без съвпадение на дестинация |
| Втори клиент към същия LAN хост | Работи | Правилото съвпадна с повече от предвидения хост |
| Блокиран клиент към LAN адреса на шлюза | Блокирано само със съответното правило INPUT | Липсва правило INPUT |
| Блокиран клиент към тунелен адрес на партньор | Все още работи | client-to-client е включено и извън обхвата на защитната стена |
Връщането е изтриване по спецификация, а не flush: iptables -D FORWARD -i tun0 -s 10.8.0.6/32 -d 192.168.1.0/24 -j DROP премахва точно този запис и оставя останалата част от веригата непокътната. Премахнете същия ред от файла, който възстановява правилата при зареждане, презаредете го и потвърдете, че клиентът отново достига LAN хоста. Flush на FORWARD би отменил и правила, които не сте написали, което превръща връщането във втори инцидент.
Преди да затворите тикета, потвърдете три неща: закаченият адрес съвпада със сертификата, правилото стои над разрешенията с ненулев брояч и файлът за постоянство съдържа същото правило, което сте тествали. Ако нещо от това липсва, блокадата е илюзия в shell сесия.