General Cajón de sastre técnico: cosas que uso, pero no lo bastante como para crearles un libro exclusivo (todavía). AdguardHome Sincronizar los nodos de Tailscale con AdGuardHome manteniendo una resolución DNS funcional Este apunte documenta cómo sincronizar los nodos de Tailscale con AdGuardHome para mantener una resolución DNS funcional, incluso si desactivamos el DNS interno de Tailscale o modificamos el resolv.conf. Todo esto es aplicable a Headscale también, que es lo que uso actualmente. Características Añade automáticamente los dominios e IPs de Tailscale a AdGuardHome. Evita depender del DNS de Tailscale si lo hemos desactivado o modificado. Permite resolver nombres .lan.internal ( o el dominio que actualmente uses ) desde cualquier equipo local. Compatible con instancias de AdGuard en Docker. Requisitos previos Tailscale debe estar operativo y configurado. AdGuardHome debe estar funcionando y accesible. Tener acceso al archivo AdGuardHome.yaml (aunque AdGuard esté en contenedor). Tener instalado jq. Funcionamiento del script El script SyncTailGuard.sh realiza lo siguiente: Ejecuta tailscale status --json para obtener todos los peers. Extrae cada nombre DNS ( DNSName) y su primera IP ( TailscaleIPs[0]). Crea una sección rewrites: con todos los nombres e IPs: rewrites: - domain: tablet01.lan.internal answer: 100.100.100.11 - domain: pc-home.lan.internal answer: 100.100.100.5 Sustituye la sección rewrites: del YAML real de AdGuard. Reinicia el contenedor con docker restart. Esto asegura que cualquier equipo en tu red que use AdGuard pueda resolver automáticamente todos los nodos de Tailscale. Comprobaciones útiles Resolución DNS: dig tablet01.lan.internal @192.168.1.5 Conectividad: ping pc-home.lan.internal Validación DNSSEC (si tienes upstreams compatibles): dig +dnssec +multi sigok.verteiltesysteme.net El flag ad en la respuesta indica que la validación es correcta. Errores comunes o decisiones importantes El script sobreescribe la sección rewrites: completa. Si tienes entradas personalizadas, debes reinyectarlas después. Si usas múltiples contenedores de AdGuard, deberás adaptar el script para repetir el proceso en cada uno. No hace validaciones de si AdGuard está en ejecución antes de reiniciar. Resumen breve Ejecuta el script para sincronizar nombres e IPs de Tailscale con AdGuard. Comprueba con dig o ping que la resolución funciona. Evita depender del DNS de Tailscale si modificas el resolv.conf. Script disponible en Gitea: SyncTailGuard.sh Ansible Actualización de varios servidores con Ansible usando Vault Automatiza la actualización de paquetes en varios servidores usando Ansible y Ansible Vault para gestionar contraseñas de forma segura. Paso 1: Crear el inventario ( ansihosts) Define los servidores que vas a administrar: [servers] server1 ansible_host=192.0.2.1 ansible_user=myuser server2 ansible_host=192.0.2.2 ansible_user=myuser Paso 2: Crear host_vars protegidos con Vault mkdir host_vars ansible-vault create host_vars/server1.yml Contenido ejemplo: ansible_ssh_pass: "password123" ansible_become_pass: "rootpassword" Repite para cada servidor: ansible-vault create host_vars/server2.yml Paso 3: Crear el playbook ( update.yml) - name: Update and upgrade using nala hosts: all become: yes tasks: - name: Run nala update and upgrade shell: nala update && nala upgrade -y register: nala_output - name: Show output of nala update and upgrade debug: var: nala_output.stdout Si no usas nala, cambia por apt-get update && apt-get upgrade -y. Paso 4: Ejecutar el playbook ansible-playbook -i ansihosts update.yml --ask-vault-pass Paso 5: Salida detallada (verbose) ansible-playbook -i ansihosts update.yml --ask-vault-pass --vvv Salida esperada PLAY [Update and upgrade using nala] ******************************* TASK [Gathering Facts] ********************************************* ok: [server1] ok: [server2] TASK [Run nala update and upgrade] ******************************** changed: [server1] changed: [server2] TASK [Show output of nala update and upgrade] ********************** ok: [server1] => { "nala_output.stdout": "All packages are up to date." } ok: [server2] => { "nala_output.stdout": "All packages are up to date." } PLAY RECAP ********************************************************* server1 : ok=3 changed=1 unreachable=0 failed=0 server2 : ok=3 changed=1 unreachable=0 failed=0 Extras útiles Automatizar el uso de Vault (opcional) Crear archivo con la contraseña: echo "contraseña" > ~/.ansible_vault_key chmod 600 ~/.ansible_vault_key Configurar ansible.cfg: [defaults] vault_password_file = ~/.ansible_vault_key Añadir más servidores Edita el archivo ansihosts. Crea nuevos archivos en host_vars/ y protégelos con Vault. Modificar el playbook Puedes adaptarlo para tareas adicionales, no solo actualizaciones. Sobre el verbose ( -v, -vv, --vvv) Usa --vvv para depurar comportamientos inesperados. Seguridad Protege siempre las contraseñas y datos sensibles con Vault u otro sistema seguro. Nota personal Uso este sistema con mi servidor principal y una Raspberry Pi. Aunque es un setup sencillo, me ahorra tiempo en tareas rutinarias. Es especialmente útil si gestionas varios servidores. Crowdsec Forzar instalación de CrowdSec 1.6.x en Ubuntu (saltando la versión antigua) Introducción CrowdSec ofrece un script de instalación automática para sistemas Linux, pero por defecto instala una versión antigua (1.4.6 en el momento de escribir esto). Este apunte documenta cómo forzar la instalación de la última versión estable (1.6.11) usando el propio repositorio oficial y una pinning policy para evitar que APT use los paquetes de Ubuntu. El script oficial de instalación funciona correctamente, pero al no modificar las prioridades de APT, termina instalando una versión antigua desde los repos de Ubuntu. Requisitos previos Ubuntu 22.04 o 24.04 Acceso root o sudo Tener instalado curl y apt configurado correctamente Instalación paso a paso 1. Ejecutar el script oficial Esto añade el repositorio de packagecloud.io a tu sistema: curl -s https://install.crowdsec.net | sudo sh 2. Comprobar las versiones disponibles apt list -a crowdsec apt-cache policy crowdsec Esto mostrará todas las versiones accesibles y su prioridad. 3. Eliminar versiones anteriores (si existieran) sudo systemctl stop crowdsec sudo apt purge crowdsec crowdsec-firewall-bouncer-iptables -y sudo apt clean && sudo apt update 4. Forzar APT a usar la versión del repo de CrowdSec Crear archivo de preferencias: sudo nano /etc/apt/preferences.d/crowdsec Y añadir: Package: crowdsec Pin: origin "packagecloud.io" Pin-Priority: 1001 Esto le dice a APT que si hay una versión de packagecloud.io, la instale aunque haya otra con más prioridad. 5. Instalar CrowdSec sudo apt update sudo apt install crowdsec 6. Verificar que se ha instalado la versión correcta apt-cache policy crowdsec El Candidate debe ser la versión 1.6.x Errores comunes o decisiones importantes El script oficial no falla, pero sin el pinning instala una versión antigüa. Hay que purgar el paquete si se ha instalado previamente desde los repos de Ubuntu. Pin-Priority: 1001 es lo que fuerza el cambio. Recuerda que Pin-Priority: 1001 solo tiene sentido si el origen coincide exactamente con el origin que marca apt-cache policy. Resumen breve El script de CrowdSec instala el repo, pero no cambia prioridades. APT usará por defecto la versión antigua de Ubuntu. El pinning manual permite forzar la instalación de la versión más reciente. Notas personales No hace falta modificar sources.list: todo se resuelve con pinning. Referencias Instalación oficial de CrowdSec Lectura de logs de Caddy con CrowdSec Reducir el tamaño de los logs de Caddy con log_skip para Crowdsec Lectura de logs de Caddy con CrowdSec Este apunte documenta la integración de logs generados por Caddy en formato JSON para que CrowdSec pueda analizarlos y actuar en consecuencia. Características Detecta patrones maliciosos en los accesos a nuestros dominios. Permite decisiones automáticas (baneo temporal, alerta, etc.). Compatible con la consola web de CrowdSec. Requisitos previos CrowdSec ya debe estar instalado y enrolado en la consola. Tener Caddy instalado y configurado. Tener instalado crowdsec-firewall-bouncer. Protección activa con IPTables Para que CrowdSec no solo detecte, sino también bloquee activamente intentos de escaneo o accesos maliciosos, es necesario instalar un bouncer de firewall. En sistemas basados en IPTables: sudo apt install crowdsec-firewall-bouncer-iptables Una vez instalado, comenzará a aplicar baneos automáticamente en función de las decisiones que tome CrowdSec. Esto incluye escaneos de puertos, rutas forzadas, comportamientos anómalos, etc. Configuración de CrowdSec Actualizar e instalar el parser necesario: sudo cscli parsers upgrade --all sudo cscli parsers install crowdsecurity/caddy-logs sudo systemctl reload crowdsec Configuración de Caddy Opcion global en el Caddyfile Define un log global en formato JSON: { log { output file /var/log/caddy/crowdsec.json { roll_size 512mb roll_keep 10 roll_keep_for 240h } format json level INFO } } Directiva reutilizable para logs por sitio (log_json_global) { log { output file /var/log/caddy/crowdsec-global.json format json level INFO } } Luego, en cada sitio: midominio.com { import log_json_global ... } Configurar acquis.yaml en CrowdSec Indicar el archivo de logs que se va a parsear: --- filenames: - /var/log/caddy/crowdsec.json labels: type: caddy Si usas otro nombre o ruta, adáptalo aquí. Aplicar cambios: sudo systemctl restart crowdsec sudo systemctl restart caddy Verificación Pasados unos minutos, confirmar que CrowdSec está leyendo el log: sudo cscli metrics Deberías ver líneas relacionadas con /var/log/caddy/crowdsec.json. Si no aparecen, revisa permisos o formato del log. Errores comunes o decisiones importantes En versiones antiguas de CrowdSec (como la 1.4.6), este parser no funcionaba bien. La versión 1.6.11 ya lo interpreta sin problemas. Puede tardar bastante en detectar comportamientos anómalos (a veces horas). Resumen breve Instalar parser crowdsecurity/caddy-logs. Configurar logs en JSON desde Caddy. Añadir el log a acquis.yaml. Verificar con cscli metrics que se está leyendo. Revisar la consola de CrowdSec para ver decisiones aplicadas. Notas personales En mi caso, tardó un par de horas en empezar a detectar cosas tras configurar todo, detectó actividad maliciosa desde IPs de Censys y aplicó baneo temporal. Esta configuración es especialmente útil si usas Caddy como proxy público y quieres respuestas automáticas ante escaneos o comportamientos raros. Dependiendo del dominio y el tráfico que reciba, puede generarse mucho ruido en los logs y hacer crecer el archivo rápidamente. Para eso se puede usar la directiva log_skip de Caddy para evitar registrar rutas que no aporten nada (como /favicon.ico, /robots.txt, assets estáticos, etc). Se realizará otro artículo para explicar bien cómo usar log_skip de forma eficiente, y cuando esté listo se enlazará desde aquí. La opción global del Caddyfile para el log, la directiva reutilizable para logs por sitio y también la directiva para evitar ruido mediante log_skip están disponibles en mi Gitea: Caddyfile en Gitea. Como se ha comentado, también se creará un artículo sobre esto y se enlazará en esta mismo artículo ( ya disponible ). Enlaces de interés Forzar instalación de CrowdSec 1.6.x en Ubuntu saltando la versión antigua Reducir el tamaño de los logs de Caddy con log_skip para Crowdsec Información sobre caddy-logs Firewall Bouncer oficial de CrowdSec (iptables) Recibir alertas de Crowdsec en Telegram Este apunte documenta cómo enviar notificaciones automáticas por Telegram cuando CrowdSec bloquea una IP, usando el plugin http de notificaciones. Es altamente recomendable tener previamente configurada la integración de logs de Caddy con CrowdSec: Lectura de logs de Caddy con CrowdSec Requisitos previos Tener CrowdSec instalado y funcionando correctamente. Haber registrado la instancia en la consola de CrowdSec (opcional, pero recomendable). Tener ya bloqueos activos o simulables para hacer pruebas. Se asume que tenemos un bot de Telegram ya creado y listo. Activar permisos para el plugin HTTP Edita el archivo /etc/crowdsec/config.yaml de CrowdSec. Aquí es donde CrowdSec define los usuarios y permisos bajo los que se ejecutan los distintos plugins, incluyendo el de notificaciones. Si los permisos son demasiado restrictivos (como es el caso por defecto), algunos plugins no podrán escribir en disco ni acceder a los sockets necesarios para operar correctamente. Este es un fallo habitual que puede bloquear la funcionalidad de alertas, especialmente en entornos donde se espera que el plugin HTTP se comunique con servicios externos como Telegram. plugin_config: user: root group: root Por defecto viene como nobody, pero eso genera errores de permisos al validar la config del plugin HTTP. Configurar el plugin HTTP para Telegram Edita o crea el archivo /etc/crowdsec/notifications/http.yaml. Si quieres usar una plantilla con formato limpio para Telegram, puedes partir de la siguiente: http.yaml de ejemplo en Gitea Este archivo incluye el formato del mensaje y los datos necesarios para enviarlo (token, chat_id, etc.). Activar la notificación en profiles.yaml Edita /etc/crowdsec/profiles.yaml y asegúrate de habilitar la notificación en ambos perfiles ( default_ip_remediation y default_range_remediation). Busca y modifica esta sección: notifications: - http_default Asegúrate de que coincida con el nombre definido en el http.yaml. Si has cambiado el nombre por otro, usa ese. Validar y probar que todo funciona Verifica la configuración: sudo crowdsec -t Prueba manualmente la notificación: sudo cscli notifications test http_default Si todo está correcto, deberías recibir el mensaje en tu bot, canal o grupo de Telegram. Comprobarlo con un ataque real Puedes simular un ataque desde otro dispositivo (por ejemplo con Termux + VPN y dirb) para generar un baneo real. En cuanto se active el baneo, deberías recibir la alerta en Telegram con un formato como este: 🚨 CrowdSec Alert 🌐 IP: 66.232.126.83 🏳️ País: US 🏢 ISP: AS29802 - HVC-AS 🧠 Motivo: crowdsecurity/http-probing 🕰️ Duración: 4h 📅 Hora: 2025-07-25T20:03:05Z 📍 Host: TuEquipo 🗞 Máquina: TuMaquina 🔗 CrowdSec CTI (https://app.crowdsec.net/cti/66.232.126.83) Errores comunes o decisiones importantes Permisos insuficientes: si dejas nobody, el plugin HTTP no podrá ejecutarse. Nombre del perfil mal escrito: el nombre http_default debe coincidir en http.yaml y profiles.yaml. Validar siempre con crowdsec -t antes de probar con ataques reales. Resumen breve Cambiar nobody por root en config.yaml. Configurar /etc/crowdsec/notifications/http.yaml para Telegram. Activar http_default en ambos perfiles de profiles.yaml. Validar con sudo crowdsec -t y testear con cscli notifications test. Probar con un ataque real para verificar que todo llega correctamente. Enlaces de interés Forzar instalación de CrowdSec 1.6.x en Ubuntu saltando la versión antigua Reducir el tamaño de los logs de Caddy con log_skip para CrowdSec Lectura de logs de Caddy con CrowdSec Documentación oficial de CrowdSec - Telegram plugin Reducir el tamaño de los logs de Caddy con log_skip para Crowdsec Este apunte sirve para analizar el log de Caddy y reducir su tamaño omitiendo rutas que generan mucho ruido pero no aportan valor en el análisis de seguridad con CrowdSec. Características Analiza el log de Caddy en formato JSON. Identifica las rutas con mayor frecuencia de acceso. Permite decidir qué rutas ignorar en el log usando log_skip. Requisitos previos Tener configurado Caddy para generar logs en formato JSON. Haber integrado CrowdSec con Caddy (ver artículo anterior). Acceso al archivo /var/log/caddy/crowdsec.json o equivalente. Identificar rutas ruidosas Se puede usar el siguiente script en Python para encontrar las URIs más repetidas: import json from collections import Counter archivo = "/var/log/caddy/crowdsec.json" uris = [] with open(archivo) as f: for linea in f: try: entrada = json.loads(linea) uri = entrada["request"]["uri"].split("?")[0] uris.append(uri) except Exception: continue # Mostrar los 20 URI más frecuentes for uri, count in Counter(uris).most_common(20): print(f"{count:>5} - {uri}") Esto permite saber qué endpoints consumen más espacio en el log. Algunos ejemplos comunes (anonimizados) podrían ser: 7180 - / 2731 - /api/sync 1126 - /remote.php/dav/files/usuario/ 554 - /login 392 - /manifest.json 200 - /favicon.ico Aplicar log_skip en Caddy Una vez identificadas las rutas que solo generan ruido, se puede usar la directiva log_skip en el Caddyfile. Esta directiva se encarga de evitar que esas rutas se escriban en el log, aunque se sigan sirviendo normalmente. Para usarla: Visita el repositorio donde se encuentra definida: Directiva log_skip en Gitea Impórtala en los sitios donde se desee reducir el ruido. Reinicia Caddy: sudo systemctl restart caddy Orden de los imports: clave para que funcione Primero se debe importar el snippet que configura el logger ( log_json_global), y luego el que contiene los filtros con log_skip ( log_ignore_ruido_common). Si lo haces al revés, puede que log_skip no tenga ningún logger al que aplicarse. Eso significa que o no se ignora nada, o se ignora en el logger por defecto (stdout). Y eso lleva a confusión o a falsos positivos al revisar los logs. En resumen: Orden ¿Qué hace? import log_json_global Declara el logger personalizado con formato, ruta, etc. import log_ignore_ruido_common Añade excepciones (rutas ignoradas) a ese logger ya activo. Mantener ese orden asegura que el log_skip actúa sobre el logger correcto. Verificación del efecto Puedes comprobar el tamaño de los logs con: ls -lh /var/log/caddy/ En pruebas reales, el uso de esta directiva ha reducido de 70 MB en dos horas a 30 MB en casi 10 horas. La diferencia es muy considerable, sobre todo si se trata de evitar escrituras innecesarias en disco. Resumen breve Usa un script para encontrar las rutas más frecuentes. Define una directiva log_skip con esas rutas. Aplícala a tus sitios en Caddy usando import. Borrar o rotar los logs actuales para comprobar bien la reducción. Reinicia Caddy y verifica el efecto. Enlaces de interés Caddyfile en Gitea con directiva log_skip Lectura de logs de Caddy con CrowdSec Forzar instalación de CrowdSec 1.6.x en Ubuntu saltando la versión antigua IPTables Restablecer conexión de SMB Estas reglas permiten la comunicación de SMB en los puertos estándar, tanto para TCP como para UDP: iptables -A INPUT -p tcp --dport 137 -j ACCEPT iptables -A INPUT -p tcp --dport 138 -j ACCEPT iptables -A INPUT -p tcp --dport 139 -j ACCEPT iptables -A INPUT -p tcp --dport 445 -j ACCEPT iptables -A INPUT -p udp --dport 137 -j ACCEPT iptables -A INPUT -p udp --dport 138 -j ACCEPT iptables -A INPUT -p udp --dport 139 -j ACCEPT iptables -A INPUT -p udp --dport 445 -j ACCEPT Wireguard: Permitir acceso a la red LAN Si los clientes de WireGuard no pueden acceder a la red local, esta regla permite la traducción de direcciones (NAT) para solucionar el problema. Asegúrate de ajustar las direcciones IP a tu configuración específica. sudo iptables -t nat -A POSTROUTING -s 100.100.0.0/24 -d 192.168.10.0/24 -j MASQUERADE SonarQube Solucionar el modo mantenimiento de SonarQube Si alguna vez SonarQube entra automáticamente en modo mantenimiento, no te preocupes. Es un problema que se resuelve fácilmente siguiendo estos pasos: Pasos para actualizar la base de datos Accede a la URL de tu instancia de SonarQube Abre tu navegador y dirígete a la URL donde tengas configurada tu instancia. Si no conoces la dirección exacta, reemplaza ip_servidor y puerto con los datos de tu instalación. Un ejemplo genérico sería: http://ip_servidor:puerto Añade /setup a la URL Para iniciar el proceso de actualización, añade /setup al final de la URL y presiona Enter. El resultado debería lucir algo así: http://ip_servidor:puerto/setup Inicia la actualización de la base de datos En la página que aparece, haz clic en la opción para actualizar las bases de datos. Espera a que finalice el proceso Cuando el proceso termine, SonarQube debería salir del modo mantenimiento y volver a estar completamente funcional. Notas adicionales Este ejemplo asume que tu instalación de SonarQube está en Docker. Si aún no tienes SonarQube instalado en Docker, puedes revisar la guía de instalación en Docker en esta entrada de la wiki. Asegúrate de que no haya interrupciones (como reinicios del contenedor) durante la actualización.