unified: Phantom Protocol 2025 complete archive integration

This commit is contained in:
NW
2026-05-18 17:28:53 +01:00
commit b680c5aeca
553 changed files with 112091 additions and 0 deletions

View File

@@ -0,0 +1,504 @@
#!/usr/bin/env python3
"""
Phantom SOCKS5 Proxy Server
Создает SOCKS5 прокси сервер, который маршрутизирует трафик через Phantom сеть
Использование:
python3 socks5-proxy.py --port 8080 --hops 3
Автор: Phantom Protocol Team 2025
"""
import socket
import threading
import struct
import select
import sys
import argparse
import time
import logging
from typing import Optional, Tuple, List
# Настройка логирования
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
# SOCKS5 константы
SOCKS5_VERSION = 0x05
SOCKS5_CONNECT = 0x01
SOCKS5_IPV4 = 0x01
SOCKS5_DOMAIN = 0x03
SOCKS5_IPV6 = 0x04
# Коды ответов SOCKS5
SOCKS5_SUCCESS = 0x00
SOCKS5_GENERAL_FAILURE = 0x01
SOCKS5_CONNECTION_NOT_ALLOWED = 0x02
SOCKS5_NETWORK_UNREACHABLE = 0x03
SOCKS5_HOST_UNREACHABLE = 0x04
SOCKS5_CONNECTION_REFUSED = 0x05
SOCKS5_TTL_EXPIRED = 0x06
SOCKS5_COMMAND_NOT_SUPPORTED = 0x07
SOCKS5_ADDRESS_TYPE_NOT_SUPPORTED = 0x08
class PhantomRoute:
"""Представляет маршрут через Phantom сеть"""
def __init__(self, hops: int = 3):
self.hops = hops
self.nodes: List[Tuple[str, int]] = []
self.build_route()
def build_route(self):
"""Построение маршрута через Phantom узлы"""
# В реальной реализации здесь будет запрос к Kademlia DHT
# Сейчас используем симуляцию
logger.info(f"Построение маршрута через {self.hops} хопов...")
# Симуляция поиска узлов в Phantom сети
available_nodes = [
("10.0.1.100", 8050),
("10.0.1.101", 8050),
("10.0.1.102", 8050),
("10.0.1.103", 8050),
("10.0.1.104", 8050),
]
# Выбор случайных узлов для маршрута
import random
self.nodes = random.sample(available_nodes, min(self.hops, len(available_nodes)))
for i, (ip, port) in enumerate(self.nodes):
logger.info(f" Хоп {i+1}: {ip}:{port}")
class PhantomConnection:
"""Подключение через Phantom сеть"""
def __init__(self, route: PhantomRoute):
self.route = route
self.socket: Optional[socket.socket] = None
self.connected = False
def connect(self, target_host: str, target_port: int) -> bool:
"""Подключение к целевому хосту через Phantom сеть"""
try:
logger.info(f"Подключение к {target_host}:{target_port} через Phantom сеть")
# Подключение к первому узлу маршрута
if not self.route.nodes:
logger.error("Маршрут не построен")
return False
first_hop = self.route.nodes[0]
logger.info(f"Подключение к первому хопу: {first_hop[0]}:{first_hop[1]}")
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.settimeout(10)
try:
self.socket.connect(first_hop)
except socket.error as e:
logger.error(f"Не удалось подключиться к первому хопу: {e}")
# Fallback: прямое подключение для демонстрации
logger.info(f"Fallback: прямое подключение к {target_host}:{target_port}")
self.socket.close()
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.settimeout(10)
self.socket.connect((target_host, target_port))
self.connected = True
return True
# Отправка команды построения туннеля
tunnel_command = self._build_tunnel_command(target_host, target_port)
self.socket.send(tunnel_command.encode('utf-8'))
# Ожидание подтверждения
response = self.socket.recv(1024).decode('utf-8')
if response.startswith("PHANTOM_TUNNEL_OK"):
logger.info("Туннель через Phantom сеть установлен")
self.connected = True
return True
else:
logger.error(f"Ошибка установки туннеля: {response}")
# Fallback: прямое подключение
logger.info(f"Fallback: прямое подключение к {target_host}:{target_port}")
self.socket.close()
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.settimeout(10)
self.socket.connect((target_host, target_port))
self.connected = True
return True
except Exception as e:
logger.error(f"Ошибка подключения: {e}")
return False
def _build_tunnel_command(self, target_host: str, target_port: int) -> str:
"""Построение команды для создания туннеля"""
command = f"PHANTOM_BUILD_TUNNEL {target_host} {target_port}"
# Добавление промежуточных хопов
for i in range(1, len(self.route.nodes)):
hop = self.route.nodes[i]
command += f" {hop[0]}:{hop[1]}"
return command + "\n"
def send(self, data: bytes) -> int:
"""Отправка данных через Phantom соединение"""
if not self.connected or not self.socket:
raise ConnectionError("Соединение не установлено")
return self.socket.send(data)
def recv(self, size: int) -> bytes:
"""Получение данных через Phantom соединение"""
if not self.connected or not self.socket:
raise ConnectionError("Соединение не установлено")
return self.socket.recv(size)
def close(self):
"""Закрытие соединения"""
if self.socket:
self.socket.close()
self.socket = None
self.connected = False
class SOCKS5Handler:
"""Обработчик SOCKS5 протокола"""
def __init__(self, client_socket: socket.socket, hops: int = 3):
self.client_socket = client_socket
self.hops = hops
self.phantom_connection: Optional[PhantomConnection] = None
def handle(self):
"""Основная обработка SOCKS5 соединения"""
try:
# Этап 1: Аутентификация
if not self._handle_authentication():
return
# Этап 2: Обработка запроса подключения
if not self._handle_connection_request():
return
# Этап 3: Проксирование данных
self._relay_data()
except Exception as e:
logger.error(f"Ошибка обработки SOCKS5: {e}")
finally:
self._cleanup()
def _handle_authentication(self) -> bool:
"""Обработка этапа аутентификации SOCKS5"""
try:
# Получение запроса аутентификации
data = self.client_socket.recv(256)
if len(data) < 2:
return False
version, nmethods = struct.unpack('!BB', data[:2])
if version != SOCKS5_VERSION:
logger.error(f"Неподдерживаемая версия SOCKS: {version}")
return False
if len(data) < 2 + nmethods:
return False
methods = struct.unpack('!' + 'B' * nmethods, data[2:2+nmethods])
# Поддерживаем только "без аутентификации" (метод 0)
if 0 in methods:
# Отправка ответа: версия + выбранный метод
response = struct.pack('!BB', SOCKS5_VERSION, 0)
self.client_socket.send(response)
logger.debug("Аутентификация SOCKS5 пройдена")
return True
else:
# Нет поддерживаемых методов
response = struct.pack('!BB', SOCKS5_VERSION, 0xFF)
self.client_socket.send(response)
return False
except Exception as e:
logger.error(f"Ошибка аутентификации SOCKS5: {e}")
return False
def _handle_connection_request(self) -> bool:
"""Обработка запроса подключения SOCKS5"""
try:
# Получение запроса подключения
data = self.client_socket.recv(4)
if len(data) < 4:
return False
version, cmd, reserved, address_type = struct.unpack('!BBBB', data)
if version != SOCKS5_VERSION:
self._send_error_response(SOCKS5_GENERAL_FAILURE)
return False
if cmd != SOCKS5_CONNECT:
self._send_error_response(SOCKS5_COMMAND_NOT_SUPPORTED)
return False
# Получение адреса назначения
target_host, target_port = self._parse_target_address(address_type)
if not target_host:
self._send_error_response(SOCKS5_ADDRESS_TYPE_NOT_SUPPORTED)
return False
logger.info(f"SOCKS5 запрос подключения к {target_host}:{target_port}")
# Подключение через Phantom сеть
route = PhantomRoute(self.hops)
self.phantom_connection = PhantomConnection(route)
if self.phantom_connection.connect(target_host, target_port):
# Отправка успешного ответа
self._send_success_response()
logger.info(f"SOCKS5 туннель к {target_host}:{target_port} установлен")
return True
else:
self._send_error_response(SOCKS5_HOST_UNREACHABLE)
return False
except Exception as e:
logger.error(f"Ошибка обработки запроса подключения: {e}")
self._send_error_response(SOCKS5_GENERAL_FAILURE)
return False
def _parse_target_address(self, address_type: int) -> Tuple[Optional[str], Optional[int]]:
"""Парсинг адреса назначения"""
try:
if address_type == SOCKS5_IPV4:
# IPv4 адрес (4 байта) + порт (2 байта)
data = self.client_socket.recv(6)
if len(data) < 6:
return None, None
ip_bytes = data[:4]
port_bytes = data[4:6]
ip = socket.inet_ntoa(ip_bytes)
port = struct.unpack('!H', port_bytes)[0]
return ip, port
elif address_type == SOCKS5_DOMAIN:
# Доменное имя: длина (1 байт) + имя + порт (2 байта)
length_data = self.client_socket.recv(1)
if len(length_data) < 1:
return None, None
domain_length = struct.unpack('!B', length_data)[0]
domain_data = self.client_socket.recv(domain_length + 2)
if len(domain_data) < domain_length + 2:
return None, None
domain = domain_data[:domain_length].decode('utf-8')
port = struct.unpack('!H', domain_data[domain_length:])[0]
return domain, port
elif address_type == SOCKS5_IPV6:
# IPv6 адрес (16 байт) + порт (2 байта)
data = self.client_socket.recv(18)
if len(data) < 18:
return None, None
ip_bytes = data[:16]
port_bytes = data[16:18]
ip = socket.inet_ntop(socket.AF_INET6, ip_bytes)
port = struct.unpack('!H', port_bytes)[0]
return ip, port
return None, None
except Exception as e:
logger.error(f"Ошибка парсинга адреса: {e}")
return None, None
def _send_success_response(self):
"""Отправка успешного ответа SOCKS5"""
# Версия + статус + зарезервировано + тип адреса
response = struct.pack('!BBBB', SOCKS5_VERSION, SOCKS5_SUCCESS, 0, SOCKS5_IPV4)
# Связанный адрес (0.0.0.0) + порт (0)
response += struct.pack('!IH', 0, 0)
self.client_socket.send(response)
def _send_error_response(self, error_code: int):
"""Отправка ответа об ошибке SOCKS5"""
response = struct.pack('!BBBB', SOCKS5_VERSION, error_code, 0, SOCKS5_IPV4)
response += struct.pack('!IH', 0, 0)
self.client_socket.send(response)
def _relay_data(self):
"""Проксирование данных между клиентом и Phantom соединением"""
if not self.phantom_connection:
return
logger.debug("Начало проксирования данных")
try:
while True:
# Ожидание данных от клиента или сервера
ready_sockets, _, error_sockets = select.select(
[self.client_socket, self.phantom_connection.socket],
[],
[self.client_socket, self.phantom_connection.socket],
1.0 # Таймаут 1 секунда
)
if error_sockets:
logger.debug("Ошибка в сокетах, завершение проксирования")
break
if not ready_sockets:
continue
# Данные от клиента к серверу
if self.client_socket in ready_sockets:
data = self.client_socket.recv(4096)
if not data:
logger.debug("Клиент закрыл соединение")
break
self.phantom_connection.send(data)
logger.debug(f"Отправлено {len(data)} байт через Phantom")
# Данные от сервера к клиенту
if self.phantom_connection.socket in ready_sockets:
data = self.phantom_connection.recv(4096)
if not data:
logger.debug("Сервер закрыл соединение")
break
self.client_socket.send(data)
logger.debug(f"Получено {len(data)} байт от Phantom")
except Exception as e:
logger.error(f"Ошибка проксирования данных: {e}")
def _cleanup(self):
"""Очистка ресурсов"""
try:
if self.phantom_connection:
self.phantom_connection.close()
self.client_socket.close()
except:
pass
class PhantomSOCKS5Server:
"""SOCKS5 прокси сервер через Phantom сеть"""
def __init__(self, host: str = '127.0.0.1', port: int = 8080, hops: int = 3):
self.host = host
self.port = port
self.hops = hops
self.server_socket: Optional[socket.socket] = None
self.running = False
def start(self):
"""Запуск SOCKS5 сервера"""
try:
self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.server_socket.bind((self.host, self.port))
self.server_socket.listen(10)
self.running = True
logger.info(f"🚀 Phantom SOCKS5 прокси запущен на {self.host}:{self.port}")
logger.info(f" Количество хопов через Phantom сеть: {self.hops}")
logger.info(f" Настройте ваш браузер или приложение:")
logger.info(f" - Тип прокси: SOCKS v5")
logger.info(f" - Адрес: {self.host}")
logger.info(f" - Порт: {self.port}")
logger.info(f" - Аутентификация: Нет")
while self.running:
try:
client_socket, client_address = self.server_socket.accept()
logger.info(f"Новое SOCKS5 подключение от {client_address[0]}:{client_address[1]}")
# Обработка клиента в отдельном потоке
handler = SOCKS5Handler(client_socket, self.hops)
client_thread = threading.Thread(target=handler.handle)
client_thread.daemon = True
client_thread.start()
except socket.error as e:
if self.running:
logger.error(f"Ошибка принятия подключения: {e}")
except Exception as e:
logger.error(f"Ошибка запуска сервера: {e}")
finally:
self.stop()
def stop(self):
"""Остановка SOCKS5 сервера"""
self.running = False
if self.server_socket:
self.server_socket.close()
logger.info("Phantom SOCKS5 прокси остановлен")
def main():
"""Главная функция"""
parser = argparse.ArgumentParser(
description='Phantom SOCKS5 Proxy - SOCKS5 прокси через Phantom сеть'
)
parser.add_argument(
'--host',
default='127.0.0.1',
help='IP адрес для прослушивания (по умолчанию: 127.0.0.1)'
)
parser.add_argument(
'--port',
type=int,
default=8080,
help='Порт для прослушивания (по умолчанию: 8080)'
)
parser.add_argument(
'--hops',
type=int,
default=3,
help='Количество хопов через Phantom сеть (по умолчанию: 3)'
)
parser.add_argument(
'--verbose',
action='store_true',
help='Подробный вывод'
)
args = parser.parse_args()
if args.verbose:
logging.getLogger().setLevel(logging.DEBUG)
# Создание и запуск SOCKS5 сервера
server = PhantomSOCKS5Server(args.host, args.port, args.hops)
try:
server.start()
except KeyboardInterrupt:
logger.info("Получен сигнал прерывания, остановка сервера...")
server.stop()
if __name__ == '__main__':
main()