Artykuł przedstawia w jaki sposób skorzystać z dostępnych w JBoss EAP narzędzi i w jaki sposób zabezpieczyć wrażliwe dane przed dostępem osób niepowołanych.
Jedna z najważniejszych spraw w IT to ochrona informacji. W swojej pracy zawodowej niejednokrotnie spotykam się z rażącymi przypadkami ignorowania tego faktu i utrzymywania np.: haseł i innych wrażliwych danych w formie plain text. Poniższy artykuł przedstawia w jaki sposób skorzystać z dostępnych w JBoss EAP narzędzi i w jaki sposób zabezpieczyć wrażliwe dane przed dostępem osób niepowołanych.
Temat artykułu będzie narzędzie VAULT. Jest to wbudowany w JBoss EAP skrypt, który umożliwi nam szyfrowanie danych wrażliwych i umieszczenie ich w binarnej zaszyfrowanej „skrzyni skarbów”.
Patrząc na ilość informacji jaką powinniśmy szyfrować dobrym pomysłem jest trzymanie wszystkiego w jednym miejscu. Jest to szczególnie istotne jeśli nasza domena JBoss jest rozproszona na kilka lub kilkanaście serwerów fizycznych lub wirtualnych. Zapanowanie nad tym jakie pliki z vault mają być gdzie skopiowane zacznie rodzić problemy organizacyjne, oraz problemy z utrzymaniem wszystkiego w odpowiedniej wersji na każdym hoście. Oczywiście można użyć zewnętrznych narzędzi np.: Puppet i dzięki niemu utrzymywać konfigurację w ryzach, ale my zajmiemy się przypadkiem najprostszym, czyli do naszej skrzyni wrzucimy zarówno hasła do baz danych jak i certyfikaty dla ssl’a.
To rozwiązanie nie przyda się jednak osobom, które regularnie podnoszą wersję JBoss EAP na swoich środowiskach. Zapytacie dlaczego? Otóż, od wersji JBoss EAP 6.1.1 zmienił się sposób zapisu informacji w vault. Nasza „skrzynia skarbów” zmienia zamek w formacie JKS (Java KeyStore) na nowe zamknięcie w formacie JCEKS (Java Cryptography Extension KeyStore). Po szczegóły odsyłam do strony Oracle.
Zacznijmy jednak od rozwiązania pierwszego – czyli starego formatu zapisu (JKS). Wygenerujmy sobie testową skrzynię na nasze szyfrowane dane, a w niej dane dla ssl i dla vault:
Generowanie przykładowego certyfikatu dla ssl:
keytool -genkey -keystore test.keystore
-storepass tajnehaslo
-keypass tajnehaslo
-keyalg RSA
-alias EAPSSL
-validity 3650
-dname "cn=LinuxPolska example,ou=admin,dc=jboss,dc=org"
Generowanie certyfikatu dla vault:
keytool -genkey -keystore test.keystore
-storepass tajnehaslo
-keypass tajnehaslo
-keyalg RSA
-alias vault
-keysize 1024
-validity 365
-dname "cn=LinuxPolska example,ou=admin,dc=jboss,dc=org"
Wykorzystane parametry:
KeyStore:
genkey: generuje klucz
keystore: plik, w którym znajdują się nasze szyfrowane dane. Jeśli plik nie istnieje to keytool utworzy plik o wskazanej przez nas nazwie. Ścieżka do pliku może być relatywna lub absolutna.
storepass: hasło do otwarcia naszego szyfrowanego pliku. Oczywiście rekomendowane jest użycie jak najbardziej skomplikowanego hasła.
Key:
keyalg: algorytm użyty do wykreowania klucza (RSA, AES, DES, etc.)
keysize: rozmiar klucza (128, 192, 256, etc)
alias: nazwa przypisana do klucza, wg której JBoss szuka certyfikatu w „skrzyni z kluczami”
validity: ilość dni ważności certyfikatu
keypass: hasło chroniące klucz. Niestety w JBoss hasło do klucza nie może być inne niż hasło do naszej zaszyfrowanej skrzyni. Miejmy nadzieję, że to niebawem ulegnie zmianie.
Sprawdzamy zawartość naszej skrzyni:
keytool -v -list -keystore test.keystore
Enter keystore password:
Keystore type: JKS
Keystore provider: SUN
Your keystore contains 2 entries
Alias name: vault
Creation date: 2015-03-21
…
Alias name: EAPSSL
Creation date: 2015-03-21
…
Potwierdzamy format pliku (JKS) komendą:
file test.keystore
test.keystore: Java KeyStore
Mając gotową skrzynię, możemy przystąpić do osadzenia w niej naszego „skarbu” czyli np.: hasła do połączenia z bazą danych w jednym z DataSource’ów. By ułatwić sobie interpretację czego dotyczy szyfrowany element, możemy podać nazwę naszego DataSource jako wartość Vault Block i szyfrowany atrybut czyli password, w polu Attribute Name. By tego dokonać w katalogu bin naszego serwera JBoss uruchamiamy skrypt vault.sh.
vault.sh
=========================================================================
JBoss Vault
JBOSS_HOME:/mediafs/jboss-eap-6.3
JAVA:/usr/java/latest/bin/java
=========================================================================
**********************************
****JBoss Vault***************
**********************************
Please enter a Digit:: 0: Start Interactive Session 1: Remove Interactive Session 2: Exit
0
Starting an interactive session
Enter directory to store encrypted files:/tmp
Enter Keystore URL:/tmp/test.keystore
Enter Keystore password:
Enter Keystore password again:
Values match
Enter 8 character salt:12345678
Enter iteration count as a number (Eg: 44):50
Enter Keystore Alias:vault
Initializing Vault
mar 21, 2015 10:23:32 AM org.picketbox.plugins.vault.PicketBoxSecurityVault init
INFO: PBOX000361: Default Security Vault Implementation Initialized and Ready
Vault Configuration in AS7 config file:
********************************************
…
</extensions>
<vault>
<vault-option name="KEYSTORE_URL" value="/tmp/test.keystore"/>
<vault-option name="KEYSTORE_PASSWORD" value="MASK-31x/z0Xn83H4JaL0h5eK/N"/>
<vault-option name="KEYSTORE_ALIAS" value="vault"/>
<vault-option name="SALT" value="12345678"/>
<vault-option name="ITERATION_COUNT" value="50"/>
<vault-option name="ENC_FILE_DIR" value="/tmp/"/>
</vault>
<management>
…
********************************************
Vault is initialized and ready for use
Handshake with Vault complete
Please enter a Digit:: 0: Store a secured attribute 1: Check whether a secured attribute exists 2: Exit
0
Task: Store a secured attribute
Please enter secured attribute value (such as password):
Please enter secured attribute value (such as password) again:
Values match
Enter Vault Block:Nazwa_DS
Enter Attribute Name:password
Secured attribute value has been stored in vault.
Please make note of the following:
********************************************
Vault Block:Nazwa_DS
Attribute Name:password
Configuration should be done as follows:
VAULT::Nazwa_DS::password::1 (typ JCEKS)
VAULT::Nazwa_DS::password::{N2N0OS00ZGQ0LWE4MmEtMWNl} (typ JKS)
********************************************
Please enter a Digit:: 0: Store a secured attribute 1: Check whether a secured attribute exists 2: Exit
2
Wygenerowany fragment XML (węzeł vault) wklejamy w odpowiednie miejsce w naszym pliku konfiguracyjnym JBoss (host.xml/standalone.xml/etc), a frazą VAULT zastępujemy nasze hasło do bazy danych w konfiguracji DataSource (domain.xml/standalone_sufix.xml) np.:
<datasource jndi-name="java:jboss/datasources/NAzwa_DS" enabled="true" use-java-context="true" pool-name="H2DS">
<connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1</connection-url>
<driver>h2</driver>
<security>
<user-name>sa</user-name>
<password>${VAULT::Nazwa_DS::password::N2N0OS00ZGQ0LWE4MmEtMWNl}</password>
--- typ JKS
--- LUB ---
--- typ JCEKS
<password>${VAULT::Nazwa_DS::password::l}</password>
</security>
</datasource>
Jak pisałem powyżej, w zależności od wersji JBoss zmienia się format wpisu VAULT dla naszych danych wrażliwych. Implikuje to również inne problemy. Otóż, jeśli w naszym pliku test.keystore trzymamy np.: certyfikaty ssl i inne dane, to zmieniając format zapisu (zamek otwierający) nasz plik z tajnymi danymi, nie będziemy mogli się do nich dostać np.: z poziomu konektora ssl. Dla czego? Ponieważ SSL KeyStore type jest na sztywno ustawiony w kodzie na JKS (Red Hat KB). Co za tym idzie od wersji JBoss EAP 6.1.1 nie zaleca się trzymania certyfikatu ssl z szyfrowanymi hasłami lub innymi elementami, które trzeba zaszyfrować. W takim wypadku powinniśmy mieć osobny plik na dane ssl i inny na szyfrowane hasła. Ale i na to są sposoby 🙂 Jednym z nich jest tymczasowe „obejście problemu”.
Jeśli użyjemy narzędzia vault.sh z JBoss EAP 6.1.1 i wyższej, nasza skrzynia nie da się otworzyć bez dodatkowego przełącznika. Zobaczmy:
keytool -v -list -keystore test.keystore
keytool error: java.io.IOException: Invalid keystore format
java.io.IOException: Invalid keystore format
at sun.security.provider.JavaKeyStore.engineLoad(JavaKeyStore.java:650)
at sun.security.provider.JavaKeyStore$JKS.engineLoad(JavaKeyStore.java:55)
at java.security.KeyStore.load(KeyStore.java:1214)
at sun.security.tools.KeyTool.doCommands(KeyTool.java:789)
at sun.security.tools.KeyTool.run(KeyTool.java:340)
at sun.security.tools.KeyTool.main(KeyTool.java:333)
Do naszej skrzyni zmienił się zamek (JCEKS). Sprawdźmy:
file test.keystore
test.keystore: Java JCE KeyStore
W takim wypadku, jeśli już zmienił się format pliku nie pozostaje nam nic innego jak wyeksportować z niego certyfikat ssl i zaimportować do nowego pliku w formacie JKS. Jeśli jednak podnieśliśmy wersję naszego JBoss’a i nie dodawaliśmy nic do pliku vault (test.keystore), to pomimo iż nowy JBoss używa domyślnie formatu JCEKS, naszą skrzynię nadal można otworzyć dodając dodatkowy przełącznik KEYSTORE_TYPE do opcji węzła vault w pliku XML:
</extensions>
<vault>
<vault-option name="KEYSTORE_URL" value="/your/path/test.keystore"/>
...
<vault-option name="KEYSTORE_TYPE" value="jks"/>
</vault>
<management>
Jednak to rozwiązanie, jak już wspomniałem wyżej, to tylko obejście problemu, które przestanie działać, w momencie gdy do infrastruktury dodany np.: nowy DataSource i będziemy chcieli by używane przez niego hasło dostępu do bazy danych było zaszyfrowane jak pozostałe hasła w innych DataSource’ach. W tym wypadku po uruchomieniu narzędzia vault.sh nasz zamek zmieni się z wersji JKS na JCEKS.
W jaki sposób otworzyć plik test.keystore po zmianie domyślnego formatu na JCEKS? Można to zrobić dopisując dodatkową opcję storetype do narzędzia keytool:
keytool -v -list -storetype jceks -keystore test.keystore
Enter keystore password:
Keystore type: JCEKS
Keystore provider: SunJCE
Alias name: vault
Creation date: 2015-03-21
Entry type: SecretKeyEntry
*******************************************
*******************************************
...
Alias name: EAPSSL
Creation date: 2015-03-21
…
I to chyba wszystko na dziś 🙂 Nim jednak podsumujemy całość, warto przypomnieć, że plik test.keystore lub inne potrzebne dla waszych host controllerów pliki, możecie albo kopiować na każdy z hostów, albo po prostu udostępniać po NFS/Samba/etc by wszystkie hosty zawsze miały dostęp do najświeższej wersji kryptowanych danych.
Podsumowując
Warto szyfrować dane, ale warto też zwrócić uwagę na to, że kryptografia cały czas coś zmienia, ulepsza, poprawia. W związku z tym zmienia się też podejście do bezpieczeństwa danych. Narzędzie VAULT jest bardzo wygodne i proste w użyciu. Każdy administrator powinien przy jego pomocy zaszyfrować jak najwięcej krytycznych/wrażliwych danych na swojej infrastrukturze produkcyjnej. Musimy jednak pamiętać, że zmiana poziomu bezpieczeństwa w nowych JBoss EAP wpływa na konieczność utrzymywania osobnego keystora dla SSL i osobnego dla VAULT.