Предисловие
В этой статье я бы хотел рассказать, как установить и настроить обратный прокси Traefik с Let’s Encrypt и fail2ban систему Croudsec. Настройка Traefik может показаться сложной на первый взгляд, однако разобравшись вы сэкономите уйму сил при добавлении и администрировании новых сервисов. Ранее я использовал Nginx Proxy Manager, но перешел на Traefik, из-за возможности прописать все сетевые параметры для сервиса прямо в docker-compose.yml
.
Статья получилась длинная, но я надеюсь ей закрыть вопросы людей, которые собираются пройти тот же путь, что и я.
Traefik
Подготовка директорий и создание конфигураций
Создадим основной каталог traefik
, а в нем каталоги log
и custom
для логов и конфигураций сервисов.
А также 2 файла acme.json
и traefik.yml
, для сертификатов и основной конфигурации. Файл acme.json
оставляем пустым однако ему нужно сменить права доступа на 600
, иначе Traefik выдаст ошибку.
|
|
В traefik.yml
перечислены глобальные конфигурации. Их можно переопределить и дополнить, для отдельных сервисов, используя labels
в docker-compose.yml
или файлы в директории custom
. Пример содержимого файла:
|
|
Docker compose
Ниже представлен пример docker-compose.yml
. Исправьте путь до конфигов и доменное имя. Traefik запустится с дашбордом и базовой аутентификацией. Но для этого нужно прописать в настройках контейнера имя пользователя и хеш пароля. Получить хеш можно с помощью следующей команды:
|
|
Если
htpasswd
нет в системе, установите пакетapache2-utils
Далее открываем docker-compose.yml
и вставляем получившуюся строку после traefik.http.middlewares.traefik-auth.basicauth.users=
|
|
Блок http закомментирован, поскольку в файле
traefik.yml
указан автоматический редирект на https.
Запускаем контейнер:
|
|
На данный момент Traefik должен был запустить свой дашборд на https://traefik.ваш-домен.com
, а также получить на него сертификат. Убедитесь что все работает корректно, прежде чем продолжить.
Подключаем сервис используя Docker
Для того чтобы Traefik пробросил подключение к новому докер контейнеру нужно:
-
Убедится, что docker выбран в качестве провайдера в файле
traefik.yml
В конфигурации, что я приводил выше, эта функция включена.
-
Подключить контейнер к docker сети
proxy-net
.Или той, что вы выбрали основной в файле
traefik.yml
-
Добавить labels:
- "traefik.enable=true" - "traefik.http.routers.example-secure.entrypoints=https" - "traefik.http.routers.example-secure.rule=Host(`example.domain.com`)" - "traefik.http.routers.example-secure.service=example" - "traefik.http.services.example.loadbalancer.server.port=80"
Исправив имя приложения (example), domain, subdomain, а также порт приложения. Если нужен http:
- "traefik.http.routers.example.entrypoints=http" - "traefik.http.routers.example.rule=Host(`example.domain.com`)"
-
По желанию, отключить проброс портов.
Если к приложению не нужен доступ в обход Traefik, лучше закрыть все лишнее.
Вот пример docker-compose.yml
моего приложение для блога (Hugo):
|
|
Подключаем сервис через файл
Напоминаю, что в файле traefik.yml
в качестве провайдера выбран еще и file
. Указана директория для этих файлов и проброшена в контейнер traefik’a. А так же установлен флаг watch
, что заставляет Trafik следить за изменениями в этой директории
Теперь, все что нам нужно, это создать файл:
|
|
|
|
И заменить в нем название приложения (example) и адрес. Конфигурация схожа с предыдущим методом, отличается лишь синтаксис.
Дополнительную информацию о провайдерах, как и весь их список читайте в документации.
Crowdsec
Установка
Обратный прокси подготовлен, теперь переходим к защите. Необходимо установить еще 2 docker контейнера, самого Crowdsec и traefik-crowdsec-bouncer. Но прежде предлагаю разобраться в терминах:
cscli
- Интерфейс командной строки для Crowdseccollection
- Набор парсеров для анализа логов определенного сервиса и правил для блокировки ip адресов.acquis.yaml
- Файл с путями до логов и их типом.bouncer
- Программа, которая фактически блокирует доступ согласно черному списку от Crowdsec. Подбирается под сервис, например в нашем случаеtraefik-crowdsec-bouncer
bouncer для Traefik.
Создаем директории и файл acquis.yaml
:
|
|
Содержимое acquis.yaml
:
|
|
Теперь исправьте под себя docker-compose.yml
:
|
|
Переменную
CROWDSEC_BOUNCER_API_KEY
укажем позже, пока оставьте как тут.
Запускаем контейнер:
|
|
За статусом Crowdsec вы можете наблюдать введя cscli metrics
внутри контейнера:
|
|
На данном этапе Crowdsec уже должен читать лог файлы от Traefik, но bouncer еще не подключен. Исправим это, запросив api ключ:
|
|
Ключ вставляем docker-compose.yml
в переменной CROWDSEC_BOUNCER_API_KEY
.
Помимо ключа, необходимо настроить Traefik, чтобы он использовал этот bouncer как middlewares. Для этого создадим файл crowdsec.yml
в директории custom
у Traefik:
|
|
Содержимое файла:
|
|
И напоследок, в файле traefik.yml
необходимо добавить этот файл в entryPoints.http.http и entryPoints.https.http:
middlewares:
- crowdsec-bouncer@file
Получившийся файл:
|
|
Теперь пересоздаем контейнеры traefik crowdsec и bouncer-traefik:
|
|
Проверка
В качестве проверки вы можете заблокировать самого себя вручную. Но будьте внимательны, при подобных проверках, НЕ потеряйте доступ к системе, на которой запущен Crowdsec!
|
|
Ip адрес 192.168.0.5
будет заблокирован на 4 часа (по умолчанию). При попытке доступа к сервисам за Traefik, вы должны получить ошибку 403
с сообщением Forbidden
. Если хотите поменять, это настраивается через environment
в docker-compose.yml
.
Получить список всех заблокированных на данный момент адресов можно следующей командой:
|
|
Посмотреть всех заблокированных, в том числе и тех, у кого истек таймаут: cscli alerts list
. А получить расширенную информацию по блокировке: cscli alerts inspect -d <ID>
.
Если все работает как нужно, разблокируйте себя следующим образом:
|
|
Если нет, проверьте логи bounser’а, traefik и crowdsec:
|
|
Использование Crowdsec Security Engines
Это веб приложение, которое может помочь вам наблюдать за блокировками на нескольких экземплярах сразу. Так же там можно подписаться на дополнительные черные списки составленные самой Crowdsec. Приложение имеет вариант премиум подписки, а в бесплатной версии можно подписаться на 3 списка.
Для того чтобы им воспользоваться, зарегистрируйтесь на сайте app.crowdsec.net. После чего, в главном меню выберете Add Security Engine
. Укажите ключ доступа в следующей команде:
|
|
После нужно будет подтвердить добавление нового Security Engine на сайте.
Добавление нового типа блокировки
Обобщая, для добавления блокировки под новый сервис, вам необходимо выполнить следующее:
- Найти подходящую коллекцию в этом списке.
- В описании коллекции зачастую перечислены логи, которые она обрабатывает. Добавляем пути к логам и название коллекции в docker compose crowdsec’a.
- Добавляем пути к логам в файл
acquis.yaml
. - Если нужен другой bouncer, ищем его в этом списке.
- Получаем ключ для нового bouncer’а командой
cscli bouncers add <bounser-name>
- Конфигурируем bouncer, и перезапускаем все контейнеры.
Iptables + Crowdsec
Источник - Secure Docker Compose stacks with CrowdSec
В качестве примера вышеописанных действий, предлагаю разобрать защиту всего сервера, а не только сервисов находящихся за Traefik. Возможно с этого следовало бы начать, но в названии статьи указан Traefik, не могу же я изменить название.
В качестве bouncer’а выбран crowdsec-firewall-bouncer, а коллекция называется crowdsecurity/iptables.
Необходимые логи в моей системе (Ubuntu) хранятся в файлах /var/log/syslog
/var/log/auth.log
. И в файл acquis.yaml
нужно добавить следующее:
|
|
---
- разделитель конфигураций, который необходим для файла yaml.
Если же в вашей системе используется Journald вам необходимо обрабатывать его. Вот ссылки по синтаксису acquis.yaml и по монтированию journal в контейнер. Обратите внимание, что они используют контейнер crowdsec основанный на debian.
Добавим репозитории Crowdsec:
|
|
Установим пакет bouncer’a:
|
|
Исправим docker-compose.yml
. Добавим название коллекции crowdsecurity/iptables
, смонтируем пути к логам, а так же установим ip вручную для контейнера, так как bouncer’у нужно связаться с api crowdsec, а порт 8080 мы не пробрасывали в систему.
Я выложу весь docker-compose.yml под спойлер
|
|
Перезапускаем контейнеры:
|
|
И получаем ключ:
|
|
Конфигурация bounser’а, находится по следующему пути:
|
|
В ней мы меняем api_url
на ip контейнера - http://172.25.0.3:8080/
и api_key
на ключ полученный выше.
Запускаем службу:
|
|
Если ошибок не возникло, вы можете убедиться, что в iptables были внесены изменения. Посмотреть ветку INPUT (по умолчанию только ее застрагивает bouncer) можно следующей командой:
|
|
pkts bytes target prot opt in out source destination
4790 249K DROP all -- * * 0.0.0.0/0 0.0.0.0/0 match-set crowdsec-blacklists src
Содержимое блок листа можно посмотреть следующим образом:
|
|
Вы можете вернуться к проверке и забанить самого себя. Однако повторюсь еще раз, НЕ потеряйте доступ к серверу. Этот bouncer заблокирует, в том числе, доступ к ssh для выбранного вами ip. Подобную проверку проводите, например, на телефоне, вне вашей wifi сети.