dns_leak: russian note alongside english

This commit is contained in:
Andrew Pimenov 2026-08-09 04:10:44 +03:00
parent 9e5ea923aa
commit 4c2da2e831
2 changed files with 47 additions and 1 deletions

View file

@ -8,6 +8,10 @@ _LEAK_NOTE = (
"This test only sees resolvers configured at the OS level. A browser using DoH " "This test only sees resolvers configured at the OS level. A browser using DoH "
"or DoT bypasses them entirely and is not covered here." "or DoT bypasses them entirely and is not covered here."
) )
_LEAK_NOTE_RU = (
"Этот тест видит только резолверы, настроенные на уровне ОС. Браузер, использующий DoH "
"или DoT, полностью обходит их и здесь не учитывается."
)
def _unquote(text: str) -> str: def _unquote(text: str) -> str:
@ -66,16 +70,28 @@ def build_adapter_result(
def build_dns_leak(results: list[AdapterLeakResult], ecs_leaked: bool) -> DnsLeak: def build_dns_leak(results: list[AdapterLeakResult], ecs_leaked: bool) -> DnsLeak:
leaking = [r.adapter for r in results if r.matches_egress_asn is False] leaking = [r.adapter for r in results if r.matches_egress_asn is False]
parts: list[str] = [] parts: list[str] = []
parts_ru: list[str] = []
if leaking: if leaking:
parts.append( parts.append(
f"DNS queries from {', '.join(leaking)} resolve through a network outside the egress ASN." f"DNS queries from {', '.join(leaking)} resolve through a network outside the egress ASN."
) )
parts_ru.append(
f"DNS-запросы с {', '.join(leaking)} разрешаются через сеть за пределами egress ASN."
)
else: else:
parts.append("No adapter resolves DNS outside the egress ASN.") parts.append("No adapter resolves DNS outside the egress ASN.")
parts_ru.append("Ни один адаптер не резолвит DNS за пределами egress ASN.")
if ecs_leaked: if ecs_leaked:
parts.append("The resolver forwards your EDNS Client Subnet, exposing your network to authoritative servers.") parts.append("The resolver forwards your EDNS Client Subnet, exposing your network to authoritative servers.")
parts_ru.append("Резолвер пересылает ваш EDNS Client Subnet, раскрывая вашу сеть авторитативным серверам.")
parts.append(_LEAK_NOTE) parts.append(_LEAK_NOTE)
return DnsLeak(per_adapter=results, ecs_leaked=ecs_leaked, note=" ".join(parts)) parts_ru.append(_LEAK_NOTE_RU)
return DnsLeak(
per_adapter=results,
ecs_leaked=ecs_leaked,
note=" ".join(parts),
note_ru=" ".join(parts_ru),
)
import asyncio import asyncio

View file

@ -93,3 +93,33 @@ def test_dns_leak_note_mentions_ecs_when_the_subnet_leaked():
leak = build_dns_leak([clean], ecs_leaked=True) leak = build_dns_leak([clean], ecs_leaked=True)
assert leak.ecs_leaked is True assert leak.ecs_leaked is True
assert "client subnet" in leak.note.lower() assert "client subnet" in leak.note.lower()
_CYRILLIC = set("абвгдеёжзийклмнопрстуфхцчшщъыьэюя")
def has_cyrillic(text: str) -> bool:
return any(ch in _CYRILLIC for ch in text.lower())
def test_dns_leak_note_ru_names_the_leaking_adapter():
leaking = build_adapter_result("Wi-Fi", ["192.168.1.1"], "203.0.113.9", "AS64501", "AS64500")
clean = build_adapter_result("wg0", ["10.7.0.1"], "203.0.113.44", "AS64500", "AS64500")
leak = build_dns_leak([clean, leaking], ecs_leaked=False)
assert leak.note_ru
assert has_cyrillic(leak.note_ru)
assert "Wi-Fi" in leak.note_ru
def test_dns_leak_note_ru_is_clean_when_every_adapter_agrees():
clean = build_adapter_result("wg0", ["10.7.0.1"], "203.0.113.44", "AS64500", "AS64500")
leak = build_dns_leak([clean], ecs_leaked=False)
assert leak.note_ru
assert has_cyrillic(leak.note_ru)
def test_dns_leak_note_ru_mentions_ecs_when_the_subnet_leaked():
clean = build_adapter_result("wg0", ["10.7.0.1"], "203.0.113.44", "AS64500", "AS64500")
leak = build_dns_leak([clean], ecs_leaked=True)
assert leak.note_ru
assert has_cyrillic(leak.note_ru)