STABLE: Reconstrucción integral de infraestructura, limpieza de middlewares obsoletos y blindaje de Traefik
This commit is contained in:
@@ -1,8 +1,12 @@
|
|||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# GITEA - CONFIGURACIÓN DE PRODUCCIÓN PARA SYNOLOGY DSM
|
# GITEA - CONFIGURACIÓN DE PRODUCCIÓN (REVISIÓN DE SEGURIDAD)
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# Este servicio corre bajo el UID 1032 y GID 100 gestionado internamente por s6.
|
# - Identidad: Ejecución bajo UID 1032 / GID 100 (Estándar OgnirNAS).
|
||||||
# Se conecta a Traefik v3 a través de la red interna de servicios.
|
# - Red: Conectado a 'services-internal-net' para aislamiento Bridge.
|
||||||
|
# - Traefik v3:
|
||||||
|
# * Se utiliza 'security-headers@file' (Middleware dinámico actualizado).
|
||||||
|
# * Vinculación explícita router-servicio para evitar estados 'disabled'.
|
||||||
|
# * Resolución de certificados vía Let's Encrypt.
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
|
|
||||||
version: "3.9"
|
version: "3.9"
|
||||||
@@ -13,29 +17,35 @@ services:
|
|||||||
container_name: gitea
|
container_name: gitea
|
||||||
restart: always
|
restart: always
|
||||||
networks:
|
networks:
|
||||||
- services-internal-net # Red compartida con el Proxy
|
- services-internal-net
|
||||||
volumes:
|
volumes:
|
||||||
- /volume1/docker/data/gitea:/data # Persistencia de datos, SSH y DB
|
- /volume1/docker/data/gitea:/data
|
||||||
environment:
|
environment:
|
||||||
# IDs de usuario confirmados para evitar conflictos de permisos en el NAS
|
|
||||||
- USER_UID=1032
|
- USER_UID=1032
|
||||||
- USER_GID=100
|
- USER_GID=100
|
||||||
- TZ=Europe/Madrid
|
- TZ=Europe/Madrid
|
||||||
# URL externa para evitar el redireccionamiento a localhost:3000
|
|
||||||
- GITEA__server__ROOT_URL=https://gitea.ognir-server.synology.me/
|
- GITEA__server__ROOT_URL=https://gitea.ognir-server.synology.me/
|
||||||
- GITEA__database__DB_TYPE=sqlite3
|
- GITEA__database__DB_TYPE=sqlite3
|
||||||
labels:
|
labels:
|
||||||
- "traefik.enable=true"
|
- "traefik.enable=true"
|
||||||
# Enrutamiento mediante Host
|
|
||||||
|
# --- Configuración del Router ---
|
||||||
- "traefik.http.routers.gitea.rule=Host(`gitea.ognir-server.synology.me`)"
|
- "traefik.http.routers.gitea.rule=Host(`gitea.ognir-server.synology.me`)"
|
||||||
- "traefik.http.routers.gitea.entrypoints=websecure"
|
- "traefik.http.routers.gitea.entrypoints=websecure"
|
||||||
- "traefik.http.routers.gitea.tls=true"
|
- "traefik.http.routers.gitea.tls=true"
|
||||||
- "traefik.http.routers.gitea.tls.certresolver=letsencrypt"
|
- "traefik.http.routers.gitea.tls.certresolver=letsencrypt"
|
||||||
# Forzamos a Traefik a usar la red interna para evitar errores de gateway
|
|
||||||
- "traefik.docker.network=services-internal-net"
|
# --- Vinculación Router-Service ---
|
||||||
|
# Define el destino explícito para habilitar el router en el Dashboard.
|
||||||
|
- "traefik.http.routers.gitea.service=gitea"
|
||||||
|
|
||||||
|
# --- Configuración del Servicio (Backend) ---
|
||||||
- "traefik.http.services.gitea.loadbalancer.server.port=3000"
|
- "traefik.http.services.gitea.loadbalancer.server.port=3000"
|
||||||
# Uso del middleware de seguridad definido en el proveedor de archivos (@file)
|
- "traefik.docker.network=services-internal-net"
|
||||||
- "traefik.http.routers.gitea.middlewares=seguridad-general@file"
|
|
||||||
|
# --- Middlewares ---
|
||||||
|
# Se actualiza de 'seguridad-general' a 'security-headers' según el inventario dinámico.
|
||||||
|
- "traefik.http.routers.gitea.middlewares=security-headers@file"
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
services-internal-net:
|
services-internal-net:
|
||||||
|
|||||||
@@ -1,9 +1,18 @@
|
|||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# TRAEFIK V3 - INFRAESTRUCTURA COMPLETA (OGNIRNAS)
|
# OGNIRNAS - INFRAESTRUCTURA CORE: TRAEFIK V3 & DOCKER-SOCKET-PROXY
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
|
# Última revisión: 2026-01-06
|
||||||
|
# Propietario: Ognir (UID 1032 / GID 100)
|
||||||
|
# Objetivo: Reverse Proxy con autenticación reforzada y aislamiento del socket.
|
||||||
|
# ==============================================================================
|
||||||
|
|
||||||
version: "3.9"
|
version: "3.9"
|
||||||
|
|
||||||
services:
|
services:
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
# SERVICE: traefik-socket-proxy
|
||||||
|
# Capa de seguridad que evita el acceso directo de Traefik al socket de Docker.
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
traefik-socket-proxy:
|
traefik-socket-proxy:
|
||||||
image: tecnativa/docker-socket-proxy:latest
|
image: tecnativa/docker-socket-proxy:latest
|
||||||
container_name: traefik-socket-proxy
|
container_name: traefik-socket-proxy
|
||||||
@@ -18,45 +27,54 @@ services:
|
|||||||
- SERVICES=1
|
- SERVICES=1
|
||||||
- VERSION=1
|
- VERSION=1
|
||||||
- EVENTS=1
|
- EVENTS=1
|
||||||
- CONNECT_TIMEOUT=30
|
|
||||||
- SERVER_TIMEOUT=30
|
|
||||||
- CLIENT_TIMEOUT=30
|
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
# SERVICE: traefik (v3.0)
|
||||||
|
# Orquestador principal. Gestiona TLS y Dashboard seguro.
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
traefik:
|
traefik:
|
||||||
image: traefik:v3.0
|
image: traefik:v3.0
|
||||||
container_name: traefik
|
container_name: traefik
|
||||||
restart: always
|
restart: always
|
||||||
user: "1032:100"
|
user: "1032:100" # Ejecución bajo el usuario Ognir para permisos de archivos
|
||||||
depends_on:
|
depends_on:
|
||||||
traefik-socket-proxy:
|
traefik-socket-proxy:
|
||||||
condition: service_started
|
condition: service_started
|
||||||
labels:
|
|
||||||
- "traefik.enable=true"
|
|
||||||
- "traefik.http.routers.traefik-dash.rule=Host(`traefik.ognir-server.synology.me`)"
|
|
||||||
- "traefik.http.routers.traefik-dash.entrypoints=websecure"
|
|
||||||
- "traefik.http.routers.traefik-dash.tls=true"
|
|
||||||
- "traefik.http.routers.traefik-dash.tls.certresolver=letsencrypt"
|
|
||||||
- "traefik.http.routers.traefik-dash.service=api@internal"
|
|
||||||
# Mantenemos el middleware pero asegúrate de limpiar caché del navegador
|
|
||||||
- "traefik.http.routers.traefik-dash.middlewares=seguridad-general@file"
|
|
||||||
- "traefik.docker.network=services-internal-net"
|
|
||||||
networks:
|
networks:
|
||||||
proxy-macvlan-net:
|
proxy-macvlan-net:
|
||||||
ipv4_address: 192.168.178.25
|
ipv4_address: 192.168.178.25 # IP estática en red local
|
||||||
services-internal-net:
|
services-internal-net: {}
|
||||||
healthcheck:
|
|
||||||
test: ["CMD", "wget", "--spider", "-q", "http://127.0.0.1:8080/ping"]
|
|
||||||
interval: 30s
|
|
||||||
timeout: 10s
|
|
||||||
retries: 3
|
|
||||||
start_period: 20s
|
|
||||||
volumes:
|
volumes:
|
||||||
- /volume1/docker/configs/traefik:/etc/traefik:ro
|
- /volume1/docker/configs/traefik:/etc/traefik:ro
|
||||||
- /volume1/docker/data/traefik:/letsencrypt
|
- /volume1/docker/data/traefik:/letsencrypt
|
||||||
- /volume1/docker/data/traefik/logs:/var/log/traefik
|
- /volume1/docker/data/traefik/logs:/var/log/traefik
|
||||||
|
|
||||||
|
labels:
|
||||||
|
- "traefik.enable=true"
|
||||||
|
- "traefik.docker.network=services-internal-net"
|
||||||
|
|
||||||
|
# --- CONFIGURACIÓN DEL ROUTER (DASHBOARD) ---
|
||||||
|
- "traefik.http.routers.traefik-dash.rule=Host(`traefik.ognir-server.synology.me`)"
|
||||||
|
- "traefik.http.routers.traefik-dash.entrypoints=websecure"
|
||||||
|
- "traefik.http.routers.traefik-dash.tls=true"
|
||||||
|
- "traefik.http.routers.traefik-dash.tls.certresolver=letsencrypt"
|
||||||
|
|
||||||
|
# --- SERVICIO INTERNO (API V3) ---
|
||||||
|
- "traefik.http.routers.traefik-dash.service=api@internal"
|
||||||
|
|
||||||
|
# --- MIDDLEWARES (ORDEN PRIORITARIO: LOGIN > SEGURIDAD) ---
|
||||||
|
# Colocamos auth-dashboard primero para asegurar que el prompt salte antes
|
||||||
|
# de aplicar las cabeceras de seguridad que podrían bloquearlo en caché.
|
||||||
|
- "traefik.http.routers.traefik-dash.middlewares=auth-dashboard@file,security-headers@file"
|
||||||
|
|
||||||
command:
|
command:
|
||||||
- "--configFile=/etc/traefik/traefik.yml"
|
- "--configFile=/etc/traefik/traefik.yml"
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# REDES EXTERNAS PRE-EXISTENTES
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
networks:
|
networks:
|
||||||
proxy-macvlan-net:
|
proxy-macvlan-net:
|
||||||
external: true
|
external: true
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
# ==============================================================================
|
|
||||||
# CONTROL DE ACCESO PERIMETRAL (WHITELIST)
|
|
||||||
# ==============================================================================
|
|
||||||
http:
|
|
||||||
middlewares:
|
|
||||||
whitelist-interna:
|
|
||||||
ipAllowList:
|
|
||||||
sourceRange:
|
|
||||||
- "127.0.0.1/32"
|
|
||||||
- "192.168.178.0/24"
|
|
||||||
- "100.64.0.0/10"
|
|
||||||
- "172.20.0.0/16"
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
# ==============================================================================
|
|
||||||
# MIDDLEWARES DE SEGURIDAD (CONFIGURACIÓN DINÁMICA)
|
|
||||||
# ==============================================================================
|
|
||||||
|
|
||||||
http:
|
|
||||||
middlewares:
|
|
||||||
seguridad-general:
|
|
||||||
headers:
|
|
||||||
# Cabeceras de seguridad recomendadas (HSTS, XSS, etc.)
|
|
||||||
forceSTSHeader: true
|
|
||||||
stsSeconds: 31536000
|
|
||||||
stsIncludeSubdomains: true
|
|
||||||
stsPreload: true
|
|
||||||
contentTypeNosniff: true
|
|
||||||
browserXssFilter: true
|
|
||||||
frameDeny: true # Evita que tu sitio sea cargado en un iframe (protección clickjacking)
|
|
||||||
referrerPolicy: "same-origin"
|
|
||||||
Reference in New Issue
Block a user