feat(telegram): add MTProto IP-based desync via custom.d script

Telegram media downloads that use MTProto (direct IP, no TLS SNI) bypass
the RKN profile's --filter-l7=tls. New custom.d script creates an ipset
with official Telegram DC CIDR ranges and runs a separate nfqws2 daemon
to desync TCP to those IPs regardless of protocol.

Also fixes custom.d install path (was missing /custom.d/ subdirectory).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
necronicle 2026-03-06 02:11:15 +03:00
parent 4f874f0581
commit e2c80021bc
2 changed files with 72 additions and 1 deletions

View file

@ -0,0 +1,62 @@
# Custom script: desync TCP to Telegram IP ranges (MTProto + CDN)
# Catches connections to Telegram DC IPs that may use MTProto (no TLS SNI)
# and thus bypass --filter-l7=tls in the main RKN profile.
#
# Works alongside the RKN profile: RKN catches Telegram TLS by domain (t-dc.net etc),
# this script catches MTProto by IP (direct DC connections without SNI).
# Telegram CIDR ranges (official: https://core.telegram.org/resources/cidr.txt)
Z2K_TG_CIDRS="91.108.4.0/22 91.108.8.0/22 91.108.12.0/22 91.108.16.0/22 91.108.20.0/22 91.108.56.0/22 91.105.192.0/23 149.154.160.0/20 185.76.151.0/24"
Z2K_TG_IPSET="z2k_telegram"
# Strategy: fake with google blob + multisplit.
# No --filter-l7=tls here — we want to catch MTProto (fake-TLS wrapped).
# No --hostlist — matching is done by ipset in iptables.
NFQWS_OPT_DESYNC_TG="${NFQWS_OPT_DESYNC_TG:---filter-tcp=443,5222 --lua-desync=fake:blob=tls_clienthello_www_google_com:repeats=6:tls_mod=rnd,dupsid --lua-desync=multisplit:pos=1,sniext+1:seqovl=1}"
alloc_dnum DNUM_TG_MTPROTO
alloc_qnum QNUM_TG_MTPROTO
zapret_custom_daemons()
{
# $1 - 1 - add, 0 - stop
local opt="--qnum=$QNUM_TG_MTPROTO $NFQWS_OPT_DESYNC_TG"
do_nfqws $1 $DNUM_TG_MTPROTO "$opt"
}
_z2k_tg_ipset_create()
{
ipset create "$Z2K_TG_IPSET" hash:net -exist 2>/dev/null || return 1
ipset flush "$Z2K_TG_IPSET" 2>/dev/null
local cidr
for cidr in $Z2K_TG_CIDRS; do
ipset add "$Z2K_TG_IPSET" "$cidr" -exist 2>/dev/null
done
}
_z2k_tg_ipset_destroy()
{
ipset destroy "$Z2K_TG_IPSET" 2>/dev/null
}
zapret_custom_firewall()
{
# $1 - 1 - run, 0 - stop
if [ "$1" = 1 ]; then
_z2k_tg_ipset_create || return 1
fi
local f="-p tcp -m multiport --dports 443,5222 -m set --match-set $Z2K_TG_IPSET dst"
fw_nfqws_post4 $1 "$f" $QNUM_TG_MTPROTO
if [ "$1" = 0 ]; then
_z2k_tg_ipset_destroy
fi
}
zapret_custom_firewall_nft()
{
# nftables variant — Keenetic uses iptables, stub for compatibility
:
}

View file

@ -795,7 +795,7 @@ step_build_zapret2() {
print_info "Установка custom.d скриптов для STUN/Discord media..."
local custom_dir="${ZAPRET2_DIR}/init.d/keenetic"
local custom_dir="${ZAPRET2_DIR}/init.d/keenetic/custom.d"
mkdir -p "$custom_dir"
if curl -fsSL "https://raw.githubusercontent.com/bol-van/zapret2/master/init.d/custom.d.examples.linux/50-stun4all" \
@ -814,6 +814,15 @@ step_build_zapret2() {
print_warning "Не удалось загрузить 50-discord-media"
fi
# Telegram MTProto: IP-based desync for Telegram DC ranges (catches non-TLS MTProto)
if [ -f "${WORK_DIR}/files/custom.d/50-telegram-mtproto" ]; then
cp -f "${WORK_DIR}/files/custom.d/50-telegram-mtproto" "${custom_dir}/50-telegram-mtproto"
chmod +x "${custom_dir}/50-telegram-mtproto"
print_success "50-telegram-mtproto установлен"
else
print_warning "50-telegram-mtproto не найден в файлах проекта"
fi
# ===========================================================================
# ЗАВЕРШЕНИЕ
# ===========================================================================