
Преобразует UDP-поток в (фальшивые) TCP-потоки, которые могут проходить через межсетевые экраны/NAT уровня 3 и уровня 4 (NAPT).
Легкий и быстрый обфускатор UDP в TCP.
Rust предоставляет только Tier 3 поддержку для платформ на базе MIPS начиная с 2023 года. Сборки Phantun для MIPS, таким образом, собираются с использованием nightly инструментария Rust и предоставляются только по принципу "насколько это возможно".
Phantun — это проект, который обфусцирует UDP-пакеты в TCP-соединения. Он нацелен на достижение максимальной производительности с минимальными издержками обработки и инкапсуляции.
Обычно используется в средах, где UDP заблокирован/ограничен, а TCP разрешён.
Phantun просто преобразует поток UDP-пакетов в обфусцированные пакеты TCP-потока. Стек TCP, используемый Phantun, спроектирован для прохождения через большинство L3/L4 stateful/stateless брандмауэров/NAT устройств. Он не сможет пройти через L7 прокси. Однако преимущество этого подхода в том, что ни один из типичных "убийц" производительности UDP-over-TCP, таких как повторные передачи и управление потоком, не возникает. Свойства базового UDP, такие как доставка с нарушением порядка, полностью сохраняются, даже если соединение выглядит как TCP с точки зрения брандмауэров/NAT.
Phantun означает "Призрачный TUN", так как это обфускатор для UDP-трафика, который делает ровно столько, чтобы заставить его проходить через stateful брандмауэры/NAT как TCP-пакеты.
Phantun написан на 100% безопасном Rust. Он был тщательно оптимизирован для хорошего масштабирования на многоядерных системах и без проблем насыщает все доступные ресурсы CPU на быстром соединении. См. раздел Производительность для результатов бенчмарков.

В приведённом ниже примере предполагается, что Сервер Phantun ожидает входящие подключения от клиентов Phantun на
порту 4567 (опция --local для сервера) и пересылает UDP-пакеты на UDP-сервер по адресу 127.0.0.1:1234
(опция --remote для сервера).
Также предполагается, что Клиент Phantun ожидает входящие UDP-пакеты на
127.0.0.1:1234 (опция --local для клиента) и подключается к серверу Phantun по адресу 10.0.0.1:4567
(опция --remote для клиента).
Phantun создаёт TUN-интерфейс как для клиента, так и для сервера. Для клиента Phantun по умолчанию назначает себе IP-адрес
192.168.200.2 и fcc8::2.
Для сервера он по умолчанию назначает 192.168.201.2 и fcc9::2. Следовательно, в вашем ядре должна быть
включена пересылка IPv4/IPv6, и должны быть настроены соответствующие правила iptables/nftables для NAT между адресом
вашей физической сетевой карты и адресом Tun-интерфейса Phantun.
Вы можете изменить имя Tun-интерфейса, создаваемого Phantun, и назначенные адреса. Запустите
исполняемый файл с опциями -h, чтобы узнать, как их изменить.
Другой способ понять эту сетевую топологию (см. диаграмму выше для иллюстрации этой топологии):
Клиент Phantun подобен машине с частным IP-адресом (192.168.200.2/fcc8::2) за роутером.
Чтобы он мог выйти в Интернет, вам нужно выполнить SNAT частного IP-адреса перед тем, как его трафик
покинет сетевой интерфейс.
Сервер Phantun подобен серверу с частным IP-адресом (192.168.201.2/fcc9::2) за роутером.
Чтобы получить к нему доступ из Интернета, вам нужно выполнить DNAT его порта прослушивания на роутере
и изменить IP-адрес назначения на тот, где сервер ожидает входящие подключения.
В этих случаях машина/iptables, на которой работает Phantun, выступает в роли "роутера", который позволяет Phantun общаться с внешним миром, используя его частные IP-адреса.
Начиная с Phantun v0.4.1, IPv6 полностью поддерживается как для TCP, так и для UDP сторон.
Для указания IPv6-адреса используйте следующий формат: [::1]:1234 с
опциями командной строки. Также поддерживается разрешение AAAA-записей. Запустите программу
с -h, чтобы увидеть подробные опции управления поведением IPv6.
Отредактируйте /etc/sysctl.conf, добавьте net.ipv4.ip_forward=1 и выполните sudo sysctl -p /etc/sysctl.conf.
net.ipv6.conf.all.forwarding=1 также необходимо установить.
Клиенту просто нужно включить SNAT на физическом интерфейсе, чтобы преобразовать адрес Phantun в адрес, который можно использовать в физической сети. Это можно сделать просто с помощью маскарадинга.
Примечание: измените eth0 на фактическое имя физического интерфейса.
table inet nat {
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
iifname tun0 oif eth0 masquerade
}
}
Примечание: приведённое выше правило использует inet в качестве типа семейства таблиц, поэтому оно совместимо
как с IPv4, так и с IPv6.
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
Серверу нужно выполнить DNAT порта прослушивания TCP на адрес TUN-интерфейса Phantun.
Примечание: измените eth0 на фактическое имя физического интерфейса и 4567 на
фактический номер TCP-порта, используемый сервером Phantun.
table inet nat {
chain prerouting {
type nat hook prerouting priority dstnat; policy accept;
iif eth0 tcp dport 4567 dnat ip to 192.168.201.2
iif eth0 tcp dport 4567 dnat ip6 to fcc9::2
}
}
iptables -t nat -A PREROUTING -p tcp -i eth0 --dport 4567 -j DNAT --to-destination 192.168.201.2
ip6tables -t nat -A PREROUTING -p tcp -i eth0 --dport 4567 -j DNAT --to-destination fcc9::2
Не рекомендуется запускать сетевые приложения от имени пользователя root. Phantun может быть запущен полностью
от имени обычного пользователя с возможностью cap_net_admin.
sudo setcap cap_net_admin=+pe phantun_server
sudo setcap cap_net_admin=+pe phantun_client
Примечание: Запустите исполняемый файл Phantun с опцией -h, чтобы увидеть полный список подробных опций.
Примечание: 4567 — это TCP-порт, на котором должен слушать Phantun, и он должен соответствовать правилу DNAT,
указанному выше. 127.0.0.1:1234 — это UDP-сервер, к которому нужно подключаться для новых соединений.
RUST_LOG=info /usr/local/bin/phantun_server --local 4567 --remote 127.0.0.1:1234
Или используйте имя хоста с --remote:
RUST_LOG=info /usr/local/bin/phantun_server --local 4567 --remote example.com:1234
Примечание: Сервер по умолчанию назначает как IPv4, так и IPv6 частные адреса на Tun-интерфейс. Если вы не хотите использовать IPv6, вы можете просто пропустить создание правила IPv6 DNAT, указанного выше, и наличие IPv6-адреса на Tun-интерфейсе не должно иметь побочных эффектов для сервера.
Примечание: 127.0.0.1:1234 — это UDP-адрес и порт, на котором должен слушать Phantun. 10.0.0.1:4567 —
это сервер Phantun, к которому подключаться.
RUST_LOG=info /usr/local/bin/phantun_client --local 127.0.0.1:1234 --remote 10.0.0.1:4567
Или используйте имя хоста с --remote:
RUST_LOG=info /usr/local/bin/phantun_client --local 127.0.0.1:1234 --remote example.com:4567
RUST_LOG=info /usr/local/bin/phantun_client --local 127.0.0.1:1234 --remote [fdxx::1234]:4567
Также поддерживается доменное имя с AAAA-записью.
Phantun стремится свести к минимуму издержки туннелирования. Издержки по сравнению с обычным UDP-пакетом следующие (на примере IPv4 ниже):
Стандартный UDP-пакет: 20 байт заголовок IP + 8 байт заголовок UDP = 28 байт
Обфусцированный пакет: 20 байт заголовок IP + 20 байт заголовок TCP = 40 байт
Обратите внимание, что Phantun не добавляет никаких дополнительных заголовков, кроме IP- и TCP-заголовков, чтобы проходить stateful проверку пакетов!
Дополнительные издержки Phantun: 12 байт. Другими словами, при использовании Phantun полезная нагрузка для
UDP-пакета уменьшается на 12 байт. Это минимальные возможные издержки при таком типе
обфускации.

Для тех, кто использует Phantun для туннелирования UDP-пакетов WireGuard®, вот несколько рекомендаций по определению правильного MTU для вашего интерфейса WireGuard.
MTU WireGuard = MTU канала - заголовок IPv4 (20 байт) - заголовок TCP (20 байт) - накладные расходы WireGuard (32 байта)
или
MTU WireGuard = MTU канала - заголовок IPv6 (40 байт) - заголовок TCP (20 байт) - накладные расходы WireGuard (32 байта)
Например, для сетевого канала с MTU 1500 байт MTU интерфейса WireGuard должен быть установлен как:
IPv4: 1500 (MTU канала) - 20 - 20 - 32 = 1428 байт
IPv6: 1500 (MTU канала) - 40 - 20 - 32 = 1408 байт
Полученный TCP-пакет данных Phantun будет размером 1500 байт, что не превышает MTU интерфейса 1500.
Пожалуйста, обратите внимание: Phantun не может корректно работать, если
размер пакета превышает MTU канала, так как Phantun не выполняет никакой IP-фрагментации
и сборки. По той же причине Phantun всегда устанавливает бит DF (Don't Fragment)
в IP-заголовке, чтобы предотвратить фрагментацию пакета промежуточными устройствами.
Также настоятельно рекомендуется использовать одинаковый MTU интерфейса на обоих концах туннеля WireGuard, иначе могут возникнуть непредвиденные потери пакетов, и эти проблемы, как правило, очень трудно диагностировать.
Хотя стек TCP довольно стабилен, ожидается, что вы должны запускать одинаковые минорные версии сервера/клиента Phantun на обоих концах, чтобы обеспечить максимальную совместимость.
Для пользователей, желающих использовать библиотеку fake-tcp в своих проектах, обратитесь к документации по библиотеке по адресу:
https://docs.rs/fake-tcp.
Производительность тестировалась на двух экземплярах AWS t4g.xlarge с 4 vCPU и 5 Гбит/с сетевым интерфейсом через локальную сеть. nftables использовался для перенаправления
UDP-потока iperf3 через туннель Phantun/udp2raw между двумя тестовыми экземплярами, и MTU был настроен для избежания фрагментации.
Использовались Phantun v0.3.2 и udp2raw_arm_asm_aes 20200818.0. Это были последние выпуски обоих проектов по состоянию на апрель 2022 года.
Команда тестирования: iperf3 -c <IP> -p <PORT> -R -u -l 1400 -b 1000m -t 30 -P 5
Статья о некоторых техниках, использованных в Phantun для достижения такого результата производительности: Writing Highly Efficient UDP Server in Rust.
udp2raw — ещё один популярный проект от @wangyu-, который очень похож на возможности Phantun. На самом деле, я вдохновлялся Phantun от udp2raw. Самая большая причина для разработки Phantun — это недостаточная производительность при работе udp2raw (особенно на многоядерных системах, таких как Raspberry Pi). Однако цель никогда не состояла в том, чтобы быть настолько же функционально полным, как udp2raw, а только поддерживать наиболее распространённые сценарии использования. В частности, режимы UDP over ICMP и UDP over UDP не поддерживаются, и нет ни анти-повтора, ни поддержки шифрования. Преимущество этого — гораздо лучшая производительность в целом и меньшие издержки MTU из-за отсутствия дополнительных заголовков внутри полезной нагрузки TCP.
Вот краткий обзор сравнения между ними, чтобы помочь вам выбрать:
Copyright 2021-2025 Datong Sun ([email protected])
Лицензировано на условиях Apache License, Version 2.0 <LICENSE-APACHE или https://www.apache.org/licenses/LICENSE-2.0> или лицензии MIT <LICENSE-MIT или https://opensource.org/licenses/MIT>, по вашему выбору. Файлы в проекте не могут быть скопированы, изменены или распространены иначе, чем в соответствии с этими условиями.
| Режим | Скорость отправки | Скорость приёма | Общая загрузка CPU |
|---|
| Прямое соединение (1 поток) | 3.00 Гбит/сек | 2.37 Гбит/сек | 25% (1 ядро на 100%) |
| Phantun (1 поток) | 1.30 Гбит/сек | 1.20 Гбит/сек | 60% (1 ядро на 100%, 3 ядра на 50%) |
udp2raw (cipher-mode=none auth-mode=none disable-anti-replay) (1 поток) | 1.30 Гбит/сек | 715 Мбит/сек | 40% (1 ядро на 100%, 1 ядро на 50%, 2 ядра простаивают) |
| Прямое соединение (5 потоков) | 5.00 Гбит/сек | 3.64 Гбит/сек | 25% (1 ядро на 100%) |
| Phantun (5 потоков) | 5.00 Гбит/сек | 2.38 Гбит/сек | 95% (все ядра задействованы) |
udp2raw (cipher-mode=none auth-mode=none disable-anti-replay) (5 потоков) | 5.00 Гбит/сек | 770 Мбит/сек | 50% (2 ядра на 100%) |
| Phantun | udp2raw |
|---|
| Обфускация UDP через FakeTCP | ✅ | ✅ |
| Обфускация UDP через ICMP | ❌ | ✅ |
| Обфускация UDP через UDP | ❌ | ✅ |
| Многопоточность | ✅ | ❌ |
| Пропускная способность | Лучше | Хорошо |
| Режим уровня 3 | TUN-интерфейс | Raw-сокеты + BPF |
| Издержки MTU туннелирования | 12 байт | 44 байта |
| Отдельные TCP-соединения для каждого UDP-соединения | Клиент/Сервер | Только сервер |
| Анти-повтор, шифрование | ❌ | ✅ |
| IPv6 | ✅ | ✅ |