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;
}
}
}