W podstawowej konfiguracji komunikacja pomiędzy serwerem RHQ oraz agentami monitorującymi poszczególne systemy nie jest ani szyfrowana ani nie ma zaimplementowanych mechanizmów uwierzytelnienia. Może to prowadzić do wielu problemów związanych z bezpieczeństwem systemów:
- jest możliwe dodanie do infrastruktury monitorującego nowego agenta i jego rejestracja w serwerze RHQ
- jest możliwe podsłuchanie ruchu pomiędzy serwerem a agentami (i tym samym poznanie konfiguracji maszyn, być może różnych dodatkowych wrażliwych informacji)
- istnieje możliwość przechwycenie komunikacji pomiędzy serwerem RHQ a agentem monitorującym oraz takie jej zmodyfikowanie, aby uzyskać wpływ na działanie agenta (a trzeba pamiętać, że agent często pracuje na uprawnieniach użytkownika
root
)
Oczywiście, takie potencjalne problemy mogą prowadzić tylko do jednego wniosku: taką konfigurację można używać tylko w ramach takiej infrastruktury, która jest kontrolowana w 100% i nikt nie powołany nie może z niej korzystać (czyli jak dla mnie to nigdy :D).
W przypadku serwera RHQ problem zabezpieczenia komunikacji oraz uwierzytelniania pomiędzy nim a agentami jest rozwiązana przy użyciu szyfrowania SSL oraz konfiguracji odpowiednich certyfikatów.
W sytuacji, gdy chcemy skonfigurować tylko szyfrowane połączenie (bez uwierzytelniania agentów) wystarczy tylko włączyć używanie protokołu SSL. Odpowiedni certyfikat powinien być już wygenerowany i domyślnie będzie znajdował się w pliku rhq-server/jbossas/server/default/conf/rhq.keystore
.
Ja postaram się przedstawić bardziej zaawansowaną konfigurację, gdzie każdy agent także uwierzytelnia się na podstawie odpowiedniego certyfikatu.
Krok 1: Utworzenie certyfikatów SSL
Aby zarówno serwer RHQ jak agent monitorujący potrafiły zidentyfikować się wzajemnie należy zdefiniować odpowiednie certyfikaty SSL, które pozwolą na ich identyfikację. Zarówno serwer RHQ jak i każdy agent musi posiadać swój własny certyfikat. Można tutaj wykorzystać zarówno istniejące certyfikaty (podpisane np. przez jakieś CA), lub też wygenerować własne korzystając z narzędzia keytool
.
Poniższe kroki należy wykonać osobno dla serwera RHQ jak i dla każdego agenta monitorującego, modyfikując odpowiednio parametry:
- Utworzenie pliku z certyfikatem oraz kluczami publicznym i prywatnym (należy pamiętać, że operację tę należy wykonać zarówno dla serwera jak i dla każdego agenta monitorującego):
keytool -genkey -dname "CN=nazwa_hosta.example.com" -keystore nazwa_hosta-keystore.dat\
-validity 3650 -alias nazwa_hosta -keyalg DSA -storetype JKS\
-keypass haslo_do_klucza_prywatnego -storepass haslo_do_pliku_z_certyfikatemPolecenie to utworzy plik o nazwie
nazwa_hosta-keystore.dat
, w którym zostanie zapisany certyfikat z podaną nazwą maszyny (ważne, należy użyć odpowiedniej nazwy, przypisanej do danej maszyny na której działa agent lub serwer). Certyfikat będzie dostępu przy użyciu nazwy zdefiniowanej przy użyciu parametrualias
, czyli w tym przypadku będzie tonazwa_hosta
. Klucz prywatny zostanie zabezpieczony hasłem podanym przy użyciu parametrukeypass
a cały plik hasłem podanym przy użyciu parametrustorepass
. Certyfikat będzie miał ważność 10 lat (wartośćvalidity
). Podane wartości należy zapamiętać, będą one potrzebne dalej. - Zapisanie utworzonego certyfikatu w osobnym pliku (co umożliwi potem jego import to pliku ze wszystkimi certyfikatami):
keytool -export -keystore nazwa_host-keystore.dat -alias nazwa_hosta\
-storetype JKS -storepass haslo_do_pliku_z_certyfikatem -file nazwa_hosta-cert - Dodanie certyfikatu do wspólnego pliku z certyfikatami
truststore.dat
:keytool -import -keystore truststore.dat -alias nazwa_hosta\
-storetype JKS -filenazwa_hosta-cert -noprompt\
-keypass haslo_do_klucza_prywatnego -storepass haslo_do_pliku_z_certyfikatemDzięki tej operacji dodamy każdy certyfikat do jednego pliku, dzięki czemu będziemy mogli ich używać w celu uwierzytelnienia agentów.
- Można w każdej chwili sprawdzić, czy i jakie certyfikaty znajdują się w pliku
truststore.dat
:keytool -list -keystore truststore.dat -storepass haslo_do_pliku_z_certyfikatem\
-storetype JKS
Po wykonaniu powyższych operacji dla każdego agenta monitorującego i serwera RHQ będziemy dysponowali zarówno zdefiniowanymi dla każdego z nich kluczami prywatnymi jak i plikiem z certyfikatami, dzięki czemu będzie możliwe sprawdzenie ich tożsamości.
Aby ułatwić sobie kolejne kroki, stworzyłem prosty skrypt, które dokładnie wykona wszystkie powyższe kroki dla każdej maszyny. Skrypt należy zapisać w pliku o nazwie create_cert.sh
a następnie wywoływać z dwoma parametrami: aliasem klucza oraz pełną nazwą maszyny, czyli np. tak:
Skrypt tworzący klucze create_cert.sh
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | #!/bin/bash ALIAS=$1 HOSTNAME=$2 KEYPASS="haslo" STOREPASS="haslo" KEYSTORE="${ALIAS}-keystore.dat" CERTSTORE="${ALIAS}-cert" TRUSTSTORE="truststore.dat" echo -n "Create SSL Cert for $ALIAS... " keytool -genkey -dname "CN=$HOSTNAME" -keystore ${KEYSTORE}\ -validity 3650 -alias $ALIAS -keyalg DSA -storetype JKS\ -keypass ${KEYPASS} -storepass ${STOREPASS} echo "done" echo "Export certficate" keytool -export -keystore ${KEYSTORE} -alias ${ALIAS}\ -storetype JKS -storepass super_haslo -file ${CERTSTORE} echo -n "Import certificate to ${TRUSTSTORE}... " keytool -import -keystore ${TRUSTSTORE} -alias ${ALIAS}\ -storetype JKS -file ${CERTSTORE} -noprompt\ -keypass ${KEYPASS} -storepass ${STOREPASS} echo "done" echo "Certificate list" keytool -list -keystore ${TRUSTSTORE} -storepass ${STOREPASS}\ -storetype JKS |
Oczywiście, należy zdefiniować w skrypcie odpowiednie hasło.
Krok 2: Dystrybucja kluczy
Odpowiednie pliki z kluczami są już utworzone, należy je teraz skopiować na odpowiednie maszyny. Należy skopiować zarówno plik ze wszystkimi certyfikatami oraz specyficzny dla każdego agenta plik z kluczem prywatnym. Należy zwrócić szczególną uwagę na to, aby odpowiednie pliku umieścić na odpowiednich maszynach.
- Instalacja certyfikatu na serwerze RHQ
Najprościej będzie umieścić plik z certyfikatem serwera (o nazwienazwa_hosta-keystore.dat
) oraztruststore.dat
w katalogu konfiguracyjnym serwera JBoss, w ramach którego pracuje RHQ. Czyli kopiujemy te pliki do katalogurhq-server/jbossas/server/default/conf
. Oczywiście można je umieścić w dowolnym innym miejscu, należy tylko pamiętać aby serwer RHQ miał możliwość ich odczytania.Należy jeszcze tak zmienić parametry dostępu do tych plików, aby tylko właściciel procesu RHQ miał możliwość ich odczytu.
- Instalacje certyfikatu w agencie monitorującym
Plik z kluczem prywatnym (nazwa_hosta-keystore.dat
) oraztruststore.dat
należy także umieścić w kataloguconf
danego agenta, czyli w katalogurhq-agent/conf
. Dzięki temu, plik ten nie zostanie usunięty podczas procesu automatycznej aktualizacji agenta. Jeszcze raz powtórzę: należy skopiować odpowiedni pliknazwa_hosta-keystore.dat
do odpowiedniego agenta.
Krok 3: Konfiguracja serwera RHQ
Teraz czas na odpowiednią konfigurację serwera RHQ, czyli włączenie szyfrowania i uwierzytelnienia. Najlepiej jest wyłączeń serwer przed przystąpieniem do realizacji kolejnych kroków.
Zaczynamy od edycji pliku konfiguracyjnego serwera rhq-server/bin/rhq-server.properties
:
- włączenie korzystania z SSL poprzez zdefiniowania transportu jako
sslservlet
:64
65
66
67rhq.communications.connector.transport=sslservlet
rhq.communications.connector.bind-address=
rhq.communications.connector.bind-port=
rhq.communications.connector.transport-params=/jboss-remoting-servlet-invoker/ServerInvokerServlet - konfiguracja magazynów z kluczami dla połączeń przychodzących:
75
76
77
78
79
80
81
82
83
84
85
86
87# Server-side SSL Security Configuration for HTTPS thru Tomcat
# These are used for browser https: access and for incoming messages from agents over sslservlet transport
# [you cannot use ${x} variables - see https://jira.jboss.org/jira/browse/JBWEB-74]
rhq.server.tomcat.security.client-auth-mode=true
rhq.server.tomcat.security.secure-socket-protocol=TLS
rhq.server.tomcat.security.algorithm=SunX509
rhq.server.tomcat.security.keystore.alias=alias_klucza_dla_serwera
rhq.server.tomcat.security.keystore.file=conf/nazwa_hosta_keystore.dat
rhq.server.tomcat.security.keystore.password=haslo
rhq.server.tomcat.security.keystore.type=JKS
rhq.server.tomcat.security.truststore.file=conf/truststore.dat
rhq.server.tomcat.security.truststore.password=haslo
rhq.server.tomcat.security.truststore.type=JKSPowyższa konfiguracja umożliwia odszyfrowanie wiadomości przychodzących od agentów. Jednocześnie pozwoli także na uwierzytelnienie tych agentów, ponieważ będzie można odczytać tylko te wiadomości od tych agentów, których klucze publiczne znajdują się w pliku
truststore.dat
. Jednocześnie będzie można określić, jaki agent dana informację wysłał. - konfiguracja magazynów z kluczami dla połączeń wychodzących:
104
105
106
107
108
109
110
111
112
113
114
115
116# Client-side SSL Security Configuration (for outgoing messages to agents)
rhq.server.client.security.secure-socket-protocol=TLS
rhq.server.client.security.keystore.file=${jboss.server.home.dir}/conf/nazwa_hosta-keystore.dat
rhq.server.client.security.keystore.algorithm=SunX509
rhq.server.client.security.keystore.type=JKS
rhq.server.client.security.keystore.password=haslo
rhq.server.client.security.keystore.key-password=haslo
rhq.server.client.security.keystore.alias=nazwa_hosta
rhq.server.client.security.truststore.file=${jboss.server.home.dir}/conf/truststore.dat
rhq.server.client.security.truststore.algorithm=SunX509
rhq.server.client.security.truststore.type=JKS
rhq.server.client.security.truststore.password=haslo
rhq.server.client.security.server-auth-mode-enabled=trueDzięki tej konfiguracji będzie można komunikować się z agentami tak, aby byli oni pewni że nadawcą jest serwer RHQ.
Krok 4: Konfiguracja agenta monitorującego
Ostatnim elementem będzie konfiguracja agenta monitorującego. Istnieją trzy sposoby na jakie można skonfigurować agenta:
- Uruchomić konfigurowanie agenta w trybie zaawansowanym, można to zrobić uruchamiając go z następującymi parametrami
--cleanconfig --setup --advanced
. - Uruchomić agenta w trybie
console
a następnie wydać poleceniesetup advanced
. - Bezpośrednio zmodyfikować plik konfiguracyjny
conf/agent-configuration.xml
i następnie uruchomić agenta z przełącznikiemcleanconfig
.
Sposoby pierwszy i drugi wymagają odpowiedzi na szereg pytań, ja przedstawię co należy zmodyfikować w pliku konfiguracyjnym.
- konfiguracja połączenia z serwerem:
120
121
122
123<entry key="rhq.agent.server.transport" value="sslservlet" />
<entry key="rhq.agent.server.bind-port" value="7443" />
<entry key="rhq.agent.server.bind-address" value="rhq-server.example.com" />
<entry key="rhq.agent.server.transport-params" value="/jboss-remoting-servlet-invoker/ServerInvokerServlet" /> - konfiguracja łączności agenta monitorującego
885
886
887<entry key="rhq.communications.connector.rhqtype" value="agent" />
<entry key="rhq.communications.connector.transport" value="sslsocket" />
<entry key="rhq.communications.connector.bind-port" value="16163" /> - konfiguracja łączności z serwerem – włączenie korzystania z uwierzytelnienia (parametr
client-auth-mode
) oraz definicja dostępu do certyfikatów:931
932
933
934
935
936
937
938
939
940
941
942<entry key="rhq.communications.connector.security.secure-socket-protocol" value="TLS" />
<entry key="rhq.communications.connector.security.keystore.file" value="conf/nazwa_hosta-keystore.dat" />
<entry key="rhq.communications.connector.security.keystore.algorithm" value="SunX509" />
<entry key="rhq.communications.connector.security.keystore.type" value="JKS" />
<entry key="rhq.communications.connector.security.keystore.password" value="haslo" />
<entry key="rhq.communications.connector.security.keystore.key-password" value="haslo" />
<entry key="rhq.communications.connector.security.keystore.alias" value="nazwa_hasla" />
<entry key="rhq.communications.connector.security.truststore.file" value="conf/truststore.dat" />
<entry key="rhq.communications.connector.security.truststore.algorithm" value="SunX509" />
<entry key="rhq.communications.connector.security.truststore.type" value="JKS" />
<entry key="rhq.communications.connector.security.truststore.password" value="haslo" />
<entry key="rhq.communications.connector.security.client-auth-mode" value="need" /> - konfiguracja łączności z klientem – włączenie korzystania z uwierzytelnienia (parametr
server-auth-mode-enabled
) oraz konfiguracja dostępu do plików z certyfikatami:944
945
946
947
948
949
950
951
952
953
954
955<entry key="rhq.agent.client.security.secure-socket-protocol" value="TLS" />
<entry key="rhq.agent.client.security.keystore.file" value="conf/nazwa_hosta-keystore.dat" />
<entry key="rhq.agent.client.security.keystore.algorithm" value="SunX509" />
<entry key="rhq.agent.client.security.keystore.type" value="JKS" />
<entry key="rhq.agent.client.security.keystore.password" value="haslo" />
<entry key="rhq.agent.client.security.keystore.key-password" value="haslo" />
<entry key="rhq.agent.client.security.keystore.alias" value="nazwa_hosta" />
<entry key="rhq.agent.client.security.truststore.file" value="conf/truststore.dat" />
<entry key="rhq.agent.client.security.truststore.algorithm" value="SunX509" />
<entry key="rhq.agent.client.security.truststore.type" value="JKS" />
<entry key="rhq.agent.client.security.truststore.password" value="haslo" />
<entry key="rhq.agent.client.security.server-auth-mode-enabled" value="true" />
Oczywiście, należy te wpisy dostosować do własnych potrzeb (w szczególności dotyczy to zdefiniowania odpowiednich haseł). Po wprowadzeniu modyfikacji, należy zatrzymać agenta i uruchomić go przy użyciu następującej komendy:
Spowoduje ona uruchomienie agenta oraz uruchomienie jego procesu konfiguracji. Należy odpowiedzieć na pierwsze pytania, poczekać aż agent połączy się z serwerem i jeżeli nie wystąpiły żadne błędy to wszystko powinno działać OK.
Jeżeli wystąpiły błędy, to trzeba je zanalizować i próbować zmienić wpisy w pliku konfiguracyjnym. Jeżeli pierwsze uruchomienie powiodło się, można już uruchomić agenta przy użyciu skryptu uruchomieniowego.
Pozostaje teraz skonfigurowanie pozostałych agentów i możemy się cieszyć szyfrowaną transmisją między serwerem RHQ a agentami.