Перейти к содержанию

Поиск

Показаны результаты для тегов 'caddy'.

  • Поиск по тегам

    Введите теги через запятую.
  • Поиск по автору

Тип контента


Форумы

  • OpeNode
    • Новости
    • Общение
  • Статьи и обсуждения
    • Docker Контейнеры
    • Прокси и Виртуальный Частные Сети
    • Сетевое оборудование
    • 3D-моделирование и 3D-печать
    • WEB технологии и их применение
    • Операционные системы и Софт
    • Домашняя инфраструктура
    • Программирование и архитектура
    • Искусственный интеллект
    • OSINT
  • Клуб DWG Проблемы сборок
  • Клуб DWG Сборки DWG
  • Zero Trust Network Темы
  • Zero Trust Network OpenZITI
  • Marzban Инструкции
  • Marzban Продвинутые инструкции
  • Marzban Вопросы и проблемы
  • Marzban Общение
  • BookWorm Общение
  • BookWorm Поиск материалов
  • Общий клуб - ОБЩЕНИЕ Предложения по КЛУБАМ
  • Общий клуб - ОБЩЕНИЕ Услуги
  • Панели управления VPN и Proxy 3x-UI/X-ui
  • Панели управления VPN и Proxy Другие решения
  • Marzneshin (Форк Marzban) Инструкции
  • RemnaWave [new] Инструкции

Категории

  • Полезные файлы
    • CMS
  • Книги - общий раздел
    • Хакинг и безопасность [FILES]
    • СУБД [FILES]
    • Сети / VoIP [FILES]
    • Веб-дизайн и программирование [FILES]
    • Mac OS; Linux, FreeBSD и прочие *NIX [FILES]
  • 3D-модели для печати
  • Marzban Файлы
  • BookWorm Книги

Поиск результатов в...

Поиск контента, содержащего...


Дата создания

  • Начало

    Конец


Дата обновления

  • Начало

    Конец


Фильтр по количеству...

Регистрация

  • Начало

    Конец


Группа


Обо мне


Пол

Найдено 3 результата

  1. Всем привет! Немного задержавшись с продолжением по личным объективным причинам, продолжаю рассказы. Для чистоты пояснений и инструкций я сделаю все эти действия с нуля и подключу одну ноду. Все данные в статье буду приводить как есть, так как все сервера и домены тестовые, можете ломиться сколько угодно они уже будут удалены. Повторяться сильно не буду, поэтому базовую настройку мы просто повторим. Относительно прошлой статьи мы сразу поменяем место для установки нашей панели. Оно будет по пути: /opt/remnawave 1. Аренда сервера Для начала, как обычно, нам нужно выбрать сервер. 1.1. Рекомендации по аренде Из последнего, что могу посоветовать к аренде: Как бы ни ругались, но проверенный за много лет: 4VPS: https://4vps.su/r/p52GUJhPv8b5 Самый стабильный для мейн-сервера в РФ Selectel: https://selectel.ru/?ref_code=8d43638548 Если нужны стабильные ноды, конечно Kamatera: https://go.cloudwm.com/visit/?bta=36601&nci=5749 2. Подготовка сервера 2.1. Установка Docker Первым делом на новом сервере ставим Docker: curl -fsSL https://get.docker.com | sh 2.2. Создание папки для проекта Remnawave mkdir -p /opt/remnawave/ 2.3. Переход в папку cd /opt/remnawave/ 2.4. Настройка домена в Cloudflare Идем в панель Cloudflare. Добавляем домен и привязываем к своему серверу (надеюсь, вы знаете, как это делать): remna.openode.xyz 2.5. Настройка страницы подписки Аналогично делаем для страницы подписки. У меня это будет: link.openode.xyz Отлично. 2.6. Установка Caddy Caddy мы будем ставить по инструкции с двухфакторной аутентификацией: https://remna.st/security/caddy-with-minimal-setup Создаем папку для Caddy. Caddy у нас будет работать в Docker, так проще для старта. Но вы можете делать на свое усмотрение. mkdir -p /opt/remnawave/caddy && cd /opt/remnawave/caddy 2.7. Создание файла Caddyfile Создаем файл Caddyfile: nano /opt/remnawave/caddy/Caddyfile Прописываем в него: { order authenticate before respond order authorize before respond security { local identity store localdb { realm local path /data/.local/caddy/users.json } authentication portal remnawaveportal { crypto default token lifetime {$AUTH_TOKEN_LIFETIME} enable identity store localdb cookie domain {$REMNAWAVE_PANEL_DOMAIN} ui { links { "Remnawave" "/dashboard/home" icon "las la-tachometer-alt" "My Identity" "/r/whoami" icon "las la-user" "API Keys" "/r/settings/apikeys" icon "las la-key" "MFA" "/r/settings/mfa" icon "lab la-keycdn" } } transform user { match origin local action add role authp/admin require mfa } } authorization policy panelpolicy { set auth url /r allow roles authp/admin with api key auth portal remnawaveportal realm local acl rule { comment "Accept" match role authp/admin allow stop log info } acl rule { comment "Deny" match any deny log warn } } } } https://{$REMNAWAVE_PANEL_DOMAIN} { route /api/* { reverse_proxy http://remnawave:3000 } handle /r { rewrite * /auth request_header +X-Forwarded-Prefix /r authenticate with remnawaveportal } route /r* { authenticate with remnawaveportal } route /* { authorize with panelpolicy reverse_proxy http://remnawave:3000 } } link.openode.xyz { reverse_proxy http://remnawave-subscription-page:3010 } Все данные у нас будут браться из environment, которые мы будем передавать в контейнер. ЕСЛИ ВЫ НЕ ХОТИТЕ ИСПОЛЬЗОВАТЬ ДВУХФАКТОРНУЮ АУТЕНТИФИКАЦИЮ ДЛЯ ВХОДА В ПАНЕЛЬ, ТО УДАЛИТЕ СТРОКУ ИЗ КОДА ВЫШЕ: require mfa 2.8. Создание файла контейнера для Caddy Создаем файл контейнера для Caddy: nano docker-compose.yml Вставляем содержимое: services: remnawave-caddy: image: remnawave/caddy-with-auth:latest container_name: 'remnawave-caddy' hostname: remnawave-caddy restart: always environment: - AUTH_TOKEN_LIFETIME=3600 - REMNAWAVE_PANEL_DOMAIN=remna.openode.xyz - AUTHP_ADMIN_USER=admin - AUTHP_ADMIN_EMAIL=admin@openode.xyz - AUTHP_ADMIN_SECRET=super-puper-openode ports: - '0.0.0.0:443:443' - '0.0.0.0:80:80' networks: - remnawave-network volumes: - ./Caddyfile:/etc/caddy/Caddyfile - remnawave-caddy-ssl-data:/data networks: remnawave-network: name: remnawave-network driver: bridge external: true volumes: remnawave-caddy-ssl-data: driver: local external: false name: remnawave-caddy-ssl-data Контейнер создали, но запускать пока не будем. Сеть мы заранее указали ту, которую создадим далее. 3. Установка панели 3.1. Создание файла docker-compose.yml Переходим в папку Remnawave и создаем файл docker-compose.yml: cd /opt/remnawave/ && nano docker-compose.yml Устанавливать будем latest-ветку, так как там сейчас все самые полезные функции. В скором времени будет релиз 1.5.0 в latest, поэтому можно будет смело его брать за базу. services: remnawave-db: image: postgres:17 container_name: 'remnawave-db' hostname: remnawave-db restart: always env_file: - .env environment: - POSTGRES_USER=${POSTGRES_USER} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - POSTGRES_DB=${POSTGRES_DB} - TZ=UTC ports: - '127.0.0.1:6767:5432' volumes: - remnawave-db-data:/var/lib/postgresql/data networks: - remnawave-network healthcheck: test: ['CMD-SHELL', 'pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}'] interval: 3s timeout: 10s retries: 3 remnawave: image: remnawave/backend:latest container_name: 'remnawave' hostname: remnawave restart: always ports: - '127.0.0.1:3000:3000' env_file: - .env networks: - remnawave-network depends_on: remnawave-db: condition: service_healthy remnawave-redis: image: valkey/valkey:8.0.2-alpine container_name: remnawave-redis hostname: remnawave-redis restart: always networks: - remnawave-network volumes: - remnawave-redis-data:/data remnawave-subscription-page: image: remnawave/subscription-page:latest container_name: remnawave-subscription-page hostname: remnawave-subscription-page restart: always environment: - REMNAWAVE_PANEL_URL=http://remnawave:3000 # Здесь мы указали контейнер и порт контейнера. Но если у вас страница будет стоять отдельно, вы должны указать здесь домен для панели - APP_PORT=3010 - META_TITLE="Subscription Page Title" - META_DESCRIPTION="Subscription Page Description" ports: - '127.0.0.1:3010:3010' networks: - remnawave-network networks: remnawave-network: name: remnawave-network driver: bridge external: false volumes: remnawave-db-data: driver: local external: false name: remnawave-db-data remnawave-redis-data: driver: local external: false name: remnawave-redis-data Для страницы подписки замените в - REMNAWAVE_PLAIN_DOMAIN=remna.openode.xyz на ВАШ домен панели Можно также добавить для страницы подписки параметр ниже: - CUSTOM_SUB_PREFIX=sub тогда получится такой вариант: remnawave-subscription-page: image: remnawave/subscription-page:latest container_name: remnawave-subscription-page hostname: remnawave-subscription-page restart: always environment: - REMNAWAVE_PANEL_URL=http://remnawave:3000 - SUBSCRIPTION_PAGE_PORT=3010 - META_TITLE="Subscription Page Title" - META_DESCRIPTION="Subscription Page Description" - CUSTOM_SUB_PREFIX=sub ports: - '127.0.0.1:3010:3010' networks: - remnawave-network После этих изменений, у вас к адресу подписки добавится дополнительный параметр в url: link.openode.xyz/sub/<uuid> Тогда и для .env (который мы будем формировать дальше) нужно будет указывать правильный параметр для sub_public_domain SUB_PUBLIC_DOMAIN=link.openode.xyz/sub Сохранили и закрыли. 3.2. Создание файла .env Создаем здесь же файл .env: nano .env И вставляем в него содержимое из файла по ссылке: https://github.com/remnawave/backend/blob/main/.env.sample Я приведу сразу готовый свой файл: cd ~/remnawave/ && nano docker-compose.yml ### APP ### APP_PORT=3000 METRICS_PORT=3001 ### API ### # Possible values: max (start instances on all cores), number (start instances on number of cores), -1 (start instances on all cores - 1) # !!! Do not set this value more that physical cores count in your machine !!! API_INSTANCES=max ### DATABASE ### # FORMAT: postgresql://{user}:{password}@{host}:{port}/{database} DATABASE_URL="postgresql://postgres:postgres@remnawave-db:5432/postgres" ### REDIS ### REDIS_HOST=remnawave-redis REDIS_PORT=6379 ### JWT ### ### CHANGE DEFAULT VALUES ### JWT_AUTH_SECRET=6ac5b3ba99b94d9e0f6b9c242691c14e3bd54492b60aff7829e6b050535d8827278c098b42d6833a314af104f2c9da8046c33a14f45c00c43117dda0ba4ea25866a3562babea7ac59c523fea04cab6c24c4f191846b73ac7420fb265b0f910ad09018f662e8daf7e6bf8173546d89687fdb839fd14f34e754b20ae1e1d556ee3 JWT_API_TOKENS_SECRET=b3e86a783d3ca63941fe48eb2fdf8901fa294b777376c77b852c98cab8e136d12f4a0b0c898a60cdda6c1a76af6f7a9acdd292a4040bc0a4a7c34091ddb25158aa785c90391e094672da646712d2ae1e6f7e2bada14a2deb9099c291bc464115fb0ae71d042baacc8f7890ea55d8eb6a42d474604429978880e851632ce187a6 ### TELEGRAM ### IS_TELEGRAM_NOTIFICATIONS_ENABLED=false #TELEGRAM_NOTIFY_USERS_CHAT_ID=change_me #TELEGRAM_NOTIFY_NODES_CHAT_ID=change_me #TELEGRAM_NOTIFY_USERS_THREAD_ID=change_me #TELEGRAM_NOTIFY_NODES_THREAD_ID=change_me TELEGRAM_OAUTH_ENABLED=false ### or TRUE (required IS_TELEGRAM_NOTIFICATIONS_ENABLED=true) TELEGRAM_OAUTH_ADMIN_IDS=change_me ### FRONT_END ### FRONT_END_DOMAIN=remna.openode.xyz ### SUBSCRIPTION PUBLIC DOMAIN ### ### RAW DOMAIN, WITHOUT HTTP/HTTPS, DO NOT PLACE / to end of domain ### ### Used in "profile-web-page-url" response header ### SUB_PUBLIC_DOMAIN=link.openode.xyz ### SWAGGER ### SWAGGER_PATH=/docs SCALAR_PATH=/scalar IS_DOCS_ENABLED=false ### PROMETHEUS ### ### Metrics are available at /api/metrics METRICS_USER=admin METRICS_PASS=admin ### WEBHOOK ### WEBHOOK_ENABLED=false ### Only https:// is allowed WEBHOOK_URL=https://webhook.site/1234567890 ### This secret is used to sign the webhook payload, must be exact 64 characters. Only a-z, 0-9, A-Z are allowed. WEBHOOK_SECRET_HEADER=vsmu67Kmg6R8FjIOF1WUY8LWBHie4scdEqrfsKmyf4IAf8dY3nFS0wwYHkhh6ZvQ ### CLOUDFLARE ### # USED ONLY FOR docker-compose-prod-with-cf.yml # NOT USED BY THE APP ITSELF # CLOUDFLARE_TOKEN=ey... ### Database ### ### For Postgres Docker container ### # NOT USED BY THE APP ITSELF POSTGRES_USER=postgres POSTGRES_PASSWORD=postgres POSTGRES_DB=postgres Для того что бы включить oAuth Telegram авторизацию - вы должны внести в вашего бота через @botfather параметр домена панели. Обязательно заменяйте все JWT-секреты на свои. Значения генерируем здесь: https://jwtsecret.com/generate 4. Запуск панели 4.1. Запуск контейнера Remnawave Поднимаем наш контейнер Remnawave: cd /opt/remnawave && docker compose up -d 4.2. Запуск контейнера Caddy Поднимаем наш контейнер Caddy: cd caddy && docker compose up -d 5. Настройка панели 5.1. Авторизация Зайдя на домен: remna.openode.xyz Видим следующее: Проходим авторизацию, в моем случае это было: admin@openode.xyz super-puper-openode 5.2. Создание токена MFA Теперь идет запрос, что нам нужно создать токен для многофакторной аутентификации. Если вы все сделали корректно, увидите окно регистрации в Remnawave: Я задал свои параметры и сохранил пароль в надежном месте. Панель готова! Создадим первого пользователя и проверим, что страница подписки работает корректно. 6. Обновление конфигурации 6.1. Обновление конфига Заходим на дашборде на страницу «Конфиг» и заменяем все содержимое на: { "log": { "loglevel": "warning" }, "inbounds": [ { "tag": "Vless TCP reality", "port": 443, "listen": "0.0.0.0", "protocol": "vless", "settings": { "clients": [], "decryption": "none" }, "sniffing": { "enabled": true, "destOverride": [ "http", "tls" ] }, "streamSettings": { "network": "tcp", "security": "reality", "tcpSettings": {}, "realitySettings": { "dest": "ftp.debian.org:443", "show": false, "xver": 0, "shortIds": [ "" ], "publicKey": "22mH2kO_6Q43slZjf-njD9TMv9xeYMA1P28PzEtqOWo", "privateKey": "Jy4FdQWKBOtLc2rvJqRxP-WMELzNhRxmUgequcAcLhQ", "serverNames": [ "ftp.debian.org" ] } } }, { "tag": "SS", "port": 8580, "listen": "0.0.0.0", "protocol": "shadowsocks", "settings": { "clients": [], "network": "tcp,udp" } } ], "outbounds": [ { "tag": "DIRECT", "protocol": "freedom", "settings": { "domainStrategy": "ForceIPv4" } }, { "tag": "BLOCK", "protocol": "blackhole" }, { "tag": "IPv4", "protocol": "freedom", "settings": { "domainStrategy": "ForceIPv4" } } ], "routing": { "rules": [ { "type": "field", "domain": [ "full:cloudflare.com", "domain:msftconnecttest.com", "domain:msftncsi.com", "domain:connectivitycheck.gstatic.com", "domain:captive.apple.com", "full:detectportal.firefox.com", "domain:networkcheck.kde.org", "full:*.gstatic.com", "domain:gstatic.com" ], "outboundTag": "DIRECT" }, { "type": "field", "protocol": [ "bittorrent" ], "outboundTag": "BLOCK" }, { "ip": [ "geoip:private" ], "type": "field", "outboundTag": "BLOCK" } ], "domainStrategy": "IPIfNonMatch" } } 6.2. Генерация ключей После этого обязательно генерируем пару ключей: Копируем эту пару ключей и заменяем содержимое в конфигурации VLESS (чтобы ваши ключи были уникальными). 7. Работа с инбаундами 7.1. Просмотр инбаундов Идем на вкладку «Инбаунды» и видим: Все инбаунды у нас автоматически подтянулись. Можно посмотреть самые важные характеристики, а также есть кнопка для массового управления ими. 8. Подключение ноды НОДА - это отдельный сервер xray, который будет на себя принимать подключения. Нода может быть установлена на одном сервере с панелью. Но это не рекомендуется по разным объективным причинам - безопасность, стабильность, скорость. Исключения составляет "соло" использование панели, например чисто для себя одного, и в таком варианте, использовать два сервера, один из которых чисто под панель, а второй под ноду - затратно. Нода это обычно зарубежный сервер. Ноды мы добавляем чтобы потом к ним подключаться. Системный требования для ноды ниже чем для панели. Обычно хватает 1 ядро, 2гб памяти и 10гб места. Если у вас нодой будут пользоваться достаточно большое количество человек, то имейте ввиду, что будут расти требования к процессору. Вот простая схема требований к ноде. до 70-100 человек (в зависимости от сетевой нагрузки) - 1 ядро 1гб до 300 человек - 2 ядра - 2 гб 10гб\с порт. до 600-800 человек - 4 ядра 8гб, и минимум 10гб\с порт. больше 1000 человек - лучше балансировку ноды, хотя бы по DNS. 8.1. Создание новой ноды Переходим в «Ноды» 2 и жмем «Создать новую ноду».. Появится такое окно Его не закрываем. Сейчас оно нам нужно для копирования ключа, а дальше мы заполним параметры сервера для подключения. 8.2. Подключение к серверу ноды Подключаемся к серверу нашей ноды (я использую Termius). 8.3. Установка скрипта ноды sudo bash -c "$(curl -sL https://github.com/DigneZzZ/remnawave-scripts/raw/main/remnanode.sh)" @ install 8.4. Ввод данных сертификата Будет предложено ввести данные сертификата из панели: Копируем из нашей панели: И вставляем как есть в нашу консоль. Дважды жмем Enter после вставки (чтобы появилась пустая строка, тогда он перейдет на следующий этап). Указываем порт (по умолчанию он 3000, можно нажать Enter). Далее задаст вопрос, хотите ли вы установить последнее ядро Xray-core (если нажать Enter, он это пропустит), но установить можно будет потом отдельно. И все. Готово. Контейнер запустится и будет ждать подключений: 8.5. Настройка параметров сервера Возвращаемся в нашу панель. Задаем параметры нашего сервера: ЗАПОМНИТЕ РАЗ И НА ВСЕГДА! ПОДКЛЮЧАЕМ НОДУ ТОЛЬКО IP-АДРЕСУ! НЕ ПО ДОМЕНУ! ДОМЕН МОЖНО УКАЗАТЬ ТОЛЬКО В НАСТРОЙКАХ ХОСТА!!! Жмем «Сохранить». Увидим сначала попытку подключения: Затем статус, что подключен: 9. Создание хостов 9.1. Создание хоста Последняя, заключительная часть создания подключения — это создание хостов. В Marzban они создавались автоматически. Здесь они создаются вручную. Идем во вкладку «Хосты». Жмем «Создать хост». Заполняем данные: Примечание — это то, как вы назовете сами свой хост и как он будет отображаться у пользователя. Например, Sweden. И к имени можно будет добавить переменные: Мы добавим только Days_left. В адресе ноды указываем либо IP-адрес сервера, либо поддомен, привязанный к этому серверу. Я укажу поддомен (это удобнее: в случае смены сервера достаточно будет поменять DNS-запись для этого адреса на новый сервер-ноду, и для пользователя смена пройдет незаметно). Выбираем наш инбаунд. А порт у нас подтянется самостоятельно из конфигурации. И ОБЯЗАТЕЛЬНО ДЕРНИТЕ СЕРЫЙ ФЛАЖОК , ПЕРЕВЕДЯ ЕГО В СОСТОЯНИЕ ВКЛЮЧЕННОГО Не знаю, как сейчас, но на некоторых клиентах была проблема, что Fingerprint не проставлялся автоматически. Поэтому давайте зададим его по умолчанию: Выбираем Chrome. Жмем «Сохранить». Готово! 9.2. Привязка инбаундов для пользователей Для уже созданных пользователей инбаунды нужно прописать принудительно, для всех новых создаваемых пользователей вы и так будете выбирать. Поэтому вернемся на вкладку «Инбаунды». И научимся работать с массовыми действиями. Включим Vless-инбаунд для ВСЕХ (но у нас это для нашего единственного пользователя): И получим такой результат: Готово! Чтобы сбросить пароль администратора (для входа в панель) или сертификаты, есть специальная консольная CLI-команда (выполнять на сервере с мейном): docker exec -it remnawave remnawave И получим такие варианты:
  2. Всем привет! Уже опубликовав статью про установку MarzNeshin, понял что старая версия моей инструкции устарела и морально и технически, учитывая что вышла свежая версия Marzban, которая привнесла большое количество изменений. С момента написания моей статьи по ФэнШую прошло больше полугода, а она остается актуальной. И этой концепции я придерживаюсь. Сегодня мы разберем установку с нуля. 0. Вводная. На момент написания статьи, мой PR к скриптам установки находится на рассмотрении, ждем пока Saint сам протестирует установку и примет PR. https://github.com/Gozargah/Marzban-scripts/pull/29 Что изменилось в скрипте: Добавлена возможность выбора версии --dev Добавлена возможность установки сразу с базой данных --database mysql или --database mariadb Обновлена функцию обновления ядра Xray, сделал также красиво как и обновление в marzban-node, без лишних текстов и уведомлений. Изменился формат выбора версии для установки: --version v0.5.2 Пока ждем обновления офф скриптов, можно воспользоваться моей репой: https://github.com/DigneZzZ/Marzban-scripts-beta Что изменилось в Marzban начиная с версии 0.7.0 я расписывал здесь: Что изменилось в концепции установки: Теперь все свои сборки я ставлю в сеть Docker, а доступ к ним организовываю через Caddy. В целом это легко и просто. А главное быстро. Каждой ноде свой инбаунд Мэйн панель - только для администрирования БД только MySQL/MariaDB Данная статья и данное решение не позволит вам подключаться к Main серверу через прокси-подключения! Эта статья и эта реализация только для ситуаций когда у вас подключение идет ТОЛЬКО К НОДАМ! 1. Подготовка сервера 1.1. Аренда сервера Если ваш сервер Marzban уже приносит, или планирует приносить хороший доход, тогда вам нужно обеспечить достаточный уровень надежности вашей инфраструктуры. 1. Не нужно экономить на хороших и надежных серверах 2. Не нужно экономить на ресурсах для хорошей нагрузки 3. Не нужно экономить на стоимости ваш серверов для НОД - стабильность подключений и качество связи - это обязательное условия роста вашего "бизнеса"/"проекта" 1. Брать сервера под Мэйн в идеале нужно у крупных провайдеров, ориентированных на корпоративных клиентов. Примеры: Selectel, Cloud.Vk.Com, Yandex Cloud, Cloud.ru и др.. Также можно рассматривать крупных провайдеров типа: AWS, Vultr, Kamatera, Hetzner, но опять же - тарифы выбираем с выделенными ядрами, не Шэред, и главное - должна быть 100% гарантия что ваш сервер не удалят и вы сможете всегда его оплачивать. 2. Ситуации с сайтами могут быть самыми разными, начиная от ДДоС атак, заканчивая наплывом клиентов. Но конечно про экономику забывать не нужно. 3. Чем лучше провайдер и каналы - тем довольнее будут клиенты. Не нужно стараться дать им 30 стран на выбор, уверяю вас, они не оценят. Отталкивайтесь от географии ваших клиентов. Для РФ это сервер в Европе. ОООЧень редко кому нужна локация в США.. и тем более где нибудь в Чили или Австралии.. Нахрена им? Поэтому, провайдер должен быть стабильный, компания иностранная. Своими рекомендациями я уже поделился в канале VPS Insider (но по причине отсутствия заинтересованности я перестал его поддерживать, оставив всю историю там) вступить можно по ссылке за 170 Звёзд ТГ: https://t.me/+lQBQTGym57hmOTAy Скорость должна быть 10Гбс - минимум 2-5Гбс. Трафика от 3-5Тб (суммарного). Конечно лучше безлимит, но качественный сервер обычно имеет лимитированный трафик. Давайте возьмем сервер здесь: https://procloud.ru?referral_id=274473 Или возьмем здесь: https://selectel.ru/?ref_code=8d43638548 Локацию берите Москва (для Мэйн сервера - без разницы) ОСь берите Ubuntu 24.04 ЦП - 2 ядра Память - 4 Гб. Диск - 30 Гб. Желательно максимально быстрый. 1.2. Взяли? Теперь подключаемся. Как и раньше я использую Termius для работы с серверами. 1.3. Первым делом запускаем обновление системы: apt update && apt upgrade -yqq 1.4. Запускаем установку Caddy Ставим Caddy sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list sudo apt update sudo apt install caddy 1.5. Ставим мой сервис CADD: sudo nano /usr/local/bin/cadd 1.6. Заполняем в открытом редакторе файл: #!/bin/bash CONFIG_FILE="/etc/caddy/Caddyfile" # Путь к файлу конфигурации Caddy LOG_LINES=20 # Количество строк журнала для вывода # Цвета для вывода в консоль RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # Без цвета (сброс) case "$1" in e) # Редактирование конфигурации nano "$CONFIG_FILE" ;; r) # Рестарт сервиса Caddy systemctl restart caddy echo -e "${GREEN}Caddy restarted.${NC}" ;; v) # Валидация конфигурационного файла caddy validate --config "$CONFIG_FILE" ;; s) # Статус сервиса Caddy systemctl status caddy | head -n 10 ;; l) # Логи сервиса Caddy journalctl -u caddy.service -n "$LOG_LINES" ;; f) # Форматирование Caddyfile caddy fmt --overwrite "$CONFIG_FILE" echo -e "${GREEN}File ${YELLOW} $CONFIG_FILE ${GREEN}has been formatted.${NC}" ;; h) # Вывод помощи echo -e "${YELLOW}Usage:${NC}" echo -e "${BLUE}cadd e${NC} - edit Caddyfile" echo -e "${BLUE}cadd r${NC} - restart Caddy" echo -e "${BLUE}cadd v${NC} - validate Caddyfile" echo -e "${BLUE}cadd s${NC} - check status of Caddy" echo -e "${BLUE}cadd l${NC} - show last ${LOG_LINES} lines from Caddy log" echo -e "${BLUE}cadd f${NC} - format file ${CONFIG_FILE}" echo -e "${BLUE}cadd h${NC} - display this help" ;; *) # Неправильный ввод команды echo -e "${RED}Invalid option!${NC} Usage: cadd {e|r|v|s|l|h|f}" ;; esac Сохранили и закрыли 1.7. Выдаем права файлу на исполнение: sudo chmod +x /usr/local/bin/cadd 1.8. Теперь поставим Docker curl -fsSL https://get.docker.com | sh 1.9. Теперь создадим нашу докер-сеть: Назовем ее caddy_net: docker network create \ --driver bridge \ --subnet 10.0.0.0/16 \ --gateway 10.0.0.1 \ caddy_net Диапазон у нас будет адресов 10.0.[0-255].[1-255] Но это с запасом. 2. Ставим Marzban. Ставить будем вариант сразу с MariaDB: sudo bash -c "$(curl -sL https://github.com/DigneZzZ/Marzban-scripts-beta/raw/main/marzban.sh)" @ install --database mariadb 2.1. Останавливаем Marzban: marzban down 2.2. Редактируем docker-compose: nano /opt/marzban/docker-compose.yml 2.3. Смотрим внимательно. Исходный вид: services: marzban: image: gozargah/marzban:latest restart: always env_file: .env network_mode: host volumes: - /var/lib/marzban:/var/lib/marzban - /var/lib/marzban/logs:/var/lib/marzban-node depends_on: mariadb: condition: service_healthy mariadb: image: mariadb:lts env_file: .env network_mode: host restart: always environment: MYSQL_ROOT_PASSWORD: password MYSQL_ROOT_HOST: '%' MYSQL_DATABASE: marzban MYSQL_USER: marzban MYSQL_PASSWORD: password command: - --bind-address=127.0.0.1 - --character_set_server=utf8mb4 - --collation_server=utf8mb4_unicode_ci - --host-cache-size=0 - --innodb-open-files=1024 - --innodb-buffer-pool-size=268435456 - --binlog_expire_logs_seconds=5184000 # 60 days volumes: - /var/lib/marzban/mysql:/var/lib/mysql healthcheck: test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"] start_period: 10s start_interval: 3s interval: 10s timeout: 5s retries: 3 Приводим содержимое к нужному виду: services: marzban: image: gozargah/marzban:latest restart: always env_file: .env # network_mode: host volumes: - /var/lib/marzban:/var/lib/marzban - /var/lib/marzban/logs:/var/lib/marzban-node depends_on: mariadb: condition: service_healthy networks: caddy_net: ipv4_address: 10.0.10.2 mariadb: image: mariadb:lts env_file: .env # network_mode: host restart: always environment: MYSQL_ROOT_PASSWORD: password MYSQL_ROOT_HOST: '%' MYSQL_DATABASE: marzban MYSQL_USER: marzban MYSQL_PASSWORD: password command: # - --bind-address=127.0.0.1 - --character_set_server=utf8mb4 - --collation_server=utf8mb4_unicode_ci - --host-cache-size=0 - --innodb-open-files=1024 - --innodb-buffer-pool-size=268435456 - --binlog_expire_logs_seconds=5184000 # 60 days volumes: - /var/lib/marzban/mysql:/var/lib/mysql healthcheck: test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"] start_period: 10s start_interval: 3s interval: 10s timeout: 5s retries: 3 networks: caddy_net: ipv4_address: 10.0.10.3 networks: caddy_net: external: true комментируем строку # network_mode: host Добавляем адреса в сети докер (хотя они нам не понадобятся уже) Gtht 2.4. Заходим в .env и приводим к виду: #UVICORN_HOST = "0.0.0.0" #UVICORN_PORT = 8000 # ALLOWED_ORIGINS=http://localhost,http://localhost:8000,http://example.com ## We highly recommend add admin using `marzban cli` tool and do not use ## the following variables which is somehow hard codded infrmation. # SUDO_USERNAME = "admin" # SUDO_PASSWORD = "admin" UVICORN_UDS: "/var/lib/marzban/marzban.socket" # UVICORN_SSL_CERTFILE = "/var/lib/marzban/certs/example.com/fullchain.pem" # UVICORN_SSL_KEYFILE = "/var/lib/marzban/certs/example.com/key.pem" DASHBOARD_PATH = "/d-dash/" XRAY_JSON = "/var/lib/marzban/xray_config.json" XRAY_SUBSCRIPTION_URL_PREFIX = "https://sub.domain.com" XRAY_SUBSCRIPTION_PATH = "yourSub" # XRAY_EXECUTABLE_PATH = "/usr/local/bin/xray" # XRAY_ASSETS_PATH = "/usr/local/share/xray" # XRAY_EXCLUDE_INBOUND_TAGS = "INBOUND_X INBOUND_Y" # XRAY_FALLBACKS_INBOUND_TAG = "INBOUND_X" TELEGRAM_API_TOKEN = 511414455:AsdgSDGsHfhFDbdfbFDFDFbdfCgw TELEGRAM_ADMIN_ID = 1111111111 TELEGRAM_LOGGER_CHANNEL_ID = -1234567890123 TELEGRAM_DEFAULT_VLESS_FLOW = "xtls-rprx-vision" # TELEGRAM_PROXY_URL = "http://localhost:8080" # DISCORD_WEBHOOK_URL = "https://discord.com/api/webhooks/xxxxxxx" CUSTOM_TEMPLATES_DIRECTORY="/var/lib/marzban/templates/" # CLASH_SUBSCRIPTION_TEMPLATE="clash/my-custom-template.yml" SUBSCRIPTION_PAGE_TEMPLATE="subscription/index.html" # HOME_PAGE_TEMPLATE="home/index.html" # V2RAY_SUBSCRIPTION_TEMPLATE="v2ray/default.json" # V2RAY_SETTINGS_TEMPLATE="v2ray/settings.json" # SINGBOX_SUBSCRIPTION_TEMPLATE="singbox/default.json" # SINGBOX_SETTINGS_TEMPLATE="singbox/settings.json" # MUX_TEMPLATE="mux/default.json" ## Enable JSON config for compatible clients to use mux, fragment, etc. Default False. # USE_CUSTOM_JSON_DEFAULT=True ## Your preferred config type for different clients ## If USE_CUSTOM_JSON_DEFAULT is set True, all following programs will use the JSON config # USE_CUSTOM_JSON_FOR_V2RAYN=False # USE_CUSTOM_JSON_FOR_V2RAYNG=True # USE_CUSTOM_JSON_FOR_STREISAND=False ## Set headers for subscription SUB_PROFILE_TITLE = "Susbcription" SUB_SUPPORT_URL = "https://t.me/support" SUB_UPDATE_INTERVAL = "2" ## External config to import into v2ray format subscription # EXTERNAL_CONFIG = "config://..." # SQLALCHEMY_DATABASE_URL = "sqlite:///db.sqlite3" # SQLALCHEMY_POOL_SIZE = 10 # SQLIALCHEMY_MAX_OVERFLOW = 30 ## Custom text for STATUS_TEXT variable # ACTIVE_STATUS_TEXT = "Active" # EXPIRED_STATUS_TEXT = "Expired" # LIMITED_STATUS_TEXT = "Limited" # DISABLED_STATUS_TEXT = "Disabled" # ONHOLD_STATUS_TEXT = "On-Hold" ### Use negative values to disable auto-delete by default USERS_AUTODELETE_DAYS = -1 USER_AUTODELETE_INCLUDE_LIMITED_ACCOUNTS = false ## Customize all notifications # NOTIFY_STATUS_CHANGE = True # NOTIFY_USER_CREATED = True # NOTIFY_USER_UPDATED = True # NOTIFY_USER_DELETED = True # NOTIFY_USER_DATA_USED_RESET = True # NOTIFY_USER_SUB_REVOKED = True # NOTIFY_IF_DATA_USAGE_PERCENT_REACHED = True # NOTIFY_IF_DAYS_LEF_REACHED = True # NOTIFY_LOGIN = True ## Whitelist of IPs/hosts to disable login notifications # LOGIN_NOTIFY_WHITE_LIST = '1.1.1.1,127.0.0.1' ### for developers # DOCS=True # DEBUG=True # If You Want To Send Webhook To Multiple Server Add Multi Address # WEBHOOK_ADDRESS = "http://127.0.0.1:9000/,http://127.0.0.1:9001/" # WEBHOOK_SECRET = "something-very-very-secret" # VITE_BASE_API="https://example.com/api/" JWT_ACCESS_TOKEN_EXPIRE_MINUTES = 0 # JOB_CORE_HEALTH_CHECK_INTERVAL = 10 # JOB_RECORD_NODE_USAGES_INTERVAL = 30 # JOB_RECORD_USER_USAGES_INTERVAL = 10 # JOB_REVIEW_USERS_INTERVAL = 10 # JOB_SEND_NOTIFICATIONS_INTERVAL = 30 SQLALCHEMY_DATABASE_URL = "mysql+pymysql://marzban:password@10.0.10.3:3306/marzban" Собственно мы корректируем параметры: Отключаем параметры: #UVICORN_HOST = "0.0.0.0" #UVICORN_PORT = 8000 Создаем параметры: UVICORN_UDS: "/var/lib/marzban/marzban.socket" XRAY_SUBSCRIPTION_URL_PREFIX = "https://sub.domain.com" XRAY_SUBSCRIPTION_PATH = "yourSub" DASHBOARD_PATH = "/d-dash/" TELEGRAM_API_TOKEN = 511414455:AsdgSDGsHfhFDbdfbFDFDFbdfCgw TELEGRAM_ADMIN_ID = 1111111111 TELEGRAM_LOGGER_CHANNEL_ID = -1234567890123 TELEGRAM_DEFAULT_VLESS_FLOW = "xtls-rprx-vision" CUSTOM_TEMPLATES_DIRECTORY="/var/lib/marzban/templates/" SUBSCRIPTION_PAGE_TEMPLATE="subscription/index.html" SUB_PROFILE_TITLE = "Susbcription" SUB_SUPPORT_URL = "https://t.me/support" SUB_UPDATE_INTERVAL = "2" USERS_AUTODELETE_DAYS = -1 USER_AUTODELETE_INCLUDE_LIMITED_ACCOUNTS = false Корректируем IP адрес подключения к нашей БД: SQLALCHEMY_DATABASE_URL = "mysql+pymysql://marzban:password@10.0.10.3:3306/marzban" Фуф. Ура. Теперь все. 2.5. Перезагружаем marzban marzban restart выглядеть должно вот так: 3.1.. Заходим в редактирование файла Caddy: cadd e 3.8. Файл будет предзаполнен. Удаляем все в файле и заполняем файл: { storage file_system { root /var/lib/caddy } email YourEmail@gmail.com acme_ca https://acme-v02.api.letsencrypt.org/directory log { output file /var/log/caddy/server.log { roll_size 30mb roll_keep 10 roll_keep_for 720h } level INFO } } sub.domain.com { # Логирование запросов log { output file /var/log/caddy/link-access.log } # Определение разрешённых путей с использованием matchers @allowed path /yourSub* # Прокси для разрешённых путей handle @allowed { reverse_proxy unix//var/lib/marzban/marzban.socket { header_up Host {host} header_up X-Real-IP {remote} } } # Для всех остальных запросов — 403 Forbidden handle { respond "403 Get the FUCK OUT!" 403 } } panel.domain.com { # Логирование запросов log { output file /var/log/caddy/panel-access.log } # Определение разрешённых путей с использованием matchers @allowed path /statics* /d-dash* /d-dash/#/login* /api* /docs* /redoc* /openapi.json # Прокси для разрешённых путей handle @allowed { reverse_proxy unix//var/lib/marzban/marzban.socket { header_up Host {host} header_up X-Real-IP {remote} } } # Для всех остальных запросов — 403 Forbidden handle { respond "403 Get the FUCK OUT!" 403 } } Сохраняем файл. 4. Проверяем и Перезапускаем Caddy проверяем файл: cadd v Если ошибок нет, тогда перезапускаем: cadd r Дальше все настройки как и всегда
  3. Вступление, или немного о том зачем и почему В моей домашней системе за последнее время накопилось значительное число сервисов, для того что бы их использовать в какой то момент стало банально не удобно и не рационально использовать доступ по http и порту. Кроме того существует ряд сервисов которое в принципе не будут работать без использования шифрования. Первоначально в моей системе использовался реверс прокси nginx proxy manager с бесплатными duckdns адресами. Со временем я перешел на использование своего домена. Важной особенностью моего сценария использования являлось то что реверс прокси использовалось только внутри локальной\впн сети и не имело внешнего доступа на 80/443 порту в сеть. Для получения сертификата обычными средствами необходимо что бы сервер мог оставить запись на 80 порту, но такой сценарий не выполним если у вас нет белого ip или возможности пробросить порты. Сценарий со временным открытием портов для обновления так же мной был признан не самым удобным по причине того что можно банально забыть. Благо для такого есть решение под названием dns challenge. При использовании такого метода подтверждения подлинности сайта выполняется путем изменения dns записи с использованием api. Такой сервис предоставляет ряд провайдеров dns, из подходящих под мои задачи это cloudflare и duckdns. Для использования многих сервисов cloudflare таких как api и защита от ddos не обязательно покупать у них домен, достаточно просто перенести управление в cloudflare. Все бы было хорошо система работала с использованием nginx proxy manager, а для внешнего доступа к ресурсам использовалась встроенная публикация сервисов keenetic. Но в один не особо прекрасный момент использования реверс прокси я столкнулся с проблемой что перестали обновляться автоматически сертификаты. Проблема как оказалось достаточна старая и исправления к ней полноценного не было, да и сам npm как по мне казался несколько избыточным и перегруженным для моего сценария использования. Таким образом началось изучение альтернативных решений для организации реверс прокси. Две самые популярные альтернативы из доступных решений это traefik и caddy. traefik - это достаточно интересное и универсальное решение, но оно в первую очередь делает упор на динамически изменяемые системы. Очень хорошо работает с докер контейнерами путем установки настроек в метках контейнеров. Но в моем кейсе использования динамическое масштабирование не планировалось и существовало много сервисов которые были запущены без использования докера. caddy в свою очередь является очень легким в настройке сервисом с большим количеством различных модулей на все случаи жизни. Единственным минусом можно выделить отсутствие интерфейса для настройки, все настройки задаются в файле (но об этом дальше). В данной статье я не планирую проводить сравнение возможностей traefik и caddy подобных сравнений на просторах сети достаточно, для моей задачи больше подошел caddy. Все дальнейшее развертывание будет показано с использованием docker-compose. Запуск контейнеров и сборка контейнеров выполнялась в portainer, но вы можете просто создать свой docker-compose файл и запустить без использования portainer. Базовый вариант настройки Сaddy Отдельно стоит отметить что сам по себе caddy крайне легковесный но и ограниченный в функционале, значительная часть возможностей предложена в дополнительных модулях. Эти модули можно как добавлять самому при сборке докер контейнера или при запуске apt пакета так и использовать готовые сборки docker с включенными модулями. На самом деле настройка реверс прокси в Caddy это крайне простая задача. Запустим докер контейнер с использованием следующего docker-compose version: '3.8' services: caddy: image: 'slothcroissant/caddy-cloudflaredns:latest' container_name: caddy restart: unless-stopped ports: - '80:80' - '443:443' environment: ACME_AGREE: true CLOUDFLARE_API_TOKEN: "aaaaaaaaadssssssssssssssssss" CLOUDFLARE_EMAIL: "asdasdasd@gmail.com" volumes: - /docker/caddy/data:/data - /docker/caddy/config:/config - /docker/caddy/Caddyfile:/etc/caddy/Caddyfile В данном примере использован готовый caddy контейнер для получения сертификатов с использованием dns challenge cloudflare. Так же существуют готовые сборки для других провайдеров например вот тут предложена неплохая подборка самых распространенных сборок. Для получения с сертификата через dns chelenge необходимо создать api ключ на cloudflare, подробней об этом приведено тут. Теперь создадим файл конфигурации на основании которого будет работать наш сервер. Этот файл называется Caddyfile он не имеет расширения и должен располагаться по пути /docker/caddy/Caddyfile (для данного варианта docker-compose). nextcloud.mydomain.ru { tls myemail@gmail.com { dns cloudflare {env.CLOUDFLARE_API_TOKEN} } reverse_proxy 192.168.0.101:1234 } Фактически у нас есть всего две секции tls и reverse_proxy. Секция tls отвечает за получение сертификата, email можно не указывать он необходим для получения напоминаний от acme о продлении сертификатов. Секция reverse_proxy описывает сами правила переадресации, для подавляющего большинства сервисов такого варианта настройки будет достаточно, но бывают исключения например vaultwarden. vaultwarden.mydomain.ru { tls myemail@gmail.com { dns cloudflare {env.CLOUDFLARE_API_TOKEN} } reverse_proxy 192.168.0.132:10380 { header_up X-Real-IP {remote_host} } } Обычно если сервис требует особых настроек для реверс прокси в документации приводятся примеры для самых популярных решений, в том числе и caddy. Для применения изменений необходимо перезапустить докер контейнер. На этом простой вариант настройки caddy закончен, если вы не планируете использовать его для публикации в интернет то можно использовать как есть и наслаждаться. Главное не забыть правильно указать dns записи. Если в настройках доменов в cloudflare указать внутренний ip например 192.168.0.132 тогда при использовании их dns можно обойтись без перезаписи и ходить только внутри своей локальной сети по https. А теперь все становиться чуточку сложнее... настройка Caddy для публикации в интернет Для использования fail2ban нам необходимо настроить правильное и удобное логирование в caddy. Сам по себе caddy формирует логи в формате json которые в принципе достаточно удобно парсятся но с ними не очень удобно работать для fail2ban, в таком случаем нам на помощь приходит модуль transform-encoder данный модуль позволяет указать шаблон форматирования для логов. Готового решения докер контейнера caddy-dns/cloudflare и caddyserver/transform-encoder увы найти мне не удалось так что будем создавать свой докер образ. Для этого нам понадобиться следующий Dockerfile. FROM caddy:builder AS builder RUN xcaddy build \ --with github.com/caddy-dns/cloudflare \ --with github.com/caddyserver/transform-encoder \ --with github.com/abiosoft/caddy-exec FROM caddy:latest COPY --from=builder /usr/bin/caddy /usr/bin/caddy Dockerfile размещаем в той же папке где и наш docker-compose файл со следующим содержимым version: '3.9' services: caddy: image: caddy-cloudflare-transform:latest build: context: . dockerfile: ./Dockerfile container_name: caddy restart: unless-stopped cap_add: - NET_ADMIN ports: - 80:80 - 443:443 environment: ACME_AGREE: true CLOUDFLARE_API_TOKEN: "aaaaaaaaassdsadfasfasf" CLOUDFLARE_EMAIL: "myemail@gmail.com" DOMAIN: mydomain.ru volumes: - /docker/caddy/data:/data - /docker/caddy/config:/config - /docker/caddy/logs:/logs - /docker/caddy/Caddyfile:/etc/caddy/Caddyfile Или можно воспользоваться моим собранным образом размещенным в репозитории https://github.com/Deniom3/caddy-cloudflare-transform Тогда docker-compose файл будет иметь вид version: '3.9' services: caddy: image: ghcr.io/deniom3/caddy-cloudflare-transform:latest container_name: caddy restart: unless-stopped cap_add: - NET_ADMIN ports: - 80:80 - 443:443 environment: ACME_AGREE: true CLOUDFLARE_API_TOKEN: "aaaaaaaaassdsadfasfasf" CLOUDFLARE_EMAIL: "myemail@gmail.com" DOMAIN: mydomain.ru volumes: - /docker/caddy/data:/data - /docker/caddy/config:/config - /docker/caddy/logs:/logs - /docker/caddy/Caddyfile:/etc/caddy/Caddyfile Отдельно обращаю внимание на environment DOMAIN она нам нужна для более простого (и безопасного) формирования Caddyfile. Создадим Caddyfile с такой структурой: (common) { header /* { -Server } } (cloudflare) { import common tls { dns cloudflare {env.CLOUDFLARE_API_TOKEN} } } (local) { @allowed remote_ip 192.168.0.0/24 handle { respond 401 } } { log access-log { include http.log.access output file /logs/access.log { roll_keep_for 48h } format transform `{ts} {request>headers>X-Forwarded-For>[0]:request>remote_ip} {request>host} {request>method} {request>uri} {status}` { time_format "02/Jan/2006:15:04:05" } } } jackett.{env.DOMAIN} { import local import cloudflare log handle @allowed { reverse_proxy 192.168.0.134:9117 } } home-assistant.{env.DOMAIN} { import cloudflare log reverse_proxy 192.168.0.125:8123 } vaultwarden.{env.DOMAIN} { import cloudflare log reverse_proxy 192.168.0.132:10380 { header_up X-Real-IP {remote_host} } } Пройдемся немного по блокам что бы понимать для чего каждый из них нужен. Секции которые объявляются в скобках () являются импортируемым, это настройки которые мы определяем один раз и можем использовать для наших остальных настроек путем вызова через import. При этом каждый такой блок может импортировать в себя другие, тем самым создавая сложные структуры. Секция common отвечает за удаление из ответа сервера имени сервера в нашем случае Caddy, это небольшая перестраховка для того что бы злоумышленники не могли по виду сервера использовать его уязвимости. Секция cloudflare отвечает за настройки получения сертификата с использованием dns challenge. Секция local служит для ограничения доступности к опубликованному сайту. В remote_ip указываются подсети или ip для которых доступ должен быть РАЗРЕШЕН, все остальные будут блокироваться и получать ответ указанный в handle respond в данном случае 401. Эта секция позволяет нам разделить и использовать один реверс прокси для внешней публикации и внутренней локальной сети. Еще одна важная секция необходимая для работы f2b это секция описания логов и их преобразования. Переопределение настроек логирования без указания конкретных hostname применяет эту настройку на все. В данном примере файл храниться в /logs/access.log внутри контейнера который соответствует на сервере /docker/caddy/logs Логи будут храниться 48 часов. Теперь рассмотрим более подробно добавление конкретных сайтов, если нам надо использовать реверс прокси только для локальной сети используем import local и запись как на примере с jackett, при этом домен можно подставлять путем автозамены как в примере, так как мы его передавали в переменные окружения при запуске контейнера. Если нам надо что бы наш реверс прокси пускал не только с ограниченного списка сетей то используем запись как в примере home-assistant, тут у нас нет секции local и простая запись reverse_proxy без проверки допустимых сетей. Если для сайта необходимо включить fail2ban обязательно указываем что должны вестись логи путем добавления записи log. На этом основная настройка закончена, прокидываем 443 порт с роутера на наш сервер через переадресацию портов и наслаждаемся нашествием китайских ботов. Кыш ботнет, или настройка f2b в докере для caddy Для своей работы f2b использует логи которые предоставляют другие сервисы, на предыдущем этапе мы настроили логи caddy для их использования с f2b теперь запустим сам docker контейнер с f2b. version: "3.9" services: fail2ban: image: crazymax/fail2ban:latest container_name: fail2ban network_mode: host cap_add: - NET_ADMIN - NET_RAW environment: F2B_LOG_LEVEL: INFO F2B_LOG_TARGET: STDOUT F2B_DB_PURGE_AGE: 1d volumes: - /docker/fail2ban/data:/data - /docker/caddy/logs/access.log:/docker/caddy/logs/access.log:ro restart: unless-stopped Обязательно даем право на чтение файла логов доступа caddy - /docker/caddy/logs/access.log:/docker/caddy/logs/access.log:ro Если данного файла еще нет то может возникнуть ошибка в работе так как docker создаст вместо файла папку с именем access.log Для исправления необходимо зайти на несколько сайтов через реверс прокси и проверить что логи создаются. Теперь настроим параметры работы f2b В папке /docker/fail2ban/data/filter.d размещаем файл caddy-custom.conf со следующими настройками. При такой настройке все обращения которые получили ответ 401 будут попадать в бан лист. # data/filter.d/caddy-custom.conf [Definition] # catch all lines that terminate with an unauthorized error failregex = <HOST> \S+ \S+ \S+ (401)$ ignoreregex = В папке /docker/fail2ban/data/jail.d файл caddy.conf [caddy] backend = auto enabled = true chain = FORWARD protocol = tcp port = http,https filter = caddy-custom maxretry = 3 bantime = 86400 findtime = 43200 logpath = /docker/caddy/logs/access.log ignoreip = 192.168.0.0/24 Запись ignoreip служит для того что бы наша локальная сеть в случае каких то ошибок с нашей стороны не улетела в бан. Перезапускаем контейнер и наслаждаемся спокойной жизнью. Но это не точно.... Подсказки и заметки на полях Некогда не удаляет файл логов при работе caddy, в некоторых случаях система может повести себя крайне не адекватно и файл больше не создастся. Если это необходимо перед удалением обязательно останавливать контейнер. Ротация логов настраивается отдельно в Caddyfile Для того что бы разбанить кого то в f2b при использовании в докере нам необходимо для стандартных команд добавлять команды по обращению внутрь контейнера: Выводим статус fail2ban docker exec -it fail2ban fail2ban-client status Выводим статус конкретной цепочки (имя цепочки берётся из Jail list предыдущей команды) docker exec -it fail2ban fail2ban-client status ИМЯ_ИЗ_JAIL_LIST Разблокируем требуемый IP-адрес из соответствующей цепочки docker exec -it fail2ban fail2ban-client set ИМЯ_ИЗ_JAIL_LIST unbanip IP_ДЛЯ_РАЗБЛОКИРОВКИ Для случая с использованием caddy команда разбана будет выглядеть так docker exec -it fail2ban fail2ban-client set caddy unbanip IP_ДЛЯ_РАЗБЛОКИРОВКИ Спасибо за внимание
×
×
  • Создать...

Важная информация

Вы принимаете наши Условия использования, Политика конфиденциальности, Правила. А также использование Мы разместили cookie-файлы на ваше устройство, чтобы помочь сделать этот сайт лучше. Вы можете изменить свои настройки cookie-файлов, или продолжить без изменения настроек.

Яндекс.Метрика