<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>asymmetricencryption &amp;mdash; Cyberdyne Systems</title>
    <link>https://noblogo.org/aytin/tag:asymmetricencryption</link>
    <description>&#34;Fare o non fare. Non c&#39;è provare!&#34;</description>
    <pubDate>Thu, 30 Apr 2026 11:34:23 +0000</pubDate>
    <item>
      <title>Come creare un certificato digitale</title>
      <link>https://noblogo.org/aytin/come-creare-un-certificato-digitale</link>
      <description>&lt;![CDATA[(pubblicato il 30 gennaio 2023)&#xA;certificati digitali&#xA;smalliFonte:  Foto di a href=&#34;https://pixabay.com/it/users/skylarvision-2957633/?utmsource=link-attribution&amp;utmmedium=referral&amp;utmcampaign=image&amp;utmcontent=3344700&#34;skylarvision/a da a href=&#34;https://pixabay.com/it//?utmsource=link-attribution&amp;utmmedium=referral&amp;utmcampaign=image&amp;utmcontent=3344700&#34;Pixabay/a/i/small&#xA;&#xA;A volte, per ragioni di test o per uso domestico (configurazione di una vpn con openvpn per es. o di un server stunnel), mi càpita di avere bisogno di un certificato digitale.&#xA;&#xA;Finché il certificato è self-signed, l&#39;operazione richiede veramente pochissimo sforzo. Ma quando devo far riferimento ad una CA interna, la questione si complica.&#xA;!--more--&#xA;Proverò adesso a descrivere le operazioni che compio quando devo creare:&#xA;&#xA;CA + certificati server +  certificati client&#xA;CA + Intermediate CA + certificati server + certificati client&#xA;&#xA;Indice&#xA;&#xA;a href=&#34;#cose-un-certificato-digitale&#34;Cos’è un certificato digitale/a&#xA;a href=&#34;#openssl&#34;OpenSSL/a&#xA;a href=&#34;#struttura-laboratorio&#34;Struttura del “laboratorio”/a&#xA;a href=&#34;#creazione-ca-certificati-client-server&#34;Caso 1: Creazione delle CA e dei certificati client e server/a&#xA;   a href=&#34;#creazione-ca-certificati-server&#34;Creazione della CA per i certificati server/a&#xA;      a href=&#34;#configurazione-ca-server&#34;Configurazione CA server/a&#xA;      a href=&#34;#creazione-ca-server&#34;Creazione CA server/a&#xA;   a href=&#34;#creazione-certificato-server&#34;Creazione del certificato server/a&#xA;      a href=&#34;#configurazione-csr-server&#34;Configurazione csr server/a&#xA;      a href=&#34;#creazione-csr-server&#34;Creazione csr server/a&#xA;      a href=&#34;#configurazione-crt-server&#34;Configurazione crt server/a&#xA;      a href=&#34;#creazione-crt-server&#34;Creazione crt server/a&#xA;   a href=&#34;#creazione-ca-certificati-client&#34;Creazione della CA per i certificati client/a&#xA;      a href=&#34;#configurazione-ca-client&#34;Configurazione CA client/a&#xA;      a href=&#34;#creazione-ca-client&#34;Creazione CA client/a&#xA;   a href=&#34;#creazione-certificato-client&#34;Creazione del certificato client/a&#xA;      a href=&#34;#configurazione-csr-client&#34;Configurazione csr client/a&#xA;      a href=&#34;#creazione-csr-client&#34;Creazione csr client/a&#xA;      a href=&#34;#configurazione-crt-client&#34;Configurazione crt client/a&#xA;      a href=&#34;#creazione-crt-client&#34;Creazione crt client/a&#xA;   a href=&#34;#riassunto&#34;Riassunto/a&#xA;a href=&#34;#creazione-ca-intermediate-certificati-client-server&#34;Caso 2: Creazione di CA, Intermediate CA e dei certificati client e server/a&#xA;&#xA;a id=&#34;cose-un-certificato-digitale&#34;Cos&#39;è un certificato digitale/a&#xA;&#xA;I certificati digitali sono degli oggetti utilizzati nelle comunicazioni per fornire un canale sicuro su un mezzo intrinsecamente insicuro (internet) e vengono costruiti secondo lo standard X.509, un protocollo che definisce il formato dei certificati e l&#39;insieme degli elementi di contorno come elementi autoritativi, elenchi di revoca e modalità di convalida.&#xA;&#xA;Un certificato digitale è un oggetto crittografico costituito da una parte pubblica (chiave pubblica + informazioni personali del possessore del certificato) e una parte privata (la chiave privata).&#xA;&#xA;La parte pubblica viene firmata digitalmente per garantire autenticazione e integrità e può essere eseguita:&#xA;&#xA;da se stesso (i cosiddetti certificati self-signed, una sorta di autocertificazione)&#xA;da una CA, un&#39;autorità superiore che garantisce che le informazioni del certificato sono di chi dice di essere.&#xA;&#xA;a id=&#34;openssl&#34;OpenSSL/a&#xA;&#xA;Per la costruzione di un certificato digitale, uso OpenSSL che è sia una libreria crittografica che implementa i protocolli TLS e SSL (deprecato), sia un toolkit professionale per l&#39;utilizzo di funzionalità di crittografia.,&#xA;&#xA;OpenSSL ha una cli molto complessa che può essere in parte configurata, soprattutto nella parte di definizione dei certificati, da un file di configurazione, openssl.cnf, un file .ini diviso in sezioni, contenenti una lista di coppie (chiave,valore).&#xA;&#xA;Nel proseguio, invece che usare un unico file omnicomprensivo, ne verrà usato solo un frammento in base al contesto (certificato o csr di ca, intermediate, server o client). Ho trovato questo approccio più flessibile e più chiaro.&#xA;&#xA;Negli esempi, userò questi file che avranno dei nomi &#34;parlanti&#34; in base a ciò che dovrò definire. Non mi dilungherò nella spiegazione delle singole opzioni perché:&#xA;&#xA;non le conosco tutte&#xA;approfondire ogni singola direttiva di openssl.cnf richiederebbe un blog dedicato.&#xA;&#xA;Si potrebbe ancora dissertare sulle versioni di openssl da usare, sui suoi fork ma non è questo il momento, forse in altri post (che sono in fase di preparazione.)&#xA;&#xA;a id=&#34;struttura-laboratorio&#34;Struttura del &#34;laboratorio&#34;/a&#xA;&#xA;Data la destinazione dei certificati (test o uso strettamente interno), i certificati vengono generati nella maniera più compatta possibile.&#xA;&#xA;Per le root CA, gli unici certificati self-signed, viene generato il csr e il crt in un&#39;unica soluzione.&#xA;Le intermediate CA vengono generate, come ogni altro certificato server / client, producendo prima un csr che viene firmato dalla root CA per produrre il crt.&#xA;Anche i certificati server e client, come detto, vengono generati come l&#39;intermediate CA, producendo prima il csr che verrà firmato da una CA.&#xA;Ogni fase (per &#34;fase&#34; intendo produzione di un csr o di un crt) sarà &#34;guidata&#34; dal frammento di file di configurazione avente quel famoso nome &#34;parlante&#34;.&#xA;Prenderò in considerazione due casistiche. In una i certificati server e client verranno validati da una root CA. Nell&#39;altro, la root CA delegherà ad una intermediate CA la validazione di certificati server / client.&#xA;Nella prima casistica, per rendere la soluzione più generica, supporrò di avere una CA distinta per i certificati client e una per i server.&#xA;&#xA;⚠️ ⚠️ ⚠️ SUPER WARNING⚠️ ⚠️ ⚠️ &#xA;Non è questo il modo formalmente corretto per la creazione di un certificato, almeno non quello da usare per un ambiente di produzione.&#xA;&#xA;Non farò nessuna assunzione sulle modalità di cifratura, né sul tuning di openssl.&#xA;&#xA;Il mio obiettivo qui è: voglio ottenere un certificato nella maniera più rapida possibile (e per rapido intendo senza troppi sbattimenti nelle configurazioni perché, alla fine, tutto può essere scriptabile e quindi veloce).&#xA;&#xA;I file di configurazione saranno composti da massimo due sezioni contenenti le extensions X.509  necessarie per la creazione dei certificati. Il resto dei parametri sarà  passato nella cli piuttosto che nel file di configurazione.&#xA;&#xA;Mi rendo conto che per una buona comprensione occorrerebbe avere un po&#39; di confidenza con: &#xA;&#xA;i concetti di cifratura asimmetrica e di certificato digitale&#xA;configurazione e utilizzo base di openssl&#xA;conoscenza di openssl.cnf e extensions X.509&#xA;&#xA;a id=&#34;creazione-ca-certificati-client-server&#34;Caso 1: Creazione delle CA e dei certificati client e server/a&#xA;&#xA;La creazione della CA consisterà in un certificato self-signed ottenuto con un unico comando. Per i certificati invece verrà prodotto prima il csr che poi sarà firmato dalla CA al fine di ottenere il certificato vero e proprio.&#xA;&#xA;Piccola nota: gli attributi basicConstraints, nsCertType, extendedKeyUsage saranno determinanti per battezzare una CA piuttosto che un certificato client/server&#xA;&#xA;a id=&#34;creazione-ca-certificati-server&#34;Creazione della CA per i certificati server/a&#xA;&#xA;La creazione del certificato sarà one-shot.&#xA;&#xA;a id=&#34;configurazione-ca-server&#34;Configurazione CA server/a&#xA;&#xA;Il file di configurazione sarà cacert.cnf&#xA;###############&#xA;cacert.cnf &#xA;###############&#xA;[ v3ca ]&#xA;basicConstraints        = critical,CA:true&#xA;keyUsage                = critical, cRLSign, keyCertSign&#xA;subjectKeyIdentifier    = hash&#xA;authorityKeyIdentifier  = keyid:always,issuer&#xA;nsCertType              = sslCA&#xA;nsComment               = &#34;OpenSSL Generated CA Root Certificate&#34;&#xA;&#xA;a id=&#34;creazione-ca-server&#34;Creazione CA server/a&#xA;OUTPUTCERT=pathoutputcert&#xA;CONFCERT=pathfilecnf&#xA;&#xA;CA SERVER &#xA;openssl req \&#xA;-config $CONFCERT/cacert.cnf \&#xA;-extensions v3ca \ &#xA;-x509 \&#xA;-days 1825 -sha512 \&#xA;-nodes -newkey rsa:4096 \&#xA;-subj &#34;/C=IT/ST=Italia/CN=GlobalSign Test RootCA&#34; \&#xA;-keyout $OUTPUTCERT/caserver.key \&#xA;-out $OUTPUTCERT/caserver.crt&#xA;&#xA;openssl req : crea un csr&#xA;-config $CONFCERT/cacert.cnf : path del file di configurazione&#xA;-extensions v3ca : sezione del file da prendere come riferimento (in questo caso per le sole extensions X.509)&#xA;-x509 : fa in modo che l&#39;output sia direttamente un certificato piuttosto che un csr&#xA;-days 1825 -sha512 : fissa la scadenza a 5 anni e setta sha512 come algoritmo di digest.&#xA;-nodes -newkey rsa:4096 : crea una chiave rsa non cifrata a 4096 bit&#xA;-subj &#34;/C=IT/ST=Roma&#34;/CN=GlobalSign Test RootCA&#34; : distinguishedname passato da cli&#xA;-keyout $OUTPUTCERT/caserver.key : path di destinazione della chiave&#xA;-out $OUTPUTCERT/caserver.crt : path di destinazione del certificato CA.&#xA;&#xA;a id=&#34;creazione-certificato-server&#34;Creazione certificato server/a&#xA;&#xA;Verrà generato prima il csr (certificate signing request) che sarà firmato dalla CA per generare il certificato effettivo.&#xA;&#xA;a id=&#34;configurazione-csr-server&#34;Configurazione csr server/a&#xA;&#xA;Il file di configurazione per il csr sarà serverreq.cnf, diviso in 3 sezioni.&#xA;&#xA;La prima, req, è quella usata da openssl req (in assenza della quale verrà sollevata un&#39;eccezione) e contiene solo il rimando alle extensions X.509 da usare.&#xA;&#xA;Come prima, le extensions X.509 (v3serverreq) definiscono i giusti attributi per questo tipo di certificato.&#xA;&#xA;N.B.&#xA;L&#39;ultima sezione è quella degli alternativesname, la cui assenza non comporta problemi nella creazione del certificato ma potrebbe far fallire i check effettuati da alcuni prodotti, ad es. i webserver che pur riconoscendo nel Common Name il nome del servizio (es. la url) scatenano ugualmente l&#39;eccezione BADCERTDOMAIN&#xA;##################&#xA;serverreq.cnf &#xA;##################&#xA;[ req ]&#xA;reqextensions = v3serverreq&#xA;&#xA;[ v3serverreq ]&#xA;basicConstraints        = CA:FALSE&#xA;subjectKeyIdentifier    = hash&#xA;keyUsage                = nonRepudiation, digitalSignature, keyEncipherment, dataEncipherment&#xA;extendedKeyUsage        = serverAuth&#xA;nsCertType              = server&#xA;nsComment               = &#34;OpenSSL Generated Server Request Certificate&#34;&#xA;subjectAltName          = @altnames&#xA;&#xA;[ altnames ]&#xA;DNS.1 = server.web.local&#xA;&#xA;a id=&#34;creazione-csr-server&#34;Creazione csr server/a&#xA;&#xA;La sintassi è sostanzialmente uguale a quanto visto per la CA con la sola eccezione del parametro -x509 (che creava un crt invece che un csr). Il csr creerà il certificato e la coppia di chiavi pubblica e privata.&#xA;OUTPUTCERT=pathoutputcert&#xA;CONFCERT=pathfilecnf&#xA;&#xA;CSR Server &#xA;openssl req \&#xA;-config $CONFCERT/serverreq.cnf \&#xA;-nodes -newkey rsa:2048 \&#xA;-subj &#34;/C=IT/ST=Italia/L=Roma/O=My Company Ltd/OU=Divisione IT web/CN=server.web.local/emailAddress=it@web.local&#34; \&#xA;-keyout $OUTPUTCERT/server.key \&#xA;-out $OUTPUTCERT/server.csr&#xA;&#xA;openssl req : crea un csr&#xA;-config $CONFCERT/serverreq.cnf : path del file di configurazione&#xA;-nodes -newkey rsa:2048 : crea una chiave rsa non cifrata a 2048 bit&#xA;-subj &#34;/C=IT/ST=Italia/L=Roma/O=My Company Ltd/OU=Divisione IT web/CN=server.web.local/emailAddress=it@web.local&#34; : distinguishedname passato da cli&#xA;-keyout $OUTPUTCERT/server.key : path di destinazione della chiave &#xA;-out $OUTPUTCERT/server.csr : path di destinazione del csr&#xA;&#xA;a id=&#34;configurazione-crt-server&#34;Configurazione crt server/a&#xA;&#xA;A differenza di prima, non ho un file di configurazioni vero e proprio. Non usando il file generico openssl.cnf, l&#39;unico file che si può invocare dal comando openssl x509 è un elenco di attributi che il certificato dovrà possedere e questo ci è sufficiente per creare certificati client o server.&#xA;&#xA;Il file di configurazione per il crt sarà servercert.cnf.&#xA;###################&#xA;servercert.cnf &#xA;###################&#xA;basicConstraints        = CA:FALSE&#xA;subjectKeyIdentifier    = hash&#xA;keyUsage                = nonRepudiation, digitalSignature, keyEncipherment, dataEncipherment&#xA;extendedKeyUsage        = serverAuth&#xA;nsCertType              = server&#xA;nsComment               = &#34;OpenSSL Generated Server Certificate&#34;&#xA;subjectAltName          = @altnames&#xA;&#xA;[ altnames ]&#xA;DNS.1 = server.web.local&#xA;&#xA;a id=&#34;creazione-crt-server&#34;Creazione crt server/a&#xA;&#xA;Di fatto, le uniche operazione che compio sono quelle di firmare con la CA il certificato, di fissare una scadenza e l&#39;algoritmo di digest (altrimenti verrà applicato un default). Il resto, lo eredito dal csr (potrei sovrascrivere alcune cose come il subj) o dalle estensioni presenti nel file.&#xA;OUTPUTCERT=pathoutputcert&#xA;CONFCERT=pathfilecnf&#xA;&#xA;CRT Server &#xA;openssl x509 \&#xA;-extfile $CONFCERT/servercert.cnf \&#xA;-req -in $OUTPUTCERT/server.csr \&#xA;-days 365 -sha384 \&#xA;-CA $OUTPUTCERT/caserver.crt \&#xA;-CAkey $OUTPUTCERT/caserver.key \&#xA;-CAcreateserial \&#xA;-out $OUTPUTCERT/server.crt&#xA;&#xA;openssl x509 : crea un certificato x509&#xA;-extfile $CONFCERT/servercert.cnf : path del file di estensioni&#xA;-req : acquisizione del file csr da far firmare&#xA;-CA $OUTPUTCERT/caserver.crt : acquisizione del certificato della CA&#xA;-CAkey $OUTPUTCERT/caserver.key : acquisizione della chiave privata della CA che firmerà il certificato&#xA;-CAcreateserial : crea un seriale randomico per il certificato da creare. Normalmente una CA crea dei seriali progressivi memorizzandoli in un database interno.&#xA;-days 365 -sha384 : fissa ad un anno la scadenza del certificato e usa sha384 come algoritmo di digest&#xA;-out $OUTPUTCERT/server.crt : path di destinazione del certificato server.&#xA;&#xA;a id=&#34;creazione-ca-certificati-client&#34;Creazione della CA per i certificati client/a&#xA;&#xA;È praticamente la stessa cosa. La differenza è solo formale visto che, tecnicamente, i comandi che andrò ad eseguire saranno praticamente gli stessi (l&#39;unica differenza di rilievo riguarderà i certificati client a cui corrisponderanno estensioni X.509 leggermente differenti)&#xA;&#xA;a id=&#34;configurazione-ca-client&#34;Configurazione della CA client/a&#xA;&#xA;È lo stesso file visto a href=&#34;#configurazione-ca-server&#34;prima/a.&#xA;&#xA;a id=&#34;creazione-ca-client&#34;Creazione della CA client/a&#xA;&#xA;OUTPUTCERT=pathoutputcert&#xA;CONFCERT=pathfilecnf&#xA;&#xA;CA Client &#xA;openssl req \&#xA;-config $CONFCERT/cacert.cnf \&#xA;-extensions v3ca \ &#xA;-x509 \&#xA;-days 1825 -sha512 \&#xA;-nodes -newkey rsa:4096 \&#xA;-subj &#34;/C=IT/ST=Italia/CN=Digicert Test RootCA&#34; \&#xA;-keyout $OUTPUTCERT/caclient.key \&#xA;-out $OUTPUTCERT/caclient.crt&#xA;C&#39;è poco da dire. L&#39;unica variazione degna di nota è il subj, per il resto è identico alla a href=&#34;#creazione-ca-server&#34;creazione della ca server/a.&#xA;&#xA;a id=&#34;creazione-certificato-client&#34;Creazione certificato client/a&#xA;&#xA;Come fatto per il server, verrà generato prima il csr che sarà firmato dalla CA per generare il certificato effettivo.&#xA;&#xA;a id=&#34;configurazione-csr-client&#34;Configurazione csr client/a&#xA;&#xA;Come per i a href=&#34;#configurazione-csr-server&#34;certificati server/a, extendedKeyUsage e nsCertType stabiliscono come viene battezzato il certificato.&#xA;##################&#xA;clientreq.cnf &#xA;##################&#xA;[ req ]&#xA;reqextensions = v3clientreq&#xA;&#xA;[ v3clientreq ]&#xA;basicConstraints        = CA:FALSE&#xA;subjectKeyIdentifier    = hash&#xA;keyUsage                = nonRepudiation, digitalSignature, keyEncipherment, dataEncipherment&#xA;extendedKeyUsage        = clientAuth&#xA;nsCertType              = client&#xA;nsComment               = &#34;OpenSSL Generated Client Request Certificate&#34;&#xA;&#xA;a id=&#34;creazione-csr-client&#34;Creazione csr client/a&#xA;&#xA;Nel csr, viene creata la chiave, rsa a 2048 bit, e viene settato il subj.&#xA;OUTPUTCERT=pathoutputcert&#xA;CONFCERT=pathfilecnf&#xA;&#xA;CSR Client &#xA;openssl req \&#xA;-config $CONFCERT/clientreq.cnf \&#xA;-nodes -newkey rsa:2048 \&#xA;-subj &#34;/C=IT/ST=Italia/L=Roma/O=Another Company Ltd/OU=User WebApp/CN=John Doe/emailAddress=john.doe@unknown.local&#34; \&#xA;-keyout $OUTPUTCERT/johndoe.key \&#xA;-out $OUTPUTCERT/johndoe.csr&#xA;&#xA;a id=&#34;configurazione-crt-client&#34;Configurazione crt client/a&#xA;&#xA;Il file di configurazione raccoglie solo le estensioni con cui il certificato viene istanziato&#xA;###################&#xA;clientcert.cnf &#xA;###################&#xA;basicConstraints        = CA:FALSE&#xA;subjectKeyIdentifier    = hash&#xA;keyUsage                = nonRepudiation, digitalSignature, keyEncipherment, dataEncipherment&#xA;extendedKeyUsage        = clientAuth&#xA;nsCertType              = client&#xA;nsComment               = &#34;OpenSSL Generated Client Certificate&#34;&#xA;&#xA;a id=&#34;creazione-crt-client&#34;Creazione crt client/a&#xA;&#xA;Come per il certificato server, il certificato client verrà creato in seguito alla firma del csr dalla CA e aver settato scadenza a algoritmo di digest (altrimenti verrà applicato un default). Essendo un certificato client, viene mostrato anche come costruire un p12, utile nei casi in cui l&#39;autenticazione  del client viene fatta dal browser.&#xA;OUTPUTCERT=pathoutputcert&#xA;CONFCERT=pathfilecnf&#xA;&#xA;CRT Client &#xA;openssl x509 \&#xA;-extfile $CONFCERT/clientcert.cnf \&#xA;-req -in $OUTPUTCERT/johndoe.csr \&#xA;-days 365 -sha384 \&#xA;-CA $OUTPUTCERT/caclient.crt \&#xA;-CAkey $OUTPUTCERT/caclient.key \&#xA;-CAcreateserial \&#xA;-out $OUTPUTCERT/johndoe.crt&#xA;&#xA;Creazione p12 &#xA;openssl pkcs12 -export -inkey $OUTPUTCERT/johndoe.key -in $OUTPUTCERT/johndoe.crt -out $OUTPUTCERT/johndoe.p12&#xA;&#xA;a id=&#34;riassunto&#34;Riassunto/a&#xA;&#xA;Di seguito, la raccolta di quanto visto finora, allo scopo di rendere un colpo d&#39;occhio immediato e di dare una base per rendere scriptabile il processo che già così, tenendo presente i file di configurazione così composti e raccogliendo in uno script i comandi proposti, crea 2 CA, un certificato server e uno client (a meno dei subj di fantasia)&#xA;&#xA;File di configurazione:&#xA;###############&#xA;cacert.cnf &#xA;###############&#xA;[ v3ca ]&#xA;basicConstraints        = critical,CA:true&#xA;keyUsage                = critical, cRLSign, keyCertSign&#xA;subjectKeyIdentifier    = hash&#xA;authorityKeyIdentifier  = keyid:always,issuer&#xA;nsCertType              = sslCA&#xA;nsComment               = &#34;OpenSSL Generated CA Root Certificate&#34;&#xA;&#xA;##################&#xA;serverreq.cnf &#xA;##################&#xA;[ req ]&#xA;reqextensions = v3serverreq&#xA; &#xA;[ v3serverreq ]&#xA;basicConstraints        = CA:FALSE&#xA;subjectKeyIdentifier    = hash&#xA;keyUsage                = nonRepudiation, digitalSignature, keyEncipherment, dataEncipherment&#xA;extendedKeyUsage        = serverAuth&#xA;nsCertType              = server&#xA;nsComment               = &#34;OpenSSL Generated Server Request Certificate&#34;&#xA;subjectAltName          = @altnames&#xA;&#xA;[ altnames ]&#xA;DNS.1 = server.web.local&#xA;&#xA;###################&#xA;servercert.cnf &#xA;###################&#xA;basicConstraints        = CA:FALSE&#xA;subjectKeyIdentifier    = hash&#xA;keyUsage                = nonRepudiation, digitalSignature, keyEncipherment, dataEncipherment&#xA;extendedKeyUsage        = serverAuth&#xA;nsCertType              = server&#xA;nsComment               = &#34;OpenSSL Generated Server Certificate&#34;&#xA;subjectAltName          = @altnames&#xA; &#xA;[ altnames ]&#xA;DNS.1 = server.web.local&#xA;&#xA;##################&#xA;clientreq.cnf &#xA;##################&#xA;[ req ]&#xA;reqextensions = v3clientreq&#xA; &#xA;[ v3clientreq ]&#xA;basicConstraints        = CA:FALSE&#xA;subjectKeyIdentifier    = hash&#xA;keyUsage                = nonRepudiation, digitalSignature, keyEncipherment, dataEncipherment&#xA;extendedKeyUsage        = clientAuth&#xA;nsCertType              = client&#xA;nsComment               = &#34;OpenSSL Generated Client Request Certificate&#34;&#xA;&#xA;###################&#xA;clientcert.cnf &#xA;###################&#xA;basicConstraints        = CA:FALSE&#xA;subjectKeyIdentifier    = hash&#xA;keyUsage                = nonRepudiation, digitalSignature, keyEncipherment, dataEncipherment&#xA;extendedKeyUsage        = clientAuth&#xA;nsCertType              = client&#xA;nsComment               = &#34;OpenSSL Generated Client Certificate&#34;&#xA;Script di creazione certificati:&#xA;OUTPUTCERT=pathoutputcert&#xA;CONFCERT=pathfilecnf&#xA;&#xA;#############&#xA;CA SERVER &#xA;#############&#xA;openssl req -config $CONFCERT/cacert.cnf -extensions v3ca -x509 -days 1825 -sha512 -nodes -newkey rsa:4096 -subj &#34;/C=IT/ST=Italia/CN=GlobalSign Test RootCA&#34; -keyout $OUTPUTCERT/caserver.key -out $OUTPUTCERT/caserver.crt&#xA;&#xA;##########&#xA;Server &#xA;##########&#xA;csr&#xA;openssl req -config $CONFCERT/serverreq.cnf -nodes -newkey rsa:2048 -subj &#34;/C=IT/ST=Italia/L=Roma/O=My Company Ltd/OU=Divisione IT web/CN=server.web.local/emailAddress=it@web.local&#34; -keyout $OUTPUTCERT/server.key -out $OUTPUTCERT/server.csr&#xA;crt&#xA;openssl x509 -extfile $CONFCERT/servercert.cnf &#xA;-req -in $OUTPUTCERT/server.csr -days 365 -sha384 -CA $OUTPUTCERT/caserver.crt -CAkey $OUTPUTCERT/caserver.key -CAcreateserial -out $OUTPUTCERT/server.crt&#xA;&#xA;#############&#xA;CA Client &#xA;#############&#xA;openssl req -config $CONFCERT/cacert.cnf -extensions v3ca -x509 -days 1825 -sha512 -nodes -newkey rsa:4096 -subj &#34;/C=IT/ST=Italia/CN=Digicert Test RootCA&#34; -keyout $OUTPUTCERT/caclient.key -out $OUTPUTCERT/caclient.crt&#xA;&#xA;##########&#xA;Client &#xA;##########&#xA;csr&#xA;openssl req -config $CONFCERT/clientreq.cnf -nodes -newkey rsa:2048 -subj &#34;/C=IT/ST=Italia/L=Roma/O=Another Company Ltd/OU=User WebApp/CN=John Doe/emailAddress=john.doe@unknown.local&#34; -keyout $OUTPUTCERT/johndoe.key -out $OUTPUTCERT/johndoe.csr&#xA;crt &#xA;openssl x509 -extfile $CONFCERT/clientcert.cnf -req -in $OUTPUTCERT/johndoe.csr -days 365 -sha384 -CA $OUTPUTCERT/caclient.crt -CAkey $OUTPUTCERT/caclient.key -CAcreateserial -out $OUTPUTCERT/johndoe.crt&#xA;p12&#xA;openssl pkcs12 -export -inkey $OUTPUTCERT/johndoe.key -in $OUTPUTCERT/johndoe.crt -out $OUTPUTCERT/johndoe.p12&#xA;&#xA;a id=&#34;creazione-ca-intermediate-certificati-client-server&#34;Caso 2. Creazione di CA, Intermediate CA e dei certificati client e server/a&#xA;&#xA;Gli esempi che seguiranno saranno presentati sullo stile del riassunto perché fondamentalmente molto simili al caso 1. Si aggiunge un punto di intermediazione in più dato dal fatto che la CA delega ad una CA &#34;subalterna&#34; l&#39;incarico di verificare le paternità di coloro i quali richiedono certificati.&#xA;&#xA;Quindi avremo:&#xA;&#xA;una root CA, certificato self-signed&#xA;un&#39;Intermediate CA, validata dalla root CA (csr + crt firmato dalla root CA)&#xA; n certificati client/server validati dall&#39;Intermediate CA (csr + crt firmato dall&#39;Intermediate CA)&#xA;&#xA;Creazione certificati&#xA;OUTPUTCERT=$HOME/stunnel/build-cert&#xA;CONFCERT=$HOME/stunnel/conf.d&#xA;&#xA;###########&#xA;Root CA &#xA;###########&#xA;openssl req -config $CONFCERT/cacert.cnf -extensions v3ca -x509 -days 1825 -sha512 -nodes -newkey rsa:4096 -subj &#34;/C=IT/ST=Italia/CN=GlobalSign Test RootCA&#34; -keyout $OUTPUTCERT/rootca.key -out $OUTPUTCERT/rootca.crt&#xA;&#xA;###################&#xA;INTERMEDIATE CA &#xA;###################&#xA;csr&#xA;openssl req -config $CONFCERT/intermediatereq.cnf -nodes -newkey rsa:2048 -subj &#34;/C=IT/ST=Italia/CN=GlobalSign Test IntermediateCA&#34; -keyout $OUTPUTCERT/intermediate.key -out $OUTPUTCERT/intermediate.csr&#xA;crt&#xA;openssl x509 -extfile $CONFCERT/intermediatecert.cnf -req -in $OUTPUTCERT/intermediate.csr -days 365 -sha384 -CA $OUTPUTCERT/rootca.crt -CAkey $OUTPUTCERT/rootca.key -CAcreateserial -out $OUTPUTCERT/intermediate.crt&#xA;&#xA;##########&#xA;Server &#xA;##########&#xA;csr&#xA;openssl req -config $CONFCERT/serverreq.cnf -nodes -newkey rsa:2048 -subj &#34;/C=IT/ST=Italia/L=Roma/O=My Company Ltd/OU=Divisione IT web/CN=server.web.local/emailAddress=it@web.local&#34; -keyout $OUTPUTCERT/server.key -out $OUTPUTCERT/server.csr&#xA;crt&#xA;openssl x509 -extfile $CONFCERT/servercert.cnf &#xA;-req -in $OUTPUTCERT/server.csr -CA $OUTPUTCERT/intermediate.crt -CAkey $OUTPUTCERT/intermediate.key -CAcreateserial -days 365 -sha384 -out $OUTPUTCERT/server.crt&#xA;&#xA;##########&#xA;Client &#xA;##########&#xA;csr&#xA;openssl req -config $CONFCERT/clientreq.cnf -nodes -newkey rsa:2048 -subj &#34;/C=IT/ST=Italia/L=Roma/O=Another Company Ltd/OU=User WebApp/CN=John Doe/emailAddress=john.doe@unknown.local&#34; -keyout $OUTPUTCERT/johndoe.key -out $OUTPUTCERT/johndoe.csr&#xA;crt&#xA;openssl x509 -extfile $CONFCERT/clientcert.cnf -req -in $OUTPUTCERT/johndoe.csr -days 365 -sha384 -CA $OUTPUTCERT/intermediate.crt -CAkey $OUTPUTCERT/intermediate.key -CAcreateserial -out $OUTPUTCERT/johndoe.crt&#xA;p12&#xA;openssl pkcs12 -export -inkey $OUTPUTCERT/johndoe.key -in $OUTPUTCERT/legs.crt -out $OUTPUT_CERT/johndoe.p12&#xA;&#xA;#DigitalCertificate #x509 #csr #openssl #ca #cryptography #AsymmetricEncryption #SymmetricEncryption #DigitalSignature]]&gt;</description>
      <content:encoded><![CDATA[<p><strong><em>(pubblicato il 30 gennaio 2023)</em></strong>
<img src="https://pixelfed.uno/storage/m/_v2/489827599091373610/42a8ecf32-5a8865/nGFJPa2PgFzw/Iofc5MJiTuOUqX8BRjCeTXxgRR5HVNb0aJIcgoFR.jpg" alt="certificati digitali">
<small><i>Fonte:  Foto di <a href="https://pixabay.com/it/users/skylarvision-2957633/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=3344700" rel="nofollow">skylarvision</a> da <a href="https://pixabay.com/it//?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=3344700" rel="nofollow">Pixabay</a></i></small></p>

<p>A volte, per ragioni di test o per uso domestico (configurazione di una vpn con openvpn per es. o di un <a href="https://noblogo.org/aytin/stunnel-cose-e-come-si-configura" rel="nofollow">server stunnel</a>), mi càpita di avere bisogno di un certificato digitale.</p>

<p>Finché il certificato è self-signed, l&#39;operazione richiede veramente pochissimo sforzo. Ma quando devo far riferimento ad una CA interna, la questione si complica.

Proverò adesso a descrivere le operazioni che compio quando devo creare:</p>
<ol><li>CA + certificati server +  certificati client</li>
<li>CA + Intermediate CA + certificati server + certificati client</li></ol>

<h2 id="indice">Indice</h2>
<ol><li><a href="#cose-un-certificato-digitale" rel="nofollow">Cos’è un certificato digitale</a></li>
<li><a href="#openssl" rel="nofollow">OpenSSL</a></li>
<li><a href="#struttura-laboratorio" rel="nofollow">Struttura del “laboratorio”</a></li>
<li><a href="#creazione-ca-certificati-client-server" rel="nofollow">Caso 1: Creazione delle CA e dei certificati client e server</a>
<ol><li><a href="#creazione-ca-certificati-server" rel="nofollow">Creazione della CA per i certificati server</a>
<ol><li><a href="#configurazione-ca-server" rel="nofollow">Configurazione CA server</a></li>
<li><a href="#creazione-ca-server" rel="nofollow">Creazione CA server</a></li></ol></li>
<li><a href="#creazione-certificato-server" rel="nofollow">Creazione del certificato server</a>
<ol><li><a href="#configurazione-csr-server" rel="nofollow">Configurazione csr server</a></li>
<li><a href="#creazione-csr-server" rel="nofollow">Creazione csr server</a></li>
<li><a href="#configurazione-crt-server" rel="nofollow">Configurazione crt server</a></li>
<li><a href="#creazione-crt-server" rel="nofollow">Creazione crt server</a></li></ol></li>
<li><a href="#creazione-ca-certificati-client" rel="nofollow">Creazione della CA per i certificati client</a>
<ol><li><a href="#configurazione-ca-client" rel="nofollow">Configurazione CA client</a></li>
<li><a href="#creazione-ca-client" rel="nofollow">Creazione CA client</a></li></ol></li>
<li><a href="#creazione-certificato-client" rel="nofollow">Creazione del certificato client</a>
<ol><li><a href="#configurazione-csr-client" rel="nofollow">Configurazione csr client</a></li>
<li><a href="#creazione-csr-client" rel="nofollow">Creazione csr client</a></li>
<li><a href="#configurazione-crt-client" rel="nofollow">Configurazione crt client</a></li>
<li><a href="#creazione-crt-client" rel="nofollow">Creazione crt client</a></li></ol></li>
<li><a href="#riassunto" rel="nofollow">Riassunto</a></li></ol></li>
<li><a href="#creazione-ca-intermediate-certificati-client-server" rel="nofollow">Caso 2: Creazione di CA, Intermediate CA e dei certificati client e server</a></li></ol>

<h2 id="a-id-cose-un-certificato-digitale-cos-è-un-certificato-digitale-a"><a id="cose-un-certificato-digitale">Cos&#39;è un certificato digitale</a></h2>

<p>I certificati digitali sono degli oggetti utilizzati nelle comunicazioni per fornire un canale sicuro su un mezzo intrinsecamente insicuro (internet) e vengono costruiti secondo lo standard <a href="https://en.wikipedia.org/wiki/X.509" rel="nofollow">X.509</a>, un protocollo che definisce il formato dei certificati e l&#39;insieme degli elementi di contorno come elementi autoritativi, elenchi di revoca e modalità di convalida.</p>

<p>Un certificato digitale è un oggetto crittografico costituito da una parte pubblica (chiave pubblica + informazioni personali del possessore del certificato) e una parte privata (la chiave privata).</p>

<p>La parte pubblica viene firmata digitalmente per garantire autenticazione e integrità e può essere eseguita:</p>
<ul><li>da se stesso (i cosiddetti certificati self-signed, una sorta di autocertificazione)</li>
<li>da una CA, un&#39;autorità superiore che garantisce che le informazioni del certificato sono di chi dice di essere.</li></ul>

<h2 id="a-id-openssl-openssl-a"><a id="openssl">OpenSSL</a></h2>

<p>Per la costruzione di un certificato digitale, uso <strong><a href="https://www.openssl.org/" rel="nofollow">OpenSSL</a></strong> che è sia una libreria crittografica che implementa i protocolli TLS e SSL (deprecato), sia un toolkit professionale per l&#39;utilizzo di funzionalità di crittografia.,</p>

<p>OpenSSL ha una cli molto complessa che può essere in parte configurata, soprattutto nella parte di definizione dei certificati, da un file di configurazione, <strong>openssl.cnf</strong>, un file <em>.ini</em> diviso in sezioni, contenenti una lista di coppie (chiave,valore).</p>

<p>Nel proseguio, invece che usare un unico file omnicomprensivo, ne verrà usato solo un frammento in base al contesto (certificato o csr di ca, intermediate, server o client). Ho trovato questo approccio più flessibile e più chiaro.</p>

<p>Negli esempi, userò questi file che avranno dei nomi “parlanti” in base a ciò che dovrò definire. Non mi dilungherò nella spiegazione delle singole opzioni perché:</p>
<ol><li>non le conosco tutte</li>
<li>approfondire ogni singola direttiva di openssl.cnf richiederebbe un blog dedicato.</li></ol>

<p>Si potrebbe ancora dissertare sulle versioni di openssl da usare, sui suoi fork ma non è questo il momento, forse in altri post (che sono in fase di preparazione.)</p>

<h2 id="a-id-struttura-laboratorio-struttura-del-laboratorio-a"><a id="struttura-laboratorio">Struttura del “laboratorio”</a></h2>

<p>Data la destinazione dei certificati (test o uso strettamente interno), i certificati vengono generati nella maniera più compatta possibile.</p>
<ul><li>Per le root CA, gli unici certificati self-signed, viene generato il csr e il crt in un&#39;unica soluzione.</li>
<li>Le intermediate CA vengono generate, come ogni altro certificato server / client, producendo prima un csr che viene firmato dalla root CA per produrre il crt.</li>
<li>Anche i certificati server e client, come detto, vengono generati come l&#39;intermediate CA, producendo prima il csr che verrà firmato da una CA.</li>
<li>Ogni fase (per “fase” intendo produzione di un csr o di un crt) sarà “guidata” dal frammento di file di configurazione avente quel famoso nome “parlante”.</li>
<li>Prenderò in considerazione due casistiche. In una i certificati server e client verranno validati da una root CA. Nell&#39;altro, la root CA delegherà ad una intermediate CA la validazione di certificati server / client.</li>
<li>Nella prima casistica, per rendere la soluzione più generica, supporrò di avere una CA distinta per i certificati client e una per i server.</li></ul>

<p>⚠️ ⚠️ ⚠️ <strong>SUPER WARNING</strong>⚠️ ⚠️ ⚠️
Non è questo il modo formalmente corretto per la creazione di un certificato, almeno non quello da usare per un ambiente di produzione.</p>

<p>Non farò nessuna assunzione sulle modalità di cifratura, né sul tuning di openssl.</p>

<p>Il mio obiettivo qui è: voglio ottenere un certificato nella maniera più rapida possibile (e per rapido intendo senza troppi sbattimenti nelle configurazioni perché, alla fine, tutto può essere scriptabile e quindi veloce).</p>

<p>I file di configurazione saranno composti da massimo due sezioni contenenti le extensions X.509  necessarie per la creazione dei certificati. Il resto dei parametri sarà  passato nella cli piuttosto che nel file di configurazione.</p>

<p>Mi rendo conto che per una buona comprensione occorrerebbe avere un po&#39; di confidenza con:</p>
<ul><li>i concetti di cifratura asimmetrica e di certificato digitale</li>
<li>configurazione e utilizzo base di openssl</li>
<li>conoscenza di openssl.cnf e extensions X.509</li></ul>

<h2 id="a-id-creazione-ca-certificati-client-server-caso-1-creazione-delle-ca-e-dei-certificati-client-e-server-a"><a id="creazione-ca-certificati-client-server">Caso 1: Creazione delle CA e dei certificati client e server</a></h2>

<p>La creazione della CA consisterà in un certificato self-signed ottenuto con un unico comando. Per i certificati invece verrà prodotto prima il csr che poi sarà firmato dalla CA al fine di ottenere il certificato vero e proprio.</p>

<p>Piccola nota: gli attributi <strong>basicConstraints</strong>, <strong>nsCertType</strong>, <strong>extendedKeyUsage</strong> saranno determinanti per battezzare una CA piuttosto che un certificato client/server</p>

<h3 id="a-id-creazione-ca-certificati-server-creazione-della-ca-per-i-certificati-server-a"><a id="creazione-ca-certificati-server">Creazione della CA per i certificati server</a></h3>

<p>La creazione del certificato sarà one-shot.</p>

<h4 id="a-id-configurazione-ca-server-configurazione-ca-server-a"><a id="configurazione-ca-server">Configurazione CA server</a></h4>

<p>Il file di configurazione sarà <strong>ca_cert.cnf</strong></p>

<pre><code>###############
# ca_cert.cnf #
###############
[ v3_ca ]
basicConstraints        = critical,CA:true
keyUsage                = critical, cRLSign, keyCertSign
subjectKeyIdentifier    = hash
authorityKeyIdentifier  = keyid:always,issuer
nsCertType              = sslCA
nsComment               = &#34;OpenSSL Generated CA Root Certificate&#34;
</code></pre>

<h4 id="a-id-creazione-ca-server-creazione-ca-server-a"><a id="creazione-ca-server">Creazione CA server</a></h4>

<pre><code>OUTPUT_CERT=&lt;path_output_cert&gt;
CONF_CERT=&lt;path_file_cnf&gt;

### CA SERVER ###
openssl req \
-config $CONF_CERT/ca_cert.cnf \
-extensions v3_ca \ 
-x509 \
-days 1825 -sha512 \
-nodes -newkey rsa:4096 \
-subj &#34;/C=IT/ST=Italia/CN=GlobalSign Test RootCA&#34; \
-keyout $OUTPUT_CERT/ca_server.key \
-out $OUTPUT_CERT/ca_server.crt
</code></pre>
<ul><li><strong>openssl req</strong> : crea un csr</li>
<li><strong>-config $CONF<em>CERT/ca</em>cert.cnf</strong> : path del file di configurazione</li>
<li><strong>-extensions v3_ca</strong> : sezione del file da prendere come riferimento (in questo caso per le sole extensions X.509)</li>
<li><strong>-x509</strong> : fa in modo che l&#39;output sia direttamente un certificato piuttosto che un csr</li>
<li><strong>-days 1825 -sha512</strong> : fissa la scadenza a 5 anni e setta sha512 come algoritmo di digest.</li>
<li><strong>-nodes -newkey rsa:4096</strong> : crea una chiave rsa non cifrata a 4096 bit</li>
<li><strong>-subj “/C=IT/ST=Roma”/CN=GlobalSign Test RootCA”</strong> : distinguished_name passato da cli</li>
<li><strong>-keyout $OUTPUT<em>CERT/ca</em>server.key</strong> : path di destinazione della chiave</li>
<li><strong>-out $OUTPUT<em>CERT/ca</em>server.crt</strong> : path di destinazione del certificato CA.</li></ul>

<h3 id="a-id-creazione-certificato-server-creazione-certificato-server-a"><a id="creazione-certificato-server">Creazione certificato server</a></h3>

<p>Verrà generato prima il csr (certificate signing request) che sarà firmato dalla CA per generare il certificato effettivo.</p>

<h4 id="a-id-configurazione-csr-server-configurazione-csr-server-a"><a id="configurazione-csr-server">Configurazione csr server</a></h4>

<p>Il file di configurazione per il csr sarà <strong>server_req.cnf</strong>, diviso in 3 sezioni.</p>

<p>La prima, <strong>req</strong>, è quella usata da <strong>openssl req</strong> (in assenza della quale verrà sollevata un&#39;eccezione) e contiene solo il rimando alle extensions X.509 da usare.</p>

<p>Come prima, le extensions X.509 (<strong>v3<em>server</em>req</strong>) definiscono i giusti attributi per questo tipo di certificato.</p>

<p><strong>N.B.</strong>
L&#39;ultima sezione è quella degli <strong>alternatives_name</strong>, la cui assenza non comporta problemi nella creazione del certificato ma potrebbe far fallire i check effettuati da alcuni prodotti, ad es. i webserver che pur riconoscendo nel <strong>Common Name</strong> il nome del servizio (es. la url) scatenano ugualmente l&#39;eccezione <strong>BAD<em>CERT</em>DOMAIN</strong></p>

<pre><code>##################
# server_req.cnf #
##################
[ req ]
req_extensions = v3_server_req

[ v3_server_req ]
basicConstraints        = CA:FALSE
subjectKeyIdentifier    = hash
keyUsage                = nonRepudiation, digitalSignature, keyEncipherment, dataEncipherment
extendedKeyUsage        = serverAuth
nsCertType              = server
nsComment               = &#34;OpenSSL Generated Server Request Certificate&#34;
subjectAltName          = @alt_names

[ alt_names ]
DNS.1 = server.web.local
</code></pre>

<h4 id="a-id-creazione-csr-server-creazione-csr-server-a"><a id="creazione-csr-server">Creazione csr server</a></h4>

<p>La sintassi è sostanzialmente uguale a quanto visto per la CA con la sola eccezione del parametro <strong>-x509</strong> (che creava un crt invece che un csr). Il csr creerà il certificato e la coppia di chiavi pubblica e privata.</p>

<pre><code>OUTPUT_CERT=&lt;path_output_cert&gt;
CONF_CERT=&lt;path_file_cnf&gt;

### CSR Server ###
openssl req \
-config $CONF_CERT/server_req.cnf \
-nodes -newkey rsa:2048 \
-subj &#34;/C=IT/ST=Italia/L=Roma/O=My Company Ltd/OU=Divisione IT web/CN=server.web.local/emailAddress=it@web.local&#34; \
-keyout $OUTPUT_CERT/server.key \
-out $OUTPUT_CERT/server.csr
</code></pre>
<ul><li><strong>openssl req</strong> : crea un csr</li>
<li><strong>-config $CONF<em>CERT/server</em>req.cnf</strong> : path del file di configurazione</li>
<li><strong>-nodes -newkey rsa:2048</strong> : crea una chiave rsa non cifrata a 2048 bit</li>
<li><strong>-subj “/C=IT/ST=Italia/L=Roma/O=My Company Ltd/OU=Divisione IT web/CN=server.web.local/emailAddress=it@web.local”</strong> : distinguished_name passato da cli</li>
<li><strong>-keyout $OUTPUT_CERT/server.key</strong> : path di destinazione della chiave</li>
<li><strong>-out $OUTPUT_CERT/server.csr</strong> : path di destinazione del csr</li></ul>

<h4 id="a-id-configurazione-crt-server-configurazione-crt-server-a"><a id="configurazione-crt-server">Configurazione crt server</a></h4>

<p>A differenza di prima, non ho un file di configurazioni vero e proprio. Non usando il file generico <strong>openssl.cnf</strong>, l&#39;unico file che si può invocare dal comando <code>openssl x509</code> è un elenco di attributi che il certificato dovrà possedere e questo ci è sufficiente per creare certificati client o server.</p>

<p>Il file di configurazione per il crt sarà <strong>server_cert.cnf</strong>.</p>

<pre><code>###################
# server_cert.cnf #
###################
basicConstraints        = CA:FALSE
subjectKeyIdentifier    = hash
keyUsage                = nonRepudiation, digitalSignature, keyEncipherment, dataEncipherment
extendedKeyUsage        = serverAuth
nsCertType              = server
nsComment               = &#34;OpenSSL Generated Server Certificate&#34;
subjectAltName          = @alt_names

[ alt_names ]
DNS.1 = server.web.local
</code></pre>

<h4 id="a-id-creazione-crt-server-creazione-crt-server-a"><a id="creazione-crt-server">Creazione crt server</a></h4>

<p>Di fatto, le uniche operazione che compio sono quelle di firmare con la CA il certificato, di fissare una scadenza e l&#39;algoritmo di digest (altrimenti verrà applicato un default). Il resto, lo eredito dal csr (potrei sovrascrivere alcune cose come il <strong>subj</strong>) o dalle estensioni presenti nel file.</p>

<pre><code>OUTPUT_CERT=&lt;path_output_cert&gt;
CONF_CERT=&lt;path_file_cnf&gt;

### CRT Server ###
openssl x509 \
-extfile $CONF_CERT/server_cert.cnf \
-req -in $OUTPUT_CERT/server.csr \
-days 365 -sha384 \
-CA $OUTPUT_CERT/ca_server.crt \
-CAkey $OUTPUT_CERT/ca_server.key \
-CAcreateserial \
-out $OUTPUT_CERT/server.crt
</code></pre>
<ul><li><strong>openssl x509</strong> : crea un certificato x509</li>
<li><strong>-extfile $CONF<em>CERT/server</em>cert.cnf</strong> : path del file di estensioni</li>
<li><strong>-req</strong> : acquisizione del file csr da far firmare</li>
<li><strong>-CA $OUTPUT<em>CERT/ca</em>server.crt</strong> : acquisizione del certificato della CA</li>
<li><strong>-CAkey $OUTPUT<em>CERT/ca</em>server.key</strong> : acquisizione della chiave privata della CA che firmerà il certificato</li>
<li><strong>-CAcreateserial</strong> : crea un seriale randomico per il certificato da creare. Normalmente una CA crea dei seriali progressivi memorizzandoli in un database interno.</li>
<li><strong>-days 365 -sha384</strong> : fissa ad un anno la scadenza del certificato e usa sha384 come algoritmo di digest</li>
<li><strong>-out $OUTPUT_CERT/server.crt</strong> : path di destinazione del certificato server.</li></ul>

<h3 id="a-id-creazione-ca-certificati-client-creazione-della-ca-per-i-certificati-client-a"><a id="creazione-ca-certificati-client">Creazione della CA per i certificati client</a></h3>

<p>È praticamente la stessa cosa. La differenza è solo formale visto che, tecnicamente, i comandi che andrò ad eseguire saranno praticamente gli stessi (l&#39;unica differenza di rilievo riguarderà i certificati client a cui corrisponderanno estensioni X.509 leggermente differenti)</p>

<h4 id="a-id-configurazione-ca-client-configurazione-della-ca-client-a"><a id="configurazione-ca-client">Configurazione della CA client</a></h4>

<p>È lo stesso file visto <a href="#configurazione-ca-server" rel="nofollow">prima</a>.</p>

<h4 id="a-id-creazione-ca-client-creazione-della-ca-client-a"><a id="creazione-ca-client">Creazione della CA client</a></h4>

<pre><code>OUTPUT_CERT=&lt;path_output_cert&gt;
CONF_CERT=&lt;path_file_cnf&gt;

### CA Client ###
openssl req \
-config $CONF_CERT/ca_cert.cnf \
-extensions v3_ca \ 
-x509 \
-days 1825 -sha512 \
-nodes -newkey rsa:4096 \
-subj &#34;/C=IT/ST=Italia/CN=Digicert Test RootCA&#34; \
-keyout $OUTPUT_CERT/ca_client.key \
-out $OUTPUT_CERT/ca_client.crt
</code></pre>

<p>C&#39;è poco da dire. L&#39;unica variazione degna di nota è il subj, per il resto è identico alla <a href="#creazione-ca-server" rel="nofollow">creazione della ca server</a>.</p>

<h3 id="a-id-creazione-certificato-client-creazione-certificato-client-a"><a id="creazione-certificato-client">Creazione certificato client</a></h3>

<p>Come fatto per il server, verrà generato prima il csr che sarà firmato dalla CA per generare il certificato effettivo.</p>

<h4 id="a-id-configurazione-csr-client-configurazione-csr-client-a"><a id="configurazione-csr-client">Configurazione csr client</a></h4>

<p>Come per i <a href="#configurazione-csr-server" rel="nofollow">certificati server</a>, <strong>extendedKeyUsage</strong> e <strong>nsCertType</strong> stabiliscono come viene battezzato il certificato.</p>

<pre><code>##################
# client_req.cnf #
##################
[ req ]
req_extensions = v3_client_req

[ v3_client_req ]
basicConstraints        = CA:FALSE
subjectKeyIdentifier    = hash
keyUsage                = nonRepudiation, digitalSignature, keyEncipherment, dataEncipherment
extendedKeyUsage        = clientAuth
nsCertType              = client
nsComment               = &#34;OpenSSL Generated Client Request Certificate&#34;
</code></pre>

<h4 id="a-id-creazione-csr-client-creazione-csr-client-a"><a id="creazione-csr-client">Creazione csr client</a></h4>

<p>Nel csr, viene creata la chiave, rsa a 2048 bit, e viene settato il subj.</p>

<pre><code>OUTPUT_CERT=&lt;path_output_cert&gt;
CONF_CERT=&lt;path_file_cnf&gt;

### CSR Client ###
openssl req \
-config $CONF_CERT/client_req.cnf \
-nodes -newkey rsa:2048 \
-subj &#34;/C=IT/ST=Italia/L=Roma/O=Another Company Ltd/OU=User WebApp/CN=John Doe/emailAddress=john.doe@unknown.local&#34; \
-keyout $OUTPUT_CERT/johndoe.key \
-out $OUTPUT_CERT/johndoe.csr
</code></pre>

<h4 id="a-id-configurazione-crt-client-configurazione-crt-client-a"><a id="configurazione-crt-client">Configurazione crt client</a></h4>

<p>Il file di configurazione raccoglie solo le estensioni con cui il certificato viene istanziato</p>

<pre><code>###################
# client_cert.cnf #
###################
basicConstraints        = CA:FALSE
subjectKeyIdentifier    = hash
keyUsage                = nonRepudiation, digitalSignature, keyEncipherment, dataEncipherment
extendedKeyUsage        = clientAuth
nsCertType              = client
nsComment               = &#34;OpenSSL Generated Client Certificate&#34;
</code></pre>

<h4 id="a-id-creazione-crt-client-creazione-crt-client-a"><a id="creazione-crt-client">Creazione crt client</a></h4>

<p>Come per il certificato server, il certificato client verrà creato in seguito alla firma del csr dalla CA e aver settato scadenza a algoritmo di digest (altrimenti verrà applicato un default). Essendo un certificato client, viene mostrato anche come costruire un p12, utile nei casi in cui l&#39;autenticazione  del client viene fatta dal browser.</p>

<pre><code>OUTPUT_CERT=&lt;path_output_cert&gt;
CONF_CERT=&lt;path_file_cnf&gt;

### CRT Client ###
openssl x509 \
-extfile $CONF_CERT/client_cert.cnf \
-req -in $OUTPUT_CERT/johndoe.csr \
-days 365 -sha384 \
-CA $OUTPUT_CERT/ca_client.crt \
-CAkey $OUTPUT_CERT/ca_client.key \
-CAcreateserial \
-out $OUTPUT_CERT/johndoe.crt

### Creazione p12 ###
openssl pkcs12 -export -inkey $OUTPUT_CERT/johndoe.key -in $OUTPUT_CERT/johndoe.crt -out $OUTPUT_CERT/johndoe.p12
</code></pre>

<h3 id="a-id-riassunto-riassunto-a"><a id="riassunto">Riassunto</a></h3>

<p>Di seguito, la raccolta di quanto visto finora, allo scopo di rendere un colpo d&#39;occhio immediato e di dare una base per rendere scriptabile il processo che già così, tenendo presente i file di configurazione così composti e raccogliendo in uno script i comandi proposti, crea 2 CA, un certificato server e uno client (a meno dei subj di fantasia)</p>

<p><strong>File di configurazione:</strong></p>

<pre><code>###############
# ca_cert.cnf #
###############
[ v3_ca ]
basicConstraints        = critical,CA:true
keyUsage                = critical, cRLSign, keyCertSign
subjectKeyIdentifier    = hash
authorityKeyIdentifier  = keyid:always,issuer
nsCertType              = sslCA
nsComment               = &#34;OpenSSL Generated CA Root Certificate&#34;

##################
# server_req.cnf #
##################
[ req ]
req_extensions = v3_server_req
 
[ v3_server_req ]
basicConstraints        = CA:FALSE
subjectKeyIdentifier    = hash
keyUsage                = nonRepudiation, digitalSignature, keyEncipherment, dataEncipherment
extendedKeyUsage        = serverAuth
nsCertType              = server
nsComment               = &#34;OpenSSL Generated Server Request Certificate&#34;
subjectAltName          = @alt_names

[ alt_names ]
DNS.1 = server.web.local

###################
# server_cert.cnf #
###################
basicConstraints        = CA:FALSE
subjectKeyIdentifier    = hash
keyUsage                = nonRepudiation, digitalSignature, keyEncipherment, dataEncipherment
extendedKeyUsage        = serverAuth
nsCertType              = server
nsComment               = &#34;OpenSSL Generated Server Certificate&#34;
subjectAltName          = @alt_names
 
[ alt_names ]
DNS.1 = server.web.local

##################
# client_req.cnf #
##################
[ req ]
req_extensions = v3_client_req
 
[ v3_client_req ]
basicConstraints        = CA:FALSE
subjectKeyIdentifier    = hash
keyUsage                = nonRepudiation, digitalSignature, keyEncipherment, dataEncipherment
extendedKeyUsage        = clientAuth
nsCertType              = client
nsComment               = &#34;OpenSSL Generated Client Request Certificate&#34;

###################
# client_cert.cnf #
###################
basicConstraints        = CA:FALSE
subjectKeyIdentifier    = hash
keyUsage                = nonRepudiation, digitalSignature, keyEncipherment, dataEncipherment
extendedKeyUsage        = clientAuth
nsCertType              = client
nsComment               = &#34;OpenSSL Generated Client Certificate&#34;
</code></pre>

<p><strong>Script di creazione certificati:</strong></p>

<pre><code>OUTPUT_CERT=&lt;path_output_cert&gt;
CONF_CERT=&lt;path_file_cnf&gt;

#############
# CA SERVER #
#############
openssl req -config $CONF_CERT/ca_cert.cnf -extensions v3_ca -x509 -days 1825 -sha512 -nodes -newkey rsa:4096 -subj &#34;/C=IT/ST=Italia/CN=GlobalSign Test RootCA&#34; -keyout $OUTPUT_CERT/ca_server.key -out $OUTPUT_CERT/ca_server.crt

##########
# Server #
##########
# csr
openssl req -config $CONF_CERT/server_req.cnf -nodes -newkey rsa:2048 -subj &#34;/C=IT/ST=Italia/L=Roma/O=My Company Ltd/OU=Divisione IT web/CN=server.web.local/emailAddress=it@web.local&#34; -keyout $OUTPUT_CERT/server.key -out $OUTPUT_CERT/server.csr
# crt
openssl x509 -extfile $CONF_CERT/server_cert.cnf 
-req -in $OUTPUT_CERT/server.csr -days 365 -sha384 -CA $OUTPUT_CERT/ca_server.crt -CAkey $OUTPUT_CERT/ca_server.key -CAcreateserial -out $OUTPUT_CERT/server.crt

#############
# CA Client #
#############
openssl req -config $CONF_CERT/ca_cert.cnf -extensions v3_ca -x509 -days 1825 -sha512 -nodes -newkey rsa:4096 -subj &#34;/C=IT/ST=Italia/CN=Digicert Test RootCA&#34; -keyout $OUTPUT_CERT/ca_client.key -out $OUTPUT_CERT/ca_client.crt

##########
# Client #
##########
# csr
openssl req -config $CONF_CERT/client_req.cnf -nodes -newkey rsa:2048 -subj &#34;/C=IT/ST=Italia/L=Roma/O=Another Company Ltd/OU=User WebApp/CN=John Doe/emailAddress=john.doe@unknown.local&#34; -keyout $OUTPUT_CERT/johndoe.key -out $OUTPUT_CERT/johndoe.csr
# crt 
openssl x509 -extfile $CONF_CERT/client_cert.cnf -req -in $OUTPUT_CERT/johndoe.csr -days 365 -sha384 -CA $OUTPUT_CERT/ca_client.crt -CAkey $OUTPUT_CERT/ca_client.key -CAcreateserial -out $OUTPUT_CERT/johndoe.crt
# p12
openssl pkcs12 -export -inkey $OUTPUT_CERT/johndoe.key -in $OUTPUT_CERT/johndoe.crt -out $OUTPUT_CERT/johndoe.p12
</code></pre>

<h2 id="a-id-creazione-ca-intermediate-certificati-client-server-caso-2-creazione-di-ca-intermediate-ca-e-dei-certificati-client-e-server-a"><a id="creazione-ca-intermediate-certificati-client-server">Caso 2. Creazione di CA, Intermediate CA e dei certificati client e server</a></h2>

<p>Gli esempi che seguiranno saranno presentati sullo stile del riassunto perché fondamentalmente molto simili al caso 1. Si aggiunge un punto di intermediazione in più dato dal fatto che la CA delega ad una CA “subalterna” l&#39;incarico di verificare le paternità di coloro i quali richiedono certificati.</p>

<p>Quindi avremo:</p>
<ul><li>una root CA, certificato self-signed</li>
<li>un&#39;Intermediate CA, validata dalla root CA (csr + crt firmato dalla root CA)
<em>n</em> certificati client/server validati dall&#39;Intermediate CA (csr + crt firmato dall&#39;Intermediate CA)</li></ul>

<p><strong>Creazione certificati</strong></p>

<pre><code>OUTPUT_CERT=$HOME/stunnel/build-cert
CONF_CERT=$HOME/stunnel/conf.d

###########
# Root CA #
###########
openssl req -config $CONF_CERT/ca_cert.cnf -extensions v3_ca -x509 -days 1825 -sha512 -nodes -newkey rsa:4096 -subj &#34;/C=IT/ST=Italia/CN=GlobalSign Test RootCA&#34; -keyout $OUTPUT_CERT/rootca.key -out $OUTPUT_CERT/rootca.crt

###################
# INTERMEDIATE CA #
###################
# csr
openssl req -config $CONF_CERT/intermediate_req.cnf -nodes -newkey rsa:2048 -subj &#34;/C=IT/ST=Italia/CN=GlobalSign Test IntermediateCA&#34; -keyout $OUTPUT_CERT/intermediate.key -out $OUTPUT_CERT/intermediate.csr
# crt
openssl x509 -extfile $CONF_CERT/intermediate_cert.cnf -req -in $OUTPUT_CERT/intermediate.csr -days 365 -sha384 -CA $OUTPUT_CERT/rootca.crt -CAkey $OUTPUT_CERT/rootca.key -CAcreateserial -out $OUTPUT_CERT/intermediate.crt

##########
# Server #
##########
# csr
openssl req -config $CONF_CERT/server_req.cnf -nodes -newkey rsa:2048 -subj &#34;/C=IT/ST=Italia/L=Roma/O=My Company Ltd/OU=Divisione IT web/CN=server.web.local/emailAddress=it@web.local&#34; -keyout $OUTPUT_CERT/server.key -out $OUTPUT_CERT/server.csr
# crt
openssl x509 -extfile $CONF_CERT/server_cert.cnf 
-req -in $OUTPUT_CERT/server.csr -CA $OUTPUT_CERT/intermediate.crt -CAkey $OUTPUT_CERT/intermediate.key -CAcreateserial -days 365 -sha384 -out $OUTPUT_CERT/server.crt

##########
# Client #
##########
# csr
openssl req -config $CONF_CERT/client_req.cnf -nodes -newkey rsa:2048 -subj &#34;/C=IT/ST=Italia/L=Roma/O=Another Company Ltd/OU=User WebApp/CN=John Doe/emailAddress=john.doe@unknown.local&#34; -keyout $OUTPUT_CERT/johndoe.key -out $OUTPUT_CERT/johndoe.csr
# crt
openssl x509 -extfile $CONF_CERT/client_cert.cnf -req -in $OUTPUT_CERT/johndoe.csr -days 365 -sha384 -CA $OUTPUT_CERT/intermediate.crt -CAkey $OUTPUT_CERT/intermediate.key -CAcreateserial -out $OUTPUT_CERT/johndoe.crt
# p12
openssl pkcs12 -export -inkey $OUTPUT_CERT/johndoe.key -in $OUTPUT_CERT/legs.crt -out $OUTPUT_CERT/johndoe.p12
</code></pre>

<p><a href="/aytin/tag:DigitalCertificate" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">DigitalCertificate</span></a> <a href="/aytin/tag:x509" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">x509</span></a> <a href="/aytin/tag:csr" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">csr</span></a> <a href="/aytin/tag:openssl" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">openssl</span></a> <a href="/aytin/tag:ca" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">ca</span></a> <a href="/aytin/tag:cryptography" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">cryptography</span></a> <a href="/aytin/tag:AsymmetricEncryption" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">AsymmetricEncryption</span></a> <a href="/aytin/tag:SymmetricEncryption" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">SymmetricEncryption</span></a> <a href="/aytin/tag:DigitalSignature" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">DigitalSignature</span></a></p>
]]></content:encoded>
      <guid>https://noblogo.org/aytin/come-creare-un-certificato-digitale</guid>
      <pubDate>Sun, 05 Mar 2023 21:38:23 +0000</pubDate>
    </item>
    <item>
      <title>Stunnel: Cos&#39;è e come si configura</title>
      <link>https://noblogo.org/aytin/stunnel-cose-e-come-si-configura</link>
      <description>&lt;![CDATA[(pubblicato il 7 gennaio 2023)&#xA;Stunnel&#xA;smalliFonte: a href=&#34;https://www.stunnel.org&#34;stunnel.org/a/i/small&#xA;&#xA;Introduzione&#xA;&#xA;Da documentazione, Stunnel agisce come un proxy per aggiungere crittografia TLS a server e/o a client già esistenti.&#xA;&#xA;Risulta quindi molto comodo quando si vuole aggiungere, attraverso un tunnel TLS, quella crittografia che manca alle nostre applicazioni per rendere le comunicazioni più sicure.&#xA;!--more--&#xA;Come in ssh, è possibile “tunnellizzare” solo connessioni TCP.&#xA;&#xA;Di stunnel esaminerò in particolare la fase di autenticazione attraverso certificato o PSK.&#xA;&#xA;Gli scenari possibili, in base alle combinazioni, sono tre:&#xA;&#xA;client tls – server in chiaro&#xA;client in chiaro – server tls&#xA;client e server in chiaro&#xA;&#xA;Nel primo caso, occorre configurare stunnel in server mode, definendo un receiver ssl, a cui il client potrà connettersi.&#xA;stunel server&#xA;smalliScenario 1: stunnel server/i/small&#xA;&#xA;Nel secondo caso, occorre configurare stunnel in client mode, definendo un sender ssl che il client userà per connettersi al server&#xA;stunnel client&#xA;smalliScenario 2: stunnel client/i/small&#xA;&#xA;Nel terzo caso, occorre configurare uno stunnel client e uno server&#xA;stunnel client e server&#xA;smalliScenario 3: stunnel client e server/i/small&#xA;&#xA;Come ulteriore evoluzione per quel che riguarda le tratte in chiaro (e non solo) di client-stunnel client, stunnel client-stunnel server, stunnel server-server, sarebbe buona norma limitarne l’accesso con un firewall.&#xA;stunnel client e server e firewall&#xA;smalliStunnel e firewall/i/small&#xA;&#xA;Se invece stunnel fosse locale (installato direttamente sul client e/o sul server), la richiesta del client o il listener del servizio, avverrebbero sull’interfaccia di loopback.&#xA;Altrimenti, in assenza di firewall, sarebbe consigliabile accertare che la rete di collegamento fra i proxy stunnel e i rispettivi client/server, sia almeno di tipo “trusted”.&#xA;&#xA;Stunnel consente un certo tuning sulla parte tls, potendo discriminare fra le cipher suites da abilitare, specificare comandi o configurazioni specifiche per openssl.&#xA;Quando si deve incapsulare una connessione in chiaro in un tunnel ssl bisogna tenere presente gli scenari menzionati prima.&#xA;Convenzioni&#xA;&#xA;Per non perdere generalità, negli esempi che seguiranno, immaginiamo che stunnel non sia locale (anche se spesso lo è).&#xA;   se stunnel in client mode è locale ⇒ accept avverrà sull’interfaccia di loopback, da dove avviene effettivamente la richiesta&#xA;   se stunnel in server mode è locale ⇒ connect avverrà sull’interfaccia di loopback, dove viene erogato effettivamente il servizio&#xA;Non faremo assunzioni sulla creazione dei certificati. Possono anche essere self-signed.&#xA;&#xA;Configurazione stunnel&#xA;&#xA;Verranno mostrate le configurazioni relative agli scenari mostrati nel modo più semplice possibile.&#xA;&#xA;accept: host e porta che ricevono la richiesta&#xA;connect: host e porta a cui girare l’accept&#xA;cert: normalmente conterrebbe il certificato pubblico che stunnel espone per autenticarsi (la parte privata viene specificata con key). Può però anche essere costituito da tutta i certificati della chain fino alla root CA, in formato pem o p12, iniziando dalla chiave privata, proseguendo con la chiave pubblica, fino a tutte le CA della chain.&#xA;key: chiave privata del certificato&#xA;client: stabilisce se stunnel funzioni in server mode oppure no&#xA;&#xA;Primo scenario&#xA;&#xA;Nel primo caso, una configurazione minimale lato server, ha bisogno:&#xA;&#xA;host e porta dello stunnel server che riceve il traffico cifrato&#xA;host e porta del server su cui girare il traffico in chiaro&#xA;certificato pubblico e chiave privata necessari per la cifratura&#xA;&#xA;Stunnel Server:&#xA;[myService]&#xA;accept = ipstunnelserver:portsts&#xA;connect = ipserver:portserver&#xA;cert = /servercrt.pembr&#xA;key = /serverkey.pem&#xA;Secondo scenario&#xA;&#xA;Nel secondo caso, una configurazione minimale lato client, ha bisogno:&#xA;&#xA;host e porta dello stunnel client da cui partirà la richiesta&#xA;host e porta del server da cui stunnel client avvierà la sessione tls&#xA;&#xA;Stunnel Client:&#xA;[myService]&#xA;client = yes&#xA;accept = ipstunnelclient:portstc&#xA;connect = ipserver:portserver&#xA;Terzo Scenario&#xA;&#xA;Il terzo caso, è una fusione dei primi due. Sono gli stunnel a gestire il grosso della comunicazione. E nei casi in cui lo stunnel viene installato sulle macchine di servizio, client e server reali usano solo l’interfaccia di loopback.&#xA;&#xA;Una configurazione minimale per il client ha bisogno di:&#xA;&#xA;host e porta dello stunnel client da cui partirà la richiesta&#xA;host e porta del server da cui stunnel client avvierà la sessione tls&#xA;&#xA;Stunnel Client:&#xA;[myService]&#xA;client = yes&#xA;accept = ipstunnelclient:portstc&#xA;connect = ipstunnelserver:portserver&#xA;Una configurazione minimale per il server ha bisogno:&#xA;&#xA;host e porta dello stunnel server che riceve il traffico cifrato&#xA;host e porta del server su cui girare il traffico in chiaro&#xA;    certificato pubblicato e chiave privata necessari per la cifratura&#xA;&#xA;Stunnel Server:&#xA;[myService]&#xA;accept = ipstunnelserver:portsts&#xA;connect = ipserver:portserver&#xA;cert = /servercrt.pem&#xA;key = /serverkey.pem&#xA;smallPiccola nota: se client e/o server dovessero supportare chiavi PSK, si potrebbe usare PSK in luogo dei certificati. Ci ritornerò più avanti./small&#xA;&#xA;Autenticazione dei client&#xA;&#xA;Le impostazioni viste finora, mostrano come incapsulare un traffico in chiaro all’interno di un tunnel tls e si basano sulla sola autenticazione lato server.&#xA;&#xA;Per migliorare la configurazione possiamo ricorrere alla mutua autenticazione facendo in modo che anche i client si autentichino.&#xA;&#xA;Una mutua autenticazione, con tutte le verifiche del caso, aumenta il grado di sicurezza comunicazione TLS ed è un efficace deterrente contro eventuali attacchi MITM. L’autenticazione sul client si può ottenere sempre con i certificati oppure, più semplicemente, con chiavi PSK.&#xA;&#xA;Autenticazione dei client con certificato&#xA;&#xA;Ad una configurazione minimale per una mutua autenticazione, lato server, si richiede che i client esibiscano il certificato e i client (che sia stunnel in client mode, un browser o qualunque altra cosa) dovranno essere in grado di esibire i certificati nel momento in cui il server li richiederà.&#xA;&#xA;Su stunnel server, alle configurazioni viste in precedenza, si aggiunge requireCert impostato a yes, che richiede ai client l’esibizione di un certificato. Se, durante l’handshake TLS, il client non esibisce un certificato, l’handshake fallisce e la connessione viene rifiutata.&#xA;&#xA;Stunnel Server:&#xA;[myService]&#xA;…&#xA;requireCert = yes&#xA;…&#xA;È sufficiente questo se i client possono manipolare i propri certificati. Altrimenti, se c’è uno stunnel client che intermedia le richieste dei client effettivi, si deve aggiungere alla sua configurazione la chiave e il certificato del client&#xA;&#xA;Stunnel Client:&#xA;[myService]&#xA;…&#xA;cert = /servercrt.pem&#xA;key = /serverkey.pem&#xA;…&#xA;Autenticazione dei client con PSK&#xA;&#xA;Per l’autenticazione PSK bisogna disporre della lista di utenti abilitati con relative chiavi esadecimali di almeno 16 bytes (ossia almeno 32 caratteri esadecimali visto che con un byte si rappresentano due esadecimali).&#xA;&#xA;La creazione di una chiave esadecimale può essere fatta velocemente con openssl.&#xA;Supponiamo di creare due utenze per Frodo e Gandalf con chiavi da 20 e 42 bytes.&#xA;echo -e &#34;frodo:&#34;$(openssl rand -hex 20)   frodopsk.txt&#xA;echo -e &#34;gandalf:&#34;$(openssl rand -hex 42)   gandalfpsk.txt&#xA;Tutte le identità dovranno confluire nel file che, nella configurazione stunnel, sarà indicato da PSKsecrets. Ad es:&#xA;cat frodopsk.txt gandalfpsk.txt   psksecrets.txt&#xA;…&#xA;frodo:84196825fab3389624dcc83eb61189e5b21099febrgandalf:5daf128419855993a2d95ba0a337c51b3f373df88e594441f2979eba6461f25676f1f825b0c76df392f2&#xA;…&#xA;E, come detto, nella configurazione dello stunnel server dovrò indicare il file delle identità:&#xA;&#xA;Stunnel Server&#xA;[myServer]&#xA;accept = ipstunnelserver:portsts&#xA;connect = ipserver:portserver&#xA;PSKsecrets = pathidentityfile/psksecrets.txt&#xA;Se il client supporta PSK, dovrà fornire identità e password. Ad es. facendo un test con openssl:&#xA;openssl sclient -port porta -pskidentity frodo -psk 84196825fab3389624dcc83eb61189e5b21099fe -tls12 -connect host&#xA;Altrimenti si configura stunnel client indicando sia l’identità, sia il file individuate da PSKsecrets.&#xA;&#xA;Stunnel Client&#xA;[myClient]&#xA;client = yes&#xA;accept = ipstunnelclient:portstc&#xA;connect = ipstunnelserver:portserver&#xA;PSKidentity = frodo&#xA;PSKsecrets = pathidentityfile/psksecrets.txt&#xA;In alternativa, per non far viaggiare il file delle identità fra tutti i client, possiamo sfruttare a nostro vantaggio il default delle identità.&#xA;&#xA;In assenza della direttiva PSKidentity, viene assunta come identità di default la prima riga del file indicato da PSKSecrets. Basta quindi creare un file con la sola identità che mi occorre, ad es. frodopsk.txt&#xA;frodo:84196825fab3389624dcc83eb61189e5b21099fe&#xA;e indicare quello in PSKSecrets. La configurazione che segue è equivalente alla precedente.&#xA;&#xA;Stunnel Client&#xA;[myClient]&#xA;client = yes&#xA;accept = ipstunnelclient:portstc&#xA;connect = ipstunnelserver:portserver&#xA;PSKsecrets = pathidentityfile/frodopsk.txt&#xA;Ulteriori considerazioni di sicurezza&#xA;Autenticazione con certificato&#xA;&#xA;La richiesta di autenticazione dei client mediante certificato è una buona misura preventiva ma può essere resa migliore.&#xA;&#xA;Nelle configurazioni viste finora, stunnel server autorizza l’accesso al servizio solo se il client si presenta con un certificato ma non c’è nulla che vincoli il certificato al servizio. In altre parole, un client in possesso di un qualunque certificato, può accedere alla risorsa.&#xA;&#xA;È possibile rafforzare il trusting fra le parti facendo in modo che stunnel autorizzi solo alcuni certificati invece che qualunque. Questo tipo di controllo può essere fatto sia su stunnel sia in client mode che in server mode.&#xA;&#xA;verifyChain = yes | no&#xA;checkEmail = email del certificato&#xA;checkHost = CN del certificato&#xA;checkIP = IP del peer che presenta il certificato&#xA;verifyPeer = yes | no&#xA;CApath =  path CA &#xA;CAfile =  file pem contenente la fullchain del certificato presentato a stunnel &#xA;&#xA;verifyChain&#xA;Impone che si possa verificare la fullchain del certificato presentato. Se uno degli issuer non viene trovato, la connessione fallisce. La fullchain viene indicata attraverso CAfile o CApath.&#xA;&#xA;CAfile&#xA;È il file contenente le CA con cui stunnel valida i certificati che gli vengono presentati. Se stunnel è in server mode, sarà la fullchain relativa ai client. Altrimenti sarà la fullchain relativa al server.&#xA;&#xA;CApath&#xA;È il path in cui si trovano le CA con cui stunnel valida i certificati che gli vengono presentati. Se lo stunnel è in server mode, sarà la fullchain realtiva ai client. Altrimenti sarà la fullchain relativa al server.&#xA;&#xA;verifyPeer&#xA;Se con CAfile e CApath si verifica la fullchain dei certificati presentati a stunnel, con verifyPeer = yes si verifica che questi certificati siano presenti anche nel suo keystore (CAfile o CApath). Permette di “legare” a stunnel i certificati che dovrà validare.&#xA;&#xA;checkEmail, checkHost, checkIP&#xA;Come per verifyPeer, sono direttive che permettono di stringere il legame fra il certificato che viene presentato e stunnel.&#xA;Verifica che l’email, il CN o l’IP del certificato che viene presentato corrispondano a quelli presenti nella configurazione.&#xA;In una configurazione lato server posso avere molteplici occorrenze di questi due campi relative ad altrettanti certificati. Il caso in cui ad es. si debbano autenticare n client.&#xA;&#xA;Se i certificati sono self-signed, verifyChain perde di significato (coinciderebbe con verifyPeer). La possibilità di generare i certificati attraverso una CA, anche interna, renderebbe il processo più strutturato anche se più complesso (si dovrà trovare un modo per distribuire la CA, se interna). Si tratta di trovare il giusto compromesso fra ampiezza del servizio (quanti utenti coinvolge?) e complessità richiesta.&#xA;&#xA;Se si tratta di realizzare un canale sicuro fra due apparati per una comunicazione server-2-server, vanno bene anche i certificati self-signed o un’autenticazione PSK. Altrimenti, soprattutto nel caso in cui l’autenticazione dei client è una fase critica, conviene valutare l’uso di una CA e una validazione il più possibile restrittiva sui client e sul server.&#xA;&#xA;Autenticazione PSK&#xA;&#xA;A differenza dell’autenticazione con certificato, l’autenticazione con PSK non prevede enhancement di sicurezza ulteriori a meno di specificare opportuni algoritmi di cifratura (cfr. paragrafo successivo).&#xA;&#xA;Cifratura&#xA;&#xA;Come sempre succede, negli scenari di cifratura asimmetrica orientatia alla connessione, l’autenticazione, per quanto possa essere accurata, costituisce solo uno degli aspetti di cui tenere conto nella fase di messa in sicurezza del servizio.&#xA;&#xA;Avere un’autenticazione con certificato generato con tutti i crismi da una CA, è certamente una gran cosa ma mette in sicurezza solo l’aspetto dell’autenticazione, per l’appunto.&#xA;&#xA;l transito dei dati è affidato alle suite di cifratura supportati da openssl e, volendo lavorare di fino, bisognerebbe stringere anche su quelli.&#xA;&#xA;Altrimenti, paradossalmente, si avrà un’autenticazione robustissima ma con algoritmi colabrodo di cifratura dei dati che, ad attaccanti ben motivati, lascerebbero delle porte spalancate per sferrare attacchi MITM per intercettare direttamente i dati, piuttosto che provare il furto di identità.&#xA;&#xA;Ad ogni modo, il default, per ragioni di compatibilità legacy, dei parametri di cifratura (da settare eventualmente su client e sul server) è il seguente:&#xA;ciphers: HIGH:!aNULL:!SSLv2:!DH:!kDHEPSK&#xA;ciphersuites: TLSAES256GCMSHA384:TLSAES128GCMSHA256:TLSCHACHA20POLY1305SHA256&#xA;dove ciphers raggruppa le suite di cifratura relativi a TLS1.2 in giù e ciphersuites riguarda invece TLS1.3.&#xA;&#xA;Configurazione servizio&#xA;&#xA;Ulteriori restrizioni possono essere aggiunte a livelllo di sistema:&#xA;&#xA;regolando i bit di setuid e setgid se stunnel gira come root&#xA;delimitando l’esecuzione del processo in una gabbia chroot&#xA;disabilitando le regonetiation (se supportato dalla versione di openssl in uso) che mitiga in parte attacchi dos di tipo CPU-exhaustion&#xA;ecc..&#xA;&#xA;Caso reale: tunnelizzare Transmission.&#xA;&#xA;Transmission è un client bittorrent che può essere controllato da remoto via rpc attraverso un’interfaccia web o altri client.&#xA;&#xA;Transmission, nelle sue varie declinazioni, non incapsula il traffico rpc in una connessione tls.&#xA;&#xA;Se si vuole che il dato in transito sia cifrato e che la connessione sia autenticata, si può ricorrere:&#xA;&#xA;ad un tunnel ssh;&#xA;all’intermediazione di un webserver come apache o nginx ;&#xA;ad uno stunnel server&#xA;&#xA;Sugli ultimi due punti si può configurare una mutua autenticazione con certificato (complessa e articolata e, per tanti client, ha un impatto significativo). Scegliamo il 3° caso.&#xA;&#xA;Esposizione dell’interfaccia web&#xA;&#xA;Scenario: abbiamo una macchina (il nostro serverino di fiducia o un nas) con transmission a bordo, presumibilmente dietro un firewall che natta il suo indirizzo privato (192.168.70.15).&#xA;&#xA;Transmission Stunnel&#xA;smallEsposizione transmission attraverso stunnel server/small&#xA;&#xA;Obiettivo: Vogliamo poter raggiungere transmission e vogliamo che i client autentichino la loro connessione prima di accedere al servizio. In base allo scenario, sappiamo che dovremmo configurare un port forwarding dall’AP fino allo stunnel server. Il server transmission rimarrà confinato nella nostra rete locale.&#xA;&#xA;Utilizzo di un client esterno&#xA;&#xA;Supponiamo di utilizzare diversi client: il browser, transmission-remote-gtk o transmission-remote-gui (transgui), tremotesf (mobile).&#xA;&#xA;La prima cosa da fare è configurare un port forwarding sul nostro AP&#xA;&#xA;    Rulesub1/sub: 9091 ⇒ 192.168.70.10:9091&#xA;&#xA;Dopodichè, configureremo stunnel in server mode davanti a transmission&#xA;[transmission]&#xA;accept = 192.168.70.10:9091&#xA;connect = 192.168.70.15:9091&#xA;cert = path stunnel conf/ssl/server/certs/stunnelcrt.pem&#xA;key = path stunnel conf/ssl/server/private/stunnelkey.pem&#xA;requireCert = yes&#xA;verifyChain = yes&#xA;verifyPeer = yes&#xA;CApath = path stunnel conf/ssl/client/certs&#xA;Alcune note sulla configurazione:&#xA;&#xA;devo disporre di un certificato per stunnel&#xA;devo disporre dei certificati per i client che si connetteranno, le cui fullchain dovranno essere localizzate nel path indicato da CApath&#xA;&#xA;A questo punto basta che i web-client puntino all’host pubblico (151.25.77.205) sulla porta 9091 e il gioco è fatto.&#xA;&#xA;Per gli altri client come transmission-remote-gtk, transgui o tremotesf, per i quali al massimo posso chiedere di usare TLS (ma non sono riuscito ad usare un’autenticazione lato client), conviene installare stunnel in client mode :&#xA;[transmission-client]&#xA;accept = localhost:9091&#xA;connect = 151.25.77.205:9091&#xA;client = yes&#xA;cert = path stunnel conf/ssl/client/laptopcrt.pem&#xA;key = path stunnel conf/ssl/client/laptopkey.pem&#xA;verifyChain = yes&#xA;verifyPeer = yes&#xA;CAPath = path stunnel conf/ssl/server/certs&#xA;Il client (ad es. sul laptop) si connetterà su localhost:9091 e dovrà disporre anche del certificato del server e della sua fullchain affinchè i check su verifyChain e verifyPeer non falliscano.&#xA;&#xA;#ca #DigitalCertificate #AsymmetricEncryption #SymmetricEncryption #cryptography #fullchain #psk #ssh #ssl #stunnel #tls #x509 #openssl]]&gt;</description>
      <content:encoded><![CDATA[<p><strong><em>(pubblicato il 7 gennaio 2023)</em></strong>
<img src="https://pixelfed.uno/storage/m/_v2/489827599091373610/42a8ecf32-5a8865/eZP2oeutp2KD/bkO44BGcvLFyYYUeCuYKXlSQzvBqgKi0Uh4fYtYk.jpg" alt="Stunnel">
<small><i>Fonte: <a href="https://www.stunnel.org" rel="nofollow">stunnel.org</a></i></small></p>

<h2 id="introduzione">Introduzione</h2>

<p>Da documentazione, Stunnel agisce come un proxy per aggiungere crittografia TLS a server e/o a client già esistenti.</p>

<p>Risulta quindi molto comodo quando si vuole aggiungere, attraverso un tunnel TLS, quella crittografia che manca alle nostre applicazioni per rendere le comunicazioni più sicure.

Come in ssh, è possibile “tunnellizzare” solo connessioni TCP.</p>

<p>Di stunnel esaminerò in particolare la fase di autenticazione attraverso certificato o PSK.</p>

<p>Gli scenari possibili, in base alle combinazioni, sono tre:</p>
<ul><li>client tls – server in chiaro</li>
<li>client in chiaro – server tls</li>
<li>client e server in chiaro</li></ul>

<p>Nel primo caso, occorre configurare stunnel in server mode, definendo un receiver ssl, a cui il client potrà connettersi.
<img src="https://pixelfed.uno/storage/m/_v2/489827599091373610/42a8ecf32-5a8865/sQc861Pfxyfg/39Yo5lasr3nAebRZbrzqtoQOskqS62aHW9fwwyo0.png" alt="stunel server">
<small><i>Scenario 1: stunnel server</i></small></p>

<p>Nel secondo caso, occorre configurare stunnel in client mode, definendo un sender ssl che il client userà per connettersi al server
<img src="https://pixelfed.uno/storage/m/_v2/489827599091373610/42a8ecf32-5a8865/nz4fkq8opVoD/HcocxYf4VwB0UtihuwlQ6pOo2CKxDCTU4X5v1UNB.png" alt="stunnel client">
<small><i>Scenario 2: stunnel client</i></small></p>

<p>Nel terzo caso, occorre configurare uno stunnel client e uno server
<img src="https://pixelfed.uno/storage/m/_v2/489827599091373610/42a8ecf32-5a8865/zxIg9C1izJPj/DqgYaAezDIab01XBFMHiDRjUqEDWxNqxMJOGDSvs.png" alt="stunnel client e server">
<small><i>Scenario 3: stunnel client e server</i></small></p>

<p>Come ulteriore evoluzione per quel che riguarda le tratte in chiaro (e non solo) di client-stunnel client, stunnel client-stunnel server, stunnel server-server, sarebbe buona norma limitarne l’accesso con un firewall.
<img src="https://pixelfed.uno/storage/m/_v2/489827599091373610/42a8ecf32-5a8865/j9Qbwy74AkaE/igU7qV0XI8gVIASWfDufiBvWeAf0OgnQ24ZLwC42.png" alt="stunnel client e server e firewall">
<small><i>Stunnel e firewall</i></small></p>

<p>Se invece stunnel fosse locale (installato direttamente sul client e/o sul server), la richiesta del client o il listener del servizio, avverrebbero sull’interfaccia di loopback.
Altrimenti, in assenza di firewall, sarebbe consigliabile accertare che la rete di collegamento fra i proxy stunnel e i rispettivi client/server, sia almeno di tipo “trusted”.</p>

<p>Stunnel consente un certo tuning sulla parte tls, potendo discriminare fra le cipher suites da abilitare, specificare comandi o configurazioni specifiche per openssl.
Quando si deve incapsulare una connessione in chiaro in un tunnel ssl bisogna tenere presente gli scenari menzionati prima.</p>

<h2 id="convenzioni">Convenzioni</h2>
<ul><li>Per non perdere generalità, negli esempi che seguiranno, immaginiamo che stunnel non sia locale (anche se spesso lo è).
<ul><li>se stunnel in <em>client mode</em> è locale ⇒ <strong>accept</strong> avverrà sull’interfaccia di loopback, da dove avviene effettivamente la richiesta</li>
<li>se stunnel in <em>server mode</em> è locale ⇒ <strong>connect</strong> avverrà sull’interfaccia di loopback, dove viene erogato effettivamente il servizio</li></ul></li>
<li>Non faremo assunzioni sulla creazione dei certificati. Possono anche essere self-signed.</li></ul>

<h2 id="configurazione-stunnel">Configurazione stunnel</h2>

<p>Verranno mostrate le configurazioni relative agli scenari mostrati nel modo più semplice possibile.</p>
<ul><li><strong>accept</strong>: host e porta che ricevono la richiesta</li>
<li><strong>connect</strong>: host e porta a cui girare l’accept</li>
<li><strong>cert</strong>: normalmente conterrebbe il certificato pubblico che stunnel espone per autenticarsi (la parte privata viene specificata con <strong>key</strong>). Può però anche essere costituito da tutta i certificati della chain fino alla root CA, in formato pem o p12, iniziando dalla chiave privata, proseguendo con la chiave pubblica, fino a tutte le CA della chain.</li>
<li><strong>key</strong>: chiave privata del certificato</li>
<li><strong>client</strong>: stabilisce se stunnel funzioni in server mode oppure no</li></ul>

<h3 id="primo-scenario">Primo scenario</h3>

<p>Nel primo caso, una configurazione minimale lato server, ha bisogno:</p>
<ol><li>host e porta dello stunnel server che riceve il traffico cifrato</li>
<li>host e porta del server su cui girare il traffico in chiaro</li>
<li>certificato pubblico e chiave privata necessari per la cifratura</li></ol>

<p><strong>Stunnel Server:</strong></p>

<pre><code>[myService]
accept = ip_stunnel_server:port_sts
connect = ip_server:port_server
cert = /server_crt.pem&lt;br&gt;
key = /server_key.pem
</code></pre>

<h3 id="secondo-scenario">Secondo scenario</h3>

<p>Nel secondo caso, una configurazione minimale lato client, ha bisogno:</p>
<ol><li>host e porta dello stunnel client da cui partirà la richiesta</li>
<li>host e porta del server da cui stunnel client avvierà la sessione tls</li></ol>

<p><strong>Stunnel Client:</strong></p>

<pre><code>[myService]
client = yes
accept = ip_stunnel_client:port_stc
connect = ip_server:port_server
</code></pre>

<h3 id="terzo-scenario">Terzo Scenario</h3>

<p>Il terzo caso, è una fusione dei primi due. Sono gli stunnel a gestire il grosso della comunicazione. E nei casi in cui lo stunnel viene installato sulle macchine di servizio, client e server reali usano solo l’interfaccia di loopback.</p>

<p>Una configurazione minimale per il client ha bisogno di:</p>
<ol><li>host e porta dello stunnel client da cui partirà la richiesta</li>
<li>host e porta del server da cui stunnel client avvierà la sessione tls</li></ol>

<p><strong>Stunnel Client:</strong></p>

<pre><code>[myService]
client = yes
accept = ip_stunnel_client:port_stc
connect = ip_stunnel_server:port_server
</code></pre>

<p>Una configurazione minimale per il server ha bisogno:</p>
<ol><li>host e porta dello stunnel server che riceve il traffico cifrato</li>
<li>host e porta del server su cui girare il traffico in chiaro
certificato pubblicato e chiave privata necessari per la cifratura</li></ol>

<p><strong>Stunnel Server:</strong></p>

<pre><code>[myService]
accept = ip_stunnel_server:port_sts
connect = ip_server:port_server
cert = /server_crt.pem
key = /server_key.pem
</code></pre>

<p><small><strong>Piccola nota</strong>: se client e/o server dovessero supportare chiavi PSK, si potrebbe usare PSK in luogo dei certificati. Ci ritornerò più avanti.</small></p>

<h2 id="autenticazione-dei-client">Autenticazione dei client</h2>

<p>Le impostazioni viste finora, mostrano come incapsulare un traffico in chiaro all’interno di un tunnel tls e si basano sulla sola autenticazione lato server.</p>

<p>Per migliorare la configurazione possiamo ricorrere alla <a href="https://noblogo.org/aytin/mutua-autenticazione" rel="nofollow"><strong>mutua autenticazione</strong></a> facendo in modo che anche i client si autentichino.</p>

<p>Una mutua autenticazione, con tutte le verifiche del caso, aumenta il grado di sicurezza comunicazione TLS ed è un efficace deterrente contro eventuali attacchi MITM. L’autenticazione sul client si può ottenere sempre con i certificati oppure, più semplicemente, con chiavi PSK.</p>

<h3 id="autenticazione-dei-client-con-certificato">Autenticazione dei client con certificato</h3>

<p>Ad una configurazione minimale per una mutua autenticazione, lato server, si richiede che i client esibiscano il certificato e i client (che sia stunnel in <em>client mode</em>, un browser o qualunque altra cosa) dovranno essere in grado di esibire i certificati nel momento in cui il server li richiederà.</p>

<p>Su stunnel server, alle configurazioni viste in precedenza, si aggiunge <strong>requireCert</strong> impostato a <strong>yes</strong>, che richiede ai client l’esibizione di un certificato. Se, durante l’handshake TLS, il client non esibisce un certificato, l’handshake fallisce e la connessione viene rifiutata.</p>

<p><strong>Stunnel Server:</strong></p>

<pre><code>[myService]
…
requireCert = yes
…
</code></pre>

<p>È sufficiente questo se i client possono manipolare i propri certificati. Altrimenti, se c’è uno stunnel client che intermedia le richieste dei client effettivi, si deve aggiungere alla sua configurazione la chiave e il certificato del client</p>

<p><strong>Stunnel Client:</strong></p>

<pre><code>[myService]
…
cert = /server_crt.pem
key = /server_key.pem
…
</code></pre>

<h3 id="autenticazione-dei-client-con-psk">Autenticazione dei client con PSK</h3>

<p>Per l’autenticazione PSK bisogna disporre della lista di utenti abilitati con relative chiavi esadecimali di almeno 16 bytes (ossia almeno 32 caratteri esadecimali visto che con un byte si rappresentano due esadecimali).</p>

<p>La creazione di una chiave esadecimale può essere fatta velocemente con openssl.
Supponiamo di creare due utenze per <em>Frodo</em> e <em>Gandalf</em> con chiavi da 20 e 42 bytes.</p>

<pre><code class="language-bash">echo -e &#34;frodo:&#34;$(openssl rand -hex 20) &gt; frodo_psk.txt
echo -e &#34;gandalf:&#34;$(openssl rand -hex 42) &gt; gandalf_psk.txt
</code></pre>

<p>Tutte le identità dovranno confluire nel file che, nella configurazione stunnel, sarà indicato da <strong>PSKsecrets</strong>. Ad es:</p>

<pre><code class="language-bash">cat frodo_psk.txt gandalf_psk.txt &gt; psksecrets.txt
…
frodo:84196825fab3389624dcc83eb61189e5b21099fe&lt;br&gt;gandalf:5daf128419855993a2d95ba0a337c51b3f373df88e594441f2979eba6461f25676f1f825b0c76df392f2
…
</code></pre>

<p>E, come detto, nella configurazione dello stunnel server dovrò indicare il file delle identità:</p>

<p><strong>Stunnel Server</strong></p>

<pre><code>[myServer]
accept = ip_stunnel_server:port_sts
connect = ip_server:port_server
PSKsecrets = &lt;path_identity_file&gt;/psksecrets.txt
</code></pre>

<p>Se il client supporta PSK, dovrà fornire identità e password. Ad es. facendo un test con <code>openssl</code>:</p>

<pre><code class="language-bash">openssl s_client -port &lt;porta&gt; -psk_identity frodo -psk 84196825fab3389624dcc83eb61189e5b21099fe -tls1_2 -connect &lt;host&gt;
</code></pre>

<p>Altrimenti si configura stunnel client indicando sia l’identità, sia il file individuate da <strong>PSKsecrets</strong>.</p>

<p><strong>Stunnel Client</strong></p>

<pre><code>[myClient]
client = yes
accept = ip_stunnel_client:port_stc
connect = ip_stunnel_server:port_server
PSKidentity = frodo
PSKsecrets = &lt;path_identity_file&gt;/psksecrets.txt
</code></pre>

<p>In alternativa, per non far viaggiare il file delle identità fra tutti i client, possiamo sfruttare a nostro vantaggio il default delle identità.</p>

<p>In assenza della direttiva <strong>PSKidentity</strong>, viene assunta come identità di default la prima riga del file indicato da <strong>PSKSecrets</strong>. Basta quindi creare un file con la sola identità che mi occorre, ad es. <strong>frodo_psk.txt</strong></p>

<pre><code>frodo:84196825fab3389624dcc83eb61189e5b21099fe
</code></pre>

<p>e indicare quello in <strong>PSKSecrets</strong>. La configurazione che segue è equivalente alla precedente.</p>

<p><strong>Stunnel Client</strong></p>

<pre><code>[myClient]
client = yes
accept = ip_stunnel_client:port_stc
connect = ip_stunnel_server:port_server
PSKsecrets = &lt;path_identity_file&gt;/frodo_psk.txt
</code></pre>

<h2 id="ulteriori-considerazioni-di-sicurezza">Ulteriori considerazioni di sicurezza</h2>

<h3 id="autenticazione-con-certificato">Autenticazione con certificato</h3>

<p>La richiesta di autenticazione dei client mediante certificato è una buona misura preventiva ma può essere resa migliore.</p>

<p>Nelle configurazioni viste finora, stunnel server autorizza l’accesso al servizio solo se il client si presenta con un certificato ma non c’è nulla che vincoli il certificato al servizio. In altre parole, un client in possesso di un qualunque certificato, può accedere alla risorsa.</p>

<p>È possibile rafforzare il trusting fra le parti facendo in modo che stunnel autorizzi solo alcuni certificati invece che qualunque. Questo tipo di controllo può essere fatto sia su stunnel sia in <em>client mode</em> che in <em>server mode</em>.</p>
<ul><li><strong>verifyChain</strong> = yes | no</li>
<li><strong>checkEmail</strong> = email del certificato</li>
<li><strong>checkHost</strong> = CN del certificato</li>
<li><strong>checkIP</strong> = IP del peer che presenta il certificato</li>
<li><strong>verifyPeer</strong> = yes | no</li>
<li><strong>CApath</strong> = &lt; path CA &gt;</li>
<li><strong>CAfile</strong> = &lt; file <strong>pem</strong> contenente la fullchain del certificato presentato a stunnel &gt;</li></ul>

<p><strong>verifyChain</strong>
Impone che si possa verificare la fullchain del certificato presentato. Se uno degli issuer non viene trovato, la connessione fallisce. La fullchain viene indicata attraverso <strong>CAfile</strong> o <strong>CApath</strong>.</p>

<p><strong>CAfile</strong>
È il <strong>file</strong> contenente le CA con cui stunnel valida i certificati che gli vengono presentati. Se stunnel è in <em>server mode</em>, sarà la fullchain relativa ai client. Altrimenti sarà la fullchain relativa al server.</p>

<p><strong>CApath</strong>
È il path in cui si trovano le CA con cui stunnel valida i certificati che gli vengono presentati. Se lo stunnel è in server mode, sarà la fullchain realtiva ai client. Altrimenti sarà la fullchain relativa al server.</p>

<p><strong>verifyPeer</strong>
Se con <strong>CAfile</strong> e <strong>CApath</strong> si verifica la fullchain dei certificati presentati a stunnel, con <strong>verifyPeer = yes</strong> si verifica che questi certificati siano presenti anche nel suo keystore (<strong>CAfile</strong> o <strong>CApath</strong>). Permette di “legare” a stunnel i certificati che dovrà validare.</p>

<p><strong>checkEmail</strong>, <strong>checkHost</strong>, <strong>checkIP</strong>
Come per <strong>verifyPeer</strong>, sono direttive che permettono di stringere il legame fra il certificato che viene presentato e stunnel.
Verifica che l’email, il CN o l’IP del certificato che viene presentato corrispondano a quelli presenti nella configurazione.
In una configurazione lato server posso avere molteplici occorrenze di questi due campi relative ad altrettanti certificati. Il caso in cui ad es. si debbano autenticare n client.</p>

<p>Se i certificati sono self-signed, <strong>verifyChain</strong> perde di significato (coinciderebbe con <strong>verifyPeer</strong>). La possibilità di generare i certificati attraverso una CA, anche interna, renderebbe il processo più strutturato anche se più complesso (si dovrà trovare un modo per distribuire la CA, se interna). Si tratta di trovare il giusto compromesso fra ampiezza del servizio (quanti utenti coinvolge?) e complessità richiesta.</p>

<p>Se si tratta di realizzare un canale sicuro fra due apparati per una comunicazione server-2-server, vanno bene anche i certificati self-signed o un’autenticazione PSK. Altrimenti, soprattutto nel caso in cui l’autenticazione dei client è una fase critica, conviene valutare l’uso di una CA e una validazione il più possibile restrittiva sui client e sul server.</p>

<h3 id="autenticazione-psk">Autenticazione PSK</h3>

<p>A differenza dell’autenticazione con certificato, l’autenticazione con PSK non prevede enhancement di sicurezza ulteriori a meno di specificare opportuni algoritmi di cifratura (cfr. paragrafo successivo).</p>

<h3 id="cifratura">Cifratura</h3>

<p>Come sempre succede, negli scenari di cifratura asimmetrica orientatia alla connessione, l’autenticazione, per quanto possa essere accurata, costituisce solo uno degli aspetti di cui tenere conto nella fase di messa in sicurezza del servizio.</p>

<p>Avere un’autenticazione con certificato generato con tutti i crismi da una CA, è certamente una gran cosa ma mette in sicurezza solo l’aspetto dell’autenticazione, per l’appunto.</p>

<p>l transito dei dati è affidato alle suite di cifratura supportati da openssl e, volendo lavorare di fino, bisognerebbe stringere anche su quelli.</p>

<p>Altrimenti, paradossalmente, si avrà un’autenticazione robustissima ma con algoritmi colabrodo di cifratura dei dati che, ad attaccanti ben motivati, lascerebbero delle porte spalancate per sferrare attacchi MITM per intercettare direttamente i dati, piuttosto che provare il furto di identità.</p>

<p>Ad ogni modo, il default, per ragioni di compatibilità legacy, dei parametri di cifratura (da settare eventualmente su client e sul server) è il seguente:</p>

<pre><code>ciphers: HIGH:!aNULL:!SSLv2:!DH:!kDHEPSK
ciphersuites: TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256
</code></pre>

<p>dove <strong>ciphers</strong> raggruppa le suite di cifratura relativi a TLS1.2 in giù e <strong>ciphersuites</strong> riguarda invece TLS1.3.</p>

<h3 id="configurazione-servizio">Configurazione servizio</h3>

<p>Ulteriori restrizioni possono essere aggiunte a livelllo di sistema:</p>
<ol><li>regolando i bit di <strong>setuid</strong> e <strong>setgid</strong> se stunnel gira come root</li>
<li>delimitando l’esecuzione del processo in una gabbia <strong>chroot</strong></li>
<li>disabilitando le <em>regonetiation</em> (se supportato dalla versione di openssl in uso) che mitiga in parte attacchi dos di tipo CPU-exhaustion</li>
<li>ecc..</li></ol>

<h2 id="caso-reale-tunnelizzare-transmission">Caso reale: tunnelizzare Transmission.</h2>

<p><strong>Transmission</strong> è un client <strong>bittorrent</strong> che può essere controllato da remoto via <strong>rpc</strong> attraverso un’interfaccia web o altri client.</p>

<p>Transmission, nelle sue varie declinazioni, non incapsula il traffico rpc in una connessione tls.</p>

<p>Se si vuole che il dato in transito sia cifrato e che la connessione sia autenticata, si può ricorrere:</p>
<ol><li>ad un tunnel ssh;</li>
<li>all’intermediazione di un webserver come apache o nginx ;</li>
<li>ad uno stunnel server</li></ol>

<p>Sugli ultimi due punti si può configurare una mutua autenticazione con certificato (complessa e articolata e, per tanti client, ha un impatto significativo). Scegliamo il 3° caso.</p>

<h2 id="esposizione-dell-interfaccia-web">Esposizione dell’interfaccia web</h2>

<p><strong>Scenario</strong>: abbiamo una macchina (il nostro serverino di fiducia o un nas) con transmission a bordo, presumibilmente dietro un firewall che natta il suo indirizzo privato (192.168.70.15).</p>

<p><img src="https://pixelfed.uno/storage/m/_v2/489827599091373610/42a8ecf32-5a8865/xP2UKA4QZMkK/OVVicpId7etadviBPtZUKHscaXrzy4vlaZAWAoBn.png" alt="Transmission Stunnel">
<small>Esposizione transmission attraverso stunnel server</small></p>

<p><strong>Obiettivo</strong>: Vogliamo poter raggiungere transmission e vogliamo che i client autentichino la loro connessione prima di accedere al servizio. In base allo scenario, sappiamo che dovremmo configurare un port forwarding dall’AP fino allo stunnel server. Il server transmission rimarrà confinato nella nostra rete locale.</p>

<h2 id="utilizzo-di-un-client-esterno">Utilizzo di un client esterno</h2>

<p>Supponiamo di utilizzare diversi client: il browser, <strong>transmission-remote-gtk</strong> o <strong>transmission-remote-gui</strong> (<em>transgui</em>), <strong>tremotesf</strong> (mobile).</p>

<p>La prima cosa da fare è configurare un port forwarding sul nostro AP</p>

<p>    Rule<sub>1</sub>: <strong>9091</strong> ⇒ 192.168.70.10:<strong>9091</strong></p>

<p>Dopodichè, configureremo stunnel in server mode davanti a transmission</p>

<pre><code>[transmission]
accept = 192.168.70.10:9091
connect = 192.168.70.15:9091
cert = &lt;path stunnel conf&gt;/ssl/server/certs/stunnel_crt.pem
key = &lt;path stunnel conf&gt;/ssl/server/private/stunnel_key.pem
requireCert = yes
verifyChain = yes
verifyPeer = yes
CApath = &lt;path stunnel conf&gt;/ssl/client/certs
</code></pre>

<p><strong>Alcune note sulla configurazione</strong>:</p>
<ul><li>devo disporre di un certificato per stunnel</li>
<li>devo disporre dei certificati per i client che si connetteranno, le cui fullchain dovranno essere localizzate nel path indicato da CApath</li></ul>

<p>A questo punto basta che i web-client puntino all’host pubblico (151.25.77.205) sulla porta 9091 e il gioco è fatto.</p>

<p>Per gli altri client come <strong>transmission-remote-gtk</strong>, <strong>transgui</strong> o <strong>tremotesf</strong>, per i quali al massimo posso chiedere di usare TLS (ma non sono riuscito ad usare un’autenticazione lato client), conviene installare stunnel in client mode :</p>

<pre><code>[transmission-client]
accept = localhost:9091
connect = 151.25.77.205:9091
client = yes
cert = &lt;path stunnel conf&gt;/ssl/client/laptop_crt.pem
key = &lt;path stunnel conf&gt;/ssl/client/laptop_key.pem
verifyChain = yes
verifyPeer = yes
CAPath = &lt;path stunnel conf&gt;/ssl/server/certs
</code></pre>

<p>Il client (ad es. sul laptop) si connetterà su localhost:9091 e dovrà disporre anche del certificato del server e della sua fullchain affinchè i check su <strong>verifyChain</strong> e <strong>verifyPeer</strong> non falliscano.</p>

<p><a href="/aytin/tag:ca" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">ca</span></a> <a href="/aytin/tag:DigitalCertificate" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">DigitalCertificate</span></a> <a href="/aytin/tag:AsymmetricEncryption" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">AsymmetricEncryption</span></a> <a href="/aytin/tag:SymmetricEncryption" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">SymmetricEncryption</span></a> <a href="/aytin/tag:cryptography" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">cryptography</span></a> <a href="/aytin/tag:fullchain" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">fullchain</span></a> <a href="/aytin/tag:psk" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">psk</span></a> <a href="/aytin/tag:ssh" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">ssh</span></a> <a href="/aytin/tag:ssl" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">ssl</span></a> <a href="/aytin/tag:stunnel" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">stunnel</span></a> <a href="/aytin/tag:tls" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">tls</span></a> <a href="/aytin/tag:x509" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">x509</span></a> <a href="/aytin/tag:openssl" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">openssl</span></a></p>
]]></content:encoded>
      <guid>https://noblogo.org/aytin/stunnel-cose-e-come-si-configura</guid>
      <pubDate>Sat, 04 Mar 2023 15:16:09 +0000</pubDate>
    </item>
  </channel>
</rss>