JDBC-Verbindung über SSL auf Mysql-Server (Tomcat)

Hier wurde erklärt, wie man den MySQL-Server konfiguriert, so dass in MySQL-Client SSL Verbindungen zum Server aufbauen kann.

Nun möchte ich die SSL-Verbindung in einer Java-Applikation, welche in einem Tomcat läuft, verwenden. Dazu wird eine JDBC-Connection über SSL zum MySQL Server aufgebaut.

Die Server- und Client-Zertifikate wurden hier bereits erstellt.

Dieser Beitrag basiert auf Link

KeyStore

Tomcat-Applikationen müssen die Zertifikate in einem Keystore gespeichert halten.

Client Packet

Ein Paket mit client Zertifikat und client key erstellen

openssl pkcs12 -export -inkey client-key.pem -in client-cert.pem -out client.packet

MyKS.jks

Einen neuen KeyStore “MyKS.jks” erstellen, der das erstellte client paket und die CA Zertifikate enthält. Als Passwort wähle ich immer das gleiche.

sudo keytool -importkeystore -deststorepass password -destkeypass password -destkeystore myKS.jks -srckeystore client.packet -srcstoretype PKCS12 -srcstorepass password -alias tomcat
sudo keytool -importcert -alias mysqlCA -trustcacerts -file /root/ca-cert.pem -keystore myKS.jks

Nicht vergessen die Berechtigung adäquat anzupassen

chmod 440 myKS.jks

Tomcat konfigurieren

JAVA_OPTS

Keystore in Tomcat-Verzeichnis kopieren. SSL konfigurieren und den keystore anmelden. Hierzu ist auch die Angabe des oben genutzen Passwortes notwendig, so dass der Keystore gelesen werden kann. Diese Properties können z.B. in catalina.sh exportiert werden (export).

In Ubuntu 14.04 findet man das startup-File von Tomcat unter

/etc/default/tomcat7
export JAVA_OPTS="-Djavax.net.ssl.keyStore=/usr/local/etc/tomcat/certs/myKS.jks -Djavax.net.ssl.keyStorePassword=password -Djavax.net.ssl.trustStore=/usr/local/etc/tomcat/certs/myKS.jks -Djavax.net.ssl.trustStorePassword=password"

oder als Java-Parameter:

-Djavax.net.ssl.keyStore=path_to_keystore_file
-Djavax.net.ssl.keyStorePassword=password
-Djavax.net.ssl.trustStore=path_to_truststore_file
-Djavax.net.ssl.trustStorePassword=password

oder man könnte dies auch in der Tomcat-Applikation als System-Properties definieren:

System.setProperty("javax.net.ssl.keyStore","path_to_keystore_file");
System.setProperty("javax.net.ssl.keyStorePassword","password");
System.setProperty("javax.net.ssl.trustStore","path_to_truststore_file");
System.setProperty("javax.net.ssl.trustStorePassword","password");

JDBC URL

Dann muss noch die Connection so angepasst werden, dass SSL verwendet wird (useSSL). Dies kann über einen connection-parameter gemacht werden.

Das kann entweder über die URL mit useSSL=true oder aber über die java.util.Properties (propertyuseSSL to true) Instanz, welche dem DriverManager.getConnection() mitgegeben wird, gemacht werden.

jdbc:mysql://mysql.server.com/database?verifyServerCertificate=false&useSSL=true&requireSSL=true

CHECK

Überprüfen ob die Verbindung auch wirklich verschlüsselt daher kommt:

 sudo tcpdump -i any -vv -X src port 3306

Vorher

13:56:05.099198 IP (tos 0x8, ttl 64, id 6943, offset 0, flags [DF], proto TCP (6), length 63)
    localhost.mysql > localhost.50479: Flags [P.], cksum 0xfe33 (incorrect -> 0xab2d), seq 3174702966:3174702977, ack 903431479, win 800, options [nop,nop,TS val 2444442 ecr 2444442], length 11
        0x0000:  4508 003f 1b1f 4000 4006 2190 7f00 0001  E..?..@.@.!.....
        0x0010:  7f00 0001 0cea c52f bd3a 1f76 35d9 4537  ......./.:.v5.E7
        0x0020:  8018 0320 fe33 0000 0101 080a 0025 4c9a  .....3.......%L.
        0x0030:  0025 4c9a 0700 0001 0000 0000 0000 00    .%L............
13:56:05.100525 IP (tos 0x8, ttl 64, id 6944, offset 0, flags [DF], proto TCP (6), length 129)
    localhost.mysql > localhost.50479: Flags [P.], cksum 0xfe75 (incorrect -> 0xec2b), seq 11:88, ack 35, win 800, options [nop,nop,TS val 2444442 ecr 2444442], length 77
        0x0000:  4508 0081 1b20 4000 4006 214d 7f00 0001  E.....@.@.!M....
        0x0010:  7f00 0001 0cea c52f bd3a 1f81 35d9 4559  ......./.:..5.EY
        0x0020:  8018 0320 fe75 0000 0101 080a 0025 4c9a  .....u.......%L.
        0x0030:  0025 4c9a 0100 0001 012c 0000 0203 6465  .%L......,....de
        0x0040:  6600 0000 1640 4073 6573 7369 6f6e 2e74  f....@@session.t
        0x0050:  785f 7265 6164 5f6f 6e6c 7900 0c3f 0001  x_read_only..?..
        0x0060:  0000 0008 8000 0000 0005 0000 03fe 0000  ................
        0x0070:  0000 0200 0004 0130 0500 0005 fe00 0000  .......0........
        0x0080:  00                                       .
13:56:05.105052 IP (tos 0x8, ttl 64, id 6945, offset 0, flags [DF], proto TCP (6), length 1781)
    localhost.mysql > localhost.50479: Flags [P.], cksum 0x04ea (incorrect -> 0x7756), seq 88:1817, ack 143, win 800, options [nop,nop,TS val 2444443 ecr 2444442], length 1729
        0x0000:  4508 06f5 1b21 4000 4006 1ad8 7f00 0001  E....!@.@.......
        0x0010:  7f00 0001 0cea c52f bd3a 1fce 35d9 45c5  ......./.:..5.E.
        0x0020:  8018 0320 04ea 0000 0101 080a 0025 4c9b  .............%L.
        0x0030:  0025 4c9a 0100 0001 0638 0000 0203 6465  .%L......8....de
        0x0040:  6604 7076 7332 0d74 656d 705f 6361 7465  f.pvs2.temp_cate
        0x0050:  676f 7279 0d74 656d 705f 6361 7465 676f  gory.temp_catego
        0x0060:  7279 0269 6402 6964 0c3f 000b 0000 0003  ry.id.id.?......
        0x0070:  0000 0000 003c 0000 0303 6465 6604 7076  .....<....def.pv
        0x0080:  7332 0d74 656d 705f 6361 7465 676f 7279  s2.temp_category
        0x0090:  0d74 656d 705f 6361 7465 676f 7279 046e  .temp_category.n
        0x00a0:  616d 6504 6e61 6d65 0c3f 00ff ffff fffc  ame.name.?......
        0x00b0:  9000 0000 003c 0000 0403 6465 6604 7076  .....<....def.pv
        0x00c0:  7332 0d74 656d 705f 6361 7465 676f 7279  s2.temp_category

Nachher

13:59:58.645194 IP (tos 0x8, ttl 64, id 60639, offset 0, flags [DF], proto TCP (6), length 52)
    localhost.mysql > localhost.50483: Flags [.], cksum 0xfe28 (incorrect -> 0xf2c8), seq 2669811453, ack 3878597006, win 851, options [nop,nop,TS val 2502828 ecr 2502828], length 0
        0x0000:  4508 0034 ecdf 4000 4006 4fda 7f00 0001  E..4..@.@.O.....
        0x0010:  7f00 0001 0cea c533 9f22 16fd e72e b18e  .......3."......
        0x0020:  8010 0353 fe28 0000 0101 080a 0026 30ac  ...S.(.......&0.
        0x0030:  0026 30ac                                .&0.
13:59:58.645264 IP (tos 0x8, ttl 64, id 60640, offset 0, flags [DF], proto TCP (6), length 105)
    localhost.mysql > localhost.50483: Flags [P.], cksum 0xfe5d (incorrect -> 0xbe29), seq 0:53, ack 1, win 851, options [nop,nop,TS val 2502828 ecr 2502828], length 53
        0x0000:  4508 0069 ece0 4000 4006 4fa4 7f00 0001  E..i..@.@.O.....
        0x0010:  7f00 0001 0cea c533 9f22 16fd e72e b18e  .......3."......
        0x0020:  8018 0353 fe5d 0000 0101 080a 0026 30ac  ...S.].......&0.
        0x0030:  0026 30ac 1703 0100 300c 3524 6529 b225  .&0.....0.5$e).%
        0x0040:  01dd ed3f 7cb5 085f 3c80 4a51 c362 e980  ...?|.._<.JQ.b..
        0x0050:  1884 4e40 0d58 d0a3 69a1 b3c1 c979 b142  ..N@.X..i....y.B
        0x0060:  09b6 3603 b43c 8a22 9d                   ..6..<.".
13:59:58.646125 IP (tos 0x8, ttl 64, id 60641, offset 0, flags [DF], proto TCP (6), length 52)
    localhost.mysql > localhost.50483: Flags [.], cksum 0xfe28 (incorrect -> 0xf227), seq 53, ack 107, win 851, options [nop,nop,TS val 2502829 ecr 2502829], length 0
        0x0000:  4508 0034 ece1 4000 4006 4fd8 7f00 0001  E..4..@.@.O.....
        0x0010:  7f00 0001 0cea c533 9f22 1732 e72e b1f8  .......3.".2....
        0x0020:  8010 0353 fe28 0000 0101 080a 0026 30ad  ...S.(.......&0.
        0x0030:  0026 30ad                                .&0.
13:59:58.646188 IP (tos 0x8, ttl 64, id 60642, offset 0, flags [DF], proto TCP (6), length 169)
    localhost.mysql > localhost.50483: Flags [P.], cksum 0xfe9d (incorrect -> 0x6a73), seq 53:170, ack 107, win 851, options [nop,nop,TS val 2502829 ecr 2502829], length 117
        0x0000:  4508 00a9 ece2 4000 4006 4f62 7f00 0001  E.....@.@.Ob....
        0x0010:  7f00 0001 0cea c533 9f22 1732 e72e b1f8  .......3.".2....
        0x0020:  8018 0353 fe9d 0000 0101 080a 0026 30ad  ...S.........&0.
        0x0030:  0026 30ad 1703 0100 7074 359c b82a c838  .&0.....pt5..*.8
        0x0040:  3a69 85b9 b43f 7648 5fe0 88c6 972c 576a  :i...?vH_....,Wj
        0x0050:  84ac c7ac 58f0 ed0c a79c 0c12 1c51 9714  ....X........Q..
        0x0060:  45d3 80ac 1fb6 fbbb 7665 9782 a61f cf0a  E.......ve......
        0x0070:  0b19 1e4e a679 6d1d 3a7b db6d 02f7 2dba  ...N.ym.:{.m..-.
        0x0080:  4c0b 2cfb ad6f b516 2128 2596 9f5f 6ab2  L.,..o..!(%.._j.
        0x0090:  640b 1876 2d52 1d4b ffcf 6a25 08d6 b985  d..v-R.K..j%....
        0x00a0:  cdf0 cd62 cacc 84e1 9a                   ...b.....
13:59:58.646838 IP (tos 0x8, ttl 64, id 60643, offset 0, flags [DF], proto TCP (6), length 52)
    localhost.mysql > localhost.50483: Flags [.], cksum 0xfe28 (incorrect -> 0xf0f8), seq 170, ack 277, win 867, options [nop,nop,TS val 2502829 ecr 2502829], length 0
        0x0000:  4508 0034 ece3 4000 4006 4fd6 7f00 0001  E..4..@.@.O.....

 

Java Cryptography Extension (JCE) Unlimited Strength

Um JAVA AES mit 256-bit Schlüssel verwenden zu können, muss eine Extension installiert werden. Für Java 8 findet man die Extension hier.

Installation

  1. Alle Java Prozesse stoppen, die das JDK verwenden
  2. Unzip von jce_policy-8.zip File. Es werden zwei Jar-Files unzippt.
    1. local_policy.jar
    2. US_export_policy.jar
  3. Diese beiden Files ersetzten die Files im JDK-Verzeichnis
    /jre/lib/security/
  4. Alle Java Prozesse wieder starten

Umgebungsvariablen und Alias

Userspezifisch

Aliase und Umgebungsvariablen können spezifisch pro User festgelegt werden. Hierzu verwendet man das ‘.bashrc’ File im eigenen Home-Verzeichnis:

Alias/Umgebungsvariable

vi ~/.bashrc

Neue Zeile

alias ll='ls -l'

einfügen

ll wird nun den Befehl ls -l im Terminal ausführen.

Auf diese Art und Weise können Umgebungsvariablen (z.B. JAVA_HOME) gesetzt werden:

JAVA_HOME=/usr/lib/JDK1.5
export JAVA_HOME

Global

Um globale Aliase und Umgebungsvariablen zu setzen, hat man mehrere Möglichkeiten:

  • /etc/profile
  • /etc/bash.bashrc
  • /etc/environment
  • Wrapper-Skript

 

/etc/profile

Dieses File ist dann der richtige Ort, wenn man von der Console bootet und das GUI (Gnome/KDE) über startx aufruft. Das /etc/profile wird also auch dann gelanden, wenn kein Window-Manager gelanden wird.

/etc/bash.bashrc

Dieses File ist dann der richtige Ort, wenn man direkt per “Login-Manager” grafisch einloggt. Man darf aber nicht vergessen, dass dieses File ignoriert wird, sobald man ein weiteres Terminal (per Alt-F?) öffnet.

/etc/environment

Hier kann man statische Variablen definieren, die für das ganze System von Interesse sind. Als Beispiel werden hier alle Umgebungsvariablen für die Programmiersprache Java definiert, die sowohl für das Ausführen als auch die Entwicklung von Java-Programmen nötig sind. Die Variable PATH kann man auch in

/etc/environment

definieren, sie wird aber in der Regel von der Shell wieder überschrieben. Somit ist es besser, PATH in der Datei

/etc/profile

zu definieren und gegebenenfalls über die benutzerspezifischen Dateien

${HOME}/.bash_profile

(Login-Shell) und

${HOME}/.bashrc

(interaktive Shell) anpassen.

Wrapper-Skript

Es kursiert in der Debian-Welt die Idee, dass Umgebungsvariablen für das Starten eines Programmes nicht nötig sein sollten. Aus diesem Grunde wird oft ein so genanntes Wrapper-Script erstellt, welches die nötigen Variablen setzt und danach das eigentlich gewünschte Programm aufruft. Das kann z.B. folgendermassen aussehen:

#!/bin/sh
export JAVA_HOME=/wo/auch/immer
exec $0.real "$@"

Das speichert man unter dem Namen nachdem das effektive ‘PROGRAMM’ zu ‘PROGRAMM.real’ umbenannt worden ist. Danach noch das execute-Falg setzen:

chmod +x PROGRAMM