Unser Newsletter rund um technische Themen,
das Unternehmen und eine Karriere bei uns.

6 Minuten Lesezeit (1224 Worte)

Zutritt erlaubt? Externe Authentifizierung für Apache Cassandra in Docker

Die Nutzung von externen Authentifizierungsdiensten wie z. B. LDAP ist ein bewährtes und gängiges Verfahren in der Praxis. Dadurch kann der Login-Prozess nach außen verlagert werden und die Verwaltung der entsprechenden Nutzerdaten (z. B. Passwörter) kann damit zentralisiert und für alle Beteiligten optimiert werden.

Wie dies im Zusammenhang mit Apache Cassandra in Docker umgesetzt wird, zeigt Ihnen dieser Blogartikel.

Wie bereits in dem Blogartikel "Der Cassandra Effekt oder wie man NoSQL Datenbanken in Container kriegt" vorgestellt, ist die Umsetzung einer Apache Cassandra-Umgebung mittels Docker einfach zu realisieren. Dieser Beitrag erweitert die dort beschriebene Umgebung um einen solchen Authentifizierungsprozess. Die zugehörige docker-compose-Datei für den Aufbau der „Basisumgebung“ kann aus folgendem Fenster herauskopiert werden.

version: '2.4'
networks:
  cassandra:
services:
  knotenA:
    image: cassandra:3.11.10
    container_name: knotenA
    hostname: knotenA
    networks:
      - cassandra
    ports:
      - "9042:9042"
    volumes:
      - ./data/knotenA:/var/lib/cassandra
      - ./etc/knotenA:/etc/cassandra
      - ./cassandra-ldap-3.11.10-1.2.0/cassandra-3.11/target/cassandra-ldap-3.11.10-1.2.0.jar:/opt/cassandra/lib/cassandra-ldap-3.11.10-1.2.0.jar
      - ./cassandra-ldap-3.11.10-1.2.0/conf/ldap.properties:/etc/cassandra/ldap.properties
      - ./scripts/init.sh:/tmp/init.sh
      - ./example_data/data/database_weather.json:/home/database_weather.json
      - ./example_data/scripts/setup.cql:/home/setup.cql

    environment: &environment
      DS_LICENSE: accept
      CASSANDRA_SEEDS: "knotenA,knonteB,knotenC"
      CASSANDRA_CLUSTER_NAME: TestCluster
      CASSANDRA_DC: TestDataCenter
      CASSANDRA_RACK: TestRack
      CASSANDRA_ENDPOINT_SNITCH: GossipingPropertyFileSnitch
      CASSANDRA_NUM_TOKENS: 128
    #entrypoint: /tmp/init.sh
  knotenB:
    image: cassandra:3.11.10
    container_name: knotenB
    hostname: knotenB
    networks:
      - cassandra
    ports:
      - "9043:9042"
    volumes:
      - ./data/knotenB:/var/lib/cassandra
      - ./etc/knotenB:/etc/cassandra
      - ./cassandra-ldap-3.11.10-1.2.0/cassandra-3.11/target/cassandra-ldap-3.11.10-1.2.0.jar:/opt/cassandra/lib/cassandra-ldap-3.11.10-1.2.0.jar
      - ./cassandra-ldap-3.11.10-1.2.0/conf/ldap.properties:/etc/cassandra/ldap.properties
    environment: *environment
  knotenC:
    image: cassandra:3.11.10
    container_name: knotenC
    hostname: knotenC
    networks:
      - cassandra
    ports:
      - "9044:9042"
    volumes:
      - ./data/knotenC:/var/lib/cassandra
      - ./etc/knotenC:/etc/cassandra
      - ./cassandra-ldap-3.11.10-1.2.0/cassandra-3.11/target/cassandra-ldap-3.11.10-1.2.0.jar:/opt/cassandra/lib/cassandra-ldap-3.11.10-1.2.0.jar
      - ./cassandra-ldap-3.11.10-1.2.0/conf/ldap.properties:/etc/cassandra/ldap.properties
    environment: *environment

  openldap:
    image: osixia/openldap:1.5.0
    container_name: openldap
    environment:
      LDAP_LOG_LEVEL: "256"
      LDAP_ORGANISATION: "ORDIX AG"
      LDAP_DOMAIN: "example.org"
      LDAP_BASE_DN: "cn=admin,dc=example,dc=org"
      LDAP_ADMIN_PASSWORD: "admin"
    tty: true
    stdin_open: true
    volumes:
      - /var/lib/ldap
      - /etc/ldap/slapd.d
      - /container/service/slapd/assets/certs/
      - ./scripts/user.ldif:/home/user.ldif
    ports:
      - "389:389"
      - "636:636"
    domainname: "example.org"
    hostname: "ldap-server"
    networks: 
      - cassandra


  # phpldapadmin:
  #   image: osixia/phpldapadmin:latest
  #   container_name: phpldapadmin
  #   environment:
  #     PHPLDAPADMIN_LDAP_HOSTS: "openldap"
  #     PHPLDAPADMIN_HTTPS: "false"
  #   networks: 
  #     - cassandra 
  #   ports:
  #     - "8080:80" 

Ein paar Grundlagen 

Zuerst jedoch ein paar wichtige Informationen. Die Open Source-Variante von Cassandra unterstützt intern nicht die Möglichkeit, die LDAP-Authentifizierung zu aktivieren. Soll die Authentifizierung über LDAP genutzt werden, muss entweder die DataStax Cassandra Distribution abonniert oder - wie es in diesem Beispiel der Fall sein wird - ein externes Plugin eingebunden werden, welches eine solche Konfiguration ermöglicht. Bei dem Plugin handelt es sich um "cassandra-ldap" von Instaclustr (https://github.com/instaclustr/cassandra-ldap). Die unterschiedlichen Releases des Plugins lassen sich über "https://github.com/instaclustr/cassandra-ldap/releases" einsehen.

Sofern eine saubere Cassandra Umgebung (mind. zwei Knoten) in Docker aufgebaut und getestet wurde, wird das oben genannte Plugin benötigt (https://github.com/instaclustr/cassandra-ldap/releases/tag/v3.11.10-1.2.0).

In diesem Beispiel wird die Cassandra Version 3.11.10 und die Plugin-Version 3.11.10-1.2.0 verwendet (Hinweis: nicht jede Cassandra Version ist mit jeder Version des Plugins kompatibel).

Machen wir uns bereit für die Authentifizierung

Sobald die ZIP-Datei mit dem Source Code heruntergeladen wurde, kann der Inhalt in das Projektverzeichnis entpackt werden. Anschließend wird in das neue Verzeichnis (cassandra-ldap-3.11.10-1.2.0/) navigiert. Mit dem folgenden Kommando wird das entsprechende Projekt erzeugt:

 mvn clean install

Der Befehl erstellt für die jeweils verwendete Cassandra Version eine JAR-Datei. In diesem Beispiel ist das entsprechende Java Archive unter "cassandra-ldap-3.11.10-1.2.0/cassandra-3.11/target/ cassandra-ldap-3.11-1.2.0.jar" zu finden. Die JAR-Datei muss in den Cassandra CLASSPATH integriert werden. Hierzu wird die JAR-Datei in das lib-Verzeichnis von Cassandra gemountet. Dies muss separat für jeden Knoten in dem Cluster erfolgen:

- ./cassandra-ldap-3.11.10-1.2.0/cassandra-3.11/target/cassandra-ldap-3.11.10-1.2.0.jar:/opt/cassandra/lib/cassandra-ldap-3.11.10-1.2.0.jar  

Neben der JAR-Datei benötigen die Cassandra Knoten die Anmeldeinformationen für den LDAP-Container. Diese Informationen werden über die "ldap.properties"-Datei bereitgestellt, welche ebenfalls auf jeden Knoten gemountet werden muss: 

- ./cassandra-ldap-3.11.10-1.2.0/conf/ldap.properties:/etc/cassandra/ldap.properties  

Die "ldap.properties"-Datei definiert den Admin Service-Benutzer des LDAP-Containers und die LDAP-Server URI, über die der Cassandra-Container mit dem LDAP-Container kommunizieren kann.

Hinweis: Die interne Cassandra Authentifizierung arbeitet im Klartext-Modus (Plain Text Authorization). Benutzername und Passwort werden also bei Verbindungsversuch im Klartext übermittelt. Die Kommunikation im LDAP selbst wird nicht verschlüsselt. Es wird empfohlen, Cassandra bspw. via SSL- und LDAP über eine TLS-Verschlüsselung zu sichern.

Achtung: Sobald die Kommunikationswege verschlüsselt wurden, muss der LDAP-Server Port in der "ldap.properties"-Datei angepasst bzw. erweitert werden. Nicht verschlüsselte Kommunikationswege verwenden standardmäßig den Port 389. Verschlüsselte hingegen meist den Port 636.

Im Anschluss müssen die LDAP-Eigenschaften in Cassandra hinterlegt werden. Somit muss die cassandra-env.sh um einen weiteren Eintrag erweitert werden:

JVM_OPTS="$JVM_OPTS -Dcassandra.ldap.properties.file 

=/etc/cassandra/ldap.properties"  

Instaclustr weist darauf hin, dass die Verwendung der NetworkTopologyStrategy für den system_auth Keyspace dringend empfohlen wird. Es muss sichergestellt werden, dass die Anzahl der Replica der Anzahl der Knoten im Datacenter entspricht. Sollte dies nicht der Fall sein, so kann der Keyspace folgendermaßen angepasst werden: 

ALTER KEYSPACE system_auth WITH replication = {'class': 'NetworkTopologyStrategy', 'dc1': '3'}  AND durable_writes = true;  

Anschließend muss der system_auth Keyspace repariert werden, damit die Information an die Knoten weitergegeben werden.

 Die Anpassungen müssen in unserem Beispiel nicht erfolgen. Die Konfiguration des system_auth Keyspace sieht hier wie folgt aus:

SELECT * FROM system_schema.keyspaces; 

 

 keyspace_name      | durable_writes | replication 

--------------------+----------------+------------------------------------------------------------------------------------- 

        system_auth |           True | {'class': 'org.apache.cassandra.locator.SimpleStrategy', 'replication_factor': '1'}  

Cassandra-seitig muss noch eine abschließende Anpassung vorgenommen werden. Dafür wird die "cassandra.yaml"-Datei auf jedem Knoten editiert: 

authenticator: LDAPAuthenticator 

authorizer: CassandraAuthorizer 

role_manager: LDAPCassandraRoleManager  

Sind wir jetzt authentifiziert? 

Nach dem Neustart der Container kann in den Logfiles die Verwendungen überprüft werden. 

LDAPAuthenticator.java:122 - org.apache.cassandra.auth.LDAPAuthenticator was initialised  

Der Login über LDAP ist jedoch noch nicht möglich. Im Gegenteil: Man kann sich weiterhin mit dem Cassandra internen Adminbenutzer anmelden

Die LDAP-Authentifizierung überprüft im ersten Schritt, ob der Benutzer, mit welchem sich angemeldet werden soll, im LDAP definiert wurde. Sollte dies nicht der Fall sein, greift der LDAP-Dienst auf die interne Cassandra Authentifizierung zurück und versucht dort den entsprechenden Benutzer ausfindig zu machen.

Um verlässlich das LDAP-Login verwenden zu können, muss ein Benutzer hinterlegt werden. Dies erfolgt über eine sogenannte .ldif-Datei.

In unserem Beispiel ist die user.ldif wie folgt aufgebaut:

dn: uid=test1,dc=example,dc=org 

objectClass: organizationalPerson 

objectClass: inetOrgPerson 

cn: test1 

uid: test1 

givenName: test1 

sn: test1 

userPassword: test  

Die user.ldif muss in den LDAP-Container gemountet werden (siehe docker-compose.yaml). Nachdem die Container ein weiteres Mal neu gestartet wurden, wird über die Kommandozeile des LDAP-Containers folgender Befehl abgesetzt: 

#Aufruf, um über die Shell zur Kommandozeile des LDAP-Containers zu gelangen 

docker exec -it openldap /bin/bash 

 

#Hinzufügen des in der user.ldif definierten Benutzers 

ldapadd -c -x -w admin -D "cn=admin,dc=example,dc=org" -f /home/user.ldif 

 

 

#gewünschte Rückmeldung 

adding new entry "uid=test1,dc=example,dc=org"  

Nach dem erfolgreichen Hinzufügen des LDAP-Benutzers kann anschließend der Login in Cassandra getestet werden: 

#Aufruf, um über die Shell zur Kommandozeile des Cassandra-Containers zu gelangen 

docker exec -it knotenA /bin/bash 

 

#Test, ob Authentifizierung erfolgreich eingebunden wurde 

cqlsh -u test1 -p test1 

 

#Ausgabe 

Connected to TestCluster 

[cqlsh 5.0.1 | Cassandra 3.11.10 | CQL spec 3.4.4 | Native protocol v4] 

Use HELP for help. 

test3@cqlsh>  

Fazit: Login-Success 

Wie auch in Teil 1 werden die vielen positiven Effekte einer Container-Architektur deutlich. Das openldap Plugin von Instaclustr ermöglicht eine kostenfreie Anbindung eines LDAP-Services. Auch die stetige Weiterentwicklung des Plugins ist ein positives Merkmal, welches für die Verwendung spricht.

Sollten Sie Fragen rund um das Thema Docker oder Apache Cassandra haben, wenden Sie sich gerne an uns oder schauen Sie sich unser Kursangebot an.

Seminarempfehlungen

 

Kommentare

Derzeit gibt es keine Kommentare. Schreibe den ersten Kommentar!
Donnerstag, 26. Dezember 2024

Sicherheitscode (Captcha)

×
Informiert bleiben!

Bei Updates im Blog, informieren wir per E-Mail.