Няма tun0? Съпоставете дешифрирания IPsec в nftables с meta ipsec
Шлюз, базиран на политики, препраща открити вътрешни пакети, които все още пристигат на eth0. Съпоставете пътя за сигурност и услугата, а не липсващ интерфейс.
Очаквате тунелен интерфейс, търсите го и в защитната стена няма нищо за съпоставяне. Това е нормално за шлюз, базиран на политики: криптираният обмен пристига на физическия интерфейс и дешифрираният вътрешен пакет, който след това се препраща, също се наблюдава като пристигащ на същия интерфейс. Няма tun0, защото нищо не го е създало.
Вътрешната заявка все още е отделен пакет със свой източник, дестинация и услуга и ядрото знае от коя асоциация за сигурност е излязъл. Именно това знание може да съпостави едно правило на защитната стена.
Два пакета, един интерфейс
Представете си входящата посока. Пристига пакет, инкапсулиран в ESP или UDP, ядрото намира съответстващата политика, дешифрира го и предава открития пакет на пътя за препращане. Правило, което гледа само името на интерфейса, не може да различи този пакет от всеки друг трафик, пристигащ по същия кабел.
Това, което го отличава, е контекстът на входящия път за сигурност, прикачен към пакета. nftables го показва като meta ipsec exists, което е вярно, когато пакетът е пристигнал през път за сигурност IPsec. Комбинирайте го с пула от клиенти, дестинацията и услугата и правилото става достатъчно конкретно, за да е безопасно.
Да пропуснете контекста е обичайната грешка и тя е грешка в сигурността, а не козметична. Правило, което приема всичко от пула клиенти, приема също толкова охотно подправен пакет от локалната мрежа, защото адресът на източника сам по себе си не е доказателство за нищо. Контекстът на пътя за сигурност е най-евтиният начин да направите източника смислен. Пишете правилото с него от самото начало, вместо да го добавяте след одит.
Напишете правилото за препращане
Да приемем удостоверена услуга за отдалечен достъп IPv4 с клиенти в 10.90.0.0/24 и една одобрена дестинация на 203.0.113.40. Фрагмент от правило за този поток изглежда така.
meta ipsec exists ip saddr 10.90.0.0/24 \
ip daddr 203.0.113.40 tcp dport 443 \
oifname "eth0" counter accept
Адресите и интерфейсът са примери за замяна. Поставете прегледания еквивалент в политиката за препращане преди правилото, което иначе би отхвърлило потока, и не изчиствайте съществуващ набор от правила, за да го инсталирате; шлюзът не е експеримент в чиста стая.
Терминът oifname си заслужава да остане. Той документира решението за изход и не позволява на правилото да съвпадне в посока, която не сте имали предвид, а това има значение на шлюз с няколко пътя към интернет. На тестова машина с една изходяща връзка терминът изглежда излишен и точно затова се премахва, преди машината да получи втора връзка.
Разрешенията за външния обмен са отделни. Входящият път на шлюза се нуждае от портовете за IKE и ESP или UDP-инкапсулация, които действително използва, и тези разрешения не дават нищо относно дешифрирания пакет отвътре. Смесването на двете е начинът, по който работещ тунел се сдобива със защитна стена, която препраща всичко.
Входящият контекст не е изходящ контекст
Същото семейство изрази покрива другата посока с rt ipsec, който описва изходящата асоциация за сигурност, която пакетът ще използва. Той отговаря на различен въпрос: не откъде е дошъл този пакет, а дали ще бъде защитен в следващия си участък.
Това разграничение има значение на шлюз, който едновременно прекратява един тунел и препраща към друг. Пакет може да пристигне дешифриран и все пак да трябва да излезе криптиран, а приемане, написано само за входящия контекст, не казва нищо за изходящото изискване. Ако политиката изисква тази защита, наборът от правила трябва да я изрази, вместо да предполага, че маршрутизацията ще се погрижи.
Дръжте двата въпроса в отделни правила, за да може читателят да види кое се налага. Едно хитро правило, което проверява и двете, е по-трудно за преглед и много по-трудно за отстраняване на грешки, когато едната му половина спре да съвпада. Две правила с броячи също ви казват кое изискване се проваля, което едно обединено правило никога няма да направи.
NAT не е решение на защитната стена
Трафикът към интернет от частен пул клиенти обикновено се нуждае от транслация на източника, за да намери отговорът пътя обратно. Но трафикът, избран за друга изходяща политика IPsec, трябва да запази нужното си освобождаване и маскирането на всеки частен източник без мисъл за следващото решение за защита го разваля.
Приемането вътре във верига NAT също не е общо разрешение. NAT и филтрирането имат различни задачи и веригата NAT не проверява всеки следващ пакет от установен поток, поради което разчитането на нея за сигурност дава правила, които изглеждат работещи при тест и се провалят под натоварване.
Обратното също е вярно и изненадва хората: приемане някъде в една базова верига за филтриране не тежи нищо срещу по-късно отхвърляне в друга приложима верига. Редът и обхватът на веригата решават изхода, а не наличието на приемане във файла.
Проверете точната вътрешна услуга
Тествайте конкретната дестинация и порт, които сте разрешили, от реален клиент и потвърдете, че отговорът се връща. След това тествайте нещо, което не сте разрешили, и проверете, че не минава, защото твърде широко правило минава първия тест също толкова добре, колкото правилното. Заявка, която изобщо не напуска клиента, също не е резултат от защитната стена, затова четете броячите, за да видите дали пакетът е бил оценяван въобще. Два теста и едно отчитане на брояч ще ви кажат повече от един следобед четене на набора от правила.
Справочникът на nftables документира meta ipsec, rt ipsec и изразите, специфични за посоката, и точно там е мястото да проверите синтаксиса спрямо инсталираната ви версия. И дръжте обхвата явен: това е пример за IPv4, той не казва нищо за IPv6 и не превръща произволното публично препращане на портове в част от услугата VPN.