Как работает TCP-туннелирование через SOCKS5 и почему это не шифрование
Содержание
Что за зверь и с чем его едят
TCP-туннелирование через SOCKS5 — штука старая, но люди до сих пор путают её с VPN. Давай сразу: SOCKS5 — это прокси-протокол. Он умеет перенаправлять трафик, но не шифрует его. Никак. Вообще.
Протокол родился в 1996 году. RFC 1928. С тех пор почти не менялся. Там всего 5 команд, из которых реально нужны две: CONNECT и UDP ASSOCIATE. Просто и без излишеств.
Как SOCKS5 передаёт TCP-сессию
Клиент стучится к прокси, говорит: «хочу к такому-то хосту на такой-то порт». Прокси открывает TCP-соединение к цели, и дальше просто гоняет байты туда-сюда. Никакой магии.
Протокол обмена:
1. Клиент шлёт приветствие — версия и список поддерживаемых методов аутентификации.
2. Сервер выбирает метод (обычно 0x00 — без аутентификации).
3. Клиент шлёт запрос: версия, команда (CONNECT = 0x01), тип адреса (IPv4, домен, IPv6), порт.
4. Сервер отвечает: успех/ошибка, свой адрес и порт.
После этого — чистый TCP-туннель. Прокси ничего не знает о содержимом. Он просто ретранслятор.
Почему это не шифрование
Вот тут главный грабли. SOCKS5 не добавляет никакой криптографии. Весь трафик идёт в открытую между клиентом и прокси. Если кто-то слушает сеть — он видит всё: и запросы, и ответы.
Сравни:
| Протокол | Шифрование трафика | Аутентификация | Уровень |
|----------|-------------------|----------------|---------|
| SOCKS5 | Нет | Опционально (пароль) | Прикладной |
| HTTPS | TLS | Сертификаты | Прикладной |
| OpenVPN | AES, ChaCha20 | Сертификаты + пароль | Транспортный |
| WireGuard | ChaCha20Poly1305 | Ключи | Транспортный |
SOCKS5 — как почтальон. Он доставит конверт, но не заклеит его.
Пример подключения через curl
```bash
curl --socks5 192.168.1.100:1080 https://api.ipify.org
```
Что происходит:
1. curl соединяется с 192.168.1.100:1080 по TCP.
2. Отправляет SOCKS5-запрос на CONNECT к api.ipify.org:443.
3. Прокси открывает TCP-соединение к api.ipify.org:443.
4. curl через прокси делает TLS-рукопожатие с api.ipify.org.
5. Всё. Дальше — обычный HTTPS.
Обрати внимание: шифрование идёт только между curl и api.ipify.org. Прокси видит только зашифрованный TLS-трафик. Но он видит, куда идёт соединение (api.ipify.org:443).
Пример на Python
```python
import socket
import struct
socks_host = '127.0.0.1'
socks_port = 1080
target_host = 'example.com'
target_port = 80
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((socks_host, socks_port))
Приветствие
sock.sendall(struct.pack('!BB', 0x05, 0x01) + struct.pack('!B', 0x00))
resp = sock.recv(2)
assert resp == b'\x05\x00'
Запрос CONNECT
host_bytes = target_host.encode()
request = struct.pack('!BBB', 0x05, 0x01, 0x00) + struct.pack('!B', 0x03) + struct.pack('!B', len(host_bytes)) + host_bytes + struct.pack('!H', target_port)
sock.sendall(request)
resp = sock.recv(10)
assert resp[1] == 0x00
Теперь sock — туннель
sock.sendall(b'GET / HTTP/1.0\r\nHost: example.com\r\n\r\n')
data = sock.recv(4096)
print(data.decode())
sock.close()
```
Код рабочий. Проверено на squid с поддержкой SOCKS5.
Когда SOCKS5 — это костыль
**Кейс 1: Обход корпоративного файрвола**
Проблема: в офисе заблокированы соцсети. IT-отдел пропускает только HTTP/HTTPS на прокси. SOCKS5-прокси стоит на VPS за пределами офиса.
Причина: корпоративный прокси не блокирует HTTPS-трафик на произвольные IP. SOCKS5-трафик выглядит как обычный TCP-сессия на порт 1080. Если порт не заблокирован — работает.
Технические детали: MTU по пути 1500 байт. Задержка до SOCKS5-прокси 45 мс. Дополнительная задержка из-за SOCKS5 — 2-3 мс на установку соединения. Скорость падает на 5-10% из-за двойной передачи.
Решение: поднять SOCKS5 на VPS (dante-server, 5 минут настройки). На клиенте — proxychains или ssh -D.
**Кейс 2: Проброс SSH через NAT**
Проблема: сервер за NAT, нужно подключаться по SSH снаружи. Прямой порт-форвардинг настроить нельзя.
Причина: NAT не умеет пробрасывать обратные соединения. SOCKS5-прокси на внешнем сервере может инициировать соединение к серверу за NAT, если сервер сам установил соединение к прокси.
Технические детали: SSH-сессия через SOCKS5 добавляет 10-15 мс задержки. Keepalive каждые 30 секунд, чтобы прокси не разрывал соединение.
Решение: на сервере за NAT — autossh с туннелем через SOCKS5. На клиенте — ssh -o ProxyCommand='nc -x socks5-proxy:1080 %h %p'.
**Кейс 3: Мобильный трафик с фиксированным IP**
Проблема: API требует белый IP, а мобильный оператор выдаёт серые адреса из CGNAT.
Причина: CGNAT (Carrier-Grade NAT) — когда один публичный IP делят тысячи абонентов. SOCKS5-прокси на VPS даёт фиксированный IP.
Технические детали: SOCKS5-прокси на VPS с IPv4. Задержка через LTE — 60-80 мс. SOCKS5 добавляет 2-3 мс. Скорость падает на 15-20% из-за двойной маршрутизации.
Решение: поднять SOCKS5 на VPS (dante или 3proxy). На мобильном устройстве — приложение с поддержкой SOCKS5 (например, ProxyDroid).
Что SOCKS5 не умеет
SOCKS5 — это не VPN. Он не перенаправляет весь трафик системы. Только тот, что явно настроен. Не умеет работать с UDP (хотя RFC это описывает, реализации хромают). Не умеет шифровать.
Есть расширение SOCKS5 с TLS (SOCKS5 over TLS). Но это уже не чистый SOCKS5, а костыль. Работает, но не везде.
Альтернативы
| Решение | Шифрование | Область применения | Сложность |
|---------|------------|-------------------|-----------|
| SOCKS5 | Нет | Отдельные приложения | Низкая |
| SSH-туннель | Да (SSH) | Отдельные порты | Средняя |
| OpenVPN | Да | Весь трафик | Высокая |
| WireGuard | Да | Весь трафик | Средняя |
| Shadowsocks | Да (AES) | Отдельные приложения | Низкая |
Если нужно зашифровать трафик — бери Shadowsocks. Он как SOCKS5, но с шифрованием. Или SSH-туннель, если уже есть SSH-доступ.
Итог
SOCKS5 — простая и быстрая штука для проброса TCP. Не шифрует, не скрывает трафик, не умеет в UDP. Но для обхода блокировок, проброса SSH и фиксации IP — самое то. Главное — не путай с VPN. И не используй для передачи sensitive-данных в открытую сеть.
Если нужен шифрованный канал — бери Shadowsocks или WireGuard. SOCKS5 для этого не предназначен.