Крот: туннели, пивоты и обход периметра
Периметр — это не стена, а набор правил: что можно наружу, что внутрь, что между сегментами. Правила почти всегда разрешают больше, чем кажется: DNS, обновления, телеметрия, доступ к облачным сервисам. Каждое разрешённое направление — потенциальный транспорт для трафика, которому там быть не полагалось.
Туннель превращает одно разрешённое соединение в произвольный канал. Пивот превращает один скомпрометированный хост в точку входа в сегмент, куда напрямую не добраться. Перехват TLS превращает доверие к сертификату в доверие к тому, кто этот сертификат выпустил.
В теме 19 основной программы VPN рассматривался как штатная технология: GRE, IPsec, WireGuard, site-to-site 6. Здесь тот же механизм берётся как средство обхода: что разрешено на выходе, как это использовать и почему фильтрация по порту не равна фильтрации по назначению. Границы: DNS-туннели — тема 05, сетевая сегментация ЦОД — тема 10.
Тень базового курса: VPN как легитимный туннель
В основной программе туннель — это способ соединить две площадки через чужую сеть. Инкапсуляция, накладные расходы, MTU, ключи — всё это разбиралось как инженерная задача 7. С точки зрения периметра та же инкапсуляция выглядит иначе: это поток, который несёт внутри себя другую сеть.
Ключевое свойство — прозрачность для фильтра. Если туннель идёт по TCP/443 и похож на HTTPS, межсетевой экран видит разрешённый протокол. Если туннель идёт по ICMP, он выглядит как диагностика. Если по DNS — как разрешение имён. Фильтр, который смотрит только на порт и протокол, пропускает всё это.
Туннели без шифрования
GRE и IP-in-IP
GRE (RFC 2784) инкапсулирует произвольный протокол в IP с типом 47 1. IP-in-IP (RFC 2003) делает то же с типом 4, но без дополнительного заголовка 2. Оба варианта не шифруют и не аутентифицируют, зато просты и дёшевы.
ip tunnel add gre0 mode gre remote 198.51.100.2 local 192.0.2.10 ttl 64
ip link set gre0 up
ip addr add 10.10.0.1/30 dev gre0
ip route add 10.20.0.0/24 dev gre0
ip tunnel add ipip0 mode ipip remote 198.51.100.2 local 192.0.2.10
ip link set ipip0 up
ip addr add 10.10.0.5/30 dev ipip0
С точки зрения внешнего наблюдателя это пакеты с протоколом 47 или 4 между двумя адресами. Если такие протоколы не фильтруются, туннель работает; если фильтруются — остаются TCP, UDP и ICMP.
SSH: -L, -R, -D, -w, ProxyJump
SSH — самый доступный туннель, потому что порт 22 часто открыт, а ключи уже есть. Четыре режима покрывают почти все задачи:
ssh -L 8080:192.0.2.20:80 user@192.0.2.10
ssh -R 9000:localhost:3000 user@198.51.100.7
ssh -D 1080 user@192.0.2.10
ssh -w 0:0 user@192.0.2.10
-L — локальный проброс: соединение на localhost:8080 уходит через SSH-сервер к 192.0.2.20:80. -R — обратный: сервер слушает 9000 и передаёт соединения клиенту. -D — динамический SOCKS5-прокси: любое соединение через localhost:1080 уходит через SSH-сервер 3. -w — туннель уровня 3: в туннель передаются IP-пакеты, а не TCP-потоки.
ssh -J user@198.51.100.7 user@192.0.2.10
ProxyJump строит цепочку: первый хост — прыжок, второй — цель. Для наблюдателя это два SSH-соединения, а не одно длинное.
Туннели с шифрованием и обход egress
chisel, ligolo-ng, socat
chisel несёт TCP и UDP поверх HTTP/WebSocket, что позволяет проходить через прокси и фильтры, разрешающие только веб. ligolo-ng поднимает TUN-интерфейс на стороне оператора и превращает удалённый агент в маршрутизатор. socat — универсальный мост между сокетами, полезный для одиночных пробросов.
chisel server -p 443 --reverse
chisel client https://198.51.100.7:443 R:socks
socat TCP-LISTEN:8080,fork TCP:192.0.2.20:80
chisel в режиме R:socks создаёт на клиенте SOCKS-прокси, через который оператор ходит в сеть за клиентом. Трафик выглядит как HTTPS к серверу.
Domain fronting и CDN
Domain fronting использует расхождение между именем в TLS SNI и заголовком Host: SNI указывает на разрешённый домен CDN, а Host — на нужный сервис за ним. CDN маршрутизирует по Host, фильтр видит SNI. После введения ECH и ужесточения политик у крупных провайдеров приём стал менее надёжным, но на мелких CDN встречается до сих пор.
curl -s https://cdn.example.com/ -H "Host: internal.example.com"
DoH, port knocking, SPA
DoH прячет DNS-запросы в HTTPS, port knocking открывает порт последовательностью подключений, single packet authorization (SPA) требует криптографически подписанный пакет до открытия порта. Все три решают одну задачу: сделать сервис невидимым для сканирования и при этом доступным для того, кто знает секрет.
curl -s -H 'content-type: application/dns-json' \
'https://cloudflare-dns.com/dns-query?name=example.com&type=A'
Пивот
Маршрут через хост и двойной пивот
Пивот — это использование скомпрометированного хоста как промежуточного. Простейший вариант: добавить маршрут через хост, на котором уже есть доступ.
ip route add 10.20.0.0/24 via 192.0.2.10
Если хост не умеет пересылать, включается форвардинг, а на хосте — NAT или прокси. Двойной пивот — цепочка из двух хостов: трафик идёт через первый во второй сегмент, оттуда — в третий. Каждый хоп добавляет задержку и точку, где можно оставить след.
Bind, reverse, SOCKS и пространства имён
Обратная оболочка инициирует соединение изнутри наружу — это проходит там, где входящие запрещены. Прямая (bind) работает, только если порт доступен снаружи. SOCKS-прокси на хосте даёт доступ ко всем TCP-назначениям, которые видит хост 4.
ssh -D 1080 -N -f user@192.0.2.10
curl --socks5 127.0.0.1:1080 http://10.20.0.5/
В Linux пивот можно построить без отдельного хоста: пространства имён и VRF позволяют держать несколько таблиц маршрутизации на одной машине. Для атакующего это означает, что «сегмент» может быть виртуальным, и обнаружить пивот по физическому порту не получится.
Перехват TLS
REDIRECT, TPROXY и mitmproxy
Прозрачный перехват на шлюзе перенаправляет трафик на прокси без настройки клиента. REDIRECT работает в nat-таблице для локально сгенерированного трафика, TPROXY — для транзитного и сохраняет исходный адрес. Цепочка с redirect обязана иметь тип nat: в цепочке type filter правило redirect не добавляется — nft отвечает Operation not supported.
nft add table inet mitm
nft add chain inet mitm prerouting '{ type nat hook prerouting priority dstnat; policy accept; }'
nft add rule inet mitm prerouting tcp dport 80 redirect to :8080
mitmproxy --mode transparent --showhost -p 8080
Для HTTPS нужен свой корневой сертификат, установленный в хранилище клиента. Тогда прокси выпускает сертификат на каждое имя, клиент ему доверяет, и содержимое читается. Если клиент проверяет pinning — привязку к конкретному сертификату или ключу — подмена обнаруживается.
JA3, JA4, ECH и 0-RTT
Отпечаток TLS (JA3, затем JA4) строится по набору шифров, расширений и порядка их следования в ClientHello. Разные клиенты дают разные отпечатки, и по ним можно отличить curl от браузера, даже если трафик шифрован.
Рукопожатие TLS 1.3 описано в RFC 8446 5; для перехвата важны две его особенности. ECH (Encrypted Client Hello) скрывает SNI, оставляя видимым только адрес сервера. 0-RTT ускоряет повторное соединение, но создаёт риск повторного воспроизведения данных. Оба механизма меняют то, что видит защита, и оба учитываются при построении детекторов.
Числа: накладные расходы и MTU
Каждый слой инкапсуляции уменьшает полезную нагрузку. GRE добавляет 24 байта, IP-in-IP — 20, VXLAN — 50, WireGuard — 60 для IPv4 и 80 для IPv6. При MTU 1500 путь через GRE даёт 1476 байт, а TCP-сегмент — 1436 байт полезной нагрузки.
MTU 1500
GRE: 1500 - 24 = 1476
TCP/IP: 1476 - 40 = 1436 (MSS)
WireGuard: 1500 - 60 = 1440
TCP/IP: 1440 - 40 = 1400
Если MTU на пути меньше, крупные пакеты теряются, и соединение «зависает» на передаче файла или TLS-рукопожатии. Лечение — MSS clamping на границе: маршрутизатор переписывает MSS в SYN, чтобы отправитель сразу выбрал размер, проходящий через туннель.
nft add rule inet filter forward tcp flags syn tcp option maxseg size set rt mtu
Второе следствие — стоимость туннеля в полосе. При полезной нагрузке 1400 из 1500 байт эффективность составляет 93 процента; двойная инкапсуляция снижает её до 87 процентов. Для канала 1 Гбит/с это разница в 60 Мбит/с, которую нужно учитывать при планировании.
Обнаружение и защита
| Приём | Признак | Контрмера |
|---|---|---|
| GRE/IP-in-IP | протоколы 47 и 4 | egress-фильтр по протоколу |
| SSH-туннель | долгие сессии к 22, нестандартные направления | ограничение 22, аудит ключей |
chisel | HTTPS к неизвестному домену, ровный поток | allowlist, TLS-инспекция |
| Domain fronting | расхождение SNI и Host | проверка согласованности |
| DoH в обход | соединения к публичным DoH | блокировка списка |
| Пивот | новые маршруты, трафик из неожиданного сегмента | сегментация, микросегментация |
| Прозрачный MITM | подмена сертификата | pinning, CT-мониторинг |
| 0-RTT | повторное использование ранних данных | ограничение 0-RTT на сервере |
Правило nftables, запрещающее GRE на выход:
nft add table inet egress
nft add chain inet egress output '{ type filter hook output priority 0; policy accept; }'
nft add rule inet egress output ip protocol gre drop
nft add rule inet egress output ip protocol ipip drop
Итоги темы
Туннель — это инкапсуляция, а инкапсуляция — это способ пронести одно через другое. Периметр, который смотрит на порты и протоколы, пропускает всё, что выглядит разрешённым; поэтому защита строится на allowlist назначений, а не на запрете портов.
Пивот превращает точку опоры в маршрут. Чем меньше сегментов видит хост, тем меньше пользы от пивота; поэтому микросегментация — не бюрократия, а прямое ограничение ущерба.
Перехват TLS возможен только там, где клиент доверяет подменённому корню. Pinning, ECH и контроль Certificate Transparency уменьшают окно, но не закрывают его полностью; поэтому чувствительный трафик защищают на прикладном уровне.
Следующая тема поднимается на уровень глобальной маршрутизации — к BGP, где ошибка в одном анонсе меняет путь для половины Интернета.
Литература
- Farinacci D., Li T., Hanks S., Meyer D., Traina P. Generic Routing Encapsulation (GRE). — RFC 2784, IETF, 2000. https://www.rfc-editor.org/rfc/rfc2784
- Perkins C. IP Encapsulation within IP. — RFC 2003, IETF, 1996. https://www.rfc-editor.org/rfc/rfc2003
- Ylonen T., Lonvick C. The Secure Shell (SSH) Connection Protocol. — RFC 4254, IETF, 2006. https://www.rfc-editor.org/rfc/rfc4254
- Leech M., Ganis M., Lee Y., et al. SOCKS Protocol Version 5. — RFC 1928, IETF, 1996. https://www.rfc-editor.org/rfc/rfc1928
- Rescorla E. The Transport Layer Security (TLS) Protocol Version 1.3. — RFC 8446, IETF, 2018. https://www.rfc-editor.org/rfc/rfc8446
- Barker E., Dang Q. Guide to IPsec VPNs. — NIST Special Publication 800-77 Rev. 1, 2020. https://doi.org/10.6028/NIST.SP.800-77r1
- Kurose J. F., Ross K. W. Computer Networking: A Top-Down Approach. 8th ed. — Pearson, 2021.