Введение:
- в августе 2023 года суверенный российский интернет покорил новую вершину — зарубежные
ресурсы впервые начали блокироваться не только по IP-адресам и DNS-именам, но и по сигнатурам
используемых протоколов,
- главной жертвой оказались протоколы, используемые в том числе (но не только и не столько) для обхода
блокировок — например, OpenVPN, WireGuard и IPSec,
- в этих условиях IT-специалистам, продолжающим работать из России с зарубежными ресурсами, жизненно
необходимы инструменты,
обеспечивающие устойчивую связь по мере нарастания ограничений.
Какими должны быть эти инструменты?
- не массовыми — чем популярнее сервис, утилита или протокол, тем вероятнее они попадут под
блокировку,
- разнотипными — чтобы не попасть под сигнатурную блокировку всем одновременно,
- размещёнными у разных провайдеров, в разных странах, на разных доменах — чтобы не попасть под
одновременную блокировку по IP или DNS,
- необязательно быстрыми — лучше иметь работающий SSH со скоростью модема,
чем полностью остаться без связи с внешним миром.
Попробуем туннелировать через ICMP:
- этот способ малоизвестен и непопулярен,
- он медленный — а значит, лишён риска стать популярным даже в том случае, если все прочие
станут жертвами блокировок,
- скорее всего, на ТСПУ
несложно обнаружить такой туннель — например, по непрерывному потоку ICMP-пакетов
большого размера между двумя узлами — но низкая популярность повышает шанс на то, что
блокировки по такой сигнатуре будут внедрены не слишком скоро,
- изначально протокол ICMP разработан для сетевой диагностики и используется утилитами ping, mtr,
tracert и т.д. — благодаря этому
его привыкли воспринимать как сугубо вспомогательный и крайне редко принимают во внимание
возможность передавать данные с его помощью.
Окно возможностей:
- не имеет смысла делать ICMP-туннель основным инструментом — лучше держать его про запас до тех
пор,
пока более быстрые, привычные и функциональные альтернативы не окажутся под запретом,
- в свою очередь, нельзя полагаться на то, что ICMP минует общая участь — для него так же
следует иметь запасной вариант,
- например, таким вариантом может быть туннелирование через DNS с помощью iodine —
соответствующую
инструкцию
уважаемый amarao-san любезно предоставил сообществу 10 лет назад.
Исходные данные:
- IP-адрес сервера = 1.2.3.4
- сеть для туннеля = 10.1.2.0/24
- ключ шифрования, общий для сервера и клиентов = ОЧЕНЬ_СЕКРЕТНАЯ_СТРОКА
Общие сведения:
- приложение для организации ICMP-туннеля состоит из одного исполняемого файла,
- один и тот же файл используется и на стороне сервера, и на стороне клиента,
- сервер может работать только под Линуксом,
- клиента можно собрать для Linux, Windows, MacOS и FreeBSD,
- на Github'e доступны два варианта — старый скомпилированный (для Ubuntu и MacOS) и новый в
исходных текстах.
Скачиваем готовый бинарник для Ubuntu:
wget -O /usr/local/sbin/hans
https://github.com/albertzak/hanstunnel/raw/master/bin/hans-ubuntu
chmod +x /usr/local/sbin/hans
Или собираем более свежую версию из исходных текстов:
apt install git make gcc g++
git clone https://github.com/friedrich/hans.git
cd hans
make
sudo install hans /usr/local/sbin/
Настраиваем автозапуск сервера:
- создаём /etc/systemd/system/icmptunnel.service
systemctl daemon-reload
systemctl enable --now icmptunnel
journalctl -xeu icmptunnel
Содержимое icmptunnel.service:
[Unit]
Description = ICMP tunnel
Docs = https://cdnnow.ru/blog/icmp-tunnel/
After = network-online.target
Wants = network-online.target
[Service]
ExecStartPre = /bin/sh -c 'echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all'
ExecStart = /usr/local/sbin/hans -s 10.1.2.0 -r -p ОЧЕНЬ_СЕКРЕТНАЯ_СТРОКА -u nobody -f -v
ExecStopPost = /bin/sh -c 'echo 0 > /proc/sys/net/ipv4/icmp_echo_ignore_all'
Restart = on-failure
[Install]
WantedBy = multi-user.target
Настраиваем клиента:
- создаём /sbin/ifconfig
- делаем его исполняемым:
chmod +x /sbin/ifconfig
Содержимое /sbin/ifconfig:
#!/bin/sh
case "$2" in
mtu ) ip link set "$1" mtu "$3" ;;
[1-9]* ) ip addr add "$2/24" dev "$1" && ip link set "$1" up ;;
* ) echo "Bad params" ;;
esac
Зачем он нужен?
- hans вызывает /sbin/ifconfig после установки соединения — для настройки туннельного MTU и
IP-адреса,
- в современных Линуксах утилиты ifconfig, netstat и route из пакета net-tools по умолчанию не
устанавливаются — их заменила утилита ip из пакета iproute2,
- поэтому место в каталоге /sbin, принадлежащее древней общесистемной утилите, теперь вакантно,
и мы можем поместить вместо неё наш самодельный суперкостыль без риска повредить систему,
- тем не менее, мы подготовили для hans замену вызова /sbin/ifconfig на /sbin/ip и ждём его принятия в
upstream:
https://github.com/friedrich/hans/pull/25.
Запускаем клиента:
sudo hans -c 1.2.3.4 -p ОЧЕНЬ_СЕКРЕТНАЯ_СТРОКА -u nobody -f -v
Проверяем на клиенте состояние туннеля (в отдельной консоли):
ip addr list dev tun0
ip route list dev tun0
Проверяем на клиенте доступ к серверу через туннель:
ping 10.1.2.1
ssh 10.1.2.1