Техпредложение: повышаем совместимость с SOF и отправкой INVALID-пакетов на легаси-билдах OpenWRT. #108
Unanswered
eierfrucht
asked this question in
Q&A
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Просьба ногами не бить, предложенный ниже скрипт целиком написан AI, но после нескольких суток работы с этим костылем я вполне им доволен. Прошу взглянуть на него и оценить, имеет ли смысл добавлять что-либо из этой логики к самому zapret2, т.к. выполнение скрипта после каждого перезапуска фаирволла или самого zapret2 — как-то совсем костыльно.
Мое окружение: древний роутер с OpenWRT 21.02, ipset, firewall3, любые связанные с IPv6 компоненты вырезаны. Zapret2 работает хорошо, SOF предсказуемо оступался время от времени (как и было предсказано), памяти все вкупе потребляет несколько мегабайт (в зависимости от настроек), все вроде бы устраивало.
Я спросил у AI, почему многие найденные через blockcheck2.sh стратегии не работают через собственно zapret2 live environment, и первая часть ответа AI была очевидной:
1. Пробитие DPI отсылкой мусора через raw sockets еще не гарантирует, что нечто более длинное и сложное не будет спалено DPI сопоставлением SNI и TLS HELLO и еще по множеству признаков, которые при тестировании через blockcheck2 просто не присутствуют в уравнении. С этим ничего сделать нельзя, кроме подыскивания иной стратегии.
2. Получение от сервера каких-то пакетов в ответ еще не гарантирует, что сервер согласится нормально пожать тебе руку (потому что во многих сценариях он получает out of spec приветствие, и многие CDN на это реагируют отлупом, плюс операционка и ее конфигурация на сервере играют свою роль). С этим тоже ничего сделать нельзя.
А вот дальше — уже интереснее.
3. Поскольку большинство DoH-серверов нормально реагируют на изувеченный zapret2 трафик, забывчивый или неопытный юзер не добавляет их IP в белый лист, и оно работает до поры до времени, а потом очередная стратегия ломает DoH, и не до конца освоивший белые списки пользователь недоумевает, что же происходит. Даже если юзер добавляет DoH-сервера в белый список, при неосторожных манипуляциях с конфигами / обновлении zapret2 файл zapret-ip-exclude.txt может перезаписаться, это остается незамеченным, и между обнаружением ошибки и осознанием, почему все сломалось, может пройти довольно большое время (если пользователь неопытен и механика работы zapret-ip-exclude.txt не вбита уже в подкорку). Предлагаемое решение: в качестве защиты от дурака специальным скриптом пускать любой трафик к DoH-серверам вообще в обход zapret2, т.к. в отличие от любых других исключаемых хостов DoH слишком критичен и его нечаянная поломка может деморализовать малоопытного юзера. Иными словами, исключение IP DoH серверов нужно продублировать где-то у пользователя совсем под носом в качестве emergency fallback option, пока пользователь еще только учится.
4. SOF на ipset нестабилен, подробности изложены в документации и дискуссиях, но можно попытаться переписать правила firewall3 так, что мутный race condition почти не будет возникать, или не будет возникать вовсе — но нужно пробовать и смотреть, как оно будет работать на разных OpenWRT от 21.02 и до более старых (и нужно вообще поменьше полагаться на локальные опции OpenWRT и иных прошивок, а ориентироваться побольше на сферический случай в вакууме, потому что даже одна и та же прошивка, собранная для разных устройств, может содержать какие-то слабо задокументированные кастомизации, которые проще заранее обойти, чем предугадать и надеяться, что пользователь вручную все проверит и настроит под себя).
5. Самое важное, что и побудило меня на открытие этого тикета. OpenWRT, по словам AI, может выборочно дропать все или только некоторые исходящие INVALID пакеты независимо от того, что указано в option drop_invalid 'X', и веры этому параметру быть не может. Список причин, по которым это может происходить, начинался с nf_conntrack_tcp_loose, net.ipv4.conf.all.rp_filter, net.ipv4.conf.default.rp_filter, а заканчивался длинной простыней текста про какие-то совсем маргинальные случаи, где к такому поведению могут приводить параметры, с которыми собрано ядро. Предлагаемое решение: не полагаться на любые манипуляции с настройками сетевого стека (как, например, что-то, что могут выполнять zapret init scripts), а явным образом проинструктировать фаерволл любые invalid-пакеты сразу же отправлять по назначению в обход всех остальных цепочек.
6. Перемещение пакетов из kernel space в user space, где живет nfqws2 — дорогое удовольствие. Почему бы нам сообразно тому, что в мануале говорится про маркировку пакетов, connbytes и т.д., не сократить цепочку обработки так, чтобы минимизировать число передач и не облегчить жизнь CPU? Также этот шаг поможет стабилизировать работу SOF.
Был предложен скрипт, который был добавлен а) в инклюды фаирволла, чтобы запускаться после каждого перезапуска фаирваолла б) в скрипт перезапуска запрета через alias в /etc/profile. Я не до конца понимаю, как достигаются результаты, но в моем случае я их прочувствовал практически сразу:
1. Несколько ранее не работавших в live environment стратегий из выдачи blockcheck2 теперь заработали — считанные единицы прибавки, но уже хорошо!
2. SOF, включенный согласно мануалу (отключаем systemwide, в конфиге ставим FLOWOFFLOAD=software) начал работать, как часы. Не факт, что поможет на других версиях OpenWRT, но 21.02 это последняя версия с ipset / firewall3, и она отлично работает даже на совсем мезозойских роутерах при должной настройке. Поэтому для легаси-устройств имеет смысл ориентироваться именно на 21.02 и не запариваться на что-то более старое.
3. Даже с полностью отключенным SOF исчезли резкие скачки нагрузки на CPU, когда с какого-нибудь хоста из текущего ipset качается здоровенная картинка или потоком идет видео. Без iptables -t mangle -m connbytes --connbytes X:Y -m mark ! --mark 0x40000000/0x40000000 что бы я в PKT_IN и PKT_OUT ни писал — CPU на некоторых коннектах сразу становилось плохо.
Подозреваю, что многое из этого наверняка можно было как-то реализовать через конфигурацию самого zapret2, поэтому за этот тикет прошу строго не ругать. Решил написать, потому что вдруг, да есть в предложенном AI решении хоть капля хорошего. Ниже прилагаю сам скрипт. Нормализация работы SOF там, где оно раньше приводило к проблемам в 1 коннекте из каждых 5, особенно заинтриговала. Общий тон ответа AI был в духе «на сообразительность пользователя надеяться бесполезно, как и на то, что манипуляции с настройками OpenWRT через init scripts гарантированно дадут результат — все, что можно силами фаирволла отправить наружу как можно раньше и как можно с меньшим пропусканием сквозь внутренние механизмы OpenWRT, так и следует отправлять»
Beta Was this translation helpful? Give feedback.
All reactions