Il lucchetto del browser non è l’unico modo per controllare un servizio HTTPS. Con openssl s_client puoi osservare l’handshake TLS e i certificati presentati dal server; con openssl x509 puoi leggere identità, emittente, nomi validi e scadenza. Il valore non sta nel produrre molto output, ma nel separare quattro domande: la porta risponde, la catena è attendibile, il certificato identifica il nome richiesto ed è ancora valido?
Obiettivo e pubblico
Al termine saprai verificare un servizio TLS remoto usando SNI e controllo esplicito dell’hostname, estrarre i dati essenziali del certificato e controllarne la scadenza tramite exit status. La guida è destinata a chi conosce terminale, pipe e codici di uscita, ma non richiede esperienza precedente con PKI.
Prerequisiti
- Un sistema Linux con OpenSSL installato.
- Risoluzione DNS e accesso TCP verso il servizio di laboratorio.
- Un hostname che sei autorizzato a verificare; negli esempi useremo
www.threathunting.it. - Una shell nella quale non siano salvati o stampati segreti applicativi.
Uso autorizzato
Limita le connessioni ai sistemi che amministri o a servizi pubblici che puoi legittimamente consultare. I comandi della lezione effettuano normali handshake TLS, ma non devono essere trasformati in scansioni massive. Non leggere, copiare o mostrare chiavi private.
Quattro verifiche diverse
Una connessione TCP riuscita non dimostra che il certificato sia valido. Una catena costruita fino a una CA attendibile non dimostra, da sola, che il certificato appartenga al nome che volevi contattare. Una corrispondenza dell’hostname non dimostra che il certificato non sia scaduto. Conviene quindi trattare separatamente:
- raggiungibilità: il client completa una connessione verso host e porta;
- negoziazione TLS: client e server concordano versione e cipher suite;
- fiducia: OpenSSL costruisce e valida una catena verso un trust anchor locale;
- identità: il nome richiesto corrisponde al certificato presentato.
Questa separazione evita frasi ambigue come «SSL funziona». Un servizio può negoziare TLS e allo stesso tempo presentare una catena incompleta o un certificato valido per un altro dominio.
Prima prova con s_client
openssl version
openssl s_client \
-connect www.threathunting.it:443 \
-servername www.threathunting.it \
</dev/null
-connect sceglie destinazione e porta. -servername invia il nome tramite SNI, necessario quando più siti condividono lo stesso indirizzo IP. Senza SNI un reverse proxy potrebbe presentare il certificato del virtual host predefinito. La redirezione da /dev/null chiude l’input invece di lasciare la sessione in attesa.
Nell’output cerca protocollo, cipher suite, certificato peer e risultato della verifica. Non interpretare però la sola riga Verify return code: 0 (ok) come prova completa dell’identità: occorre richiedere esplicitamente anche il controllo del nome.
Rendere la verifica vincolante
openssl s_client \
-connect www.threathunting.it:443 \
-servername www.threathunting.it \
-verify_hostname www.threathunting.it \
-verify_return_error \
</dev/null
-verify_hostname confronta il nome atteso con l’identità del certificato. -verify_return_error interrompe l’handshake quando la verifica produce un errore. Quest’ultima opzione è importante negli script: s_client è uno strumento diagnostico e, per impostazione predefinita, può continuare anche dopo aver mostrato errori di verifica.
Dopo il comando controlla subito il codice di uscita:
status=$?
printf 'Exit status: %s\n' "$status"
Il valore zero indica che quel comando si è concluso correttamente nelle condizioni richieste. Non riutilizzare $? dopo altri comandi, perché rappresenta sempre l’ultima operazione eseguita.
Catena inviata e catena verificata non sono la stessa cosa
openssl s_client \
-connect www.threathunting.it:443 \
-servername www.threathunting.it \
-showcerts \
</dev/null
-showcerts mostra l’elenco dei certificati inviati dal server, nell’ordine ricevuto. La documentazione OpenSSL precisa che non è necessariamente una catena già verificata. Il server normalmente invia il certificato finale e gli intermedi necessari; la root di fiducia dovrebbe trovarsi nell’archivio locale del client.
Una catena incompleta può sembrare funzionante su un dispositivo che possiede già l’intermedio e fallire su un client pulito. Per una diagnosi ripetibile registra quindi versione di OpenSSL, archivio di fiducia utilizzato e messaggi di verifica, non soltanto i blocchi PEM visualizzati.
Estrarre il certificato finale e leggerlo con x509
Per una lettura compatta puoi passare il primo certificato presentato a openssl x509:
openssl s_client \
-connect www.threathunting.it:443 \
-servername www.threathunting.it \
</dev/null 2>/dev/null |
openssl x509 -noout \
-subject \
-issuer \
-dates \
-serial \
-ext subjectAltName
| Opzione | Domanda a cui risponde |
|---|---|
-subject | A quale identità è intestato il certificato? |
-issuer | Quale autorità lo ha emesso? |
-dates | Da quando e fino a quando è valido? |
-serial | Qual è il numero seriale assegnato dall’emittente? |
-ext subjectAltName | Quali nomi DNS o indirizzi sono dichiarati nei SAN? |
Questa pipeline è utile per l’ispezione, ma nasconde su stderr i dettagli dell’handshake. Durante un malfunzionamento esegui anche il comando completo: sopprimere gli errori troppo presto può eliminare proprio l’evidenza necessaria.
Controllare la scadenza in uno script
x509 -checkend controlla se il certificato resterà valido oltre un intervallo espresso in secondi. Trenta giorni corrispondono a 2.592.000 secondi:
openssl s_client \
-connect www.threathunting.it:443 \
-servername www.threathunting.it \
</dev/null 2>/dev/null |
openssl x509 -noout -checkend 2592000
status=$?
if [ "$status" -eq 0 ]; then
echo "Il certificato supera la soglia di 30 giorni"
else
echo "Certificato vicino alla scadenza oppure controllo non riuscito"
fi
Il ramo non zero deve restare prudente: potrebbe indicare una scadenza ravvicinata, ma anche input assente o non interpretabile. In un monitoraggio serio conserva l’errore originale e separa il fallimento della connessione dal risultato temporale.
Verificare un nuovo IP senza cambiare il DNS
Durante una migrazione puoi collegarti direttamente a un indirizzo di documentazione mantenendo il nome TLS corretto:
openssl s_client \
-connect 192.0.2.10:443 \
-servername www.threathunting.it \
-verify_hostname www.threathunting.it \
-verify_return_error \
</dev/null
192.0.2.10 è un indirizzo riservato agli esempi e va sostituito con l’IP autorizzato del laboratorio. Destinazione TCP, nome SNI e nome verificato svolgono ruoli diversi: cambiare l’IP non significa che il certificato debba contenere quell’IP, se il servizio viene normalmente identificato dal nome DNS.
Laboratorio isolato
Esegui il laboratorio da una postazione autorizzata e salva gli output in una directory temporanea priva di segreti:
lab_dir="$(mktemp -d)"
openssl version > "$lab_dir/version.txt"
openssl s_client \
-connect www.threathunting.it:443 \
-servername www.threathunting.it \
-verify_hostname www.threathunting.it \
-verify_return_error \
-showcerts \
</dev/null > "$lab_dir/handshake.txt" 2>&1
status=$?
printf '%s\n' "$status" > "$lab_dir/exit-status.txt"
Leggi poi handshake.txt e individua protocollo negoziato, cipher suite, certificati inviati e risultato della verifica. Non usare output costruiti in anticipo: il valore dell’esercizio è collegare ogni conclusione alla riga osservata.
Risultato atteso e criteri di successo
- Il comando termina con exit status zero quando catena e hostname superano i controlli richiesti.
- Sai distinguere il certificato finale dagli intermedi inviati dal server.
- Riesci a indicare subject, issuer, validità e SAN senza aprire o stampare alcuna chiave privata.
- Il test della scadenza distingue la soglia scelta dalla data completa mostrata con
-dates.
Ripristino e pulizia
Il laboratorio non modifica il servizio remoto né la configurazione locale di OpenSSL. Esamina la directory prima di eliminarla: gli output possono contenere hostname, indirizzi e dettagli dell’infrastruttura.
find "$lab_dir" -maxdepth 1 -type f -printf '%f\n'
rm -r -- "$lab_dir"
Verifica attentamente il valore della variabile prima della rimozione. Non sostituire l’ultima riga con comandi più ampi o percorsi costruiti manualmente.
Errori di interpretazione comuni
- Dimenticare SNI: il server può presentare il certificato di un altro virtual host.
- Fermarsi a “Verify return code: 0”: richiedi anche il controllo esplicito dell’hostname.
- Credere che showcerts mostri una catena verificata: mostra ciò che il server ha inviato.
- Nascondere stderr durante la diagnosi: potresti perdere il motivo reale del fallimento.
- Confondere scadenza e disponibilità: un certificato temporalmente valido può comunque avere hostname errato o catena non attendibile.
- Leggere la chiave privata senza necessità: per il controllo remoto non serve accedere a
privkey.pem.
Glossario
- TLS
- Protocollo che protegge confidenzialità e integrità della comunicazione e consente l’autenticazione tramite certificati.
- SNI
- Indicazione del nome del server inviata durante l’handshake, utile quando più servizi TLS condividono lo stesso IP.
- Certificato finale
- Certificato presentato dal servizio per la propria identità, chiamato anche leaf o end-entity certificate.
- Intermedio
- Certificato di una CA che collega il certificato finale a un trust anchor.
- Trust anchor
- Punto di fiducia configurato localmente, spesso una CA root.
- SAN
- Subject Alternative Name, estensione che contiene i nomi e gli eventuali indirizzi associati al certificato.
Cosa ricordare
-connect,-servernamee-verify_hostnamerispondono a domande diverse.s_clientè diagnostico: usa-verify_return_errorquando vuoi che un errore renda il comando fallito.-showcertsmostra i certificati inviati, non certifica da solo la validità della catena.x509 -checkendè adatto agli script solo se gestisci anche errori di connessione e parsing.- La verifica di un servizio remoto non richiede di aprire o mostrare la sua chiave privata.
Fonti essenziali
Documentazione primaria consultata e verificata il 12 ottobre 2026.
COMMUNITY
Non ci sono ancora commenti. Puoi iniziare tu la conversazione.