🌐 Languages: English · Русский
Самохостинговый роутер и менеджер прозрачного прокси для Raspberry Pi 4/5 (или любого другого Linux-сервера). Может стоять рядом с роутером, а может быть роутером — брать линию провайдера, раздавать адреса, делать NAT и Wi-Fi. В обоих случаях перехватывает LAN-трафик через nftables TPROXY и маршрутизирует его через xray-core по вашим правилам — домен, GeoIP, GeoSite, MAC, порт, протокол.
📸 Скриншоты: перейти к галерее.
- Что это
- Режим роутера
- Почему PiTun?
- Скриншоты
- Архитектура
- Возможности
- Поддерживаемые протоколы
- Быстрый старт
- Обновление
- Конфигурация
- Удаление
- Разработка
- Стек технологий
- Благодарности
- Вклад в проект
- Лицензия
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 из той самой сети, которую она сейчас пересоберёт.
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 ГБ+ диском.
Provisioning VPS и оркестрация x-ui (с v1.3.0) — нажмите чтобы развернуть · 6 скриншотов
Маршрутизация и ноды — нажмите чтобы развернуть · 6 скриншотов
Устройства, DNS и диагностика — нажмите чтобы развернуть · 4 скриншота
Режим шлюза — 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) — считываются через сам туннель тестом скорости и проверкой интернета, поэтому флаг показывает, где трафик реально выходит наружу (у цепочки — последний хоп, а не входной, чей адрес хранится). База для этого не нужна. Дополнительно можно определять страну по адресу при импорте — если положить MaxMindGeoLite2-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.
Если нужен исходник рядом с работающим стеком (например для разработки или 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.
Если хочешь подготовить хост вручную — вот эквивалентный чеклист. Всё
ниже должно быть сделано до 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Для специфичной для 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-dataUninstall обрабатывает каждую разновидность установки —
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.
- FastAPI — HTTP-фреймворк
- SQLModel + SQLAlchemy — ORM
- Pydantic — валидация
- Alembic — миграции
- Uvicorn — ASGI-сервер
- httpx + aiohttp — HTTP-клиенты
- asyncssh — async SSH-клиент для auto-deploy на VPS и удалённой диагностики
- websockets — стриминг логов установки
- aiosqlite — async SQLite
- python-jose + bcrypt — auth
- psutil — метрики хоста
- docker-py — Docker API клиент (lifecycle Naive sidecar)
- PyYAML — импорт Clash YAML
- React, Vite, TypeScript
- Tailwind CSS — стили
- TanStack Query — server state
- Zustand — UI state
- React Router — роутинг
- Recharts — графики метрик
- Lucide — иконки
- Twemoji — рисунки флагов
(CC-BY 4.0) в виде вебшрифта Twemoji Country Flags
сборки TalkJS (MIT). Лежит у нас, только флаги, 78 КБ: в Windows глифов
флагов нет вовсе, и без него нода
🇨🇭 vless-…выглядит какCH vless-… - axios — HTTP-клиент
- Vitest + Testing Library — тесты
- Docker + Compose
- nginx — отдача фронта + WebSocket-прокси
- Tecnativa/docker-socket-proxy — ограниченный доступ к Docker API из бэкенда
Совместимость с форматами импорта (V2RayN / Shadowrocket / Clash JSON) вдохновлена форматами этих проектов — никакой код не заимствован.
Bug-репорты и PR приветствуются. См. CONTRIBUTING.md
— стиль кода, конвенции PR, что не должно попадать в репо.
BSD 3-Clause © PiTun contributors
Дисклеймер. PiTun — инструмент управления сетью. Вы отвечаете за соответствие законам вашей юрисдикции и условиям использования любых upstream-провайдеров, с которыми вы его применяете. Maintainers не дают никаких гарантий и не несут ответственности за неправомерное использование.















