Skip to content

Latest commit

 

History

History
1048 lines (883 loc) · 68.6 KB

File metadata and controls

1048 lines (883 loc) · 68.6 KB

PiTun

🌐 Languages: English · Русский

Самохостинговый роутер и менеджер прозрачного прокси для Raspberry Pi 4/5 (или любого другого Linux-сервера). Может стоять рядом с роутером, а может быть роутером — брать линию провайдера, раздавать адреса, делать NAT и Wi-Fi. В обоих случаях перехватывает LAN-трафик через nftables TPROXY и маршрутизирует его через xray-core по вашим правилам — домен, GeoIP, GeoSite, MAC, порт, протокол.

CI License Platform

📸 Скриншоты: перейти к галерее.


Содержание


Что это

PiTun превращает небольшую Linux-машину в прозрачный прокси-шлюз для домашней сети — а с версии 1.6.0 и в сам роутер, если вам так нужно. Трафик перехватывается на уровне ядра, маршрутизируется через один из поддерживаемых VPN-протоколов и либо туннелируется, либо отправляется напрямую, либо блокируется — всё согласно правилам из веб-интерфейса.

Две формы, одна коробка. Какая работает — выбирается одним переключателем в панели, по умолчанию шлюз:

Шлюз — рядом с роутером Роутер — вместо него
Кто раздаёт адреса ваш роутер PiTun
Кто делает NAT ваш роутер PiTun
Как охватываются устройства указать им шлюзом PiTun самим фактом присутствия в сети
Что нужно из железа любая коробка, хватит одного порта два порта и более
Wi-Fi вашего роутера PiTun, если адаптер умеет раздавать

Режим шлюза — щадящий: в сети ничего не меняется, и через PiTun идут только те устройства, которые вы на него направили. Режим роутера охватывает всю сеть по построению — включая технику, у которой никаких настроек прокси и не предусмотрено.

Изначально проект разрабатывался и тестировался на Raspberry Pi 4 / 5 (64-bit Raspberry Pi OS), но также собираются linux/amd64 образы — так что любой Intel/AMD мини-PC, NUC, старый ноутбук или x86_64 сервер с Docker подходит ничуть не хуже. Мульти-арх образы для linux/arm64 и linux/amd64 собирает release-workflow.

Подходит для случая, когда нужна единая политика выхода для всего дома (TV, телефоны, IoT) без установки клиентов на каждое устройство и без зависимости от облачно-управляемых роутеров.

Три прокси-эндпоинта одновременно, делят общий набор правил:

Эндпоинт Порт по умолчанию Назначение
TPROXY 7893 Прозрачный шлюз — устройства указывают этот хост как gateway
SOCKS5 1080 Явный прокси для браузеров и приложений
HTTP 8080 Для приложений без поддержки SOCKS5

Режим роутера

С версии 1.6.0 PiTun — полноценный роутер. Не прокси, который заодно что-то пересылает: он берёт линию провайдера, держит DHCP-сервер, делает NAT, работает файрволом и поднимает Wi-Fi. Всё, что прокси умел раньше, продолжает работать поверх — правила, ротация узлов, цепочки, журнал DNS.

Включается в Роутер → Режим работы. Предлагается только на железе с двумя и более физическими портами и никогда не включается сам.

Аплинк — в тех видах, в каких линия провайдера реально бывает:

Режим Что это
DHCP Адрес от провайдера. То, что у большинства называется IPoE
Статика Выданные вам адрес, шлюз и DNS
PPPoE Логин и пароль, сессию поднимает сам PiTun
VLAN-метка 802.1Q на порту аплинка, отдельно или вместе с любым из перечисленного
Клон MAC Показать провайдеру нужный MAC — для линий с привязкой

Сеть снизу. DHCP со своим пулом и сроком аренды, плюс закреплённые за устройствами адреса прямо со страницы «Устройства». PiTun объявляет себя резолвером, поэтому правила маршрутизации и журнал DNS-запросов охватывают и те устройства, которые ни на что не подписывались. LAN может состоять из нескольких портов — розетки и радио объединяются в один сегмент, так что ноутбук по кабелю и телефон по Wi-Fi оказываются в одной подсети и видят друг друга.

Wi-Fi. WPA2 или переходный WPA2/WPA3, диапазон и канал, скрытая сеть при желании, код страны соблюдается. PiTun сначала проверяет, что адаптер вообще умеет работать точкой доступа: многие карты умеют только подключаться, а выяснять это в момент, когда hostapd отказывается стартовать, поздно — рабочая конфигурация к тому времени уже разобрана.

Файрвол. Аплинк не принимает снаружи ничего нового — одно общее правило вместо списка портов, который надо помнить. Панель, SSH и собственные слушатели xray сидят на 0.0.0.0: из LAN они доступны, снаружи их не видно. Два исключения нужны, чтобы линия работала: DHCP-ответы, которые приходят как NEW, а не RELATED, и ICMP, без которого не работает определение MTU по пути. Если PiTun стоит за другим роутером, его «WAN» — это ваша же сеть, и панель с SSH туда можно открыть осознанно; при публичном адресе на аплинке включение будет отклонено.

Смена режима перестраивает сеть под вами. Запасного пути у режима роутера нет — PiTun и есть роутер, — поэтому неудачное применение оставило бы некому его отменить. PiTun сам возвращается в режим шлюза, пока вы не подтвердите, что сеть работает, а неподтверждённое изменение не переживает перезагрузку. Первое переключение делайте там, где до коробки можно дотянуться, а не по SSH из той самой сети, которую она сейчас пересоберёт.

Почему PiTun?

Self-hosted прокси-менеджеров уже хватает: OpenWrt + podkop / passwall / passwall2 / homeproxy, xKeen на Keenetic, Hiddify, Outline и другие. Все они хорошо решают сценарий «поставить на маленький роутер, настроить bypass, забыть». PiTun построен вокруг возможностей, которых в этих лёгких, роутер-bound решениях просто нет:

  • Разверни свой собственный VPN одним кликом из UI. Добавь SSH- доступ к своему VPS → нажми «Deploy NaiveProxy / WireGuard / x-ui» → PiTun сам зайдёт по SSH, прогонит установщик, запишет новую Node в свою БД, и через 30 секунд твой трафик уже идёт через неё. Никаких SSH-and-curl ритуалов. (VPS = небольшой удалённый Linux-сервер, который ты арендуешь за несколько долларов в месяц.) Все данные — креды, токены панелей, правила — лежат только на твоём железе, ни в каком чужом облаке.

  • Двухпрыжковые цепочки между панелями. Связывай две x-ui панели (популярная веб-панель управления VPN-серверами) в единую цепочку с управляемыми клиентами на каждом канале. Трафик устройства идёт VPS-A → VPS-B → интернет. Ни один конкурирующий router-based инструмент так не умеет из одного UI.

  • Туннелируй один протокол через другой прямо из формы ноды. Хочешь, чтобы WireGuard-нода ходила наружу через VLESS-туннель? Открой форму редактирования WG-ноды, выбери VLESS-ноду в дропдауне «Chain» — готово. PiTun сам сконфигурирует xray outbound так, что handshake WireGuard (и весь последующий трафик) сначала идёт через VLESS, и только потом приходит на твой WG-сервер. Полезно, если у твоего VPS-провайдера зарезан чистый WG.

  • Правила маршрутизации по группам устройств. Создай свою группу устройств и заведи под неё отдельные правила маршрутизации. Примеры:

    • Группа «Дети» → блокирует азартные игры и гонит трафик через нод с родительским контролем.
    • Группа «Рабочий ноут» → корпоративные домены идут direct (мимо VPN), всё остальное — через отдельную ноду.
    • Группа «Смарт-ТВ» → блокирует рекламу и пускает стриминг через конкретную высокоскоростную ноду.

    Устройства назначаются в группу через дропдаун на странице Devices — никаких клиентских приложений на каждое устройство ставить не надо.

  • Авто-ротация активной ноды по расписанию. NodeCircle каждые N минут выбирает следующий живой VPN-сервер, перед переключением пингует каждый кандидат, пропускает мёртвые и подменяет нод без обрыва уже установленных соединений.

  • Три прокси-эндпоинта на один набор правил — прозрачный шлюз для всей LAN (TPROXY), SOCKS5 для приложений с явным прокси, HTTP для legacy-клиентов. Большинство инструментов заставляют выбирать что-то одно.

  • Он может заменить роутер целиком. Те пакеты работают на роутере, потому что он им нужен. PiTun может им быть: линия провайдера (DHCP, статика, PPPoE, VLAN, клон MAC), DHCP-сервер, NAT, файрвол и Wi-Fi — см. Режим роутера. Одна коробка вместо двух, и политика прокси распространяется на всю сеть по построению, а не только на те устройства, которые вы не забыли на него направить.

vs. router-based пакеты (podkop, passwall, passwall2, homeproxy, xKeen): они блестяще решают «все устройства, минимальная настройка» на роутере за $30 с 64 МБ RAM, и если это всё, что нужно, — они и есть более лёгкий ответ. PiTun нужен тогда, когда тебе нужна server-side оркестрация (разворачивать и управлять своими VPS), многоуровневая политика трафика (разные правила для разных групп устройств), коробка, которая сама может быть роутером, а не ездить на чужом, и современный веб-интерфейс с удобной мобильной версией — поменять правило с телефона, хоть из ванной — за цену необходимости иметь RPi 4/5 (или любой маленький Linux-box) с 64 ГБ+ диском.

Скриншоты

Дашборд — нажмите чтобы развернуть · 1 скриншот
Dashboard
Provisioning VPS и оркестрация x-ui (с v1.3.0) — нажмите чтобы развернуть · 6 скриншотов
Servers

Servers — инвентарь VPS, бэйджи развёртываний (NaiveProxy / WireGuard / x-ui), one-click auto-install по SSH

Server tasks

Server tasks — live-лог установки через WebSocket, фильтры по статусу, сохранённый tail для завершённых задач

Панели X-ui

Панели X-ui — управление inbounds + клиентами на 3x-ui / x-ui-pro, healthcheck, sync, ротация фейк-сайта

Proxy Chains

Proxy Chains — двухзвенный VLESS+Reality через две x-ui панели, независимые каналы со своими SNI / Reality-ключами

Deploy modal

Deploy modal — выбор протокола (Naive / x-ui / WG), домен + LE email если нужно, live-стрим установки

Chain healthcheck

Chain healthcheck — API панелей, состояние xray, наличие inbounds, routing на relay плюс live testOutbound для хопа relay→exit

Маршрутизация и ноды — нажмите чтобы развернуть · 6 скриншотов
Ноды

Ноды — протоколы, транспорты, латентность, унифицированная палитра пилюль (protocol blue / transport green / reality purple / tls orange)

Маршрутизация

Маршрутизация — drag-приоритеты, массовый импорт, round-trip V2RayN/Shadowrocket, multi-tag редактор match-value

Balancers

Balancers — группировка нод по стратегии xray leastPing / random

Node Circles

Node Circles — бесшовная ротация через xray gRPC API, TCP pre-ping с retry, двухуровневый auto-failover

Подписки

Подписки — авто-обновление, per-OS Happ-пресеты, custom UA

Geo-профили

Geo-данные — три переключаемых upstream-профиля (Loyalsoldier / runetfreedom / v2fly) + scheduled refresh

Устройства, DNS и диагностика — нажмите чтобы развернуть · 4 скриншота
DNS

DNS — правила по доменам, FakeDNS-пул, лог запросов со статистикой

Устройства

Устройства — сканирование LAN, OUI vendor lookup, политики per-device

Диагностика

Диагностика — доступность DNS, состояние шлюза, здоровье xray, снимок ресурсов, экспорт диагностики для багрепортов

Настройки

Настройки — TPROXY / TUN / DNS / health check / GeoData scheduler / kill switch

Архитектура

Режим шлюза — PiTun стоит рядом с роутером и проксирует те устройства, которые на него направили:

                 ┌──────────────────────────────────────────────┐
  Устройства ──►   PiTun-хост (RPi / mini-PC)                  
  (LAN)                                                        
                   nftables TPROXY :7893                       
                                                              
                                                              
                   xray-core ─┬─ правила (geoip / geosite /    
                                 domain / IP / MAC / port)    
                                                              
                              ├─► proxy   (VPN-нода / chain)   
                              ├─► direct  (домашний роутер)    
                              └─► block                        
                                                               
                   + балансировщики (leastPing / random)       
                   + Node Circles (авторотация активной ноды)  
                   + DNS по доменам (plain / DoH / DoT)        
                 └──────────────────────────────────────────────┘

Режим роутера — тот же движок, но оба конца сети держит PiTun. Прокси-слой выше не меняется; добавляется всё, что делает роутер:

                 ┌──────────────────────────────────────────────┐
Провайдер ──────►│ WAN  dhcp / статика / pppoe / vlan / mac     
                                                              
                   ├─ nftables: NAT (masquerade) + файрвол     
                       аплинк не принимает новых входящих     
                       TCP MSS подрезается под MTU пути       
                                                              
                                                              
                  ┌──────── прокси-движок, схема выше ───────┐ 
                  └──────────────────────────────────────────┘ 
                                                              
                   ├─ dnsmasq: DHCP + закреплённые адреса      
                   ├─ hostapd: точка доступа Wi-Fi             
                                                              
 Устройства ◄────┤ LAN  один или несколько портов в мосту br-lan│
 (кабель+Wi-Fi)        провод и радио в одной подсети          
                 └──────────────────────────────────────────────┘
                   каждое изменение под watchdog с подтверждением

Веб-интерфейс общается с FastAPI-бэкендом, который владеет процессом xray-core, набором правил nftables и SQLite-базой со всеми настройками. Фронтенд — single-page React-приложение, отдаваемое через nginx.

Возможности

Роутер (v1.6.0 — см. Режим роутера)

  • Два режима работы: шлюз рядом с роутером или роутер вместо него. Выбор явный, по умолчанию шлюз
  • Аплинк: DHCP (IPoE), статика, PPPoE, метка VLAN 802.1Q, клон MAC — причём NAT, файрвол и счётчики следуют за тем интерфейсом, которым трафик реально уходит, включая ppp-линк и тегированный подынтерфейс
  • DHCP-сервер с пулом, сроком аренды и закреплёнными за устройствами адресами
  • LAN из нескольких портов — розетки и радио в одном мосту, одна подсеть, общий пул DHCP
  • Точка доступа Wi-Fi — WPA2 или переходный WPA2/WPA3, диапазон, канал, скрытый SSID, код страны; с предварительной проверкой, что адаптер вообще умеет раздавать
  • WAN, не принимающий снаружи ничего нового, с возможностью осознанно опубликовать туда панель и SSH, когда PiTun стоит за другим роутером — и с отказом, если адрес аплинка оказался публичным
  • Watchdog с подтверждением — изменение, сломавшее сеть, откатывается само, и неподтверждённое не переживает перезагрузку
  • Диагностика аплинка по счётчикам nftables — для отказов, которые иначе молчат: нет DHCP-ответов, не возвращается ICMP, трафик уходит мимо аплинка

Ядро

  • Прозрачный прокси через TPROXY + nftables, без клиента на устройствах
  • SOCKS5 / HTTP прокси в LAN
  • Опциональный TUN-режим и комбинированный TPROXY+TUN
  • Блокировка QUIC (UDP/443) — принудительный fallback на TCP, который TPROXY умеет перехватывать
  • Цепочки туннелей — VLESS внутри WireGuard и т.д.
  • Рекурсивные multi-hop цепочкиconfig_gen транзитивно проходит по chain_node_id, прошивая каждый хоп (exit → mid → entry) с детекцией циклов и лимитом глубины (WireGuard — только exit-хоп)
  • Proxy Chains (multi-panel, двухзвенный VLESS+Reality через две x-ui панели с независимыми каналами; управляемые клиенты, per-channel delete, live healthcheck)
  • Фрагментация TLS ClientHello (anti-DPI) — тумблер в Settings бьёт исходящий ClientHello на несколько пакетов, чтобы DPI не смог поймать SNI за одно чтение; полностью на стороне клиента, настраиваемые режим пакетов / длина / интервал, по умолчанию выключено (нужен bundled xray 26.x)
  • Kill switch — отключение всего форвард-трафика при падении xray

Маршрутизация

  • Типы правил: mac, src_ip, dst_ip, domain, port, protocol, geoip, geosite
  • Действия: proxy, direct, block, node:<id>, balancer:<id>
  • Drag-and-drop приоритеты, массовый импорт, round-trip с V2RayN/Shadowrocket JSON
  • Per-MAC исключения («это устройство всегда direct, то — всегда через ноду #5»)
  • Routing Sets — списки правил на группу устройств («Дети» блокируют азартные игры, «Работа» гонит корп-домены direct). Назначение устройств поштучно или пачкой; правила набора применяются первыми, затем fall-through к глобальным. Устойчивы к DHCP (по MAC, через выделенные per-set loopback TPROXY-порты + inboundTag в xray). Экспорт/импорт с учётом наборов — выбор scope, разрешение конфликтов, импорт в Global / существующий / новый набор
  • Route Explainer — вставь домен, URL или IP и увидь, какое правило победит и куда выйдет: proxy, direct или block

Здоровье и устойчивость

  • Фоновая проверка живости с двухуровневым auto-failover: если упавшая нода входит в активный NodeCircle — failover делегирует восстановление кругу (он пропускает мёртвых соседей через pre-ping + retry); иначе идёт по настраиваемому списку fallback-нод
  • Единый speed test — сначала гейтит по достижимости (Google / Cloudflare 204 с повтором, так что мёртвая нода падает за ~1с вместо перебора всех fallback), затем меряет среднее после прогрева плюс пик; стримит в реальном времени, сохраняет оба числа и помечает замер старше 6ч как устаревший
  • Автоматические фоновые speed-проверки — прогон по выбранному scope (все / подписка / группа / конкретные ноды) по интервалу, чтобы best / min_speed и UI оставались свежими без ручного теста; последовательно, со staleness-guard и изоляцией ошибок по каждой ноде
  • Проверка достижимости в один тап — подтверждает, что нода реально проносит трафик в интернет (204 через живой туннель), отдельно от сырой скорости
  • Supervisor для Naive sidecars — авторестарт упавших контейнеров с rate-limiter (sliding window)
  • Лента событий на Dashboard показывает failover-ы, рестарты sidecar, обновления geo, ротации circle

Балансировка и ротация

  • Группы балансировки (стратегии xray leastPing / random)
  • Node Circles — расписание бесшовной ротации активной ноды через xray gRPC API (соединения не рвутся). Режим best плюс фильтры кандидатов max_latency_ms и min_speed_mbps выбирают по реальным данным скорости (не тестированные ноды получают презумпцию невиновности), а smart-skip не даёт плановой ротации уйти со здоровой ноды с низким пингом — ручная «ротация сейчас» крутит всегда

Подписки

  • Периодическое обновление с VLESS / VMess / Trojan / SS / Hysteria2 / Clash YAML / xray JSON URL-подписок
  • User-Agent шаблоны — редактируемая таблица (add / edit / delete) вместо старых захардкоженных пресетов; каждая строка несёт UA-строку и опциональные кастомные request-заголовки, с экспортом / импортом каталога
  • Флаги стран у нод (🇳🇱 vless-nl) — считываются через сам туннель тестом скорости и проверкой интернета, поэтому флаг показывает, где трафик реально выходит наружу (у цепочки — последний хоп, а не входной, чей адрес хранится). База для этого не нужна. Дополнительно можно определять страну по адресу при импорте — если положить MaxMind GeoLite2-Country.mmdb рядом с geo-данными; без него эта половина просто молчит
  • Опциональный regex-фильтр, настраиваемый интервал

Устройства и DNS

  • Сканирование LAN через arp-scan, OUI vendor lookup
  • Per-device политика маршрутизации (default / always-include / always-bypass)
  • DNS-правила по доменам (plain, DoH, DoT)
  • FakeDNS-пул для sniffing-friendly geoip-резолва
  • Лог DNS-запросов со статистикой
  • Управление host-сетью — смена собственного gateway / DNS бокса из Settings → Network с авто-бэкапом и откатом в один клик; предупреждает о routing self-loop (gateway указывает на сам бокс) или double-hop через другой PiTun

Серверы и развёртывания

  • Инвентарь удалённых VPS (host, SSH-доступы, теги) отдельно от runtime- нод — async-SSH probe, записи о развёртываниях помнят какой протокол/порт настроен на какой машине, опционально — manual provisioning скрипты (Caddy + naive, xray, харднинг SSH) по тому же SSH-каналу
  • One-click auto-deploy по SSH для NaiveProxy, WireGuard, x-ui (3x-ui / x-ui-pro) — live-стриминг лога, статус-бэйджи, cascade-cleanup при удалении
  • Тумблер Direct на каждой странице — любая SSH-операция сервера / панели / цепочки идёт через активную ноду по умолчанию (тот же туннель, что и LAN); переключатель Direct возвращает одну операцию на прямой дозвон, чтобы достучаться до бокса, пока активная нода лежит
  • Отдельная страница Панели X-ui — полное управление инбаундами и клиентами панели (6 готовых пресетов: Reality / TLS / domain), live healthcheck (API панели, xray, nginx, UFW, TLS-сертификат, диск, память), синхронизация cache↔panel для добавленных вручную клиентов, ротация рандомного / своего фейк-сайта
  • Сканер REALITY-dest / SNI там, где создаётся inbound — проверяет кандидата (IP или домен) через активную ноду на TLS 1.3 + HTTP/2 и показывает, что там на самом деле отвечает, вместо угадывания цели маскировки по зашитому списку
  • Подключить панель, которую ставил не PiTun. Импортируешь сервер, где x-ui уже стоит, — раньше страница X-ui оставалась пустой, потому что панелью считалась только развёрнутая через PiTun. Теперь достаточно вставить строку xui:// из установки или просто свой логин от панели: токен API будет получен сам, причём существующий переиспользуется, а не выпускается новый на каждую попытку
  • Панель едет вместе со своим сервером — сервер, выгруженный с секретами, несёт и регистрацию панели (конверт v3), так что при восстановлении на другой коробке x-ui не остаётся установленным и неучтённым
  • Политика времени жизни соединений Xray — один набор таймаутов для самой коробки и всех зарегистрированных панелей. Дефолт Xray убивает простаивающее соединение из пула через пять минут — это то самое «работает, а потом нет» у SDK- и агентских клиентов; панели правятся, а не перезаписываются, и одной кнопкой изменение уходит на все сразу

Эксплуатация

  • One-click обновление GeoIP / GeoSite — три переключаемых upstream- профиля: Loyalsoldier (CN-ориентированный community-список), runetfreedom (курируемый список для рунета), v2fly (vanilla baseline)
  • Обновление из UI — Settings → Updates проверяет GitHub (через активную ноду, так что урезанный прямой маршрут не помеха), показывает что нового и применяет с живым прогрессом через host-side агента
  • Полноформатный JSON Export/Import для Nodes и Servers — версионный конверт, режимы append/replace, опциональная редактирование секретов (отдельно от URI/subscription импорта, который работает только на одну ноду)
  • Plain-text URI экспорт (.txt, по одному vless://… на строку) — расшарить список нод в любой v2rayN-совместимый клиент; единая кнопка Import авто-определяет формат URI vs JSON-бандл. Плюс экспорт URI одной ноды прямо с её карточки
  • Резервная копия всей конфигурации — Settings → Backup & Restore выгружает настройки, подписки, ноды, наборы правил, DNS-правила, балансировщики, круги, устройства и шаблоны UA одним файлом и восстанавливает их на чистой коробке. Секреты — по явному согласию, так что файл, отправленный на разбор, не несёт учётных данных; перед записью восстановление показывает, что именно добавится, изменится и удалится
  • Блокировка входа (lockout) — пять подряд неудачных логинов блокируют аккаунт на 15 минут (HTTP 429 + Retry-After); основной защитник от перебора в LAN-only сети
  • Встроенная страница диагностики (DNS, шлюз, статус xray, ресурсы)
  • Стриминг логов xray
  • Многоязычный UI (English / Русский)

Поддерживаемые протоколы

Протокол Заметки
VLESS Plain, TLS, REALITY, XTLS Vision; транспорты WebSocket / gRPC / xhttp / HTTP/2 / HTTPUpgrade / mKCP / QUIC
VMess То же меню транспортов, что и VLESS
Trojan TLS / WebSocket / gRPC / xhttp
Shadowsocks Все современные stream / AEAD шифры
WireGuard Нативный xray-outbound; работает в составе цепочек
Hysteria2 UDP, опциональный obfuscation password
SOCKS5 Как outbound (например, для chain)
NaiveProxy Sidecar-контейнер на каждую ноду (Caddy + forwardproxy на серверной стороне); xray подключается через локальный SOCKS5

Быстрый старт

Системные требования

Ресурс Минимум Рекомендуется
CPU 64-bit ARM (RPi 4) или x86_64, 4 ядра RPi 5 / любой современный x86_64 мини-PC
RAM 1 GB 2 GB+ (помогает с naive sidecars и большими geo-обновлениями)
Диск 4 GB свободного места 8 GB+ (Docker-образы + рост БД + DNS query log)
Сеть 1 LAN-интерфейс, статический IP, лучше проводной 1× wired GbE для LAN
Сеть — режим роутера 2 физических порта (один к провайдеру, второй в сеть) 2× wired GbE плюс Wi-Fi-адаптер с поддержкой точки доступа
OS Любой современный 64-bit Linux с ядром ≥ 5.4 (поддержка TPROXY) Raspberry Pi OS 64-bit, Debian 12+, Ubuntu 22.04+
Архитектуры linux/arm64 (RPi 4/5) · linux/amd64 (Intel/AMD мини-PC, NUC, x86_64 сервер)

Требования

  • Одна из поддерживаемых архитектур выше
  • Docker + Docker Compose v2
  • Root-доступ на хосте (nftables + raw socket binding)
  • Статический LAN IP для хоста
  • Для режима роутера: два и более физических порта, а если PiTun должен раздавать Wi-Fi — адаптер с поддержкой точки доступа. PiTun проверит адаптер сам и скажет об этом до того, как что-либо будет разобрано

Установка — одной командой

Самый простой путь — скачать всё и поднять стек одной командой. Скрипт тянет pre-built образы из последнего GitHub Release, локального docker build не происходит — на свежем RPi занимает ~5 минут. Если интернет упадёт во время скачивания, перезапусти ту же команду: завершённые загрузки пропустятся, оборванные продолжатся (атомарный rename .tmp → final).

curl -fsSL https://raw.githubusercontent.com/DaveBugg/PiTun/master/install.sh | sudo bash

Внимание — передача флагов через pipe. Флаги вида --flag ниже должны попадать в наш installer, а не в bash. Рабочих форм три, выбирай ту, которую сложнее всего ошибиться при копипасте:

(A) Foolproof — скачать и запустить:

curl -fsSL https://raw.githubusercontent.com/DaveBugg/PiTun/master/install.sh \
     -o /tmp/pitun-install.sh
sudo bash /tmp/pitun-install.sh --version v1.4.12

(B) Pipe с разделителем bash -s -- (-s -- обязателен):

curl -fsSL https://raw.githubusercontent.com/DaveBugg/PiTun/master/install.sh \
     | sudo bash -s -- --version v1.4.12

(C) Через переменную окружения (без -s -- шаманства):

curl -fsSL https://raw.githubusercontent.com/DaveBugg/PiTun/master/install.sh \
     | sudo PITUN_VERSION=v1.4.12 bash

Так делать НЕ нужно: curl ... | sudo bash --version v1.4.12 — bash съедает --version как свой собственный флаг (печатает версию bash и выходит) до того как наш installer вообще запустится. Частая ловушка копипаста.

Полезные флаги (работают через любую из трёх форм выше; примеры в форме B):

# Конкретная версия (пример тега — актуальный смотри в GitHub Releases)
... | sudo bash -s -- --version v1.4.12

# Принудительная сборка из исходников (если релиза ещё нет или
# тестируешь локальные изменения). Медленнее, нужен стабильный
# интернет на время docker build.
... | sudo bash -s -- --build

# Гибридный offline-режим — указать директорию с заранее скачанными
# артефактами. ЛЮБОЙ файл из директории используется как есть;
# отсутствующие — докачиваются обычным образом.
# Также авто-определяется при запуске install.sh из директории, в
# которой уже лежат любые из шести ожидаемых файлов — флаг
# `--offline` в этом случае не нужен. Подробности и список файлов:
# docs/INSTALL_OFFLINE.md.
... | sudo bash -s -- --offline /tmp/pitun-artifacts

# Своя директория установки (по умолчанию: /opt/pitun)
... | sudo bash -s -- --dir /srv/pitun

# Просто посмотреть что сделает, без изменений
... | sudo bash -s -- --dry-run

После завершения:

  • Web UI на http://<ip-хоста>/, логин admin / password (смени при первом входе через Settings → Account).
  • /opt/pitun/.env сгенерирован со случайным SECRET_KEY и авто-детектом сетевого блока с интерфейса дефолтного маршрута: INTERFACE, LAN_CIDR, GATEWAY_IP (это LAN-IP самого PiTun, не роутера), VITE_API_BASE_URL, VITE_WS_BASE_URL, CORS_ORIGINS. Проверь через head -30 /opt/pitun/.env перед боевым запуском; если что-то не так — отредактируй и docker compose -f /opt/pitun/docker-compose.yml restart.

Полный список опций — install.sh --help.

Установка через git clone

Если нужен исходник рядом с работающим стеком (например для разработки или patch'ей перед деплоем) — классический путь тоже работает:

git clone https://github.com/DaveBugg/PiTun pitun
cd pitun

# Подготовка хоста: ставит Docker (если нет), xray-core, GeoIP/GeoSite,
# системные пакеты, kernel-модули, sysctl-tweaks, log rotation, cron на
# ежедневную очистку. Пропустить можно — см. «Ручная установка» ниже.
sudo bash scripts/setup.sh

cp .env.example .env
# Отредактируйте .env — минимум: SECRET_KEY, INTERFACE, LAN_CIDR,
# GATEWAY_IP (это LAN-IP самого PiTun — то, что устройства будут
# использовать как default gateway). Случайный SECRET_KEY:
# openssl rand -hex 32
#
# Совет: вместо ручной правки можно запустить `sudo bash install.sh
# --skip-host-prep` из этого же checkout — оно автодетектит все
# сетевые значения с дефолтного интерфейса и пишет в .env (только при
# первой генерации).

docker compose up -d --build

Веб-интерфейс слушает LAN IP хоста на порту 80. Логин по умолчанию — admin / password, смените при первом входе через Settings → Account.

Ручная установка (без setup.sh)

Если хочешь подготовить хост вручную — вот эквивалентный чеклист. Всё ниже должно быть сделано до docker compose up:

# 1. Системные пакеты
sudo apt update
sudo apt install -y curl wget ca-certificates nftables iproute2 \
    net-tools iptables arp-scan dnsutils unzip jq cron

# 2. Освобождаем UDP/5353 (порт PiTun-DNS)
sudo systemctl stop avahi-daemon avahi-daemon.socket || true
sudo systemctl disable avahi-daemon avahi-daemon.socket || true
sudo systemctl mask avahi-daemon || true

# 3. Sysctl: IP-forwarding + TPROXY loopback
sudo tee /etc/sysctl.d/99-pitun.conf <<'EOF'
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1
net.ipv4.conf.all.route_localnet = 1
EOF
sudo sysctl --system

# 4. TPROXY-модули (загрузить сейчас + закрепить на следующую загрузку)
sudo modprobe nft_tproxy xt_TPROXY
echo -e "nft_tproxy\nxt_TPROXY" | sudo tee /etc/modules-load.d/pitun.conf

# 5. Docker + Compose v2 (пропустить если уже стоит)
curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker "$USER"   # потом logout + login

# 6. Базы GeoIP/GeoSite (bind-mount RW в контейнер бэкенда — чтобы их
#    можно было обновлять из UI без пересборки образа). Сам xray-бинарник
#    идёт внутри backend-образа начиная с v1.2.0 — устанавливать на хост
#    отдельно не нужно.
sudo mkdir -p /usr/local/share/xray
sudo curl -fsSL -o /usr/local/share/xray/geoip.dat   https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat
sudo curl -fsSL -o /usr/local/share/xray/geosite.dat https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat

# 7. Статический IP на LAN-интерфейсе (NetworkManager / dhcpcd / netplan
#    — что у твоего дистрибутива; не скриптуем т.к. инструмент разный).

# 8. Можно деплоить
cp .env.example .env && $EDITOR .env
docker compose up -d --build

Почему geo-базы на хосте, а не внутри образа. geoip.dat / geosite.dat обновляются из UI (GeoData → Update). Их хранение bind-mount'ом значит что один curl обновляет файлы на месте — без rebuild образа. Сам бинарник xray, наоборот, теперь идёт внутри backend-образа (с v1.2.0; раньше ставился на хост). Один host-side prerequisite меньше, версия привязана к тегу релиза.

Готовые образы

CI release-workflow публикует загружаемые Docker-tarball'ы (linux/amd64 и linux/arm64) как assets к GitHub Release. Удобно для air-gapped / свежих RPi-инсталляций:

# На машине с интернетом
curl -LO https://github.com/DaveBugg/PiTun/releases/download/vX.Y.Z/pitun-backend-vX.Y.Z-arm64.tar.gz
curl -LO https://github.com/DaveBugg/PiTun/releases/download/vX.Y.Z/pitun-frontend-vX.Y.Z.tar.gz

# Перенесите на хост и:
docker load < pitun-backend-vX.Y.Z-arm64.tar.gz
tar -xzf pitun-frontend-vX.Y.Z.tar.gz -C frontend/dist/
docker compose up -d

Setup-скрипты

Для специфичной для RPi первичной настройки (first boot, OS-зависимости, сеть) в scripts/ лежат хелперы — см. scripts/README.md.

Обновление

Из панели. Settings → Updates проверяет GitHub — через активную ноду, так что придушенный прямой маршрут не помеха, — показывает, что изменилось, и применяет с живым прогрессом.

Кнопка обновляет коробку не сама: она пишет запрос, который выполняет агент на хосте, потому что обновление подменяет тот самый контейнер, из которого отдаётся панель. Установщик этого агента ставит. На коробке, установленной до v1.6.2, его нет, и кнопка будет висеть на 0% бесконечно — поставьте один раз:

bash /opt/pitun/scripts/pitun-update.sh --install-agent

Автообновление это не включает. Агент выполняет только тот запрос, который вы сделали сами.

Из командной строки. Запустите установщик с версией: он распознает существующую установку, сначала снимет копию базы и откажется откатываться назад:

curl -fsSL https://raw.githubusercontent.com/DaveBugg/PiTun/master/install.sh      -o /tmp/pitun-install.sh
sudo bash /tmp/pitun-install.sh --version v1.6.2

По расписанию — отдельно от кнопки и по желанию: ежедневный systemd-таймер, который без явной просьбы только отчитывается:

bash /opt/pitun/scripts/pitun-update.sh --install-timer          # проверить и сообщить
bash /opt/pitun/scripts/pitun-update.sh --install-timer --apply  # проверить и обновить

Любой путь перед началом снимает копию SQLite в /opt/pitun/data-backup-pre-vX.Y.Z-*.db, а режим роутера поднимается сам после пересоздания контейнеров.

Конфигурация

Все runtime-настройки идут через веб-интерфейс. Что нужно задать до первого запуска через .env:

Переменная Default Что
SECRET_KEY changeme-… Ключ подписи JWT — openssl rand -hex 32
INTERFACE eth0 Имя LAN-интерфейса на хосте
LAN_CIDR 192.168.1.0/24 Ваша LAN-подсеть (автодетектится install.sh)
GATEWAY_IP 192.168.1.100 LAN-IP самого PiTun — устройства задают это как default gateway. (Имя оставлено для обратной совместимости; это не IP роутера.) Автодетектится install.sh.
BACKEND_PORT 8000 Порт бэкенда (за nginx)
TPROXY_PORT_TCP 7893 TCP-листенер TPROXY
DNS_PORT 5353 Внутренний DNS-форвардер
NAIVE_PORT_RANGE_START 20800 Range для Naive sidecar портов
NAIVE_IMAGE pitun-naive:latest Тег образа (билд локально или из release)

Полный аннотированный пример: .env.example.

О GATEWAY_IP: имя переменной осталось с тех времён когда LAN- gateway фичи ещё не было, и относится к самому PiTun-хосту, а не к роутеру. Если в .env лежит несовпадающий с реальным IP интерфейса — бэкенд автоматически синкнет живой IP в БД при первом GET /settings, так что в UI всегда будет правда. У LAN_CIDR такой же runtime- fallback с версии 1.2.3.

Удаление

Чтобы полностью снести PiTun с хоста:

# Интерактивно — спрашивает перед операциями уровня хоста:
sudo bash /opt/pitun/scripts/uninstall.sh

# Headless подготовка к re-image — снести всё включая host-tweaks:
sudo bash /opt/pitun/scripts/uninstall.sh --purge

# Превью того что будет удалено, без изменений:
sudo bash /opt/pitun/scripts/uninstall.sh --dry-run

# Сохранить БД + конфиги под будущую переустановку:
sudo bash /opt/pitun/scripts/uninstall.sh --yes --keep-data

Uninstall обрабатывает каждую разновидность установки — registry-pull, локальная сборка (--build), offline бандлы, dev compose-стек, динамические naive-sidecar'ы, backup-папки от хот-деплоев. Идемпотентен (повторный запуск на уже очищенном хосте честно скипает отсутствующее, не падает) и безопасен по умолчанию (спрашивает перед изменениями nftables / sysctl / DNS / swap / host network).

Главные флаги:

Флаг Эффект
--dry-run Только превью — ничего не трогать.
-y / --yes Без вопросов на стандартных удалениях.
--purge Всё, включая host network.
--keep-data Сохранить БД + конфиги (data/ остаётся).
--keep-network Никогда не трогать файлы network manager.
--keep-xray Оставить /usr/local/bin/xray + geo.

Полный список и обоснование каждого флага — в scripts/README.ru.md. Phase 7 (host network) — единственный HIGH-RISK шаг. Может оборвать SSH если IP PiTun ранее менялся через Settings UI. Открой вторую SSH-сессию до подтверждения если ты не на локальной консоли.

Разработка

# Бэкенд
cd backend
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt -r requirements-dev.txt
python -m uvicorn app.main:app --reload --port 8000
python -m pytest tests/ -q

# Фронтенд
cd frontend
npm ci
npm run dev          # http://localhost:5173
npm run build        # tsc + vite (отлавливает type errors)
npm run test:ci
npm run lint

Полный Docker-стек — в docker-compose.yml. Для локальной разработки UI без RPi-специфики (TPROXY, nftables) Docker не обязателен — auth, ноды, правила маршрутизации и большая часть UI работают на macOS/Windows против бэкенда на localhost:8000.

См. CONTRIBUTING.md — конвенции PR и стиль кода.

Стек технологий

Бэкенд — Python 3.11, FastAPI, SQLModel/SQLAlchemy, Alembic, Pydantic v2, Uvicorn, httpx, aiohttp, aiosqlite, bcrypt, python-jose, psutil, docker-py, PyYAML.

Фронтенд — React 19, TypeScript, Vite, Tailwind CSS 3, TanStack Query (React Query) v5, Zustand, React Router 6, Recharts, Lucide React, axios, clsx, tailwind-merge.

Инфраструктура — Docker + Compose, nginx (frontend), Tecnativa docker-socket-proxy (read-only Docker API из бэка), nftables, systemd.

Тесты — pytest, Vitest, Testing Library.

Благодарности

PiTun — это glue-код поверх зрелых проектов, без которых ничего из этого бы не существовало:

Прокси / сетевое ядро

  • XTLS/Xray-core — собственно прокси-движок. PiTun управляет процессом xray-core, генерирует ему конфиг и общается с его gRPC API.
  • klzgrad/naiveproxy — Chromium-based HTTPS-туннелирующий прокси, используется как sidecar на каждую naive-ноду. Образ собирается из upstream-релизов в docker/naive/.
  • Caddy + caddyserver/forwardproxy (форк klzgrad) — рекомендуемый сервер для NaiveProxy. Скрипт scripts/setup-naive-server.sh собирает его через xcaddy.
  • MHSanaei/3x-ui — upstream x-ui панель (v3.1.0). В режиме «bare» PiTun автоматически устанавливает её и управляет inbounds/клиентами через API панели.
  • GFW4Fun/x-ui-pro — форк 3x-ui с доменом + nginx + LE, используется в режиме «xui-pro» и как relay/exit-узлы в Proxy Chains.
  • GFW4Fun/randomfakehtml — фейк-сайт шаблоны, бандлятся при установке xui-pro и используются встроенной функцией «ротация fakesite».
  • Loyalsoldier/v2ray-rules-dat — базы GeoIP / GeoSite, которые xray использует в матчерах geoip: / geosite:. PiTun тянет последние geoip.dat и geosite.dat отсюда.
  • MaxMind GeoLite2 — GeoIP-MMDB lookups (опционально).
  • netfilter / nftables — kernel-side TPROXY interception.
  • arp-scan — сканирование устройств в LAN.

Бэкенд

Фронтенд

Инфраструктура

Совместимость с форматами импорта (V2RayN / Shadowrocket / Clash JSON) вдохновлена форматами этих проектов — никакой код не заимствован.

Вклад в проект

Bug-репорты и PR приветствуются. См. CONTRIBUTING.md — стиль кода, конвенции PR, что не должно попадать в репо.

Лицензия

BSD 3-Clause © PiTun contributors


Дисклеймер. PiTun — инструмент управления сетью. Вы отвечаете за соответствие законам вашей юрисдикции и условиям использования любых upstream-провайдеров, с которыми вы его применяете. Maintainers не дают никаких гарантий и не несут ответственности за неправомерное использование.