You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Leak between private space and per-app split tunneling #1153
Leak between private space and per-app split tunneling
The government has ordered Russian tech companies to spy on users and detect VPNs. Yandex discovered and is actively exploiting this vulnerability. This vulnerability puts all private servers of users at risk, potentially ending up on a blacklist.
Almost all mobile clients based on xray/sing-box run a local socks5 proxy without authentication.
At the same time, per-app split tunneling is implemented using VpnService, which redirects traffic to tun2socks (or something similar). But if there is spyware on the user's device (for example, as part of a government application), nothing prevents it from connecting directly to this socks5 proxy, bypassing VpnService, and discovering the user's external IP address.
Disable the local SOCKS proxy entirely - sing-box does not require a proxy for the tun inbound.
Require authorization for the proxy - either with auth data generated by the app or set by the user.
With either option, we may enforce this behavior entirely or give a toggle to the user. I think we should prefer the behavior that prevents leaking by default but give a toggle to the user if they know what they are doing.
Reacted by Terramin, Alexey, Yegor, ‮, Ilya Yurensky, orlalex, Gamover92, Evgeny Penkov, thealien, Zavar30 and 17 more
At present, this issue is resolved by a simple routing rule, which blocks all traffic destined for the SOCKS proxy.
{
"inbound": ["mixed-in", "socks-in"],
"outbound": "block"
}
Where should this be written?
Routes - Create new - Custom configuration
RU: Маршруты - Создать новый - Пользовательская конфигурация
Reacted by Maxim Mordasov, endless1739, Dmitry, Mastade, KeineDX4, F1Soda, Thanty, IWebghostI, orlalex, Skilazer and 3 more
Thanks, this prevents leakage of outbound IP, but doesn't prevent observing of VPN app presence on device. For example Yandex.Market app still see and warning about this.
It’s impossible to hide the fact that you’re using a VPN without root access. And in my opinion, there’s no need to anyway.
The main thing is that the IP address of the exit node isn’t leaked (when using per-app split tunnelling)
Incidentally, there are a few issues with this on xray kernels. I had to create a fork to patch this vulnerability.
It’s impossible to hide the fact that you’re using a VPN without root access.
Is there no other way to implement per-app split tunneling on non-rooted devices other than through the tap2socks?
And in my opinion, there’s no need to anyway.
We'll see in a month or two when Russian apps stop allowing users to access their services with the socks5 port detected on the device.
The problem isn’t even the proxy, which can be disabled, but the interface detection (tun0, wg0, etc.), which cannot be hidden without root access.
As a temporary solution, you could use a "system clone" (essentially creating another system with its own apps) on BBK smartphones (Oppo, 1+, Realme, Vivo).
It’s also worth remembering that many companies use legitimate VPNs to access their remote resources. So the scenario you’ve described seems unfeasible.
Even if Im wrong and such apps do appear, they can always be patched.
Android, in system menu > Setting > Network and Internet(for me) > VPN > NekoBox > Configure > enable "Always-on VPN", enable "Block connection without VPN"
Now all connection, access via NekoBox, add application to Route "direct" if need direct access
Add application to Route "proxy" if need use proxy profile
Думаю нашел еще одно решение.
NekoBox > Настройки > Сервисный режим > VPN
NekoBox > Настройки > Режим VPN для приложений - Выключить
Последовательность правил очень важна, чем выше, тем раньше оно применяется !!!
NekoBox > Маршруты > Создать Маршруты > Имя "proxy", Выбрать приложения, Outbound - "Прокси"
NekoBox > Маршруты > Создать Маршруты > Имя "direct", Выбрать приложения, Оutbound - "Обход"
Android системе > Настройки > Мобильная сеть(у меня) > VPN > NekoBox > Настройки > Включить "Постоянная VPN сеть", включить "Блокировать соединения без VPN"
Теперь все соединения в сеть управляются через NekoBox, добавляя в правило "direct" приложения ходят напрямую.
Добавляя приложение в правило "proxy" будет ходить через vpn/proxy
Еще раз повторю последовательность правил важна, чем оно выше тем раньше применяется !
@Gpalm1 why?.. The point is that we proxy only specific apps and specific domains, all other domains are beind processed with the last rule, which is direct outbound. So no matter what ip checker is used - if it's url is not in the proxying list, it will go through the last direct rule. At least, it works for me this way on my device (realme gt 7 pro)
And i actually got another challenge - attempting to deal with naïve proxy. It keeps socks5 open no matter what i do, guess it just works that way, but not sure actually. Will be much grateful if someone points me how to figure it out.
It happens with naïve proxy only:
And that telegram dc being accessed via socks is real pain in my butt and potential leak of vpn external ip (while vless connections are totally fine, as i posted some messages above), but i have no idea how to fix it
A you about line 1 about socks or last line about mtproto?
I think both things in report in checker.
I have the same "warns", but:
Socks5 blocked in routing an any connection closed (can be check by curl or any other tool)
Checker says it found Mtproto on ... port with spcks5.. really?.. looks like stupidity.
Ok, try to use socks5 proxy (opened by NekoBox but blocked by routing rule) in telegram - i thing tg will not work.
But checker says it saw mtproto!)))
Ru: я думаю, это какая-то глупость в отчёте чекера. Про сокс написано, что открыто, тут правильно, но коннекта не будет, если проверять руками. А последний пункт про мтпрото да ещё на порте, который выше обозначается как найденный сокс5 - тут звучит как бред.
@thealien guess i should ask rknrardener devs about it. I agree, it looks pretty strange, maybe it reports that tg is "accessible" in case it finds socks port no matter can it connect to it or not
@thealien Несколько вопросов, первое:
Я так понимаю в конфигах на правилах нет нужды прописывать аутбаунд? Потому что если проверять и сравнивать то выходит что аутбаунд в самом некобоксе так же справляется с задачей, то есть вместо: { "inbound": ["mixed-in", "socks-in"], "outbound": "block" }
Достаточно написать: { "inbound": ["mixed-in", "socks-in"] }
И в самом приложении в аутбаунд выбрать "Блокировать", результат выходит я так понимаю тот же, второе по поводу последнего правила: { "ip_cidr": ["0.0.0.0/0", "::/0"], "outbound": "block" }
Что именно оно делает? Всё остальное блокирует либо пускает в обход прокси если написать "direct"? (К слову опять же в результате проверки я так понял что "block" будет стоять выше в приоритете, то есть если прописать "block" и в приложении выбрать "direct" или прописать "direct" и выбрать "block" то всё равно будет "block")
Если да и всё остальное должно как-то пускаться, то не лучше в целом убрать это правило и просто написать: { "outbound": "direct" }
В таком конфиге некобокс вроде как точно пропускает всё остальное в обход прокси и проблемы что в браузере всё проксируется не возникает и тогда уже если нужно можно делать правило чтобы проксировались только определённые домены.
Не считаю что разбираюсь в теме, просто спрашиваю на основе того что я пытался делать пока бился над решением. В любом случае всё заработало (вместе с решением @s809) и за предложенное решение спасибо!
Всё верно.
Я когда искал инфу о том,что писать в когфигах рулов, были примеры с условием + аутбаунд. Так и пошло в начале и в примерах.
Ну и вообще очевидно, что кастом конфиг просто сливается с рулом, будучи в приоритете (т.е. аутбаунд в json конфиге рула перезапишет то, что выбрали в ui рула).
И да, логичнее и очевиднее в конфиге оставить только те условия, которые нельзя и выбрать в ui, а тот же аутбаунд юзать в ui, чтобы не было путаницы и недопонимания.
А ещё, как я дошел до ip_cidr.
Я хотел последним правилом блочить все, но если создать правило и в ui выбрать outboud block, то ничего не происходило. Как мне сказал гпт - это из-за того, что условий нет и в финальный конфиг правило просто не попадает (но честно - финальный конфиг я не перепроверял).
И в итоге спросил у гпт, как сделать, чтобы рул блочил весь трафик. Получил пример кастом конфига с ip cidr, который заработал. И я ним делился в исходном виде :)
Но очевидно, что достичь цель можно и другими настройками и более кратко и оптимизировано (о чем вы выше и написали).
Что именно оно делает?
Мне гпт говорит такое (и поведение вроде получаю описанное, нужное), цитата
Если в роутинге NekoBox указать:
JSON
{
"ip_cidr": ["0.0.0.0/0", "::/0"],
"outbound": "block"
}
ты получишь полную блокировку всего IP-трафика.
Почему
0.0.0.0/0 → охватывает все IPv4 адреса
::/0 → охватывает все IPv6 адреса
То есть правило матчится на любое соединение, у которого известен целевой IP.
Фактически: 👉 любое подключение, которое дошло до стадии определения IP, будет отправлено в outbound block.
About telnet to socks5.
It is success because port opened and telnet can connect.
But actually request will be blocked (i mean real request via socks5).
Check should be like curl --proxy socks5h://127.0.0.1:2080 2ip.io
(in termux for example)
But!
It doesn't matter, because U just delete socks5 inbound and now it doesn't exist at all and no problem here.
And i actually got another challenge - attempting to deal with naïve proxy. It keeps socks5 open no matter what i do, guess it just works that way, but not sure actually. Will be much grateful if someone points me how to figure it out.
It happens with naïve proxy only:
And that telegram dc being accessed via socks is real pain in my butt and potential leak of vpn external ip (while vless connections are totally fine, as i posted some messages above), but i have no idea how to fix it
Viyorez попробуй добавить самое нижнее правило (в конец всех правил) такое: src ip (source) - 0.0.0.0/0, ::/0 -> Обход каким-то чудом у меня заработало
это НЕ в конфиг!! в графич интерфейс
Try adding a bottom-most rule like this: src ip (source) - 0.0.0.0/0, ::/0 -> direct Somehow it worked for me.
and-rassk не помогло, термукс все также выдает айпишник впна, хардединг детектит. может нам списаться где нить? ибо тут не удобно
Самый хардкорный способ понять, что не так и почему отличается - сравнить итоговые json конфиги, которые видны в логах (журнал) при запуске соединения.
Например через https://jsondiff.com (либо другой сервис для сравнивания json структур).
(но конечно это приемлемо для конфигов родственных программ, тут конечно форк, но мало ли, что под капотом в логике изменено)
P.s. а общие настройки точно одинаковые? Я про список аппов в главных настройках (не роутинге), там одинаково и режим одинаковый?
список приложений тот же, да, эскортом пользовался. правило те же.
поподробнее про джсон конфиги, я не особо понял что сделать и как он работает
Этот вопрос лучше адресовать разработчикам самого ядра (sing-box), так как NekoBox - это только графическая оболочка, и добавление новых протоколов зависит от того, появятся ли они в самом ядре.
Давайте не будем уводить обсуждение в сторону.
Простите, а разве sing-box не поддерживает xhttp? Как тогда на винде у меня на нем xhttp ключ работает?
Добавил отключалку для mixed-in socks5 с блокировкой неиспользуемых контролов, и автогенерируемые креды для naive и подобных, т.к. сейчас они полностью открыты, и через них виден реальный внешний IP впн. С этим теперь не требуется делать отдельные правила для отключения mixed-in и кастомные джейсоны
@thealien Подскажите, а приложения из главных настроек (режим VPN для приложений) нужно убирать? Я создал правило с приложениями, убрал их из настроек и они перестали работать(
Activity
neur0ner25 commentedon Apr 7, 2026
+1
Fa1ry7a1l commentedon Apr 7, 2026
itsTPM commentedon Apr 7, 2026
I see two solutions that may work:
tuninbound.With either option, we may enforce this behavior entirely or give a toggle to the user. I think we should prefer the behavior that prevents leaking by default but give a toggle to the user if they know what they are doing.
nyan-ame commentedon Apr 7, 2026
+1
maxi08pa commentedon Apr 7, 2026
+!!!
priZrak7495 commentedon Apr 7, 2026
+1
sou1jacker commentedon Apr 7, 2026
At present, this issue is resolved by a simple routing rule, which blocks all traffic destined for the SOCKS proxy.
{ "inbound": ["mixed-in", "socks-in"], "outbound": "block" }priZrak7495 commentedon Apr 7, 2026
Where should this be written?
sou1jacker commentedon Apr 7, 2026
Routes - Create new - Custom configuration
RU: Маршруты - Создать новый - Пользовательская конфигурация
YegorKehl commentedon Apr 7, 2026
Thanks, this prevents leakage of outbound IP, but doesn't prevent observing of VPN app presence on device. For example Yandex.Market app still see and warning about this.
sou1jacker commentedon Apr 7, 2026
It’s impossible to hide the fact that you’re using a VPN without root access. And in my opinion, there’s no need to anyway.
The main thing is that the IP address of the exit node isn’t leaked (when using per-app split tunnelling)
Incidentally, there are a few issues with this on xray kernels. I had to create a fork to patch this vulnerability.
YegorKehl commentedon Apr 7, 2026
Is there no other way to implement per-app split tunneling on non-rooted devices other than through the tap2socks?
We'll see in a month or two when Russian apps stop allowing users to access their services with the socks5 port detected on the device.
sou1jacker commentedon Apr 7, 2026
The problem isn’t even the proxy, which can be disabled, but the interface detection (tun0, wg0, etc.), which cannot be hidden without root access.
As a temporary solution, you could use a "system clone" (essentially creating another system with its own apps) on BBK smartphones (Oppo, 1+, Realme, Vivo).
It’s also worth remembering that many companies use legitimate VPNs to access their remote resources. So the scenario you’ve described seems unfeasible.
Even if Im wrong and such apps do appear, they can always be patched.
Samamy commentedon Apr 7, 2026
I think find another "fix".
Думаю нашел еще одно решение.
Еще раз повторю последовательность правил важна, чем оно выше тем раньше применяется !
thealien commentedon Apr 7, 2026
Check this, add 3 rules to routing:
before these rules exec
curl 2ip.io --interface tun0returns vpn's ipbut with rules it return error like
curl: (7) Failed to connect to 2ip.io port 80 after 133 ms: Could not connect to server(tested in ternux and ofcourse termux not whitelisted)) )
26 remaining items
IdiotEbrilo commentedon Apr 11, 2026
@Gpalm1 why?.. The point is that we proxy only specific apps and specific domains, all other domains are beind processed with the last rule, which is direct outbound. So no matter what ip checker is used - if it's url is not in the proxying list, it will go through the last direct rule. At least, it works for me this way on my device (realme gt 7 pro)
IdiotEbrilo commentedon Apr 11, 2026
And i actually got another challenge - attempting to deal with naïve proxy. It keeps socks5 open no matter what i do, guess it just works that way, but not sure actually. Will be much grateful if someone points me how to figure it out.
It happens with naïve proxy only:
And that telegram dc being accessed via socks is real pain in my butt and potential leak of vpn external ip (while vless connections are totally fine, as i posted some messages above), but i have no idea how to fix it
thealien commentedon Apr 11, 2026
A you about line 1 about socks or last line about mtproto?
I think both things in report in checker.
I have the same "warns", but:
Ok, try to use socks5 proxy (opened by NekoBox but blocked by routing rule) in telegram - i thing tg will not work.
But checker says it saw mtproto!)))
Ru: я думаю, это какая-то глупость в отчёте чекера. Про сокс написано, что открыто, тут правильно, но коннекта не будет, если проверять руками. А последний пункт про мтпрото да ещё на порте, который выше обозначается как найденный сокс5 - тут звучит как бред.
IdiotEbrilo commentedon Apr 11, 2026
@thealien guess i should ask rknrardener devs about it. I agree, it looks pretty strange, maybe it reports that tg is "accessible" in case it finds socks port no matter can it connect to it or not
IdiotEbrilo commentedon Apr 11, 2026
@thealien checked a bit, and got confused. The first curl was executed with vless up (got rejected), the second with naïve (got connected).
Funny thing is in both cases the first rule in routing chain was this one:
Upd: 2080 gets inaccessible if the only inbound available is tun, which is done by that your config:
But naïve fails with it
Also keep in mind that if you remove that tun config and leave socks blocking rule active you'll be able to curl 127.0.0.1:2080
DarkSide-DarkSide commentedon Apr 12, 2026
@thealien Несколько вопросов, первое:
Я так понимаю в конфигах на правилах нет нужды прописывать аутбаунд? Потому что если проверять и сравнивать то выходит что аутбаунд в самом некобоксе так же справляется с задачей, то есть вместо:
{ "inbound": ["mixed-in", "socks-in"], "outbound": "block" }Достаточно написать:
{ "inbound": ["mixed-in", "socks-in"] }И в самом приложении в аутбаунд выбрать "Блокировать", результат выходит я так понимаю тот же, второе по поводу последнего правила:
{ "ip_cidr": ["0.0.0.0/0", "::/0"], "outbound": "block" }Что именно оно делает? Всё остальное блокирует либо пускает в обход прокси если написать "direct"? (К слову опять же в результате проверки я так понял что "block" будет стоять выше в приоритете, то есть если прописать "block" и в приложении выбрать "direct" или прописать "direct" и выбрать "block" то всё равно будет "block")
Если да и всё остальное должно как-то пускаться, то не лучше в целом убрать это правило и просто написать:
{ "outbound": "direct" }В таком конфиге некобокс вроде как точно пропускает всё остальное в обход прокси и проблемы что в браузере всё проксируется не возникает и тогда уже если нужно можно делать правило чтобы проксировались только определённые домены.
Не считаю что разбираюсь в теме, просто спрашиваю на основе того что я пытался делать пока бился над решением. В любом случае всё заработало (вместе с решением @s809) и за предложенное решение спасибо!
thealien commentedon Apr 12, 2026
Всё верно.
Я когда искал инфу о том,что писать в когфигах рулов, были примеры с условием + аутбаунд. Так и пошло в начале и в примерах.
Ну и вообще очевидно, что кастом конфиг просто сливается с рулом, будучи в приоритете (т.е. аутбаунд в json конфиге рула перезапишет то, что выбрали в ui рула).
И да, логичнее и очевиднее в конфиге оставить только те условия, которые нельзя и выбрать в ui, а тот же аутбаунд юзать в ui, чтобы не было путаницы и недопонимания.
А ещё, как я дошел до ip_cidr.
Я хотел последним правилом блочить все, но если создать правило и в ui выбрать outboud block, то ничего не происходило. Как мне сказал гпт - это из-за того, что условий нет и в финальный конфиг правило просто не попадает (но честно - финальный конфиг я не перепроверял).
И в итоге спросил у гпт, как сделать, чтобы рул блочил весь трафик. Получил пример кастом конфига с ip cidr, который заработал. И я ним делился в исходном виде :)
Но очевидно, что достичь цель можно и другими настройками и более кратко и оптимизировано (о чем вы выше и написали).
Мне гпт говорит такое (и поведение вроде получаю описанное, нужное), цитата
thealien commentedon Apr 12, 2026
About telnet to socks5.
It is success because port opened and telnet can connect.
But actually request will be blocked (i mean real request via socks5).
Check should be like curl --proxy socks5h://127.0.0.1:2080 2ip.io
(in termux for example)
But!
It doesn't matter, because U just delete socks5 inbound and now it doesn't exist at all and no problem here.
neur0ner25 commentedon Apr 12, 2026
Just read this issues.
Viyorez commentedon Apr 12, 2026
and-rassk не помогло, термукс все также выдает айпишник впна, хардединг детектит. может нам списаться где нить? ибо тут не удобно
Viyorez commentedon Apr 12, 2026
список приложений тот же, да, эскортом пользовался. правило те же.
поподробнее про джсон конфиги, я не особо понял что сделать и как он работает
alexeygritsenko commentedon Apr 12, 2026
Простите, а разве sing-box не поддерживает xhttp? Как тогда на винде у меня на нем xhttp ключ работает?
Ну если вы уверены что он не поддерживает xhttp, тогда у них есть официальный репозиторий тут https://github.com/SagerNet/sing-box
neur0ner25 commentedon Apr 12, 2026
Если вы настроили работу приложений не через прокси а выбрали российские приложения в обход то правило 0.0.0.0/0 вам не нужно.
IdiotEbrilo commentedon Apr 14, 2026
Добавил отключалку для mixed-in socks5 с блокировкой неиспользуемых контролов, и автогенерируемые креды для naive и подобных, т.к. сейчас они полностью открыты, и через них виден реальный внешний IP впн. С этим теперь не требуется делать отдельные правила для отключения mixed-in и кастомные джейсоны
Кому нужно - в репе собранный и подписанный релиз
ПР тут - #1166
Отдельная благодарность @dv4mp1r3 и @x64BitWorm
UPD: немного поправил интерфейс для большей логичности
acanthis commentedon Apr 17, 2026
@thealien Подскажите, а приложения из главных настроек (режим VPN для приложений) нужно убирать? Я создал правило с приложениями, убрал их из настроек и они перестали работать(