====== Установка и настройка Fail2ban для Nginx Proxy Manager ======
===== Описание =====
Данная инструкция описывает процесс установки и настройки Fail2ban для защиты Nginx Proxy Manager от:
* Сканирования уязвимостей
* 404 флуда
* DoS атак
* SSH брутфорса
===== Требования =====
* Ubuntu Server 24.04 (или аналогичный дистрибутив)
* Nginx Proxy Manager установленный в Docker
* Root доступ к серверу
===== Быстрая установка (автоматический скрипт) =====
**Рекомендуется:** Используйте автоматический скрипт установки для быстрой настройки всей системы за один шаг.
==== Шаг 1: Создание скрипта установки ====
nano install-fail2ban.sh
==== Шаг 2: Содержимое скрипта ====
Скопируйте следующий код в файл:
#!/bin/bash
################################################################################
# Скрипт автоматической установки и настройки Fail2ban для Nginx Proxy Manager
# Версия: 1.0
# Дата: 2025-11-30
################################################################################
set -e # Остановка при ошибке
# Цвета для вывода
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Функция вывода сообщений
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Проверка прав root
if [[ $EUID -ne 0 ]]; then
log_error "Этот скрипт должен быть запущен с правами root"
exit 1
fi
log_info "Начало установки и настройки Fail2ban для Nginx Proxy Manager"
echo ""
################################################################################
# НАСТРОЙКИ - ИЗМЕНИТЕ ПОД СВОИ НУЖДЫ
################################################################################
# Путь к логам Nginx Proxy Manager
NPM_LOG_DIR="/opt/nginxpm/data/logs"
# Имя контейнера Nginx Proxy Manager
NPM_CONTAINER_NAME="nginxpm"
# Директории Fail2ban
FAIL2BAN_BASE="/opt/fail2ban"
FAIL2BAN_SCRIPTS="${FAIL2BAN_BASE}/scripts"
FAIL2BAN_LOGS="${FAIL2BAN_BASE}/logs"
FAIL2BAN_CONFIG="${FAIL2BAN_BASE}/config"
FAIL2BAN_JAIL_D="${FAIL2BAN_CONFIG}/jail.d"
FAIL2BAN_FILTER_D="${FAIL2BAN_CONFIG}/filter.d"
# Файл лога для fail2ban
NGINX_ACCESS_LOG="${FAIL2BAN_LOGS}/nginx-access.log"
# Игнорируемые IP (локальные сети)
IGNORE_IP="127.0.0.1/8 ::1 192.168.0.0/24 172.16.0.0/12 10.0.0.0/8"
################################################################################
# Шаг 1: Проверка существования Nginx Proxy Manager
################################################################################
log_info "Проверка наличия контейнера Nginx Proxy Manager..."
if ! docker ps --format "{{.Names}}" | grep -q "^${NPM_CONTAINER_NAME}$"; then
log_error "Контейнер ${NPM_CONTAINER_NAME} не найден или не запущен"
log_error "Убедитесь что Nginx Proxy Manager установлен и запущен"
exit 1
fi
if [ ! -d "$NPM_LOG_DIR" ]; then
log_error "Директория логов ${NPM_LOG_DIR} не найдена"
exit 1
fi
log_info "Контейнер ${NPM_CONTAINER_NAME} найден и работает"
echo ""
################################################################################
# Шаг 2: Установка Fail2ban
################################################################################
log_info "Установка Fail2ban..."
apt update -qq
apt install -y fail2ban >/dev/null 2>&1
log_info "Fail2ban успешно установлен"
echo ""
################################################################################
# Шаг 3: Создание структуры каталогов
################################################################################
log_info "Создание структуры каталогов..."
mkdir -p "${FAIL2BAN_SCRIPTS}"
mkdir -p "${FAIL2BAN_LOGS}"
mkdir -p "${FAIL2BAN_JAIL_D}"
mkdir -p "${FAIL2BAN_FILTER_D}"
log_info "Структура каталогов создана"
echo ""
################################################################################
# Шаг 4: Создание скрипта парсера логов
################################################################################
log_info "Создание скрипта парсера логов..."
cat > "${FAIL2BAN_SCRIPTS}/parse-nginx-logs.sh" << 'PARSER_EOF'
#!/bin/bash
# Скрипт парсинга логов nginx-proxy-manager для fail2ban
LOG_DIR="/opt/nginxpm/data/logs"
LOG_FILE="/opt/fail2ban/logs/nginx-access.log"
CONTAINER_NAME="nginxpm"
PARSER_LOG="/opt/fail2ban/logs/parser.log"
mkdir -p "$(dirname "$LOG_FILE")" "$(dirname "$PARSER_LOG")"
if ! docker ps --format "table {{.Names}}" | grep -q "^${CONTAINER_NAME}$"; then
echo "$(date): Контейнер $CONTAINER_NAME не найден" >> "$PARSER_LOG"
exit 1
fi
if [ ! -d "$LOG_DIR" ]; then
echo "$(date): Директория $LOG_DIR не найдена" >> "$PARSER_LOG"
exit 1
fi
> "$LOG_FILE"
processed_files=0
total_lines=0
for logfile in "$LOG_DIR"/proxy-host-*_access.log; do
if [ -f "$logfile" ]; then
lines_from_file=$(tail -n 2000 "$logfile" | wc -l)
tail -n 2000 "$logfile" >> "$LOG_FILE"
processed_files=$((processed_files + 1))
total_lines=$((total_lines + lines_from_file))
echo "$(date): Обработан: $(basename "$logfile") - $lines_from_file строк" >> "$PARSER_LOG"
fi
done
if [ $processed_files -eq 0 ]; then
echo "$(date): Файлы логов не найдены" >> "$PARSER_LOG"
touch "$LOG_FILE"
fi
chmod 644 "$LOG_FILE"
MINUTE=$(date +%M)
if [ "$MINUTE" = "00" ]; then
final_lines=$(wc -l < "$LOG_FILE" 2>/dev/null || echo "0")
echo "$(date): Обработано $processed_files файлов, $final_lines записей" >> "$PARSER_LOG"
fi
if [ -f "$PARSER_LOG" ] && [ $(stat -c%s "$PARSER_LOG" 2>/dev/null || echo 0) -gt 5242880 ]; then
mv "$PARSER_LOG" "$PARSER_LOG.old"
touch "$PARSER_LOG"
chmod 644 "$PARSER_LOG"
fi
if [ -f "$LOG_FILE" ] && [ $(stat -c%s "$LOG_FILE" 2>/dev/null || echo 0) -gt 10485760 ]; then
mv "$LOG_FILE" "$LOG_FILE.old"
touch "$LOG_FILE"
chmod 644 "$LOG_FILE"
echo "$(date): Ротация лог-файла" >> "$PARSER_LOG"
fi
exit 0
PARSER_EOF
chmod +x "${FAIL2BAN_SCRIPTS}/parse-nginx-logs.sh"
log_info "Скрипт парсера создан"
echo ""
################################################################################
# Шаг 5: Первый запуск парсера
################################################################################
log_info "Первый запуск парсера..."
"${FAIL2BAN_SCRIPTS}/parse-nginx-logs.sh"
if [ -f "$NGINX_ACCESS_LOG" ]; then
log_info "Лог-файл создан: ${NGINX_ACCESS_LOG}"
log_info "Количество строк: $(wc -l < ${NGINX_ACCESS_LOG})"
else
log_error "Не удалось создать лог-файл"
exit 1
fi
echo ""
################################################################################
# Шаг 6: Создание фильтров Fail2ban
################################################################################
log_info "Создание фильтров Fail2ban..."
cat > "${FAIL2BAN_FILTER_D}/nginx-scan-block.conf" << 'FILTER_SCAN_EOF'
[Definition]
failregex = ^\[.*\] - \d+ \d+ - GET https? .* ".*(/\.env|/\.git|/\.aws|/\.ssh|/config|/backup|wp-config|phpinfo|admin/config|server-status|server-info).*" \[Client \]
^\[.*\] - 40\d \d+ - GET https? .* ".*\.(php|asp|jsp|cgi|pl|py).*" \[Client \]
^\[.*\] - \d+ \d+ - GET https? .* ".*\.\.\/.*" \[Client \]
^\[.*\] - \d+ \d+ - GET https? .* ".*(union|select|insert|update|delete|drop|create|alter).*" \[Client \]
^\[.*\] - \d+ \d+ - (GET|POST) https? .* ".*(