miércoles, 2 de abril de 2025

Nginx (XI) Openresty. Resolución de problemas

 1. No encuentra xmauth.lua en la sentencia lua "require xmauth"

xmauth.lua es una función propia por tanto no no se puede descargar de internet. En principio se coloca en el mismo lugar que nginx.conf y luego se debe indicar a ruta a la variable lua_package_path

2. En un proceso largo (como la descarga de todos los decretos) aparece el error 504 Gateway Timeout 

Hay que darle un valor alto a la variable proxy_read_timeout por ejemplo 1000s (1000 segundos)
Si el cliente es lento (que no es el caso) existen estos parámetros: 
  • proxy_connect_timeout 90s;  # Default is 60s
  • proxy_send_timeout 90s;     # Default is 60s
  • send_timeout 90s;           # Default is 60s

3. No se redirige al endpoint /softprop

Es debido a que :
  • Se ha borrado la ruta location=endpoint {
  • No se redirige desde otra ruta

martes, 1 de abril de 2025

Nginx (X) Configurar Openresty para login con certificado cliente

 1. Obtener los certificados de las CA de confianza.

Podemos partir de descargar las autoridades de certificacióbn de confianza (CA ) que tenemos instaladas en Google Chrome, para ello:

  • En windows: Ir a chrome e indicar esta url: chrome://certificate-manager/crscerts,  que es donde se definen las CA de confianza y darle al botón "export" y elegir como nombre de fichero ca.cert y tipo Base64-encoded ASCII, multiple certificates (*.pem,; *.crt) y se guarda en una carpeta concreta.



  • En linux (Ubuntu), ejecutar:
    # Extract all system-trusted CAs (PEM format)
    sudo cp /etc/ssl/certs/ca-certificates.crt ~/ca.crt
    

Ahora que ya tenemos el fichero ca.cer. De todas formas podemos combinar ambos ficheros si tenemos los dos sistemas operativos. Si al fichero de windows lo llamamos ca_win.cer y al de ubuntu lo llamamos ca_linux.cer podemos ejecutar:

# Unir los ficheros
cat ca_win.cer ca_linux.cer > ca_all.cer


2. Configurar openresty para obtener los datos del certificdo de cliente


Añadimos a la configuración de TSL la parte para tratar el certificado del cliente. Veamos la parte básica adaptada a nuestro nginx.conf

worker_processes  auto;

#error_log  logs/error.log;
error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    error_log /usr/local/openresty/nginx/logs/error.log info;

    access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;
    
    #--- BEGIN EDU
    # Enable Lua shared dictionary for sessions
    lua_shared_dict sessions 10m;
    
    # Load the resty modules we need
    lua_package_path '/usr/local/share/lua/5.1/?.lua;/usr/local/lib/lua/5.1/?.lua;/usr/local/share/lua/5.1/resty/?.lua;/usr/local/openresty/lualib/?.lua;/usr/local/openresty/nginx/conf/?.lua;/usr/local/openresty/site/lualib/?.lua;/usr/local/openresty/site/lualib/resty/?.lua;;';
    lua_package_cpath './?.so;/usr/local/lib/lua/5.1/?.so;/usr/lib/x86_64-linux-gnu/lua/5.1/?.so;/usr/lib/lua/5.1/?.so;/usr/local/lib/lua/5.1/loadall.so;/home/eduard/.luarocks/lib/lua/5.1/?.so;;';
        
    # Initialize the IP filter module at the http level
    init_by_lua_block {
        require("resty.core")
        require("resty.iputils").enable_lrucache()
    }
    # Enable cache
    proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=100m inactive=60m use_temp_path=off;

    # Creamos una bateria de servidores para softprop con un solo servidor
    upstream softpropsrv {
        server 0.0.0.0:5001;
        #server 127.0.0.1:5001;
        #server el_que_sea.com;
    }     
    # Hacemos un "rate limiting" para evitar un número de peticiones excesivas
    # Define rate limit (10 requests per second, with a burst of 20) por IP
    limit_req_zone $binary_remote_addr zone=my_api_limit:10m rate=10r/s;
    #--- END EDU
    
    

    server {
        #listen       8080;
        listen       8449 ssl; #->New
        
        server_name  localhost;
        #server_name  edu.tavernes.es;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;
        #-> Begin new
        # SSL certificate configuration
        ssl_certificate     /usr/local/openresty/nginx/conf/wildcard2023Nginx.crt;
        ssl_certificate_key /usr/local/openresty/nginx/conf/wildcard2023Nginx.rsa;
        
        # Client certificate part
        ssl_client_certificate /etc/nginx/ssl/ca.crt; # Set of all the CA certrificates
	ssl_verify_client on;  # Require client certificate
	ssl_verify_depth 2;
    
        # Optional SSL settings for security and performance
        ssl_protocols       TLSv1.2 TLSv1.3;
        ssl_ciphers         HIGH:!aNULL:!MD5;

        # Common proxy settings (optional)
        proxy_set_header X-Real-IP        $remote_addr;
        proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;
        proxy_set_header Host             $host;
        proxy_set_header X-Forwarded-Proto https;
    

        location / {
            # Aplicamos el rate limiting a esta ruta	
            limit_req zone=my_api_limit burst=30 delay=10;
            
            # Get info from client certificate
            proxy_pass http://127.0.0.1:5000/;  # Forward request to Python app
	    proxy_set_header X-SSL-Client-Cert $ssl_client_cert;
	    proxy_set_header X-SSL-Client-Verify $ssl_client_verify;
	    proxy_set_header X-SSL-Client-DN $ssl_client_s_dn;
	    proxy_set_header X-SSL-Client-Serial $ssl_client_serial;
            
            # Filter by UE country
            content_by_lua_block{
                local filter = require("eu_filter")
                local client_ip = ngx.var.remote_addr
                if not filter.filter() then
					ngx.status = ngx.HTTP_FORBIDDEN
					ngx.say("Access denied: Your location is not permitted.")
					return ngx.exit(ngx.HTTP_FORBIDDEN)
				end
				
                
            }
            #root   html;
            #index  index.html index.htm;
        }
        # Location of static files
        location /static/ {
	    
	    #1. Solo ficheros dentro del servidor openresty (nginx)
            ## Are good both root and alias, but in alias you must append "static/" to the path
            ##root /home/eduard/MyPython/11.softprop-01;  # Path where static files are stored
            #alias /home/eduard/MyPython/11.softprop-01/static/;  # Path where static files are stored
            
            ## Use browser cache !!! 
            #expires max;
            #access_log off;
            #gzip on;
            #gzip_types text/css application/javascript image/svg+xml;
            
            #2. Solo ficheros dentro del uno de los servidores que actuan como web servers del upstream "softpropsrv"
            proxy_pass https://softpropsrv/static/;
            proxy_set_header Host $host;
            proxy_ssl_verify off;  # If using SSL
            proxy_cache my_cache;
            proxy_cache_valid 200 30d;
            proxy_cache_use_stale error timeout updating;
            add_header X-Cache-Status $upstream_cache_status;
        }
        
        # Serve the login form
        location = /login {
            include nginx.conf.login;
        }
        
        location = /initial {
            include nginx.conf.initial;
        }
        
        # Protected proxy location
        location /protected {
            include nginx.conf.protected;
        }
        
        #location = /success {
        #    include nginx.conf.success;
        #}
        
        location = /error {
            include nginx.conf.error;
        }
        
        location = /logout {
            include nginx.conf.logout;
        }

        location = /softprop {
            # Time for waiting a response
            proxy_read_timeout 1000s;    # Default is 60s
            include nginx.conf.softprop;
        }
#error_page 404 /404.html; # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } }