Обновить
0

Пользователь

Отправить сообщение

Разраб ты красава, держи обертку, позже вэб версию, возможно сделаем.

#!/usr/bin/env python3

-- coding: utf-8 --

“”" RKN Block Checker PRO — Unified IPv4-only checker with interactive UI & smart analysis. Drop-in replacement for original rkn-check. “”" import re import sys import socket import io

==========================================================

1. ПАТЧ: Принудительный IPv4 (до импорта библиотеки)

==========================================================

oldgetaddrinfo = socket.getaddrinfo def ipv4only_getaddrinfo(*args, **kwargs): res = oldgetaddrinfo(*args, **kwargs) v4 = [r for r in res if r[0] == socket.AF_INET] return v4 if v4 else res socket.getaddrinfo = ipv4only_getaddrinfo

==========================================================

2. ИМПОРТ ОРИГИНАЛЬНОГО CLI

==========================================================

from rkn_checker.cli import main as origmain

==========================================================

3. УТИЛИТЫ: Цвета и Форматирование

==========================================================

class C: G = ‘\033[92m’; Y = ‘\033[93m’; R = ‘\033[91m’ B = ‘\033[94m’; GR = ‘\033[90m’; BOLD = ‘\033[1m’; RES = ‘\033[0m’

def print_box(title, lines): w = 70 print(f"{C.BOLD}{C.B}{‘═’*w}{C.RES}“) print(f”{C.BOLD} {title}{C.RES}“) print(f”{C.BOLD}{C.B}{‘═’*w}{C.RES}“) for l in lines: print(f” {l}“) print(f”{C.B}{‘═’*w}{C.RES}\n")

==========================================================

4. АНАЛИЗАТОР ВЫВОДА

==========================================================

def analyze(raw_output, target): status_line = “” status_color = C.GR raw_lower = raw_output.lower()

# === БЛОКИРОВКИ РН ===
if 'TCP_RESET' in raw_output or 'Connection reset' in raw_output:
    status_line = "🔴 Заблокировано РН: сброс соединения (RST)"
    status_color = C.R
elif 'TLS_BLOCK' in raw_output or 'handshake failed' in raw_output or 'SNI filtered' in raw_lower:
    status_line = "🟡 Заблокировано РН: фильтрация по SNI (TLS)"
    status_color = C.Y
elif 'DNS poisoning' in raw_output or 'DNS_BLOCK' in raw_output:
    status_line = "🔴 Заблокировано РН: отравление DNS"
    status_color = C.R
elif 'TIMEOUT' in raw_output and any(x in raw_lower for x in ['telegram','discord','twitter','youtube','instagram','whatsapp']):
    status_line = "🔴 Заблокировано РН: пакеты отбрасываются (DROP)"
    status_color = C.R

# === САЙТ НЕ РАБОТАЕТ / ТЕХНИЧЕСКИЕ ОШИБКИ ===
elif 'NXDOMAIN' in raw_output or 'non-existent domain' in raw_lower:
    status_line = "⚫ Домен не существует"
    status_color = C.GR
elif 'Connection refused' in raw_output:
    status_line = "⚫ Сайт не отвечает на порту 443"
    status_color = C.GR
elif 'No route to host' in raw_output or 'Network unreachable' in raw_lower:
    status_line = " Нет маршрута до хоста (проблема сети)"
    status_color = C.GR
elif 'HTTP 5' in raw_output or '502' in raw_output or '503' in raw_output:
    status_line = "⚫ Ошибка на стороне сервера (5xx)"
    status_color = C.GR
elif 'DOWN' in raw_output and 'TCP failed' in raw_output:
    status_line = "⚫ Сайт недоступен"
    status_color = C.GR

# === ДОСТУПЕН ===
elif '[✓]' in raw_output or 'HTTP: 200' in raw_output or 'HTTP: 301' in raw_output:
    status_line = "🟢 Сайт доступен"
    status_color = C.G

# === НЕ ОПРЕДЕЛЕНО ===
else:
    status_line = "⚪ Статус не определён"
    status_color = C.GR

# === Сбор технических деталей ===
details = []

ip_match = re.search(r'IP:\s*([\d\.]+)', raw_output)
if ip_match: details.append(f"Ваш IP: {ip_match.group(1)}")

isp_match = re.search(r'ISP:\s*(.+?)(?=\n)', raw_output)
if isp_match: details.append(f"Провайдер: {isp_match.group(1).strip()}")

dns_match = re.search(r'DNS:\s*(.+?)(?:\n|$)', raw_output)
if dns_match: details.append(f"DNS: {dns_match.group(1).strip()}")

tcp_match = re.search(r'TCP:\s*(.+?)(?:\n|$)', raw_output)
if tcp_match: details.append(f"TCP: {tcp_match.group(1).strip()}")

http_match = re.search(r'HTTP:\s*(.+?)(?:\n|$)', raw_output)
if http_match: details.append(f"HTTP: {http_match.group(1).strip()}")

# === Формируем вывод ===
lines = [f"{status_color}{status_line}{C.RES}", ""]

if details:
    lines.append(f"{C.GR}Детали:{C.RES}")
    for d in details:
        lines.append(f"  • {d}")
    lines.append("")

if '🔴' in status_line or '🟡' in status_line:
    lines.append(f"{C.GR}Ресурс:{C.RES} {target}")

print_box(f"RKN Block Checker — {target}", lines)
return 0 if '🟢' in status_line else 1

==========================================================

5. MAIN: Логика запуска

==========================================================

def main(): args = sys.argv[1:]

# Пропускаем перехват, если запрошен JSON, help или version
if any(x in args for x in ['--json', '-h', '--help', '--version', '-V']):
    sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
    sys.exit(_orig_main())

# === Логика обработки аргументов ===
if not args:
    # Интерактивный режим
    print(f"\n{C.BOLD}🔍 RKN Block Checker PRO (IPv4-only){C.RES}")
    print(f"{C.GR}   Введите домен или IP (Ctrl+C для выхода){C.RES}\n")
    try:
        target = input(f"{C.B}→{C.RES} Цель: ").strip()
        if not target: sys.exit(0)
        target = re.sub(r'^https?://', '', target).rstrip('/')
        args = ['--url', target, '-v', '--timeout', '12', '--no-self-info']
    except (KeyboardInterrupt, EOFError):
        print("\nВыход.")
        sys.exit(0)
elif args[0] and not args[0].startswith('-'):
    # Прямой ввод домена
    target = args[0]
    target = re.sub(r'^https?://', '', target).rstrip('/')
    args = ['--url', target, '-v', '--timeout', '12', '--no-self-info']
# Если есть флаги, оставляем args как есть

# Извлекаем целевой домен для отчёта
if '--url' in args:
    target = args[args.index('--url') + 1]
else:
    target = "unknown"

sys.argv = ['rkn-check'] + args

# Перехватываем вывод
buf = io.StringIO()
real_out = sys.stdout
sys.stdout = buf

try:
    _orig_main()
except SystemExit:
    pass
except Exception as e:
    buf.write(f"CRITICAL: {e}\n")
finally:
    sys.stdout = real_out

raw = buf.getvalue()
exit_code = analyze(raw, target)
sys.exit(exit_code)

if name == ‘main’: main()

Информация

В рейтинге
Не участвует
Зарегистрирован
Активность