Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Режим IpSet #152

Open
vitidev opened this issue Oct 12, 2024 · 18 comments
Open

Режим IpSet #152

vitidev opened this issue Oct 12, 2024 · 18 comments

Comments

@vitidev
Copy link

vitidev commented Oct 12, 2024

Возможно бредовая идея, но все же озвучу.

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

На хабре есть статья, где с помощью dnsmasq можно заполнять ipset для нужных доменов на лету и потом роутить по этому ipset в туннель. Фатальным недостатком является необходимость дернуть запросом днс для нужного домена, для чего нужно выключать всякие dns over tls в браузерах, мудрить в андроидах и так далее.
ruantiblock обладает тем же недостатком. Вообще решение через dns обладает одним и те же фатальным недостатком.

А что если попробовать подобный подход. Ведь, в отличие от днс, запросы идут всегда.

Сейчас софт работает так (ну как я понимаю)

1 все запросы на 443 перенаправляются в queue 537 и попадают в софт
2 он накапливает данные для нового коннекта пока не получит sni
3 если sni подходит под условия, то начинается коверканье выходных пакетов
4 и все это добро идет на выход

Что если после детекта sni, если sni подходит под условия (есть в списке хостов и задан ipset), то добавить в ipset destination ip, который, как я понимаю, можно выдрать (ведь можно же выдрать???) из последнего пакета сформировавшего sni (и тем самым избежать проблемы с разницей в днс ответах) и просто добавить его в этот ipset (если он ранее был туда добавлен - для скорости кешировать в памяти). Ну чтобы было минимум переделок.
Как я понял, этот ip вполне подходит

И далее для выходящего трафика можно далее настроить и включать/выключать впн с правилом "заворачивай в меня для всех кто в ipset".

какая стратегия лучше....
1 просто пишем в ipset и потом включать/выключать впн по нужде (ну да туда пойдут запросы с фрагментацией)
2 впн всегда включен и софт просто переключает режими "коверкаем/ipset" и обнуляет ipset при переключении в режим "коверкаем" и начинает его заполнять при переключении в режим "ipset"
....тут нужно подумать.

Но сначала вопрос "вообще правильно ли я мыслю и возможно ли такое?"

@Waujito
Copy link
Owner

Waujito commented Oct 12, 2024

Не могу уловить идею. Зачем так делать? Если заблокировано по IP, анблок вообще не отработает. Если заблокировано просто, можно обходить ТСПУ.

Если говорить про doh, вы его спокойно можете на роутере развернуть.

@vitidev
Copy link
Author

vitidev commented Oct 12, 2024

Если заблокировано просто, можно обходить ТСПУ.

Это если можно. Не далее как сегодня чинили очередную "всё сломалось, обход не работает".
Последняя ли это поломка? Нет конечно. Будут еще? конечно будут.
А пока ищется очередной фикс очередной "обновили ТСПУ" надо как то жить.

вот у меня стоит на роутере. И если ломается youtubeUnblock, то приходится воевать с зоопарком гудбайдпи/байдпи на разных устройствах, что еще тот геморрой (ведь там тоже синхронно сломалось).

Либо же подрубать впн - но туда не хочется заворачивать весь трафик. А только те же домены для которых работает youtubeUnblock.
А как это сделать? Мне нужно где то брать правильные подсети чтобы забивать ими роутинг. Неблагодарное занятие.

Если говорить про doh,

doh тут вообще не причем. Просто подход "мы для нужного домена впишем по запросу нужный ip в ipset" (фича dnsmasq) требует чтобы клиент дернул этот dnsmasq, то есть воспользовался днс роутера, а не своим. И заставлять всех пользоваться днс роутера принципиально неудобно, поэтому и не пользуюсь.

А так youtubeUnblock сможет не только sni портить, а и заполнять ipset. Если порча sni не помогает - переключился на впн и ждешь "фикса порчи sni". И, в отличие от подхода с днс, клиентские устройства никак настраивать не надо - ведь мимо не пройдешь.

@Waujito
Copy link
Owner

Waujito commented Oct 12, 2024

На лету такое вряд ли получится делать. Даже если анблок просто статично стоит и смотрит на sni мимо него, у нас не получится перенаправить существующее соединение через vpn. Даже если мы просто будем стоять и смотреть какие сайты куда подключаются, мы не можем гарантировать то, что в следующий раз он туда же ткнётся (ситуация с ютубом как вариант)
Поэтому лучший вариант в таких случаях это искать в интернете сети нужных нам айпи адресов и просто добавлять их

@vitidev
Copy link
Author

vitidev commented Oct 12, 2024

у нас не получится перенаправить существующее соединение через vpn.

так и не нужно ничего перенаправлять.

Что делает dnsmasq? Он ничего не отслеживает. Получил домен, получил ip, если домен в вайтлисте - вписать ip в ipset
Этакий точечный автопоиск и заполнение таких адресов.

Так и тут. Получили домен (sni), получили ip (destnation ip), если домен в вайтлисте (и включена фича) - вписать ip в ipset
Этакий точечный автопоиск и заполнение таких адресов.

то есть то же самое.
не нужно гарантировать "в следующий раз". Достаточно гарантий "этот ip соотносится с вайтлистом, поэтому попадет в ipset (если не попал ранее)". И ничего более.

А далее пользователь замутит что ему удобно на основании этого ipset.

@PulseDiver
Copy link

PulseDiver commented Oct 15, 2024

Возможно бредовая идея, но все же озвучу.

Если у вас Openwrt, попробуйте пакет PBR (Policy Based Routing) - он это делает из коробки. есть в родной репе.

@vitidev
Copy link
Author

vitidev commented Oct 15, 2024

@PulseDiver Гугление намекает что даже для политики основанной на dest_addr все равно будет использоваться резолвинг днс

"If you’re using domain names in the dest_addr option of the policy, it is recommended to use dnsmasq.nftset options for resolver_set. Otherwise, the domain name will be resolved when the service starts up and the resolved IP address(es) will be added to an apropriate set or an iptables or nft rule. Resolving a number of domains on start is a time consuming operation, while using the dnsmasq.nftset options allows transparent and fast addition of the correct domain IP addresses to the apropriate set on DNS request or when resolver is idle."

что на корню ломает весь смысл "не зависеть от разницы днс на разных устройствах"

@Waujito
Copy link
Owner

Waujito commented Oct 15, 2024

Что могу сказать. В целом никто не запрещает развернуть ip логгер на анблоке. Можно просто в функции mangle.c->process_tcp_packet после строки if (vrd.target_sni) написать эту логику. А дальше уже в тот же ipset писать, и в PBR, или еще куда нибудь. Тут уж исходники есть, сборщики есть, а дальше у кого на что фантазии хватит

@vitidev
Copy link
Author

vitidev commented Oct 15, 2024

@Waujito
Решение "пишем ip в какой то лог, потом парсим этот лог и формируем ipset" имеет слишком большой лаг.

Решение "сразу пишем в ipset" уже требует приемлемых знаний c++ чтобы правильно прикручивать подсказки от ИИ (особенно учитывая что оно не должно тянуть новых зависимостей и придется работать с тем, что уже есть) и не перестрелять все ноги.

Достать ip просто, а вот остальное...

ИИ говорит что это возможно, но по факту выдает оторванный от реальности код для libmnl (наполнен разными константами, про которые ни гугл, ни гитхаб не выдают ни одного ответа)

Ну да, можно просто тупо в конфиге задать команды для шелла, которые потом просто заполнять нужными ip и вызывать через system(), но все равно нужно же кешировать ip чтобы лишний раз не дергать систему. Что опять же требует знаний чтобы не наделать утечек памяти.

В общем это я смогу сделать разве что через 21 день по "сишному календарю"

@PulseDiver
Copy link

PulseDiver commented Oct 15, 2024

@PulseDiver Гугление намекает что даже для политики основанной на dest_addr все равно будет использоваться резолвинг днс

"If you’re using domain names in the dest_addr option of the policy, it is recommended to use dnsmasq.nftset options for resolver_set. Otherwise, the domain name will be resolved when the service starts up and the resolved IP address(es) will be added to an apropriate set or an iptables or nft rule. Resolving a number of domains on start is a time consuming operation, while using the dnsmasq.nftset options allows transparent and fast addition of the correct domain IP addresses to the apropriate set on DNS request or when resolver is idle."

что на корню ломает весь смысл "не зависеть от разницы днс на разных устройствах"

"не зависеть от разницы днс на разных устройствах" - запретите на роутере использовать в своей сетке собственные днс устройств,
т.е использовать только днс роутера. в дополнние настройте днс на роутере чз doh, например пакет https dns proxy с анонимными серверами, чтобы не палить страну чз dns leaks

@vitidev
Copy link
Author

vitidev commented Oct 15, 2024

@PulseDiver

запретите на роутере использовать в своей сетке собственные днс устройств

Я хочу облегчить себе жизнь, а не усложнять. Само требование "вы на клиенте настраивайте вот так" меня не устраивает. И "не настроите не пущу" не является лечением этой проблемы.

@Waujito
Copy link
Owner

Waujito commented Oct 15, 2024

У iptables и nftables разные ipsetы. Для iptables есть libipset, для nftables libnftnl. На последних версиях openwrt стоит система nftables. Пример здесь: https://git.netfilter.org/libnftnl/tree/examples/nft-set-elem-add.c

@vitidev
Copy link
Author

vitidev commented Oct 15, 2024

@Waujito ух как страшно выглядит. Еще страшнее чем ИИ выдала

Получается что решение "в лоб" самое простое.

0 добавляем в конфиг опцию "писать в ..." и "вызвать команду такую то"
1 при старте софта ничего не делаем. Никаких чтений "ранее мы добавляли эти ip". Это даст оверхед для первоначальных добавлений уже добавленных, но этим можно пренебречь
2 заводим какую нибудь структуру для кеширования ip. минимально хешсет, но раз это ip, то можно и более экономно хранить
домены хранить не нужно. мы всего лишь отсекаем повторные обращения к одному ip
2 в ветке if (vrd.target_sni) если активна опция "писать в ..."
а) если нет в кеше ip
б) заносим в кеш ip (или как конечный шаг. тут спорно как лучше)
в) берем команду из конфига. подставляем в нее ip
г) вызываем шелл команду через system. Команда выполняется долго, но не дольше чем тот же dnsmasq делает то же самое.
д) результат можно и в лог записать.

Никаких зависимостей от платформы.

Ничего не забыл?

@Waujito
Copy link
Owner

Waujito commented Oct 15, 2024

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

Плюс не понимаю, про какой кэш вы говорите. Лучший вариант тут действительно использовать libnftnl, максимально низкоуровневую коммуникацию с nftables в ядре. Делать system из программы - худший вариант, который только может быть.

@PulseDiver
Copy link

PulseDiver commented Oct 15, 2024

@PulseDiver

запретите на роутере использовать в своей сетке собственные днс устройств

Я хочу облегчить себе жизнь, а не усложнять. Само требование "вы на клиенте настраивайте вот так" меня не устраивает. И "не настроите не пущу" не является лечением этой проблемы.

Почему усложнить-то? Все клиенты в вашей домашней сетке будут использовать единый dns от роутера, выданный по dhcp. От того, что у вас каждое устройство живет само по себе, наоборот, все усложняяет. Но в любом случае, вам решать. Я только предложил. ;)

@Waujito
Copy link
Owner

Waujito commented Oct 15, 2024

Вот согласен. С единым doh dns избавляемся от проблемы настройки его на каждом телевизоре и прочих устройствах

@vitidev
Copy link
Author

vitidev commented Oct 15, 2024

@PulseDiver

Я знаю про вариант с единым dns сервером. Но он неудобен. Да сам этот issue именно потому и родился. Я об этом в стартовом посте и описал как основную причину поиска других решений.

Я не хочу отключать включать переключать что-то в зависимости от того, где устройство находится. Сидишь дома - выключи privacy dns, вышел куда то - включи.

От того, что у вас каждое устройство живет само по себе, наоборот, все усложняяет

ничего не усложняет, а наоборот. Это такая же реализация как это делает dnsmasq во всяких там PBR, просто не на этапе запроса днс (что и требует дополнительных приседаний на устройствах), а на уровне самого запроса, который никуда мимо не пройдет независимо от что там на устройстве (QUIC не в счет). Ведь у нас есть хост и ip (который, судя по всему, подходит). Далее просто делаем то же самое.

@PulseDiver
Copy link

PulseDiver commented Oct 15, 2024

Дак не нада ничего выключать переключать. Doh живет на своем порту. Роутер блокирует днс запросы во внешку и перенаправлет их от устройств в домашней сетке на порт doh и все. Вышли на улицу - мобила юзает днс провайдера.

@vitidev
Copy link
Author

vitidev commented Oct 15, 2024

@PulseDiver
в андроид 9+ используется Dns over Tls. И мне нисколько не хочется выключать его ради роутера. И я сомневаюсь что андроид проигнорирует настройку ради ответа от обычного днс, которому он никак не может доверять (я конечно не проверял, но как бы в этом и есть смысл шифрования днс чтобы в него никто не лез и не видел что там)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants