Вопрос или проблема
Допустим, у меня есть контейнер с обратным прокси Nginx для публичного доступа (A), который перенаправляет трафик на веб-сервис (B). Этот контейнер A является местом, где заканчиваются TLS-соединения. Сервер Docker также находится за внешним сервисом обратного прокси. Я успешно извлекаю и записываю реальные IP-адреса из заголовков. Никаких проблем.
Как сконфигурировать действие fail2ban для блокировки (например, DROP) трафика с реального IP, выходящего из контейнера A? Веб-сервис B увидит заголовок XFF с реальным IP.
Вот что сейчас делают мои iptables (iptables -nL
):
Цепочка INPUT (политика ACCEPT)
целевой прот окт источник место назначения
fail2ban-auth-fail tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
Цепочка FORWARD (политика ACCEPT)
целевой прот окт источник место назначения
DOCKER-USER all -- 0.0.0.0/0 0.0.0.0/0
DOCKER-ISOLATION-STAGE-1 all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
DOCKER all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
DOCKER all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
Цепочка OUTPUT (политика ACCEPT)
целевой прот окт источник место назначения
Цепочка DOCKER (2 ссылки)
целевой прот окт источник место назначения
ACCEPT tcp -- 0.0.0.0/0 172.20.128.1 tcp dpt:443
ACCEPT tcp -- 0.0.0.0/0 172.20.128.1 tcp dpt:80
Цепочка DOCKER-ISOLATION-STAGE-1 (1 ссылка)
целевой прот окт источник место назначения
DOCKER-ISOLATION-STAGE-2 all -- 0.0.0.0/0 0.0.0.0/0
DOCKER-ISOLATION-STAGE-2 all -- 0.0.0.0/0 0.0.0.0/0
RETURN all -- 0.0.0.0/0 0.0.0.0/0
Цепочка DOCKER-ISOLATION-STAGE-2 (2 ссылки)
целевой прот окт источник место назначения
DROP all -- 0.0.0.0/0 0.0.0.0/0
DROP all -- 0.0.0.0/0 0.0.0.0/0
RETURN all -- 0.0.0.0/0 0.0.0.0/0
Цепочка DOCKER-USER (1 ссылка)
целевой прот окт источник место назначения
RETURN all -- 0.0.0.0/0 0.0.0.0/0
Цепочка fail2ban-auth-fail (1 ссылка)
целевой прот окт источник место назначения
DROP tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 STRING match "X-Forwarded-For: 184.75.215.178" ALGO name bm TO 65535
RETURN all -- 0.0.0.0/0 0.0.0.0/0
Как видно, я уже пытаюсь сопоставить пакеты с помощью строки XFF, и этот IP-адрес является реальным IP, а не адресом прокси-сервера.
Может быть, причина в цепочке INPUT?
Вот мои основные действия:
actionstart = iptables -N fail2ban-<name>
iptables -A fail2ban-<name> -j RETURN
iptables -I <chain> -p <protocol> --dport <port> -j fail2ban-<name>
actionban = iptables -I fail2ban-<name> 1 -p tcp --dport 80 -m string --algo bm --string 'X-Forwarded-For: <ip>' -j DROP
Смотрите здесь https://github.com/fail2ban/fail2ban/issues/2292
Вам необходимо сконфигурировать fail2ban
, чтобы он добавил правило iptables
в цепочку DOCKER-USER
– или вы дублируете правила (как и я) – одно использует цепочку по умолчанию для защиты хоста – другое защищает открытые контейнеры Docker.
Это то, что помогло мне с подобной проблемой. Если вы настраиваете Crowdsec или fail2ban:
Crowdsec:
sudo iptables -I FORWARD -m set --match-set crowdsec-blacklists src -j DROP
Для fail2ban что-то похожее на это:
sudo iptables -I FORWARD 1 -p tcp -j f2b-HTTPS
На самом деле, у fail2ban есть свои “цели” в iptables, вы можете найти их все с помощью
sudo iptables -L | grep f2b
Это создаст запись в iptables перед правилом Docker, которая отклонит запросы до того, как они дойдут до правила Docker (которое позволяет их все)
Ответ или решение
Управление трафиком с помощью Docker, iptables и fail2ban: Полный гайд
Введение
Организация безопасного и эффективного сетевого окружения для приложений, работающих в контейнерах Docker, требует внимательного подхода к настройке сетевых правил и контроля доступа. В данной статье мы подробно рассмотрим, как интегрировать автоматическую защиту от нежелательного трафика, используя fail2ban для блокировки IP-адресов на основе заголовка X-Forwarded-For
, а также роли iptables
в этом процессе.
Архитектура
У вас настроена система, в которой Nginx-обратный прокси (контейнер A) обрабатывает входящие TLS-соединения и пересылает запросы веб-сервису (контейнер B). Вы уже настроили извлечение реальных IP-адресов из заголовков, что является хорошей основой для дальнейшей защиты.
Проблема
Ваша основная задача — сконфигурировать fail2ban для блокировки трафика от "запрещённых" реальных IP-адресов на уровне контейнера A с использованием iptables
.
Текущая конфигурация iptables
Ваши текущие правила iptables выглядят следующим образом:
Chain INPUT (policy ACCEPT)
target prot opt source destination
fail2ban-auth-fail tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
Chain FORWARD (policy ACCEPT)
target prot opt source destination
DOCKER-USER all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
DOCKER all -- 0.0.0.0/0 0.0.0.0/0
...
Примечание: DOCKER-USER
– это невидимая цепь в вашем iptables, которая позволяет вам вставить свои правила перед стандартными правилами Docker.
Настройка fail2ban
Основные действия fail2ban
-
Создание цепочки для fail2ban: Это выполняется на этапе
actionstart
. Ваши действия уже включает создание цепочки для каждого jail. -
Добавление правила блокировки: В
actionban
необходимо указать адреса, которые будут блокироваться.
actionstart = iptables -N fail2ban-<name>
iptables -A fail2ban-<name> -j RETURN
iptables -I DOCKER-USER -p <protocol> --dport <port> -j fail2ban-<name>
actionban = iptables -I fail2ban-<name> 1 -p tcp --dport 80 -m string --algo bm --string 'X-Forwarded-For: <ip>' -j DROP
Здесь важно заменить <name>
на имя вашего jail, а <protocol>
и <port>
на соответствующие значения.
Рекомендации по улучшению конфигурации
-
Использование цепочки DOCKER-USER: Как вы уже заметили, гораздо лучше вставлять ваши правила в цепочку
DOCKER-USER
, так как это будет гарантировать, что они будут обработаны прежде, чем попадут в цепь Docker. Это предотвращает дублирование правил.Пример команды для интеграции:
iptables -I DOCKER-USER -m string --algo bm --string "X-Forwarded-For: <ip>" -j DROP
- Отладка fail2ban: Используйте команды, чтобы убедиться, что ваш jail работает корректно. Например:
fail2ban-client status
fail2ban-client status <jail_name>
- Проверка правил iptables: Убедитесь, что ваши правила настроены правильно, вы можете использовать следующую команду:
sudo iptables -L -n -v
Заключение
Настройка fail2ban вместе с iptables для блокировки реальных IP-адресов в Docker-контейнерах — это критически важный элемент безопасности ваших публично доступных приложений. Убедитесь, что вы тестируете настройки в безопасной среде перед их внедрением, и используйте логи для мониторинга произведенных изменений.
С помощью предложенной конфигурации вы сможете более эффективно управлять трафиком, минимизируя риск возникновения атак и создавая более безопасную среду для ваших приложений.