#!/bin/bash # masoara-nginx-rpc2.sh (PE rpc2, trimis cu `ssh ... 'bash -s'`): reteta nginx a remedierii (profilul `nginx`) masurata pe un nginx REAL, # in container (nginx:alpine, cu OpenSSL-ul lui Alpine), pe 127.0.0.1:8446, cu EXACT directivele retetei pentru hndl-exposed + # tls12-accepted + hsts-missing: `ssl_ecdh_curve X25519MLKEM768:X25519; ssl_protocols TLSv1.3; add_header Strict-Transport-Security # "max-age=31536000" always;`. Preconditia retetei (nginx legat de OpenSSL >= 3.5) se citeste din `nginx -V`. Sonde: node 24 de pe rpc2 # (hibrid singur, clasic singur, TLS 1.2 refuzat), HSTS prin curl. Container si imagine sterse la sfarsit. RPC-ul local cronometrat. set -u D=/root/nginx-reteta; rm -rf "$D"; mkdir -p "$D/certs" "$D/conf"; cd "$D" || exit 2 N=/opt/node24/bin/node rpc() { local t0=$(date +%s%N); curl -s -m 5 -H 'content-type: application/json' -d '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}' http://127.0.0.1:8545 | grep -o '"result":"0x[0-9a-f]*"' | head -1; echo " ($(( ($(date +%s%N) - t0) / 1000000 )) ms)"; } echo "== RPC inainte: $(rpc)" openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 -nodes -keyout certs/privkey.pem -out certs/fullchain.pem -days 2 -subj '/CN=proba.local' > /dev/null 2>&1 && chmod 644 certs/*.pem && echo "cert ok" cat > conf/default.conf <<'EOF' server { listen 127.0.0.1:8446 ssl; server_name proba.local; ssl_certificate /etc/nginx/certs/fullchain.pem; ssl_certificate_key /etc/nginx/certs/privkey.pem; # EXACT fragmentul retetei (remediere.mjs, profilul nginx): ssl_ecdh_curve X25519MLKEM768:X25519; ssl_protocols TLSv1.3; add_header Strict-Transport-Security "max-age=31536000" always; location / { return 200 "ok\n"; } } EOF cp tls-sonda.mjs "$D/" 2>/dev/null || true echo "== imaginea nginx:alpine"; docker pull -q nginx:alpine > /dev/null 2>&1; docker image inspect nginx:alpine --format 'imagine: {{.Id}} {{.Size}} octeti' | cut -c1-90 echo "-- preconditia retetei: nginx -V (OpenSSL)"; docker run --rm nginx:alpine nginx -V 2>&1 | grep -iE 'nginx version|openssl' | cut -c1-160 docker rm -f nginx-reteta > /dev/null 2>&1 docker run -d --name nginx-reteta --network host -v "$D/conf/default.conf:/etc/nginx/conf.d/default.conf:ro" -v "$D/certs:/etc/nginx/certs:ro" nginx:alpine > /dev/null; sleep 2 docker ps --filter name=nginx-reteta --format 'container: {{.Status}}' echo "-- nginx -t in container"; docker exec nginx-reteta nginx -t 2>&1 | tail -1 rele=0 cere() { local nume="$1" ast="$2"; shift 2; out=$("$@" 2>&1); c=$?; if [ "$c" = "$ast" ]; then echo " OK $nume -> cod $c: $(printf '%s' "$out" | cut -c1-170)"; else echo " RAU $nume -> cod $c (asteptat $ast): $(printf '%s' "$out" | cut -c1-170)"; rele=$((rele + 1)); fi; } cere "hibrid singur (X25519MLKEM768)" 0 $N /root/nginx-reteta-sonda.mjs 127.0.0.1 8446 X25519MLKEM768 cere "clasic singur (X25519, rezerva din reteta)" 0 $N /root/nginx-reteta-sonda.mjs 127.0.0.1 8446 X25519 cere "hibrid + clasic (preferinta)" 0 $N /root/nginx-reteta-sonda.mjs 127.0.0.1 8446 X25519MLKEM768:X25519 cere "client TLS 1.2 (ssl_protocols TLSv1.3: refuz)" 1 $N /root/nginx-reteta-sonda.mjs 127.0.0.1 8446 X25519 TLSv1.2 echo "-- HSTS (curl -k)"; curl -sk -m 10 -D - -o /dev/null https://127.0.0.1:8446/ | grep -iE '^(strict-transport-security|HTTP)' | tr -d '\r' docker logs nginx-reteta 2>&1 | grep -iE 'emerg|error' | head -3 echo "== curatenie"; docker rm -f nginx-reteta > /dev/null 2>&1; docker rmi nginx:alpine > /dev/null 2>&1 && echo "imaginea stearsa"; cd /root && rm -rf "$D" /root/nginx-reteta-sonda.mjs; docker ps -a --format '{{.Names}}' | grep -c nginx-reteta | sed 's/^/containere ramase: /' echo "== RPC dupa: $(rpc)" echo "reteta nginx: $((4 - rele)) din 4 sonde cum trebuie" [ "$rele" = 0 ] && exit 0 || exit 1