Tomcat

Script per lanciare apache tomcat

Le variabili di ambiente possono essere settate in setclasspath.sh all'inizio in modo da esser sempre lette in startup che in shutdown

cat ./lancio.sh

JAVA_HOME=/opt/jdk1.6.0_21/
JRE_HOME=$JAVA_HOME
export JAVA_HOME
export JRE_HOME
echo $JRE_HOME
/opt/apache-tomcat-6.0.26/bin/startup.sh

cat stoppa.sh

JAVA_HOME=/opt/jdk1.6.0_21/
JRE_HOME=$JAVA_HOME
export JAVA_HOME
export JRE_HOME
echo $JRE_HOME
/opt/apache-tomcat-6.0.26/bin/shutdown.sh

La variabile aumentare la memoria in tomcat , qui sta a 1 GB di partenza e 2 GB di massimo.
C'è anche la variabile per utf-8

JAVA_OPTS="-Xms1000m -Xmx2000m -XX:PermSize=1000M -XX:MaxPermSize=2000M -Dfile.encoding=UTF-8"

Tomcat su porte diverse per istanze multiple

Per eseguire tomcat su porte diverse dalle predefinite bisogna cambiare il servizio di shutdown e tutti i connettori dal file server.xml

<Connector connectionTimeout=”20000″ port = “8080″ protocollo = “HTTP/1.1″ redirectPort=”8443″/>
<Server port=”8005″ shutdown=”SHUTDOWN”>
<Connector port=”8009″ protocol=”AJP/1.3″ redirectPort=”8443″/>
# A questo punto è possibile riavviare ancora il sistema e le due istanze (compresi i monitor) dovrebbero funzionare insieme senza problemi

Sito di riferimento di questa sezione è [http://sites.google.com/site/fabiocassanelli/how-to-1/apachetomcat-istanzemultiple
questo]

Tomcat logs

Dalla pagina http://tomcat.apache.org/tomcat-6.0-doc/config/valve.html ho visto la parte Access Log Valve
Decommentando dal server.xml alla fine questa direttiva si avviano i log

 <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"  
               prefix="valve_access_log." suffix=".log" pattern="%U" resolveHosts="false"/>

Nella pagina della doc ci sono diversi commenti su come fare le direttive
Per esempio io ho modificato pattern
il default cioè con pattern="common" da come output nel file qu
10.248.83.230 - - [11/Jul/2012:12:15:51 +0000] "GET /nomewebapp/eventi.xml?cod=3090300170 HTTP/1.1" 200 2060

mentre con pattern="%U"
/nomewebapps/eventi.xml

Tomcat su porta 80

Se si lancia tomcat con utenza non di root o con privilegi non di administrator (che è la cosa più saggia da fare) non si può metterlo in ascolto delle porte inferiori a 1024. Quindi se si vuole che il tomcat risponda direttamente alle chiamate verso la porta 80 senza avere un proxy in mezzo si può fare un redirect con iptables

iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080

ovviamente deve essere eseguito con permessi di root

Per annullare questa regola sopra in centos ho eseguito /etc/init.d/iptables stop

Tomcat e ssl

Il link di riferimento è questo

Configuration

Prepare the Certificate Keystore

Tomcat fino alla versione 7 opera con questi formati JKS, PKCS11 or PKCS12. JKS è il formato delle chiavi di java creato dal comando keytool. Gli altri formati sono standard internet è possono essere manipolati tra le altre cose da openssl e microsoft key manager.

Ongi entry in un keystore è identificata da un alias string. Molte implementazioni di keystore trattano gli alias in maniera case insensitive ma è disponibile una modalità case sentive. La specifica PKCS11 richiede che gli alias siano case sentive. . Quindi bisogna stare attenti.

Per importare un certificato esistente in un JKS Keystore leggere la doc di keytool. Attenzione che openssl spesso aggiunge commenti leggibili prima della chiave ma keytool non supporta questo. Quindi rimuovere i commenti prima di importare un certificato con keytool.

Per importare un certificato esistente in un JSK keystore firmato dalla propria ca in un pkcs12 keystore usando openssl eseguire il comando

openssl pkcs12 -export -in mycert.crt -inkey mykey.key -out mycert.p12 -name tomcat -CAfile myCA.crt -caname root -chain

Per maggiori dettagli vedere la doc di openssl

Per creare un nuovo keystore from scratch contenente un certificato singolo auto firmato eseguire il seguente comando

$JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA

L'algoritmo di tipo RSA è da preferire perchè garantisce compatibilità con altri server e componenti.
Questo comando creerà un nuovo file, nella home directory dell'utente sotto il quale viene lanciato, chiamato .keystore. Per specificare una locazione diversa specificare il parametro -keystore seguito dal path name completo. Bisognerà anche riflettere la locazione nel file server.xml come si vedrà più avanti.
$JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA -keystore /path/to/my/keystore

Inserire la password del keystore quella di default è "changeit" (all lower case) , che deve essere di almeno 6 caratteri. La password deve essere specificata anche in server.xml come vedremo in futuro. Dopo verrà richiesta anche la password del certificato bisogna inserire la stessa del keystore, questa è una limitazione di tomcat, premendo enter verrà fatto in automatico. Se non si inserisce la stessa password si otterrà un errore "java.io.IOException: Cannot recover key"

Edit the Tomcat Configuration File

Tomcat può usare due differenti implementazioni di ssl:

  1. the JSSE implementation provided as part of the Java runtime (since 1.4)
  2. the APR implementation, which uses the OpenSSL engine by default.

I dettagli ovviamente dipendono da quale configurazione vogliamo usare. L'implementazione usata da tomcat è scelta automaticamente a meno che non viene sovrascritta come mostrato sotto.
Se la tua installazione usa APR allora userà l'implementazione apr ssl, altrimenti userà l'implmentazione java jsse .

Per evitare auto configuration puoi definire un classname nell'attributo protocollo del connettore.
Per definire un connettore jsse senza curarsi di come le librerie apr vengono caricate o meno usare

<-- Define a blocking Java SSL Coyote HTTP/1.1 Connector on port 8443 -->
<Connector protocol="org.apache.coyote.http11.Http11Protocol" port="8443" .../>

<-- Define a non-blocking Java SSL Coyote HTTP/1.1 Connector on port 8443 -->
<Connector protocol="org.apache.coyote.http11.Http11NioProtocol" port="8443" .../>

La piccola differenza sta nel metodo bloccante o meno.

Alternativamente specificando un connettor apr (la libreria apr deve essere disponibile)

<-- Define a APR SSL Coyote HTTP/1.1 Connector on port 8443 -->
<Connector protocol="org.apache.coyote.http11.Http11AprProtocol" port="8443" .../>

Se si sta usando un apr si ha una opzione per configurare un motore openssl alternativo.

<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="someengine" SSLRandomSeed="somedevice" />

Il valore di default è
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" SSLRandomSeed="builtin" />

Per usare ssl sotto apr bisogna essere sicuri che l'attributo del motore ssl è settato a qualcosa diverso da off. Se si usa qualcosa di diverso dal valore di default on deve essere un nome di motore valido.
Se non si è compilato il supporto ssl nel nostro tomcat si può mettere questa configurazione a off.
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="off" />

SSLRandomeSeed permette di specificare una sorgente di entropia. Ambienti di produzione hanno bisogno di una sorgente di entropia affidabile ma questo può richiedere molto tempo per sbrigarsi si può usare una sorgente come /dev/urarndom che permette un partenza veloce di Tomcat.

Il passo finale è configurare il Connector in $CATALINA_BASE/conf/server.xml ci sono degli esempi inclusi di default nel file per JSSE è qualcosa come questo:

<-- Define a SSL Coyote HTTP/1.1 Connector on port 8443 -->
<!--
<Connector 
           port="8443" maxThreads="200"
           scheme="https" secure="true" SSLEnabled="true"
           keystoreFile="${user.home}/.keystore" keystorePass="changeit"
           clientAuth="false" sslProtocol="TLS"/>
-->

L'esempio sopra genererà un'eccezione se si ha apr e tomcat native library nel proprio pat, così tomcat proverà a usare il connettore apr . Il connettore apr usa differenti attributi per le chiavi ssl e i certificati ecco un esempio.
<-- Define a SSL Coyote HTTP/1.1 Connector on port 8443 -->
<!--
<Connector 
           port="8443" maxThreads="200"
           scheme="https" secure="true" SSLEnabled="true"
           SSLCertificateFile="/usr/local/ssl/server.crt" 
           SSLCertificateKeyFile="/usr/local/ssl/server.pem"
           clientAuth="optional" SSLProtocol="TLSv1"/>
-->

La porta per ssl di tomcat è la 8443 (la default per https è 443). In alcuni sistemi operativi è necessario run tomcat su porte più basse della 1024. Se si cambia il numero di porta , di dovrebbe anche cambiare il valore specificato per il redirectPort nel connettore non-SSL. Questo permette a tomcat di fare automaticamente il redirect agli utenti che provano ad accedere a pagine con una costante di sicurezza che specifica che è richiesto ssl come richiesto dalla specifica della servlet.

Ci sono diverse opzioni disponibili che dipendono da come è stato configurato precedentemente il keystore.

  • Se si sta usando un JSSE casato su connettore ssl le opzioni ssl sono documentate nell' "Apache Tomcat Configuration Reference" a questo link , che è una pagina dove viene definita la sintassi dei parametri.
  • Se invece si sta usando un connector apr il riferimento è questo sono sempre altre opzioni disponibili.

Dopo aver configurato il tutto riavviare il tomcat e https://localhost:8443 si dovrebbe vedere la solita home page (tranne se è stata modificata) ma in sicurezza. Se non va sotto c'è la sezione dei problemi. Se stai operando su una macchina server non dimenticare di aprire la porta 8443 sul firewall … bischero.

Installing a Certificate from a Certificate Authority

Prima eseguire quello sopra che non è strettamente necessario ma aiuta a fare pratica.

Create a local Certificate Signing Request (CSR)

Per ottenere un certificata da una c.a. prima bisogna crearsi una Certificate Signing Request (CSR) questo verrà usato dalla c.a. per creare il certificato. Bisogna eseguire questi passi:

  • creare un certificato locale nel keystore
keytool -genkey -alias tomcat -keyalg RSA -keystore <your_keystore_filename>

In alcuni casi potrebbe essere necessario inserire il dominio nei campi "first e lastname" per creare un working Certificate. Per un certificato di tipo wildcard come nome immettere *.dominio.com
  • creare il CSR con
keytool -certreq -keyalg RSA -alias tomcat -file certreq.csr  -keystore <your_keystore_filename>

Adesso si ha un file chiamato certeq.csr che si può mandare alla c.a e in restituzione si ottiene un certificato.

Importing the Certificate

Prima di importare il certificato nel keystore bisogna importare quella chiamata Chain Certificate or Root Certificate nel keystore.

For Verisign.com trial certificates go to: http://www.verisign.com/support/verisign-intermediate-ca/Trial_Secure_Server_Root/index.html
For Trustcenter.de go to: http://www.trustcenter.de/certservices/cacerts/en/en.htm#server
For Thawte.com go to: http://www.thawte.com/certs/trustmap.html

  • importare la Chain Certificate into your keystore
keytool -import -alias root -keystore <your_keystore_filename> -trustcacerts -file <filename_of_the_chain_certificate>
  • infine importare il nuovo certificato fornito dalla c.a.
keytool -import -alias tomcat -keystore <your_keystore_filename> -file <your_certificate_filename>

Ecco qui una pagina web di una certification autority dove spiega i processi di registrazione

Altri comandi utili per il keystore

Leggere i file di un keystore

keytool -list -v -keystore keys/my.keystore

Se si leva l'opzione -v si possono leggere le informazioni in maniera più coincisa

Keytool

Per riuscire ad usare bene il keytool ho trovato un ottima guida che spiega tutto quello che serve per manipolare un keytool.

Sopra abbiamo visto i passi per avere un certificato pubblico con la creazione del csr ecc. In questa guida invece si spiega come manipolare le chiavi già create e come trasformabili per sistemi microsoft iis.

Per estrarre la chiave privata del certificato non c'è un comando diretto del keytool ma o si usa un frontend (uno free è KeyTool-IUI o a pagamento e Keystore Explorer) per il keytool oppure si compila un programma java apposta.

Extracting the certificate (public key)

Per prima cosa estraiamo la chiave pubblica.

The result is a DER (binary) formatted certificate into the file exported.crt

keytool -export -alias mykey -keystore keystore -file exported-der.crt

Simply view & verify it
openssl x509 -noout -text -in exported-der.crt -inform der

Now you will want to convert it to another format - PEM - which is more widely used in applications such as apache and by openssl to do the PKCS12 conversion.
openssl x509 -out exported-pem.crt -outform pem -in exported-der.crt -inform der

Extracting the private key

Poi estraiamo la chiave privata tramite dei programmi java che sono in allegato alla pagina

ExportPriv.java - now compiles on Java2 1.6!

javac ExportPriv.java Base64Coder.java

The key will be produced to STDOUT so I suggest you redirect > to exported-pkcs8.key. Enter your own values for keystore, alias and password.

java ExportPriv <keystore> <alias> <password> > exported-pkcs8.key

cat exported-pkcs8.key 
-----BEGIN PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMKTXSLw/mT0IHfIvwXd3Mr9DSL+oOHF0Rqmfdd4Mtb
OaMXQyk34G6/Yhx6WRthqQ62GgHwEsJayAAOWRc+ZcaueJVsoeWFJfJXxLQ7Rq6JJNL6AmCWK5rfFvAvArpXdxQ0M+w
[...]
yS03EKrUnMA2k8U6OpeqIZynvnFkw8Di76b0PeKacmMHK6+qdk5+MtjuXlgX0exGBNsG8ChGAPeYI7w==
-----END PRIVATE KEY-----

NOTE: Some users have reported that ExportPriv is outputting the base64 private key all on one line. In order to function properly with openssl, you need to ensure that there are no more than 64 printable characters on each line. See Base64 for more information.

By now you probably realize, the private key is being exported as PKCS#8 PEM format. To get it into the RSA format that works with Apache (see below) you can issue the following command:

openssl pkcs8 -inform PEM -nocrypt -in exported-pkcs8.key -out exported.key

Combine extracted public/private keys into PKCS12 format

Questo l'ho usato per convertire in un formato che piacesse ad iis.

A PKCS12 format file is typically suffixed with .p12 or .pfx. It is more commonly used on the Microsoft platform.

Now that you have the private key and public key (certificate) combo that go together you can package them in pkcs12-formatted file… this should do the trick for using with IIS, for example.

openssl pkcs12 -export -out exported.pfx -inkey exported.key -in exported-pem.crt

Attacco a tomcat

Un piccolo attacco a un tomcat 6 di cui era lasciata aperta l'interfaccia di manger
Ecco i log di access

119.59.100.25 - "PUT /manager/deploy?path=/vZDVWufM HTTP/1.1" 200 398
119.59.100.25 - "GET /vZDVWufM/tsIjYPjO.jsp HTTP/1.1" 200 309
119.59.100.25 -  "GET /manager/undeploy?path=/vZDVWufM HTTP/1.1" 200 400

Inserimento dell'applicazione , richiamo e poi undeploy per evitare di vedere cosa è stato messo.
Il tomcat per errore girava con permessi di root ed è stata compromessa tutta la macchina, che chiamava mille risorse esterne generando 50mila connessioni

Sessione condivisa tra domini multipli

Ho provato un modo per mantenere la sessione tra ip multipli. Per esempio se ho una macchina registrata con due ip alfa.esempio.com e beta.esempio.com e la necessità di condividere la sessione, per motivi di carico del networking, posso mettere dentro un file contex.xml (che sia a livello applicativo o generale del tomcat) un parametro nella direttiva

<Context sessionCookieDomain=".esempio.com">

In questo modo il cookie di sessione viene mantenuto nella navigazione.

Secondo me questa cosa sarebbe utile se avessi più macchine ovviamente con ip differenti e sessione condivisa tramite meccanismi di cluster.
http://stackoverflow.com/questions/82645/best-way-for-allowing-subdomain-session-cookies-using-tomcat

Salvo diversa indicazione, il contenuto di questa pagina è sotto licenza Creative Commons Attribution-ShareAlike 3.0 License