# Relay SNI (passthrough) para *.alumnos.codecrypto.dev # # Traefik (delante, dueño del 443) reenvía aquí, sin descifrar, los nombres # ..alumnos.codecrypto.dev (p. ej. lista.jviejo.alumnos.codecrypto.dev) # nginx lee el SNI del ClientHello (ssl_preread) y manda TODO lo que cuelgue de # a UN solo socket Unix por alumno, que abrió con `ssh -R`: # /var/lib/alumnos//web.sock # El reparto por nombre (proyecto) lo hace el Traefik del propio alumno. # # El usuario es [a-z][a-z0-9]{2,19} (como valida alta-alumno.sh); la regex no admite barras ni # puntos en el usuario, por lo que no hay path traversal posible. Se exige al menos una etiqueta # antes del usuario, así `traefik.alumnos...` o `.alumnos...` nunca entran aquí. user nginx nginxsock; # grupo nginxsock (gid 2000): puede conectar a los sockets worker_processes auto; error_log /dev/stderr warn; pid /var/run/nginx.pid; events { worker_connections 4096; } stream { log_format sni '$remote_addr [$time_local] sni=$ssl_preread_server_name ' 'backend=$backend status=$status in=$bytes_received ' 'out=$bytes_sent t=$session_time'; access_log /dev/stdout sni; map $ssl_preread_server_name $backend { # entre comillas: nginx interpretaría las llaves de {2,19} como un bloque "~^(?:[a-z0-9-]+\.)+(?[a-z][a-z0-9]{2,19})\.alumnos\.codecrypto\.dev$" unix:/var/lib/alumnos/$alumno/web.sock; # Cualquier otro SNI: Traefik ya lo filtra; si llega aquí, se cierra al instante. default 127.0.0.1:1; } server { listen 9443; # Con PROXY protocol desde Traefik (ver traefik/alumnos.yml) usar en su lugar: # listen 9443 proxy_protocol; ssl_preread on; proxy_pass $backend; proxy_connect_timeout 5s; proxy_timeout 1h; # conexiones largas (websockets, SSE) } }