bolt Valebyte VPS desde $4/mes — NVMe, despliegue en 60s.

Obtener VPS arrow_forward
eco Principiante Tutorial/Cómo hacer

CrowdSec en VPS: fail2ban colaborativo para SSH, Nginx y Docker

calendar_month Sep 23, 2026 schedule 21 min de lectura visibility 27 vistas
CrowdSec на VPS: коллективный fail2ban для SSH, Nginx и Docker
info

¿Necesitas un servidor para esta guía? Ofrecemos servidores dedicados y VPS en más de 50 países con configuración instantánea.

¿Necesitas un VPS para esta guía?

Explore otras opciones de servidores dedicados en

CrowdSec en un VPS: fail2ban colaborativo para SSH, Nginx y Docker

TL;DR

CrowdSec se instala en un VPS como un demonio de análisis de logs: detecta actividad sospechosa en SSH, Nginx y contenedores Docker, y luego bloquea direcciones IP maliciosas mediante firewall-bouncer. A diferencia del fail2ban clásico, CrowdSec puede utilizar reputación IP colaborativa, pero la decisión de bloquear y la aplicación de sanciones permanecen en su servidor.

  • Para un servidor de producción pequeño, bastan 2 vCPU, 2–4 GB de RAM y 40–80 GB de SSD.
  • Se configurarán SSH, Nginx, logs de Docker y firewall-bouncer para nftables.
  • Para HTTPS se utiliza Caddy con obtención automática de certificados Let’s Encrypt.
  • La configuración de CrowdSec se almacena por separado de los archivos actualizados automáticamente.
  • Al final se configurarán la verificación, las copias de seguridad, las actualizaciones y el diagnóstico de errores comunes.

1. TL;DR

CrowdSec es un sistema moderno de detección y bloqueo de ataques, a menudo denominado fail2ban colaborativo. Lee logs del sistema y de aplicaciones, aplica escenarios de detección y transmite decisiones a firewall-bouncer. Como resultado, los intentos de fuerza bruta de contraseñas SSH, el escaneo de Nginx y parte de los ataques contra servicios Docker se bloquean antes de que el atacante obtenga muchos intentos.

Ni CrowdSec ni fail2ban sustituyen las actualizaciones, las claves SSH, los privilegios mínimos y la correcta publicación de puertos Docker. El objetivo principal de esta guía es obtener protección multicapa para un VPS sin instalar una plataforma de gestión independiente.

  • Sistema operativo: Debian 12 o Ubuntu Server 24.04 LTS.
  • CrowdSec: rama 1.6.x, la rama estable actual para 2026.
  • Reverse proxy: Nginx 1.26+ o Caddy 2.9+; el ejemplo utiliza ambos componentes en distintos escenarios.
  • Firewall: nftables mediante firewall-bouncer.
  • Docker Engine: rama estable actual 27/28, instalada desde el repositorio oficial de Docker.

2. Contenido

La guía está diseñada para un VPS limpio con una dirección IPv4 pública. Los comandos se proporcionan para Debian 12 y Ubuntu 24.04; los nombres de paquetes y las rutas en estos sistemas son prácticamente idénticos.

Si Nginx, Docker o fail2ban ya están funcionando en el servidor, guarde sus configuraciones antes de la instalación. Es especialmente importante comprobar qué puertos están publicados por los contenedores Docker: publicar un puerto mediante Docker puede eludir las reglas habituales de ufw, por lo que en producción es mejor controlar el acceso a nivel de Docker, nftables y reverse proxy.

  1. Primero se crea un administrador independiente y se restringe SSH.
  2. Luego se instalan los componentes básicos y CrowdSec.
  3. Después se conectan las colecciones de escenarios para Linux, SSH, Nginx y Docker.
  4. Se activa firewall-bouncer, que convierte las decisiones de CrowdSec en bloqueos reales.
  5. Se realizan pruebas de logs, escenarios, firewall y HTTPS.

3. Qué configuramos y por qué

Diagrama: 3. Qué configuramos y por qué
Diagrama: 3. Qué configuramos y por qué

Cómo funciona CrowdSec

CrowdSec consta de varias partes lógicas. Local API almacena decisiones y recibe eventos del security engine. Engine lee logs, transmite líneas a parsers y escenarios, y los escenarios determinan el comportamiento: fuerza bruta de contraseñas, escaneo de rutas, un gran número de errores o indicios de un patrón de exploit conocido.

Tras activarse un escenario, aparece una decisión, por ejemplo, bloquear una IP durante cuatro horas. Bouncer recibe esta decisión y la aplica al tráfico entrante. Para Linux con nftables, normalmente se trata de una cadena independiente en netfilter, por lo que el servidor web no necesita implementar el bloqueo por sí mismo.

Componente Propósito Qué comprobar
Security engine Lee logs y ejecuta escenarios cscli metrics
Parsers Transforman líneas de logs en eventos cscli hub list
Scenarios Determinan secuencias sospechosas cscli scenarios list
Firewall-bouncer Bloquea IP mediante nftables cscli bouncers list
Central API Publica y recibe reputación colaborativa Estado del registro y pull

Por qué no es simplemente un reemplazo de fail2ban

Fail2ban normalmente analiza solo logs locales y crea una regla de bloqueo local. Esto funciona bien contra ataques repetidos a un servidor específico. CrowdSec añade un motor de escenarios unificado, una gestión cómoda de colecciones y la posibilidad de utilizar señales de otras instalaciones mediante Central API.

La reputación colaborativa no significa que cada dirección se considere automáticamente peligrosa para siempre. Las decisiones tienen un tipo, origen y período de validez. El administrador puede ver una decisión, eliminarla o añadir una propia. Para sistemas críticos se recomienda activar primero la observación y comprobar los false positive, y después ampliar los bloqueos.

Qué estará protegido

  • SSH: fuerza bruta de contraseñas, gran cantidad de conexiones fallidas e intentos de escaneo.
  • Nginx: solicitudes masivas a rutas inexistentes, URL sospechosas y algunos patrones de ataque conocidos.
  • Docker: no protege el contenedor en sí, sino los logs de aplicaciones y el reverse proxy. Si la aplicación escribe eventos útiles en stdout, pueden recopilarse mediante Docker logging driver o un archivo.
  • Firewall del sistema: bloqueo de IP a nivel del kernel, antes de que la solicitud sea procesada por la aplicación.

Opciones self-hosted y cloud-managed

Los WAF, CDN y security gateway cloud-managed son convenientes cuando se necesita proteger muchos dominios, distribuir tráfico por regiones o filtrar automáticamente DDoS volumétricos. A cambio, hay que pagar mensualmente, dirigir el DNS a través de una red de terceros y aceptar las limitaciones del proveedor.

CrowdSec self-hosted en un VPS es adecuado para un servidor, un equipo pequeño, una API privada, un servidor Git, un panel de administración y aplicaciones donde es importante tener control total sobre los logs. Al mismo tiempo, un VPS no puede detener un ataque DDoS grande: si el canal o la NIC virtual del proveedor se saturan, el firewall local ya no ayudará.

4. Qué configuración de VPS se necesita para esta tarea

Diagrama: 4. Qué configuración de VPS se necesita para esta tarea
Diagrama: 4. Qué configuración de VPS se necesita para esta tarea

CrowdSec consume poca CPU y memoria. La carga principal no depende del agente en sí, sino del volumen de logs, el número de escenarios, la velocidad de las solicitudes de Nginx y la cantidad de contenedores. Para SSH y un sitio web, los requisitos son mínimos; para varias aplicaciones hay que tener en cuenta su propio consumo de RAM.

Escenario CPU RAM Disco Red
SSH y un Nginx pequeño 1 vCPU 1 GB 20–30 GB SSD 100 Mbit/s
Docker, 2–5 servicios y CrowdSec 2 vCPU 4 GB 60–80 GB NVMe 1 Gbit/s
Varios sitios y tareas de CI 4 vCPU 8 GB 100–160 GB NVMe 1 Gbit/s

Opción práctica para la mayoría de las instalaciones

Para esta guía es razonable elegir 2 vCPU, 4 GB de RAM, 60–80 GB NVMe, una IPv4 pública y un puerto de 1 Gbit/s. Esta capacidad permite ejecutar simultáneamente CrowdSec, Nginx o Caddy, Docker Compose y varias aplicaciones pequeñas. Si los contenedores usan PostgreSQL, Elasticsearch, GitLab o compilación de imágenes, la RAM debe aumentarse por separado.

Como una de las opciones, puede elegir un VPS con estas características. Lo importante son los recursos, la estabilidad del disco, la disponibilidad de copias de seguridad y la posibilidad de configurar un registro DNS inverso, no el nombre de un plan específico.

Cuándo se necesita un dedicated

Un servidor dedicado no es necesario por CrowdSec en sí. Se justifica cuando la máquina ejecuta bases de datos con alto I/O, decenas de contenedores, workers de CI/CD, servidores de juegos, un GitLab grande, un nodo de blockchain propio o varias máquinas virtuales.

Para CrowdSec se debe asignar como mínimo una vCPU y 512 MB de RAM, pero en un dedicated es conveniente reservar 2–4 vCPU y 4–8 GB de RAM para el security stack y los servicios del sistema. No almacene la única copia de los archivos de respaldo en el mismo servidor físico.

Impacto de la ubicación

La ubicación afecta principalmente a la latencia hacia los usuarios y a los requisitos legales sobre los datos. Para CrowdSec, la distancia a Central API normalmente no es crítica: los eventos se analizan localmente. Para una aplicación web, elija una región más cercana a la audiencia principal y, para un VPS administrativo, tenga en cuenta la ruta desde su lugar de trabajo.

Compruebe si el proveedor ofrece un registro PTR, IPv6, filtrado de SMTP saliente y la posibilidad de abrir los puertos entrantes necesarios. Además, aclare la política sobre security scanners: CrowdSec no debe utilizarse para el escaneo activo de redes ajenas.

5. Preparación del servidor

Inicio de sesión y creación de administrador

A continuación se utiliza el nombre deploy. Sustitúyalo por el suyo. Realice el primer inicio de sesión como root solo para la configuración inicial y, después, use sudo. Antes de modificar SSH, mantenga abierta la sesión actual y pruebe el nuevo acceso en una segunda terminal.

# Обновляем индексы пакетов
sudo apt update

# Устанавливаем обновления безопасности и исправления
sudo apt full-upgrade -y

# Создаём отдельного пользователя
sudo adduser deploy

# Разрешаем ему выполнять административные команды
sudo usermod -aG sudo deploy

# Создаём каталог для публичных SSH-ключей
sudo install -d -m 700 -o deploy -g deploy /home/deploy/.ssh

Desde el equipo local, agregue la clave pública. No copie la clave privada al servidor.

# Выполняется на вашем рабочем компьютере
ssh-copy-id deploy@SERVER_IP

# Проверяем вход новым пользователем в отдельном терминале
ssh deploy@SERVER_IP

Paquetes básicos

# Устанавливаем диагностику, шифрование, редактор и управление репозиториями
sudo apt install -y \
  ca-certificates curl gnupg jq git vim htop lsof unzip \
  apt-transport-https software-properties-common \
  nftables rsyslog logrotate

# Проверяем время и синхронизацию часов
timedatectl status

# Включаем системную синхронизацию времени
sudo timedatectl set-ntp true

Endurecimiento de SSH

Primero asegúrese de que el acceso mediante clave funciona. Después, desactive la autenticación por contraseña y el acceso de root. Si tiene automatizaciones que aún usan contraseña, dejarán de funcionar tras aplicar el archivo.

# Создаём отдельный drop-in для sshd
sudo tee /etc/ssh/sshd_config.d/10-hardening.conf >/dev/null <<'EOF'
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
LoginGraceTime 20
X11Forwarding no
AllowUsers deploy
EOF

# Проверяем синтаксис до перезапуска
sudo sshd -t

# Применяем конфигурацию без закрытия текущих сессий
sudo systemctl reload ssh

Firewall antes de instalar CrowdSec

Abra únicamente SSH, HTTP y HTTPS. Si SSH funciona en otro puerto, sustituya el valor en las reglas. No exponga puertos de bases de datos ni servicios Docker a Internet sin necesidad.

# Включаем nftables при загрузке
sudo systemctl enable --now nftables

# Создаём базовый firewall: loopback, established, SSH и web
sudo tee /etc/nftables.conf >/dev/null <<'EOF'
#!/usr/sbin/nft -f
flush ruleset

table inet filter {
    chain input {
        type filter hook input priority filter; policy drop;

        iifname "lo" accept
        ct state established,related accept
        ct state invalid drop

        ip protocol icmp accept
        ip6 nexthdr ipv6-icmp accept

        tcp dport 22 accept
        tcp dport { 80, 443 } accept
    }

    chain forward {
        type filter hook forward priority filter; policy drop;
    }

    chain output {
        type filter hook output priority filter; policy accept;
    }
}
EOF

# Загружаем правила
sudo nft -f /etc/nftables.conf

# Проверяем активный набор правил
sudo nft list ruleset

¿Es necesario fail2ban?

En la tarea, fail2ban se instala como medida de seguridad básica, pero no se deben ejecutar sin criterio dos sistemas de bloqueo independientes con los mismos umbrales. De lo contrario, los sistemas pueden bloquear direcciones según sus propias reglas y el diagnóstico se volverá más complejo. Tras comprobar CrowdSec, normalmente se deja solo este para SSH y web, mientras que fail2ban se desactiva o se utiliza para una aplicación independiente.

# Устанавливаем fail2ban как временный или резервный механизм
sudo apt install -y fail2ban

# Создаём безопасный локальный конфиг SSH jail
sudo tee /etc/fail2ban/jail.d/sshd.local >/dev/null <<'EOF'
[sshd]
enabled = true
backend = systemd
port = ssh
maxretry = 6
findtime = 10m
bantime = 10m
EOF

# Перезапускаем fail2ban и смотрим состояние
sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd

Tras poner CrowdSec en producción, puede desactivar este jail y mantener fail2ban instalado para activarlo manualmente en caso de emergencia:

# Отключаем дублирующий SSH-jail после успешной проверки CrowdSec
sudo sed -i 's/^enabled = true/enabled = false/' /etc/fail2ban/jail.d/sshd.local
sudo systemctl restart fail2ban

6. Instalación de CrowdSec, Nginx y Docker

Схема: 6. Установка CrowdSec, Nginx и Docker
Diagrama: 6. Instalación de CrowdSec, Nginx y Docker

Instalación de CrowdSec

En Debian y Ubuntu, use el repositorio oficial de CrowdSec, no PPA aleatorios. La versión del paquete puede ser más reciente que la indicada en el artículo. En 2026, oriéntese por la rama estable 1.6.x y compruebe el paquete antes de fijar una versión.

# Добавляем официальный signing key CrowdSec
curl -fsSL https://packagecloud.io/crowdsec/crowdsec/gpgkey \
  | sudo gpg --dearmor -o /usr/share/keyrings/crowdsec-archive-keyring.gpg

# Добавляем официальный apt-репозиторий
echo "deb [signed-by=/usr/share/keyrings/crowdsec-archive-keyring.gpg] https://packagecloud.io/crowdsec/crowdsec/debian/ bookworm main" \
  | sudo tee /etc/apt/sources.list.d/crowdsec.list

# Обновляем индексы и устанавливаем CrowdSec 1.6.x
sudo apt update
sudo apt install -y crowdsec

# Включаем сервис и проверяем установленную версию
sudo systemctl enable --now crowdsec
sudo cscli version

En Ubuntu 24.04, sustituya el nombre en clave del repositorio por uno compatible con el repositorio oficial si la entrada actual no es adecuada. La comprobación apt policy crowdsec mostrará de dónde procede el paquete.

# Показываем источник и доступную версию пакета
apt policy crowdsec

# Проверяем состояние systemd-сервиса
sudo systemctl status crowdsec --no-pager

Instalación de colecciones básicas

Una colección es un conjunto de parsers, escenarios y archivos de registro para un servicio específico. No instale todo indiscriminadamente: los escenarios adicionales aumentan el ruido y el consumo de recursos.

# Обновляем индекс Hub
sudo cscli hub update

# Устанавливаем сценарии Linux и SSH
sudo cscli collections install crowdsecurity/linux
sudo cscli collections install crowdsecurity/sshd

# Устанавливаем парсеры и сценарии Nginx
sudo cscli collections install crowdsecurity/nginx

# Проверяем установленные коллекции
sudo cscli collections list

Instalación de firewall-bouncer

Para nftables se necesita el paquete firewall-bouncer con backend nftables. El nombre del paquete puede variar según la distribución y el repositorio, por lo que primero busque el paquete disponible.

# Ищем доступные варианты bouncer
apt-cache search crowdsec | grep -i bouncer

# Устанавливаем bouncer для nftables
sudo apt install -y crowdsec-firewall-bouncer-nftables

# Включаем применение решений на firewall
sudo systemctl enable --now crowdsec-firewall-bouncer

# Проверяем состояние bouncer
sudo systemctl status crowdsec-firewall-bouncer --no-pager

Instalación de Nginx

Nginx es necesario para disponer de un access log claro y para el proxy de aplicaciones. Si el reverse proxy ya está implementado con Caddy, no es obligatorio instalar Nginx; en ese caso, se conecta la colección para Caddy o el registro de la aplicación. Para el esquema principal, mantendremos Nginx.

# Устанавливаем Nginx из системного репозитория
sudo apt install -y nginx

# Запускаем web-сервер и добавляем его в автозагрузку
sudo systemctl enable --now nginx

# Проверяем локальный HTTP-ответ
curl -I http://127.0.0.1

Instalación de Docker Engine

Para producción, use Docker Engine oficial y no el paquete obsoleto docker.io si necesita el plugin Compose actualizado y correcciones. La versión 27/28 es adecuada para una instalación típica de CrowdSec en 2026.

# Добавляем ключ официального репозитория Docker
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg \
  | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

# Подключаем репозиторий Docker для Debian 12
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian bookworm stable" \
  | sudo tee /etc/apt/sources.list.d/docker.list

# Устанавливаем Engine, CLI и Compose plugin
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# Разрешаем deploy работать с Docker без sudo
sudo usermod -aG docker deploy

# Проверяем Docker и Compose
sudo docker version
sudo docker compose version

Después de añadir el grupo, debe volver a iniciar sesión por SSH. El grupo docker concede de facto permisos de root, así que no añada usuarios no autorizados ni monte el socket de Docker dentro de contenedores no confiables.

7. Configuración y verificación

Conexión de registros de SSH y Nginx

En Debian, SSH suele escribir en journald o en /var/log/auth.log. Nginx utiliza por defecto /var/log/nginx/access.log y /var/log/nginx/error.log. Revise la configuración activa de CrowdSec: indicará qué archivos de acquisition ya han sido creados por el paquete.

# Показываем источники логов CrowdSec
sudo cscli acquisitions list

# Проверяем наличие системных и Nginx-журналов
sudo ls -l /var/log/auth.log /var/log/nginx/access.log /var/log/nginx/error.log

# Читаем последние сообщения CrowdSec
sudo journalctl -u crowdsec -n 100 --no-pager

Si no se ha creado el archivo de acquisition, añada una configuración independiente. El formato puede variar ligeramente entre versiones, por lo que después de realizar cambios compruebe siempre la sintaxis reiniciando el servicio.

# Создаём источник логов Nginx
sudo tee /etc/crowdsec/acquis.d/nginx.yaml >/dev/null <<'EOF'
filenames:
  - /var/log/nginx/access.log
  - /var/log/nginx/error.log
labels:
  type: nginx
EOF

# Создаём источник системного auth.log
sudo tee /etc/crowdsec/acquis.d/sshd.yaml >/dev/null <<'EOF'
filenames:
  - /var/log/auth.log
labels:
  type: syslog
EOF

# Перезапускаем engine после изменения источников
sudo systemctl restart crowdsec

# Проверяем источники ещё раз
sudo cscli acquisitions list

Configuración de Nginx

El sitio debe usar un proxy para la aplicación únicamente mediante loopback o una red Docker interna. No publique el puerto de la aplicación directamente si el acceso a ella debe realizarse a través de Nginx.

# Создаём виртуальный хост для example.com
sudo tee /etc/nginx/sites-available/example.com >/dev/null <<'EOF'
server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;

    access_log /var/log/nginx/example.access.log;
    error_log  /var/log/nginx/example.error.log warn;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_read_timeout 60s;
    }
}
EOF

# Включаем сайт
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/example.com

# Удаляем дефолтный сайт при необходимости
sudo rm -f /etc/nginx/sites-enabled/default

# Проверяем конфигурацию и применяем её
sudo nginx -t
sudo systemctl reload nginx

En producción, sustituya el dominio por el real y apunte el registro DNS A a la IPv4 del VPS. Para IPv6, añada un registro AAAA solo después de comprobar que el firewall y la aplicación gestionan correctamente IPv6.

HTTPS mediante Caddy

Si no desea gestionar manualmente los certificados en Nginx, Caddy puede convertirse en el único reverse proxy. No ejecute Caddy y Nginx simultáneamente en los puertos 80 y 443. A continuación se muestra una alternativa independiente con Docker Compose: detenga Nginx o asígnele un puerto interno.

# Создаём каталог Caddy
sudo mkdir -p /opt/caddy/data /opt/caddy/config
sudo chown -R deploy:deploy /opt/caddy

# Переходим в каталог проекта
cd /opt/caddy

# Создаём файл с reverse proxy и автоматическим HTTPS
cat > Caddyfile <<'EOF'
example.com {
    encode gzip zstd

    reverse_proxy app:8080

    header {
        X-Content-Type-Options nosniff
        X-Frame-Options SAMEORIGIN
        Referrer-Policy strict-origin-when-cross-origin
    }
}
EOF

# Описываем Caddy и приложение в Compose
cat > compose.yaml <<'EOF'
services:
  app:
    image: nginx:1.27-alpine
    restart: unless-stopped
    expose:
      - "8080"

  caddy:
    image: caddy:2.9-alpine
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - ./data:/data
      - ./config:/config
    depends_on:
      - app
EOF

# Запускаем стек и проверяем контейнеры
docker compose up -d
docker compose ps

En un proyecto real, sustituya la imagen de prueba de la aplicación por la suya. Caddy solicitará el certificado automáticamente si el DNS ya apunta al VPS y los puertos entrantes 80/443 están disponibles. Si Nginx permanece como reverse proxy externo, Caddy debe escuchar únicamente en un puerto interno y TLS debe terminar en Nginx.

Recopilación de registros de Docker

CrowdSec no debe leer directamente la base de datos binaria de Docker. Para un servidor pequeño, es más sencillo configurar archivos JSON de Docker y dirigirlos a acquisition. Limitar el tamaño de los registros es obligatorio; de lo contrario, un contenedor ruidoso puede llenar el disco.

# Ограничиваем размер стандартных Docker-логов
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json >/dev/null <<'EOF'
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "5"
  }
}
EOF

# Перезапускаем Docker; контейнеры могут кратко прерваться
sudo systemctl restart docker

# Проверяем конфигурацию Docker
docker info --format '{{.LoggingDriver}}'

La colección de Docker puede analizar eventos mediante un parser adecuado, pero el formato concreto depende de la versión de CrowdSec y de la aplicación. Primero instale la colección y revise sus archivos de acquisition:

# Обновляем Hub и устанавливаем коллекцию Docker
sudo cscli hub update
sudo cscli collections install crowdsecurity/docker

# Просматриваем файлы коллекции
sudo find /etc/crowdsec -type f | grep -i docker

# Перезапускаем CrowdSec после установки коллекции
sudo systemctl restart crowdsec

Registro del bouncer y verificación de decisiones

Durante la instalación, el paquete normalmente crea automáticamente una clave API para el bouncer. Si no se crea la clave, genérela manualmente y añádala a la configuración del bouncer. No publique esta clave en Git ni la envíe en issues públicos.

# Смотрим зарегистрированные bouncer
sudo cscli bouncers list

# При необходимости создаём новый ключ
sudo cscli bouncers add firewall-local

# Проверяем локальные решения
sudo cscli decisions list

# Смотрим статистику чтения логов и срабатывания сценариев
sudo cscli metrics

Prueba segura de bloqueo

No pruebe un baneo desde su IP de trabajo principal: podría perder el acceso. Utilice una dirección temporal, la consola del proveedor o una decisión local de corta duración. Después de la prueba, elimine la decisión.

# Добавляем тестовый адрес на одну минуту; замените TEST_IP
sudo cscli decisions add --ip TEST_IP --duration 1m --reason "manual-test"

# Проверяем, что решение появилось
sudo cscli decisions list

# Проверяем цепочки CrowdSec в nftables
sudo nft list ruleset | grep -i crowdsec -A 12

# Удаляем тестовое решение
sudo cscli decisions delete --ip TEST_IP

Verificación de SSH y HTTP

# Проверяем открытые TCP-порты на самом сервере
sudo ss -lntup

# Проверяем локальный Nginx
curl -I http://127.0.0.1

# Проверяем HTTPS с внешнего компьютера
curl -I https://example.com

# Проверяем сообщения bouncer
sudo journalctl -u crowdsec-firewall-bouncer -n 100 --no-pager

# Проверяем ошибки Nginx за последние строки
sudo tail -n 50 /var/log/nginx/error.log

Configuración de notificaciones

Para empezar, basta con revisar periódicamente las métricas y los registros de systemd. En producción, resulta útil conectar monitorización: Prometheus node exporter, Uptime Kuma, Zabbix u otra herramienta que ya se esté utilizando. No envíe líneas completas de registros en las notificaciones si pueden contener tokens, URL con secretos o datos personales.

8. Copias de seguridad y mantenimiento

Qué se debe guardar

  • /etc/crowdsec/ — acquisition, configuraciones locales y escenarios que haya modificado.
  • /etc/crowdsec/bouncers/ — configuración de firewall-bouncer.
  • /etc/ssh/, /etc/nginx/, /etc/nftables.conf y la configuración de Caddy.
  • Archivos de Compose, plantillas de Docker secrets y variables de entorno sin exponer secretos en los registros.
  • Datos de aplicaciones: bases de datos, cargas de usuarios, certificados y persistent volumes.
  • Lista de paquetes y salida de configuración para restaurar el entorno en un nuevo VPS.

No se debe considerar una Docker image como copia de seguridad de los datos. La imagen puede descargarse de nuevo, pero el contenido del volume, la base de datos y las claves no. Para PostgreSQL, realice un dump lógico y, para MySQL o MariaDB, utilice la herramienta de dump correspondiente antes de copiar los archivos.

Ejemplo de dump de PostgreSQL

# Создаём каталог для локальных временных дампов
sudo install -d -m 700 /var/backups/postgres

# Выполняем сжатый дамп конкретной базы
sudo -u postgres pg_dump -Fc appdb \
  > /var/backups/postgres/appdb-$(date +%F).dump

# Удаляем локальные дампы старше семи дней
sudo find /var/backups/postgres -type f -mtime +7 -delete

Restic en S3 externo

Las copias de seguridad deben estar fuera del VPS: en un almacenamiento de objetos compatible con S3, en un servidor independiente o en dos ubicaciones independientes. Pase los secretos de Restic mediante un archivo de entorno con permisos 600. El ejemplo utiliza almacenamiento compatible con S3; sustituya la URL y el bucket por los suyos.

# Устанавливаем restic
sudo apt install -y restic

# Создаём файл секретов с закрытыми правами
sudo tee /root/.restic-env >/dev/null <<'EOF'
export AWS_ACCESS_KEY_ID='CHANGE_ME'
export AWS_SECRET_ACCESS_KEY='CHANGE_ME'
export RESTIC_REPOSITORY='s3:https://s3.example.net/server-backups'
export RESTIC_PASSWORD='CHANGE_ME_LONG_RANDOM_PASSWORD'
EOF
sudo chmod 600 /root/.restic-env

# Инициализируем репозиторий один раз
sudo bash -c 'source /root/.restic-env && restic init'

No incluya en el archivo directorios con archivos temporales y caché de Docker. El archivo secreto de Restic no debe incluirse sin cambios junto con el archivo de respaldo: guarde la contraseña en un gestor de secretos o en una copia offline.

# Создаём скрипт резервного копирования
sudo tee /usr/local/sbin/backup-server.sh >/dev/null <<'EOF'
#!/usr/bin/env bash
set -Eeuo pipefail

source /root/.restic-env

restic backup \
  /etc/crowdsec \
  /etc/nginx \
  /etc/ssh \
  /etc/docker \
  /etc/nftables.conf \
  /opt \
  /var/backups/postgres \
  --tag "$(hostname)-$(date +%F)"

restic forget \
  --keep-daily 7 \
  --keep-weekly 4 \
  --keep-monthly 6 \
  --prune
EOF

# Разрешаем запускать скрипт только root
sudo chmod 700 /usr/local/sbin/backup-server.sh

# Выполняем первый backup вручную
sudo /usr/local/sbin/backup-server.sh

# Проверяем список snapshots
sudo bash -c 'source /root/.restic-env && restic snapshots'

Cron y verificación de restauración

# Запускаем backup ежедневно в 03:15
echo '15 3   * root /usr/local/sbin/backup-server.sh >> /var/log/backup-server.log 2>&1' \
  | sudo tee /etc/cron.d/backup-server

# Проверяем структуру cron-файла
sudo chmod 644 /etc/cron.d/backup-server
sudo cat /etc/cron.d/backup-server

# Тестируем восстановление одного файла в отдельный каталог
sudo mkdir -p /tmp/restic-restore
sudo bash -c 'source /root/.restic-env && restic restore latest --target /tmp/restic-restore --include /etc/crowdsec/config.yaml'

Una copia de seguridad se considera funcional solo después de la restauración. Una vez al mes, cree un VPS temporal o un directorio independiente y compruebe que la configuración se puede leer, que la base de datos se importa y que Docker Compose se inicia con las variables restauradas.

Actualizaciones

CrowdSec, el bouncer y los parsers pueden actualizarse sin detener las aplicaciones de los usuarios, pero cualquier cambio en el firewall siempre debe verificarse. Antes de actualizar, guarde las decisiones y la configuración actuales. Para un solo VPS, es mejor elegir una ventana de mantenimiento breve, especialmente si se actualizan el kernel, Docker o Nginx.

# Сохраняем список установленных пакетов
dpkg-query -W -f='${binary:Package}\t${Version}\n' \
  | sudo tee /var/backups/packages-$(date +%F).txt

# Обновляем пакеты
sudo apt update
sudo apt upgrade -y

# Обновляем коллекции CrowdSec из Hub
sudo cscli hub update
sudo cscli hub upgrade

# Проверяем сервисы после обновления
sudo systemctl --failed
sudo systemctl status crowdsec crowdsec-firewall-bouncer nginx --no-pager

Para varios servidores, utilice un despliegue escalonado: primero actualice un VPS de prueba, revise las métricas y los registros, y después los demás. Una actualización continua solo es posible si hay un segundo reverse proxy o balanceador. Un servidor sin nodo de respaldo requiere una ventana de mantenimiento normal.

9. Solución de problemas y preguntas frecuentes

¿Por qué CrowdSec no detecta eventos SSH?

Compruebe dónde escribe sshd: journalctl -u ssh, /var/log/auth.log u otro archivo. A continuación, ejecute sudo cscli acquisitions list y asegúrese de que la fuente tenga el label correcto. Compruebe los permisos de lectura y reinicie CrowdSec. Si se utiliza journald sin archivo, configure la acquisition para systemd conforme a la documentación de la versión instalada, en lugar de añadir una ruta inexistente.

Se crean decisiones, pero las IP no se bloquean. ¿Qué comprobar?

Primero ejecute sudo cscli bouncers list y asegúrese de que el bouncer esté registrado y tenga un último pull reciente. A continuación, compruebe systemctl status crowdsec-firewall-bouncer y la presencia de cadenas de CrowdSec en nft list ruleset. Una causa frecuente es tener instalada la variante iptables del bouncer en un sistema con nftables. Instale el paquete correcto y compruebe el backend en la configuración del bouncer.

¿Qué configuración de VPS es mínimamente adecuada?

Para un único SSH y un Nginx pequeño, técnicamente bastan 1 vCPU, 1 GB de RAM y 20–30 GB de SSD. El mínimo práctico para Docker y varios servicios es 2 vCPU, 4 GB de RAM y 60 GB de NVMe. Se necesita una IPv4 pública, una red estable y la posibilidad de abrir TCP 22, 80 y 443. Si se prevén una base de datos, compilaciones de CI o contenedores pesados, considere 8 GB de RAM o más.

¿Qué elegir para esta tarea: VPS o dedicated?

Para CrowdSec, SSH, Nginx y varios contenedores, un VPS es suficiente. Dedicated se justifica no por el security stack en sí, sino por una alta carga de aplicaciones, una gran cantidad de RAM, I/O intensivo de disco o el requisito de aislamiento físico. Si el proveedor de VPS ofrece recursos garantizados, un disco independiente y copias de seguridad, será más sencillo y económico de mantener. Elija dedicated ante una carga sostenida, no «por si acaso».

¿Por qué un contenedor Docker es accesible desde Internet aunque el puerto no esté permitido en nftables?

Docker modifica las reglas de forwarding y NAT, por lo que un puerto publicado puede eludir el modelo de filtrado esperado. La mejor solución es no publicar el puerto hacia el exterior: use expose y conecte el contenedor a la red interna del reverse proxy. Si la publicación es obligatoria, añada reglas explícitas a las cadenas de Docker o utilice una arquitectura de firewall independiente, tras probarla previamente en un servidor de pruebas.

¿Cómo eliminar el bloqueo erróneo de mi IP?

Consulte las decisiones con el comando sudo cscli decisions list. Elimine una dirección concreta mediante sudo cscli decisions delete --ip YOUR_IP. Si la dirección vuelve a aparecer, localice la fuente en las métricas y los registros. La causa puede ser un reverse proxy mal configurado: CrowdSec ve la IP del balanceador en lugar de la del cliente, o su monitorización genera demasiadas solicitudes. Configure trusted proxies solo para direcciones conocidas y no confíe en un encabezado X-Forwarded-For arbitrario.

¿Se pueden mantener fail2ban y CrowdSec al mismo tiempo?

Técnicamente sí, pero los mismos SSH-jails generan duplicación y complican la investigación. Para un esquema sencillo, deje CrowdSec como única fuente de bloqueos y desactive fail2ban. El funcionamiento simultáneo se justifica si fail2ban protege un servicio independiente para el que no existe un parser de CrowdSec adecuado. En ese caso, separe los jails, los períodos de bloqueo y las cadenas de firewall; después, documente qué componente responde a cada tipo de evento.

Caddy no emite HTTPS. ¿Qué comprobar?

Asegúrese de que los registros DNS A y AAAA apunten al servidor correcto y de que los puertos 80 y 443 sean accesibles desde el exterior. Si existe AAAA pero IPv6 no está configurado, el cliente ACME puede dirigirse a la dirección incorrecta: corrija temporalmente IPv6 o configúrelo correctamente. Compruebe los registros docker compose logs caddy, asegúrese de que ningún otro proceso haya ocupado los puertos y no ejecute simultáneamente un Nginx externo y Caddy en el mismo socket.

El disco se llena rápidamente de registros. ¿Cómo solucionarlo?

Compruebe el tamaño de los directorios con los comandos sudo du -xhd1 /var/log /var/lib/docker. Configure logrotate para Nginx, los límites de Docker max-size y max-file, así como la retención para journald. No elimine manualmente los registros activos: tras la rotación, envíe un reload al servicio. A continuación, compruebe que CrowdSec lee el nuevo archivo y no ha perdido la posición después de la rotación.

10. Conclusiones y próximos pasos

Esquema: 10. Conclusiones y próximos pasos
Esquema: 10. Conclusiones y próximos pasos

En el VPS ya funcionan el engine de CrowdSec, los escenarios para SSH y Nginx, firewall-bouncer sobre nftables y servicios Docker controlados. El acceso por SSH está limitado a claves, el tráfico web pasa por un reverse proxy y las configuraciones y los datos están preparados para realizar copias de seguridad.

El siguiente paso es conectar la monitorización de métricas y realizar periódicamente pruebas de restauración. A medida que aumente la carga, traslade las bases de datos y las aplicaciones a nodos independientes y, si dispone de varios VPS, utilice registros centralizados y un proceso de actualización unificado.

  1. Compruebe los false positive con tráfico real y añada excepciones solo para redes de confianza.
  2. Configure staged updates, backup externo y una prueba mensual de disaster recovery.
  3. Para varios dominios o servidores, añada un WAF/CDN externo sin sustituir con él la protección local de CrowdSec.

¿Te fue útil esta guía?

Tus comentarios nos ayudan a mejorar nuestras guías.

Compartir esta publicación:

Envía esta guía a alguien a quien pueda resultarle útil.

Telegram VKVK WhatsApp Facebook LinkedIn XX

crowdsec en vps: fail2ban colectivo para ssh, nginx y docker
support_agent
Valebyte Support
Usually replies within minutes
Hi there!
Send us a message and we'll reply as soon as possible.