Autor: Francisco

  • Administración de permisos para Tomcat en Linux

    Contexto

    Tomcat instalado manualmente en /opt/tomcat, con el servicio configurado para ejecutarse bajo un usuario y grupo dedicados:

    [Service]
    User=tomcat
    Group=tomcat
    
    Environment="CATALINA_BASE=/opt/tomcat"
    Environment="CATALINA_HOME=/opt/tomcat"

    El usuario tomcat debe tener control sobre los archivos necesarios para ejecutar la aplicación, generar logs y trabajar con directorios temporales.

    1. Cómo agregar la «s» en permisos de directorios

    Para obtener algo como drwxrwsr-x, hay que activar el bit setgid:

    chmod g+s /opt/tomcat

    Verificación:

    ls -ld /opt/tomcat
    drwxrwsr-x tomcat tomcat /opt/tomcat

    ¿Qué hace el bit setgid?

    Cuando un directorio tiene setgid:

    • Los archivos creados dentro heredan el grupo del directorio padre.
    • Evita problemas cuando varios usuarios despliegan archivos.
    • Muy útil para directorios compartidos.
    2775 drwxrwsr-x tomcat:tomcat /opt/tomcat

    El 2 inicial representa el bit setgid.

    2. Problema al reconectar una sesión Screen

    Comando ejecutado:

    screen -r 1560987.pts-0.servidor-app

    Error:

    There is a screen on:
        1560987.pts-0.servidor-app (Attached)
    
    There is no screen to be resumed matching 1560987.pts-0.servidor-app.

    Causa

    La sesión ya está conectada desde otra terminal.

    Solución

    Forzar el detach y reconectar:

    screen -d -r 1560987.pts-0.servidor-app

    Ver sesiones activas:

    screen -ls

    3. Permisos recomendados para Tomcat

    Propietario

    chown -R tomcat:tomcat /opt/tomcat

    Directorios

    find /opt/tomcat -type d -exec chmod 750 {} \;

    Resultado: drwxr-x---

    Archivos

    find /opt/tomcat -type f -exec chmod 640 {} \;

    Resultado: -rw-r-----

    Scripts ejecutables

    find /opt/tomcat/bin -type f -name "*.sh" -exec chmod 750 {} \;

    Resultado: -rwxr-x---

    4. Permisos recomendados por directorio

    Directorio raíz

    chmod 2755 /opt/tomcat

    Resultado: drwxr-sr-x. Mantiene el grupo heredado, permite navegación, evita escrituras accidentales.

    Configuración

    chmod -R 750 /opt/tomcat/conf

    Protege archivos como server.xml, context.xml, tomcat-users.xml y logging.properties.

    Logs

    chmod -R 750 /opt/tomcat/logs

    Tomcat necesita crear, modificar y rotar logs.

    Directorios temporales

    chmod -R 750 /opt/tomcat/temp
    chmod -R 750 /opt/tomcat/work

    Tomcat escribe ahí JSP compilados, archivos temporales y cachés.

    Aplicaciones

    chmod -R 750 /opt/tomcat/webapps

    Tomcat debe leer los WAR, desplegar aplicaciones y puede generar archivos de trabajo.

    5. Script para generar reporte de permisos

    Guarda todos los permisos actuales en el home del usuario:

    #!/bin/bash
    
    OUTPUT="$HOME/permisos_tomcat.txt"
    
    echo "Fecha de generación: $(date)" > "$OUTPUT"
    echo "--------------------------------------------------" >> "$OUTPUT"
    
    find /opt/tomcat -printf '%M %u %g %p\n' | while read perms user group path
    do
        octal=$(stat -c "%a" "$path")
        echo "$octal $perms $user:$group $path" >> "$OUTPUT"
    done
    
    echo "Reporte guardado en: $OUTPUT"
    chmod +x ver_permisos.sh
    ./ver_permisos.sh

    6. Hallazgos típicos en un servidor real

    Correcto

    2775 drwxrwsr-x tomcat:tomcat /opt/tomcat
    2775 drwxrwsr-x tomcat:tomcat /opt/tomcat/work

    El uso de setgid es adecuado.

    Problema 1: logs con 777

    777 drwxrwxrwx tomcat:tomcat /opt/tomcat/logs

    Riesgo: cualquier usuario del servidor puede crear archivos, modificar logs o borrar información.

    Corrección:

    chmod 750 /opt/tomcat/logs

    Problema 2: catalina.out con propietario incorrecto

    640 -rw-r----- otrouser:otrouser /opt/tomcat/logs/catalina.out

    Riesgo: Tomcat puede fallar al escribir.

    Corrección:

    chown tomcat:tomcat /opt/tomcat/logs/catalina.out

    Problema 3: aplicación desplegada por otro usuario

    Es común encontrar una aplicación bajo /opt/tomcat/webapps/ con propietario distinto a tomcat, cuando otro usuario es quien la despliega. No es necesariamente incorrecto, pero Tomcat debe tener acceso de lectura y debe existir coherencia en los permisos.

    Opción A (más simple):

    chown -R tomcat:tomcat /opt/tomcat/webapps/nombre-app

    Opción B (si otro usuario despliega): agregarlo al grupo tomcat:

    usermod -aG tomcat usuario_deploy

    Y mantener:

    chmod -R 775 /opt/tomcat/webapps/nombre-app
    chmod g+s /opt/tomcat/webapps/nombre-app

    7. Configuración recomendada para producción

    chown -R tomcat:tomcat /opt/tomcat
    
    chmod 2755 /opt/tomcat
    
    chmod -R 750 /opt/tomcat/conf
    chmod -R 750 /opt/tomcat/logs
    chmod -R 750 /opt/tomcat/temp
    chmod -R 750 /opt/tomcat/work
    chmod -R 750 /opt/tomcat/webapps
    
    find /opt/tomcat/bin -name "*.sh" -exec chmod 750 {} \;

    Regla práctica

    • Directorios: 750
    • Archivos: 640
    • Scripts: 750
    • Directorios compartidos: 2775
    • Nunca usar 777 salvo casos excepcionales y temporales.
    • Mantener propietario tomcat:tomcat en todo aquello que Tomcat necesite escribir.

  • Montando mi propio relay Nostr en el homelab

    Por qué Nostr

    Nostr es un protocolo descentralizado de comunicación: en lugar de depender de un servidor central que controla quién publica y quién no, cualquiera puede correr su propio relay, un nodo que almacena y retransmite mensajes firmados criptográficamente. Quería entender el protocolo desde dentro, no solo leyendo sobre él, así que decidí montar mi propio relay en el homelab.

    Primer intento: la imagen oficial

    Empecé probando con un docker compose up directo, esperando que la imagen pre-construida funcionara sin más. No fue tan simple. Después de varios intentos de ajustar el config.toml y recrear el contenedor, terminé optando por compilar el proyecto desde el código fuente:

    git clone https://github.com/scsibug/nostr-rs-relay.git
    cd nostr-rs-relay
    docker build -t nostr-rs-relay .

    Compilar desde fuente me dio más control sobre la configuración y el Dockerfile, a costa de un par de horas extra de prueba y error con el archivo de configuración y el build.

    El docker-compose.yml final

    Después de resolver el build, el archivo de composición quedó simple, montando la configuración y la base de datos SQLite como volúmenes:

    services:
      nostr:
        image: nostr-rs-relay:latest
        container_name: nostr
        command: ["./nostr-rs-relay", "--config", "/etc/nostr-rs-relay/config.toml"]
        volumes:
          - ./config.toml:/etc/nostr-rs-relay/config.toml
          - ./nostr.db:/app/nostr.db
        ports:
          - "8080:8080"
        restart: unless-stopped

    El relay guarda los eventos en una base de datos SQLite local (nostr.db), y la configuración del relay (nombre, descripción, límites) vive en config.toml, montado como volumen externo para poder editarlo sin reconstruir la imagen.

    Publicando el relay sin abrir puertos

    Como con el resto de mis servicios, no quería abrir puertos en el router. Usé Cloudflare Tunnel, dedicado exclusivamente a este servicio:

    cloudflared tunnel create nostr-relay
    cloudflared tunnel route dns nostr-relay relay.inforsupports.com

    Esto deja el relay accesible desde internet en wss://relay.inforsupports.com, sin exponer la IP del homelab ni el puerto 8080 directamente.

    Verificando que funciona de verdad

    No basta con que el contenedor corra, hay que confirmar que el relay realmente responde al protocolo y que otros nodos lo pueden descubrir. Un par de comandos útiles:

    curl -H "Accept: application/nostr+json" https://relay.inforsupports.com

    Esto debe devolver la información del relay en formato NIP-11. También revisé que apareciera listado en directorios públicos como nostr.watch, lo cual confirma que el relay es visible y alcanzable desde la red Nostr en general.

    Lo que me llevo de este experimento

    Más allá del protocolo en sí, este ejercicio fue un recordatorio de algo que aplica a cualquier infraestructura: lo que importa no es que algo «encienda», sino poder verificar que funciona correctamente desde afuera. Entre compilar desde fuente, depurar el config.toml y confirmar la visibilidad pública, el camino tuvo más curvas de las que esperaba, pero terminó siendo una buena forma de aprender el protocolo de punta a punta.

    Si tienes un cliente Nostr y quieres probarlo, el relay sigue activo en wss://relay.inforsupports.com.