No description
  • C# 76.6%
  • Vue 12.6%
  • TypeScript 8.1%
  • CSS 2%
  • Dockerfile 0.4%
  • Other 0.3%
Find a file
2026-06-23 18:04:22 +03:00
.config База базовая 2026-05-02 01:07:19 +03:00
.forgejo/workflows CI: переход на cavicode/runner:docker 2026-06-23 18:04:22 +03:00
CaviCode-SSO-Client@fd7d9dfec5 CI: переход на cavicode/runner:docker 2026-06-23 18:04:22 +03:00
scripts Надеюсь оно работает, по списку всё работает 2026-05-02 22:04:07 +03:00
src SSO Fix 2026-06-21 14:48:52 +03:00
tests Отказоустойчивость Agent 2026-06-16 01:15:26 +03:00
.dockerignore Надеюсь оно работает, по списку всё работает 2026-05-02 22:04:07 +03:00
.env.example CI Fix 2026-06-21 15:19:27 +03:00
.gitignore Надеюсь оно работает, по списку всё работает 2026-05-02 22:04:07 +03:00
.gitmodules SSO клиент 2026-06-15 19:33:39 +03:00
CaviCode.Tunnels.sln База базовая 2026-05-02 01:07:19 +03:00
Development.md Отказоустойчивость Agent 2026-06-16 01:15:26 +03:00
Directory.Build.props База базовая 2026-05-02 01:07:19 +03:00
docker-compose.shared-network.example.yml Фикс тунелей 2026-05-10 03:11:22 +03:00
docker-compose.sso-bundled.yml ports fix 2026-06-21 15:45:04 +03:00
docker-compose.sso-external.yml ports fix 2026-06-21 15:45:04 +03:00
docker-compose.yml CI Fix 2026-06-21 15:19:27 +03:00
global.json База базовая 2026-05-02 01:07:19 +03:00
README.md Авто DNS/ReverseProxy 2026-05-10 04:04:25 +03:00

CaviCode-Tunnels

CaviCode-Tunnels - это система, которую вы разворачиваете у себя, чтобы безопасно публиковать внутренние сервисы с удаленных серверов через один контролируемый шлюз.

Проект нужен, когда есть несколько машин, контейнеров или домашних/офисных серверов за NAT, а наружу нужно аккуратно отдать только выбранные сервисы: панели, API, игровые серверы, админские инструменты или другие TCP-сервисы. Вместо открытия портов на каждом узле CaviCode-Tunnels строит управляемый туннель до шлюза и публикует наружу только явно разрешенные маршруты.

Система хорошо работает рядом с CaviCode-DNS: Tunnels отвечает за WireGuard, агентов, правила доступа и внутренние адреса сервисов, а CaviCode-DNS - за DNS, Caddy, TLS, Anubis, публичные reverse-proxy и Minecraft-маршруты.

Как это работает

CaviCode-Tunnels состоит из трех основных частей:

  • Controller - центральная панель и API. Здесь хранится состояние узлов, сервисов, правил доступа, журнал действий и настройки интеграций.
  • Gateway - WireGuard-шлюз. Через него удаленные узлы соединяются с вашей инфраструктурой.
  • Agent - небольшой сервис на удаленном узле. Он подключается к Controller, получает конфигурацию и открывает локальный проброс портов только для разрешенных сервисов.

Обычный поток выглядит так:

  1. Администратор поднимает CaviCode-Tunnels на сервере-шлюзе.
  2. В панели создается одноразовый токен подключения для нового узла.
  3. На удаленном сервере запускается команда установки агента.
  4. Агент регистрируется, получает WireGuard-конфигурацию и начинает отправлять сигнал активности.
  5. Администратор выбирает сервис на узле, например 127.0.0.1:8080, и публикует его через шлюз.
  6. Шлюз открывает только нужный порт, агент пропускает только разрешенный трафик, а CaviCode-DNS при необходимости создает публичный маршрут.

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

Что умеет

  • подключать удаленные узлы через одноразовые токены;
  • поднимать встроенный WireGuard-шлюз;
  • публиковать выбранные TCP-сервисы через один шлюз;
  • импортировать сервисы из Docker-контейнеров на агенте;
  • хранить журнал действий и изменений;
  • показывать состояние узлов, сервисов, политик и проверок в панели управления;
  • экспортировать резервную копию и собирать диагностический архив;
  • работать с CaviCode-DNS в ручном режиме или через API-токен;
  • отзывать узлы и блокировать повторное использование токенов.

Развертывание через Docker Compose

Для запуска нужен Linux-сервер с Docker и Docker Compose. Шлюз должен иметь доступ к /dev/net/tun, возможность управлять сетевыми правилами и публично доступный UDP-порт WireGuard.

Минимальный сценарий:

cp .env.example .env

Откройте .env и обязательно поменяйте секреты:

POSTGRES_PASSWORD=change-me-tunnels

Проверьте адреса и порты:

CONTROL_BIND_IP=127.0.0.1
WEB_PORT=18080
API_PORT=5080

WIREGUARD_BIND_IP=0.0.0.0
WIREGUARD_PORT=51820

Управляющую web-панель и API обычно лучше держать на 127.0.0.1 или приватном адресе, а наружу отдавать через CaviCode-DNS/Caddy или другой reverse proxy. WireGuard UDP-порт, наоборот, должен быть доступен удаленным агентам.

Запуск:

docker compose up -d

После старта откройте панель:

http://127.0.0.1:18080

Дальше мастер настройки проведет через создание первого администратора, проверку окружения и настройку шлюза.

Важные переменные

Основные параметры находятся в .env.example.

POSTGRES_PASSWORD должен быть изменен перед рабочим запуском.

CONTROL_BIND_IP управляет тем, на каком адресе слушают web/API порты. Для публичной установки безопаснее оставлять 127.0.0.1 и публиковать панель через защищенный reverse proxy.

WIREGUARD_BIND_IP и WIREGUARD_PORT задают публичный UDP-адрес шлюза. Этот порт должен быть доступен агентам.

WIREGUARD_INSTALL_MISSING_TOOLS=false оставлен выключенным намеренно: Docker image уже содержит wireguard-tools, iproute2, nftables и iptables. Работающий контейнер не должен выполнять apt-get install во время настройки.

Подключение узла

После первичной настройки:

  1. Откройте раздел узлов.
  2. Создайте токен подключения.
  3. Скопируйте команду установки.
  4. Выполните ее на удаленном Linux-сервере.
  5. Дождитесь появления узла в панели.

Агент будет периодически отправлять сигнал активности и получать актуальную конфигурацию. Если узел перестанет выходить на связь, это будет видно в панели.

Публикация сервиса

Сервис публикуется только явно:

  1. Выберите узел.
  2. Укажите локальный адрес сервиса, например 127.0.0.1:8080.
  3. Назначьте внешний порт или маршрут.
  4. Включите сервис.

CaviCode-Tunnels применит правила на шлюзе и отправит агенту конфигурацию локального проброса. Без опубликованного сервиса трафик через туннель не разрешается.

Интеграция с CaviCode-DNS

Интеграция может работать в двух режимах.

В ручном режиме CaviCode-Tunnels показывает готовые параметры сервиса и маршрута, которые можно перенести в CaviCode-DNS самостоятельно.

В API-режиме CaviCode-Tunnels использует внешний интеграционный токен из CaviCode-DNS и создает или обновляет reverse-proxy/Minecraft маршруты через официальный API CaviCode-DNS. Если указан внешний IP для DNS, Tunnels также создает отсутствующую A/AAAA-запись для hostname сервиса, не перезаписывая уже существующую запись. Токен хранится как защищенный секрет и не возвращается обратно через API или UI.

Если CaviCode-DNS и CaviCode-Tunnels запущены как два соседних Docker Compose проекта, подключите оба проекта к общей внешней сети cavicode-shared через docker-compose.shared-network.example.yml или локальный override. Тогда reverse proxy upstream для панели Tunnels должен быть http://cavicode-tunnels-web:80, а API URL интеграции DNS из Tunnels — http://cavicode-dns-api:5000. Не используйте 127.0.0.1 как upstream между контейнерами: внутри контейнера это сам контейнер, а не хост.

Для опубликованных сервисов в таком Docker-сценарии Caddy тоже не должен ходить напрямую к WireGuard IP агента вроде 10.5.5.3:18000: этот адрес виден API-контейнеру шлюза, но не соседнему Caddy-контейнеру. Shared-network override включает gateway-side TCP proxy и экспортирует upstream как http://cavicode-tunnels-api:<порт>; API уже пересылает соединение дальше в WireGuard-туннель. При PublishedServices:UpstreamMode=GatewayProxy API сам запускает listener-ы на портах опубликованных включенных сервисов; если Caddy получает connection refused на cavicode-tunnels-api:<порт>, значит API-контейнер запущен без этого режима, не пересоздан после обновления или сервис отключен. Если соединение с Caddy устанавливается, но страница долго висит без ответа, проверяйте доступность TunnelBindIp:TunnelBindPort из API-контейнера в WireGuard-туннеле и agent-side forwarder на узле; API-side proxy ограничивает попытку подключения параметром GatewayServiceProxy:ConnectTimeoutSeconds.

Домен самой панели из PublicControllerUrl, например tunnels.example.com, нельзя использовать как публичный домен сервиса или hostname DNS-маршрута. Для сервисов выделяйте отдельные имена вроде git.example.com; иначе CaviCode-DNS может начать отправлять /login панели на порт опубликованного сервиса.

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

В панели есть раздел операций для экспорта резервной копии, пробного восстановления, диагностического архива, свежих логов агентов и отката политик.

Восстановление сейчас работает только как предварительная проверка: оно показывает, что будет создано, обновлено или удалено, но не применяет изменения к рабочему состоянию. Опасные секции вроде ссылок на секреты, настроек транспорта и WireGuard-пиров показываются отдельными предупреждениями.

Для разработки

Информация для разработки, тестов, структуры решения и локальной сборки вынесена в Development.md.