(Italiano) Come abilitare HTTPS su Apache Karaf Pax Web
Quante volte ci siamo trovati nella condizione di combattere con la configurazione del protocollo HTTPS? Sicuramente una miriade di volte e mai andata a buon fine a primo colpo.
In questo post vedremo come configurare il protocollo HTTPS per il container OSGi Apache Karaf. Il container Apache Karaf implementa le specifiche OSGi HTTP Service tramite il componente software Pax Web.
Pax Web estende OSGi HTTP Service con un supporto migliore per servlet, filtri, listener, pagine di errore e JSP al fine di soddisfare le più recenti versioni delle specifiche che sono alla base delle servlet. Pax Web supporta il protocollo SSL/TLS (HTTPS) grazie a Jetty che include appunto il supporto a questo protocollo di sicurezza.
La versione di Apache Karaf di riferimento è la 4.0.8 che utilizza la versione 4.3.0 di Pax Web che possiede le seguenti caratteristiche:
- Servlet 3.1
- JSP 2.3
- JSF 2.2
- Jetty 9.2.x
- Tomcat 8.0.x (sperimentale)
- supporto per CDI (tramite Pax-CDI)
- supporto Servlet 3.1 con il Whiteboard extender
- supporto delle Websockets JSR 356 (solo Jetty)
- Web-Fragments
1. Installazione di Pax Web
Partendo dall'assunzione che abbiate un'istanza di Apache Karaf 4.0.8 installata e avviata, l'installazione di Pax Web avviene come feature Karaf eseguendo i seguenti comandi dalla console di Apache Karaf:
karaf@root()> feature:install http karaf@root()> feature:install http-whiteboard karaf@root()> feature:install war
I comandi mostrati in precedenza eseguono l'installazione dell'implementazione di OSGi HTTP Service, dell'HTTP Whiteboard e del Web Container per il supporto completo delle specifiche JSP/Servlet.
Per verificare la corretta installazione delle feature, sempre dalla console di Apache Karaf eseguire i due comandi a seguire:
karaf@root()> feature:list | grep http karaf@root()> feature:list | grep war
L'esecuzione di questi due comandi producono l'output mostrato a seguire con evidenza dello stato dei bundle che in questo caso sono correttamente in Started.
pax-http-jetty | 4.3.0 | | Started | org.ops4j.pax.web-4.3.0 | pax-http | 4.3.0 | | Started | org.ops4j.pax.web-4.3.0 | Implementation of the OSGI HTTP Service pax-http-whiteboard | 4.3.0 | | Started | org.ops4j.pax.web-4.3.0 | Provide HTTP Whiteboard pattern support http | 4.0.8 | x | Started | standard-4.0.8 | Implementation of the OSGI HTTP Service http-whiteboard | 4.0.8 | x | Started | standard-4.0.8 | Provide HTTP Whiteboard pattern support pax-war | 4.3.0 | | Started | org.ops4j.pax.web-4.3.0 | Provide support of a full WebContainer war | 4.0.8 | x | Started | standard-4.0.8 | Turn Karaf as a full WebContainer
L'installazione di Pax Web crea il file di configurazione org.ops4j.pax.web.cfg (posizionato in ${karaf.home}/etc) su cui torneremo successivamente per aggiungere i parametri di configurazione necessari per attivare il protocollo HTTPS.
2. Generazione del keystore JKS
Per il prossimo step dobbiamo generare il "cassettino" dove andrà riposta la nostra coppia di chiavi o key pair (privata e pubblica), coppia che sarà poi utilizzata per instaurare le connessioni sicure via SSL/TLS. Tutto ciò che server per generare la coppia di chiavi è il keytool.
A seguire tutti i comandi necessari per produrre il keystore in formato JKS (Java KeyStore) che posizioneremo all'interno della directory ${karaf.home}/etc/keystore
dove ${karaf.home} è la root directory d'installazione di Apache Karaf.
$ cd ${karaf.home} $ cd etc $ mkdir keystore $ cd keystore $ keytool -genkeypair -keyalg RSA -validity 2048 \ -alias dontesta-karaf \ -dname "cn=karaf.dontesta.it, ou=R&D Labs, o=Antonio Musarra's Blog, C=IT, L=Rome, S=Italy" \ -keypass changeit -storepass changeit \ -keystore dontesta-karaf-server.jks \ -ext SAN=DNS:www.dontesta.it,DNS:services.dontesta.it
L'esecuzione del keytool genera il file dontesta-karaf-server.jks contenente la coppia di chiavi e che possiamo verificare attraverso l'esecuzione del comando a seguire:
$ keytool --list --keystore dontesta-karaf-server.jks -storepass changeit -rfc
Il risultato del comando precedente è mostrato subito sotto:
Tipo keystore: JKS Provider keystore: SUN Il keystore contiene 1 voce Nome alias: dontesta-karaf Data di creazione: 28-feb-2017 Tipo di voce: PrivateKeyEntry Lunghezza catena certificati: 1 Certificato[1]: -----BEGIN CERTIFICATE----- MIIDyTCCArGgAwIBAgIEU9S/EDANBgkqhkiG9w0BAQsFADB8MQ4wDAYDVQQIEwVJdGFseTENMAsG A1UEBxMEUm9tZTELMAkGA1UEBhMCSVQxHzAdBgNVBAoTFkFudG9uaW8gTXVzYXJyYSdzIEJsb2cx ETAPBgNVBAsMCFImRCBMYWJzMRowGAYDVQQDExFrYXJhZi5kb250ZXN0YS5pdDAeFw0xNzAyMjgy MjE4MTlaFw0yMjEwMDgyMjE4MTlaMHwxDjAMBgNVBAgTBUl0YWx5MQ0wCwYDVQQHEwRSb21lMQsw CQYDVQQGEwJJVDEfMB0GA1UEChMWQW50b25pbyBNdXNhcnJhJ3MgQmxvZzERMA8GA1UECwwIUiZE IExhYnMxGjAYBgNVBAMTEWthcmFmLmRvbnRlc3RhLml0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A MIIBCgKCAQEAsPuxJftWgDzQ9JhhWN6bjybKjCz04L5OC5dNKrF9FBMl/2Xw07aC0g3uB6dILCqf L8+i8aUZnSl147i3eyUq6Zsk0UquNK3Q+7/pi1WZHfIpSuZsL5x+jLI3sInREGTw63Jf4+6pa2LH hoJ20/G90dvyJIjBLT/DpnTQiHdKhaEZxpNB2dclSmrwkKiiA7+AEyzhKmkJ5zDJWIAbpIyfAk5n uD/s/rzh7PQj0ElHSAraUp94qA/XuqobtONLp7pPOMZoX6hbBLd40eWvPN6dMmTc+Dd5qSC7gzhu RPzmg+dhmxwRkTtup1A3IaXg+hXU0gNfUtl0NNNKobSiJVx8ewIDAQABo1MwUTAwBgNVHREEKTAn gg93d3cuZG9udGVzdGEuaXSCFHNlcnZpY2VzLmRvbnRlc3RhLml0MB0GA1UdDgQWBBQK1gn2lg8U EOv1roC7mpRj7V5rjjANBgkqhkiG9w0BAQsFAAOCAQEAICgixak/wuV5/4HbeqQtOddVxmXzvGRP oMvdTfmrw+pquHg9p4ThAcbYa/7depJRzBJukbCIb2VJ2CMbhFaIKytwHpVq6+FmeseLtNJGEb8W Gz8/yLi7W36CrCXTlw6PBrm3x0K4sg/7egDcj72+hKhImmgdjrTAOabkYcktQJvlKgHSWdmH8ZrW pLirNLwlXwsbHqlx4SDWVJ8xov1Cq3/jH6u4VQtjicGfkZFMgMH0pUSg66oY2ED7T5+tkkHX94TI axosd560C9wa+9LNh0XIfu9BqeI5QCuN66m4KaQ2cRcWZEM/Rvd01ameMLgx5JzLrXPRqgekPzkP GoISPA== -----END CERTIFICATE-----
Se volessimo ottenere maggiori informazioni circa il certificato pubblico, è possibile farlo, sfruttando sempre il keytool, in questo modo:
$ keytool --printcert --file dontesta-karaf-server.pub.pem
il file dontesta-karaf-server.pub.pem contiene il certificato pubblico x509 in formato PEM (Privacy Enhanced Mail) estratto dal comando keytool --list
.A seguire l'output del comando precedente:
Proprietario: CN=karaf.dontesta.it, OU=R&D Labs, O=Antonio Musarra's Blog, C=IT, L=Rome, ST=Italy Autorità emittente: CN=karaf.dontesta.it, OU=R&D Labs, O=Antonio Musarra's Blog, C=IT, L=Rome, ST=Italy Numero di serie: 53d4bf10 Valido da: Tue Feb 28 23:18:19 CET 2017 a: Sun Oct 09 00:18:19 CEST 2022 Impronte digitali certificato: MD5: C6:D6:0B:82:1B:38:4C:30:2A:72:2C:58:F5:92:5F:33 SHA1: B6:02:29:B8:7C:F5:5F:D6:5D:B6:E9:D2:54:DC:49:32:57:CD:3A:23 SHA256: 29:9A:50:B5:92:26:20:9D:7D:87:D7:16:A7:4D:E0:47:FC:08:B3:59:91:81:75:7F:C9:DF:A7:56:7F:83:3F:80 Nome algoritmo firma: SHA256withRSA Versione: 3 Estensioni: #1: ObjectId: 2.5.29.17 Criticality=false SubjectAlternativeName [ DNSName: www.dontesta.it DNSName: services.dontesta.it ] #2: ObjectId: 2.5.29.14 Criticality=false SubjectKeyIdentifier [ KeyIdentifier [ 0000: 0A D6 09 F6 96 0F 14 10 EB F5 AE 80 BB 9A 94 63 ...............c 0010: ED 5E 6B 8E .^k. ] ]
L'utilizzo del keytool per alcuni potrebbe risultare ostico, esistono per i più pigri dei tool come per esempio KeyStore Explore che facilitano di gran lunga le operazioni di gestione (come per esempio l'importazione di certificati, l'esportazione in formati vari, etc.) dei JKS.
Nel nostro caso abbiamo generato un certificato self-signed ma nei casi reali la situazione è diversa, ovvero, sarà in genere una PKI a distribuire i certificati digitali in uno dei formati standard. Il certificato digitale ricevuto potrà poi essere importato sul proprio JKS per esempio.
A questo punto abbiamo ciò che serve per abilitare il protocollo HTTPS su Pax Web.
3. Abilitazione del protocollo HTTPS
L'abilitazione del protocollo HTTPS per Pax Web avviene attraverso la configurazione di una serie di properties che andranno inserite all'interno del file di configurazione org.ops4j.pax.web.cfg (situato in ${karaf.home}/etc). Le properties da configurare sono:
- org.osgi.service.http.secure.enabled=true
- org.ops4j.pax.web.ssl.keystore=${karaf.etc}/keystore/dontesta-karaf-server.jks
- org.ops4j.pax.web.ssl.password=changeit
- org.ops4j.pax.web.ssl.keypassword=changeit
Quelli indicati sopra sono i parametri minimi richiesti per configurare correttamente il supporto HTTPS, esisto altri parametri di configurazione ampiamente documentati su Pax Web nella sezione Configuration SSL.
Il file di configurazione completo per l'attivazione del protocollo HTTPS è mostrato a seguire:
javax.servlet.context.tempdir = /Users/amusarra/Progetti/Karaf/runtime/apache-karaf-4.0.8/data/pax-web-jsp org.ops4j.pax.web.config.file = /Users/amusarra/Progetti/Karaf/runtime/apache-karaf-4.0.8/etc/jetty.xml org.osgi.service.http.port = 8181 org.osgi.service.http.secure.enabled=true org.ops4j.pax.web.ssl.keystore=${karaf.etc}/keystore/dontesta-karaf-server.jks org.ops4j.pax.web.ssl.password=changeit org.ops4j.pax.web.ssl.keypassword=changeit
Al momento del salvataggio del file di configurazione la modifica è applicata immediatamente.
2017-03-01 00:04:15,656 | INFO | onfig-1-thread-1 | JettyServerImpl | 87 - org.ops4j.pax.web.pax-web-jetty - 4.3.0 | Pax Web available at [0.0.0.0]:[8181] 2017-03-01 00:04:15,723 | INFO | onfig-1-thread-1 | JettyFactoryImpl | 87 - org.ops4j.pax.web.pax-web-jetty - 4.3.0 | SPDY not available, creating standard ServerConnector for Https 2017-03-01 00:04:15,724 | INFO | onfig-1-thread-1 | JettyServerImpl | 87 - org.ops4j.pax.web.pax-web-jetty - 4.3.0 | Pax Web available at [0.0.0.0]:[8443]
Dai log risulta che la configurazione è stata applicata correttamente e Pax Web è nelle condizioni di fornire risorse tramite il protocollo HTTPS ma non è ancora attivo, infatti, nessun servizio HTTPS è in listen sulla porta 8443 (porta di default). Al deploy della prima applicazione web, il servizio HTTPS sarà effettivamente listen sulla porta 8443.
4. Test tramite Web Application
Al fine di fare un test, possiamo installare sulla nostra istanza di Apache Karaf la Web Console tramite il comando feature:install webconsole
che una volta terminato attiva la web console e con essa anche il protocollo HTTPS, così come mostrato sul file di log.
2017-03-01 01:09:29,591 | INFO | onfig-1-thread-1 | JettyServerImpl | 87 - org.ops4j.pax.web.pax-web-jetty - 4.3.0 | Pax Web available at [0.0.0.0]:[8443] 2017-03-01 01:09:31,047 | INFO | FelixStartLevel | ServerConnector | 75 - org.eclipse.jetty.util - 9.2.19.v20160908 | Started secureDefault@6a784c06{SSL-http/1.1}{0.0.0.0:8443}
A questo punto puntiamo il nostro browser all'indirizzo https://localhost:8443 e se tutto è andato per il verso giusto dovremmo vedere instaurata la connessione HTTPS e riuscire a vedere anche il certificato (così come mostrato in Figura 1).
Si può fare altro?
Certamente 🙂 Una tipica connessione TLS/SSL (per esempio via browser internet) prevede un tipo di autenticazione denominata unilaterale : solo il server è autenticato (il client conosce l’identità del server), ma non vice-versa (il client rimane anonimo e non autenticato). Il client (browser web, EmailUI, Java Client, etc…) valida il certificato del server controllando la firma digitale dei certificati del server, verificando che questa sia valida e riconosciuta da una Certificate Authority conosciuta utilizzando una cifratura a chiave pubblica. Questo è il caso che abbiamo mostrato nel corso di quest'articolo.
Il prossimo passo quale potrebbe essere? Come configurare e realizzare una connessione in HTTPS tra un browser e il nostro server Apache Karaf, con mutua autenticazione, e quindi anche con l’autenticazione del client presso il server, attraverso l’utilizzo di un certificato X509 appositamente generato.