gSpotx2f / ruantiblock_openwrt

Обход блокировок в OpenWrt с помощью Tor или VPN
GNU General Public License v3.0
164 stars 15 forks source link

Обновление таймаута для правил dnsmasq при инициации нового соединения #35

Closed sirburpalot closed 1 year ago

sirburpalot commented 1 year ago

Возможно, следует добавить такую возможность в качестве опции, чтобы, например, во время листания твиттера не приходилось перезапускать приложение, когда действие записи заканчивается.

Не эксперт в nft, но после чтения документации смог написать следующее правило, и оно вроде бы работает: $NFT_CMD add rule $NFT_TABLE "$NFT_ACTION_CHAIN" ip daddr @$NFTSET_DNSMASQ ct state new set update ip daddr @$NFTSET_DNSMASQ

sirburpalot commented 1 year ago

(ct state new добавил из опасений, что слишком частое обновление таймаута скажется на производительности. Также, возможно, есть смысл маркировать не пакеты, а соединения, чтобы по истечении действия записи существующие соединения не разрывались, но не знаю, насколько это реалистично.)

gSpotx2f commented 1 year ago

Возможно, следует добавить такую возможность в качестве опции, чтобы, например, во время листания твиттера не приходилось перезапускать приложение, когда действие записи заканчивается.

Вы не пробовали увеличить значение таймаута записей сета nftables (в который dnsmasq добавляет IP адреса) в конфиге /etc/ruantiblock/ruantiblock.conf?

NFTSET_DNSMASQ_TIMEOUT="3h"

Там сейчас прописано значение 1h (1 час). Попробуйте увеличить до нескольких часов: 3h, 5h и т.д. Конкретное число можно подобрать опытным путём. Проблема в том, что резолвер ОС на компьютере (или устройстве) кэширует IP, чем чаще DNS-запросы определённого домена - тем дольше он сохраняется в кэше. В каких-то ситуациях одного часа не хватает - IP удаляется из сета, а резолвер ОС не делает DNS-запросов (и соответственно dnsmasq не добавляет IP в сет), потому что IP адрес у него уже закэширован. Также, кэширует запросы и резолвер на роутере (сам dnsmasq), который является DNS-сервером для ваших устройств. Приложение твиттера (или браузер), в любом случае, делает запросы к API для получения новых данных, и по идее, должно запрашивать DNS время от времени.

Не эксперт в nft, но после чтения документации смог написать следующее правило, и оно вроде бы работает: $NFT_CMD add rule $NFT_TABLE "$NFT_ACTION_CHAIN" ip daddr @$NFTSET_DNSMASQ ct state new set update ip daddr @$NFTSET_DNSMASQ

Хорошая идея! Давно хотел покапаться в nftables погубже, но времени не хватает сейчас. ИМХО, ct state new можно убрать (об этом ниже). Действие для обновления таймаута я добавил в то же правило, где выполняется первая проверка по сету в цепочке $NFT_BLLIST_CHAIN, ибо в варианте с отдельным правилом, получается что пакет два раза проверяется на вхождение в один и тот же сет (в двух разных правилах). Пока потестирую, потом добавлю коммит...

Также, возможно, есть смысл маркировать не пакеты, а соединения, чтобы по истечении действия записи существующие соединения не разрывались, но не знаю, насколько это реалистично.)

Да оно вроде и сейчас так работает, уже установленные соединения не разрываются при удалении IP из сета. Я не сетевик ни разу и понимаю всю эту схему так: пакетный фильтр (netfilter) отслеживает состояние соединений (conntrack) и, по умолчанию, новые (или обновлённые, в т.ч. записи в сетах) правила применяются к новым соединениям, а не к тем которые уже установлены, т.е. ваше условие ct state new предполагается, как-бы, неявно и его можно не указывать в правиле в данном случае. Для отбора пакетов уже установленных соединений нужно указывать явно ct state established и т.п. Если посмотреть на счётчики правил (которые метят пакеты для VPN), в них попадают только первые пакеты соединений. Кстати, можно провести эксперимент, поставив закачиваться большой файл с заблокированного сайта и во время закачки (когда уже существует установленное соединение) очистить сет nft flush set ip r d. Соединение не прервётся и файл докачается, но новая попытка закачать тот же файл (т.е. установить новое соединение) будет безуспешной.

sirburpalot commented 1 year ago

Если не указать ct state new, то таймаут все-таки обновляется с каждым отправленным пакетом. Я проверил.