summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernd Kalbfuss <langweiler@rueblitorte.de>2021-04-11 22:39:05 +0200
committerBernd Kalbfuss <langweiler@rueblitorte.de>2021-04-11 22:39:05 +0200
commit3d7c0d1e969d4fb1e46d67d4ec8a0f5046e3766b (patch)
tree47e8add637795ea755f1a46c29c57fbe15e9700d
parent6473ecb3691c177d155b8c33bc97e842eaa9df33 (diff)
Re-added cloud server documentation.
-rw-r--r--Infrastruktur/Cloud-Server.mdwn681
1 files changed, 681 insertions, 0 deletions
diff --git a/Infrastruktur/Cloud-Server.mdwn b/Infrastruktur/Cloud-Server.mdwn
new file mode 100644
index 00000000..b542776c
--- /dev/null
+++ b/Infrastruktur/Cloud-Server.mdwn
@@ -0,0 +1,681 @@
+[[!meta title="Cloud-Server der Starship Factory"]]
+
+[[!toc startlevel=2]]
+
+# Cloud-Server
+
+Der Cloud-Server dient zum Austausch von Dateien und Informationen zwischen den Mitgliedern der Starship Factory. Er dient primär zur Bereitstellung einer NextCloud-Instanz für diese Zweck. Neben dieser ist zusätzlich ein LDAP-Server zur Benutzerverwaltung und Authentifizierung installiert.
+
+Der Cloud-Server wurde von Bernd Kalbfuss (aka Langweiler) eingerichtet. Er wird aktuell von den folgenden Personen administriert:
+
+| Name | Spitzname/Benutzername | E-Mail |
+| --------------- | ---------------------- | ------------------------- |
+| Bernd Kalbfuss | langweiler | langweiler@rueblitorte.de |
+| Fabian Thoma | fabianthoma | f@bianthoma.me |
+| Cedric Spindler | zedcat | cedric.spindler@gmail.com |
+
+## Hardware
+
+Der Cloud-Server läuft auf einem HP ProLiant ML110-Server der vermutlich 5. Generation. Er besitzt eine CPU mit zwei Kernen. Die Leistungsdaten der CPU sind wie folgt:
+
+| Merkmal | Wert |
+| ------------- | ---- |
+| Product | Intel(R) Xeon(R) CPU 3065@2.33GHz |
+| Vendor | Intel Corp. |
+| Physical ID | 4 |
+| Bus info | cpu@0 |
+| Version | C1 |
+| Slot | CPU 1 |
+| Size | 2012MHz |
+| Capacity | 3300MHz |
+| Width | 64 bits |
+| Clock | 1333MHz |
+| Capabilities | lm fpu fpu_exception wp vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ht tm pbe syscall nx x86-64 constant_tsc arch_perfmon pebs bts rep_good nopl cpuid aperfmperf pni dtes64 monitor ds_cpl smx est tm2 ssse3 cx16 xtpr pdcm lahf_lm pti dtherm cpufreq |
+| Configuration | cores=2 enabledcores=2 threads=2 |
+
+Der Server ist insgesamt 6 GB (2 x 2GB, 2 x 1 GB) RAM bestückt. Es handelt sich um SDR2 ECC RAM mit 800 MHz Taktfrequenz.
+
+Der Server ist mit den folgenden Laufwerken (Festplatten mit Magnetspeicher) ausgestattet:
+
+| # | Description | Product | Vendor | Physical ID | Bus info | Logical name | Version | Serial | Size |
+| - | ----------- | ---------------- | --------------- | ------------ | ------------ | -------------| ------- | --------------- | -------------- |
+| 0 | ATA Disk | GB0160CAABV | | 0 | scsi@0:0.0.0 | /dev/sda | HPG1 | 5RX79N7K | 149GiB (160GB) |
+| 1 | ATA Disk | WDC WD10EARS-00Y | Western Digital | 1 | scsi@0:0.1.0 | /dev/sdb | 0A80 | WD-WCAV58006740 | 931GiB (1TB) |
+| 2 | ATA Disk | GB0160CAABV | | 2 | scsi@1:0.0.0 | /dev/sdc | HPG1 | 5RX795WB | 149GiB (160GB) |
+| 3 | ATA Disk | WDC WD10EARS-00Y | Western Digital | 3 | scsi@1:0.1.0 | /dev/sdd | 0A80 | WD-WCAV58065900 | 931GiB (1TB) |
+
+## Netzeinbindung
+
+Der Server ist über eine Gigabit-Ethernetschnittstelle mit dem lokalen Netz der Starship Factory verbunden. Der primäre Hostname ist ***cloud.lab.starship-factory.ch***. Es sind die folgenden DNS-Einträge gesetzt:
+
+
+| Netzwerk | Hostnamen | IPv4 | Bemerkung |
+| -------- | ------------------------------------------------------------ | ------------- | ---------------------------- |
+| LAN | cloud.lab.starship-factory.ch<br />ldab.lab.starship-factory.chsind | 100.64.1.200 | Interne Adresses des Servers |
+| WAN | cloud.lab.starship-factory.ch<br />ldap.lap.starship-factory.ch | 5.226.148.123 | Externe Adresse des Routers |
+
+Auf dem WAN-Router sind für IPv4 die folgenden Port-Weiterleitungen eingerichtet:
+
+| Dienst | Port WAN-Router | Port Cloud-Server |
+| ------ | --------------- | ----------------- |
+| http | 80 | 80 |
+| https | 443 | 443 |
+| ssh | 49160 | 22 |
+
+## Grundkonfiguration
+
+Als Betriebssystem kommt *GNU/Linux* zum Einsatz. Als Distribution wird [OpenMediaVault](https://www.openmediavault.org/), welches auf *Debian* basiert, verwendet.
+
+Soweit nicht anders angegeben, wurden zusätzliche Pakete/Software stets aus dem offiziellen Debian-Repository mittels *apt* installiert. Aktuell sind die folgenden Komponenten zusätzlich installiert:
+
+* System Security Services Daemon
+* Uncomplicated Firewall
+* Fail2Ban
+* Let's encrypt Certbot
+* Docker
+
+### Volumen und Partitionierung
+
+Die Laufwerke sind wie folgt partitioniert und in das Dateisystem eingebunden:
+
+| # | Logical name | Partition | Mountpoint | Bemerkungen |
+| - | ------------ | --------- | ------------------------------------ | ------------ |
+| 0 | sda | sda1 | /boot | |
+| | | sda2 | | |
+| | | md0 | | RAID0 device |
+| | | md0p1 | [SWAP] | |
+| | | md0p2 | / | |
+| 1 | sdb | md1 | /srv/dev-disk-by-id-md-name-debian-1 | RAID0 device |
+| 2 | sdc | sdc1 | /boot | Not used |
+| | | sdc2 | | |
+| | | md0 | | RAID0 device |
+| | | md0p1 | [SWAP] | |
+| | | md0p2 | / | |
+| 3 | sdd | md1 | /srv/dev-disk-by-id-md-name-debian-1 | RAID0 device |
+
+Die RAID-Speicher sind als Soft-Raids mittels *md* konfiguriert. Der Bootloader *Grub* ist im MBR des Laufwerks *sda* installiert. Er ist so konfiguriert, dass er aus der Partition *sda1* bootet.
+
+Das Verzeichnis */var/lib/docker/volumes* wurde mittels eines symbolischen Links vom Wurzeldateisystem auf *md0p2* in das Verzeichnis */srv/dev-disk-by-id-md-name-debian-1/docker/volumes* auf der grösseren Datenpartition *md1* verlagert.
+
+### Openmediavault
+
+Die Web-Konfigurationsoberfläche von *OpenMediaVault* ist über die folgenden Adressen zu erreichen:
+
+| Protokoll | URL |
+| --------- | --------------------- |
+| http | http://<host\>:5000/ |
+| https | https://<host\>:5001/ |
+
+Die Anfrage via *http* wird automatisch auf *https* umgeleitet. Bisher wurde nur ein selbstgezeichnetes Zertifikat hinterlegt, so dass beim ersten Zugriff eine Ausnahmeregel eingerichtet werden muss.
+
+Die Anmeldung erfolgt mittels des Benutzers *admin* oder eines anderen zuvor angelegten Benutzerkontos. Die System-Administratoren wurden der Unix-Gruppe *openmediavault-admin* hinzugefügt, um ihnen administrative Rechte innerhalb der Konfigurationsoberfläche zu gewähren.
+
+Die Konfiguration von OMV wurde mittels der folgenden Einträge in der Systemkonfigurationsdatei angepasst:
+
+**/etc/default/openmediavault**
+
+ ...
+ OMV_NFSD_MOUNTDOPTS="-p 32767"
+
+Der Eintrag für *OMV_NFSD_MOUNTDOPTS* zwingt den *NFS-mountd* auf einen festen Port, so dass eine statische Firewall-Regel angelegt werden kann. Informationen zur erweiterten Konfiguration können dem [OMV-Handbuch](https://openmediavault.readthedocs.io/en/5.x/various/advset.html) entnommen werden.
+
+Die restliche Konfiguration wurde mittels der Konfigurations-Oberfläche vorgenommen und ist im Folgenden nicht weiter dokumentiert.
+
+### Sicherheit
+
+Das Authentifizierungssystem ist um den *System Security Services Demon (sssd)* erweitert, um die Authentifizierung gegen *LDAP* zu ermöglichen. Die LDAP-Benutzer werden lokal zwischengespeichert, so dass die Autentifizierung auch im Fall eines Ausfalls des LDAP-Servers weiterhin möglich ist.
+
+**/etc/sssd/sssd.conf**
+
+ [sssd]
+ config_file_version = 2
+ services = nss, pam
+ domains = starship-factory.ch
+ #debug = 7
+
+ [nss]
+ filter_groups = root
+ filter_users = root
+ #debug = 7
+
+ [pam]
+
+ [domain/starship-factory.ch]
+ # SSSD can resolve user information from a number of different sources
+ # such as LDAP, local files, and Active Directory. This option sets
+ # the domain's source of identity information.
+ id_provider = ldap
+
+ # As with identity providers, SSSD can authenticate in a variety of ways.
+ # By default, SSSD will use the value of id_provider.
+ #auth_provider = ldap
+
+ # The access provider controls the source for determining who is allowed
+ # to access the system. Even if a user successfully authenticates, if they
+ # don't meet the criteria provider by the access provider, they will be
+ # denied access.
+ access_provider = ldap
+
+ # The verbosity of this domains log file.
+ #debug = 7
+
+ # Enumeration is discouraged for performance reasons.
+ enumerate = true
+
+ # The URI(s) of the directory server(s) used by this domain.
+ ldap_uri = ldaps://ldap.lab.starship-factory.ch
+
+ # The LDAP search base you want SSSD to use when looking
+ # for entries. There are options for search bases for various types
+ # of searches, such as users. Read the sssd-ldap man page for details.
+ ldap_search_base = dc=starship-factory,dc=ch
+
+ # The DN used to search your directory with. It must have read access to
+ # everything your system needs.
+ ldap_default_bind_dn = cn=omv-ldap-user,ou=system-users,dc=starship-factory,dc=ch
+
+ # The password of the bind DN.
+ ldap_default_authtok = <Passwort>
+
+ # This enables or disables credential caching. I.e. after successfully
+ # authenticating a user, the credentials will be stored locally. If the
+ # domain is unavailable, users will still be able to login using the
+ # cached information.
+ cache_credentials = true
+
+ # By default, the credential cache never expires. If you want sssd to
+ # remove cached credentials, this option will cause them to expire
+ # after the number of days it is set to.
+ #account_cache_expiration = 0
+
+ # These define the criteria the access provider uses to control who
+ # is allowed to login. In this case, any user that matches the
+ # LDAP filter in this example will be allowed access. Any entry
+ # that has an objectClass of posixAccount will be allowed access.
+ ldap_access_order = filter
+ ldap_access_filter = (objectClass=posixAccount)
+
+ # The file containing CA certificates you want sssd to trust.
+ ldap_tls_cacert = /etc/ssl/certs/ca-certificates.crt
+
+ # The TLS ciphers you wish to use. SSSD uses OpenSSL style cipher
+ # suites
+ #ldap_tls_cipher_suite = HIGH
+
+ # This defines how sssd will handle server certificates. Demand means
+ # that we are requiring the host portion of the URI to match the
+ # certificate's subject or an SAN, the current time is within the valid
+ # times on the certificate, and that it's signing chain ends with a CA
+ # in the file defined by ldap_tls_cacert.
+ ldap_tls_reqcert = demand
+
+ # Use this if users are being logged in at /.
+ # This example specifies /home/DOMAIN-FQDN/user as $HOME. Use with pam_mkhomedir.so
+ override_homedir = /home/%u
+
+ # Always use bash shell. This is required since Synology diskstation
+ # returns "sh" as the default setting and the shell cannot be modified
+ # in the web interface.
+ override_shell = /bin/bash
+
+Um die Sicherheit zu erhöhen, ist die *Uncomplicated Firewall (ufw)* installiert und aktiviert. Die *default policy* ist *deny*. Die folgenden Ports bzw. Anwendungen sind für den externen Zugriff freigegeben:
+
+```3
+To Action From
+-- ------ ----
+Samba ALLOW Anywhere
+21/tcp ALLOW Anywhere
+5001 ALLOW Anywhere
+5000 ALLOW Anywhere
+32767 ALLOW Anywhere
+NFS ALLOW Anywhere
+SSH ALLOW Anywhere
+WWW ALLOW Anywhere
+WWW Secure ALLOW Anywhere
+LDAP ALLOW Anywhere
+LDAPS ALLOW Anywhere
+Samba (v6) ALLOW Anywhere (v6)
+21/tcp (v6) ALLOW Anywhere (v6)
+5001 (v6) ALLOW Anywhere (v6)
+5000 (v6) ALLOW Anywhere (v6)
+32767 (v6) ALLOW Anywhere (v6)
+NFS (v6) ALLOW Anywhere (v6)
+SSH (v6) ALLOW Anywhere (v6)
+WWW (v6) ALLOW Anywhere (v6)
+WWW Secure (v6) ALLOW Anywhere (v6)
+LDAP (v6) ALLOW Anywhere (v6)
+LDAPS (v6) ALLOW Anywhere (v6)
+```
+
+Der Port 21 ist für den FTP-Dienst geöffnet, die Ports 5000 und 5001 für die OMV-Konfigurationsoberfläche (*http* und *https*). Der Port 32767 wird für die Verbindung zum NFS-mountd benötigt.
+
+Weiterhin ist das Paket *fail2ban* installiert, um *"Brute force"*-Angriffen vorzubeugen. Die Möglichkeit der Anmeldung von *root* mittels *SSH* wurde deaktiviert.
+
+### Reverse Proxy
+
+Auf dem Cloud-Server ist ein *Nginx*-Web-Server installiert und als inverser Proxy konfiguriert. Über diesen werden externe *http*-Anfragen an die Docker-Container weitergeleitet und gegebenenfalls verschlüsselt (*https*). Konkret ermöglicht der Reverse Proxy den Zugriff auf die *NextCloud*-Instanz sowie die Konfigurationsoberflächen für den *LDAP*-Server.
+
+Die Konfiguration ist in der Datei */etc/nginx/sites-available/nextcloud-reverse-proxy* hinterlegt. Die Konfiguration ist durch Verlinkung in das Verzeichnis */etc/nginx/sites-enabled* aktiviert.
+
+**/etc/nginx/sites-available/nextcloud-reverse-proxy**
+
+ server {
+ listen 80;
+ server_name cloud.lab.starship-factory.ch ldap.lab.starship-factory.ch;
+
+ if ($host = ldap.lab.starship-factory.ch) {
+ return 301 https://$host$request_uri;
+ } # managed by Certbot
+
+ if ($host = cloud.lab.starship-factory.ch) {
+ return 301 https://$host$request_uri;
+ } # managed by Certbot
+
+ return 404; # managed by Certbot
+ }
+
+ server {
+ listen 443 ssl;
+ server_name cloud.lab.starship-factory.ch;
+ # Apply letsencrypt nginx ssl configuration
+ include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
+
+ # If you use Lets Encrypt, you should just need to change the domain.
+ # Otherwise, change this to the path to full path to your domains public certificate file.
+ ssl_certificate /etc/letsencrypt/live/cloud.lab.starship-factory.ch/fullchain.pem; # managed by Certbot
+ ssl_certificate_key /etc/letsencrypt/live/cloud.lab.starship-factory.ch/privkey.pem; # managed by Certbot
+ ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
+
+ # Log Location. the Nginx User must have R/W permissions. Usually by ownership.
+ access_log /var/log/nginx/access.log;
+
+ # Allow up to 512M upload size
+ client_max_body_size 512M;
+
+ location / {
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_pass http://cloud.lab.starship-factory.ch:8080;
+ proxy_read_timeout 30;
+ }
+ }
+
+ server {
+ listen 443 ssl;
+ server_name ldap.lab.starship-factory.ch;
+
+ # Apply letsencrypt nginx ssl configuration
+ include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
+
+ # If you use Lets Encrypt, you should just need to change the domain.
+ # Otherwise, change this to the path to full path to your domains public certificate file.
+ ssl_certificate /etc/letsencrypt/live/cloud.lab.starship-factory.ch/fullchain.pem; # managed by Certbot
+ ssl_certificate_key /etc/letsencrypt/live/cloud.lab.starship-factory.ch/privkey.pem; # managed by Certbot
+ ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
+
+ # Log Location. the Nginx User must have R/W permissions. Usually by ownership.
+ access_log /var/log/nginx/access.log;
+
+ # Forward to LDAP account manager
+ location / {
+ # Allow access from local network, but deny rest of the world.
+ allow 100.64.0.0/16;
+ deny all;
+
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_pass http://cloud.lab.starship-factory.ch:8100/;
+ proxy_read_timeout 30;
+ }
+
+ # Forward to phpldapadmin
+ location /phpldapadmin/ {
+ # Allow access from local network, but deny rest of the world.
+ allow 100.64.0.0/16;
+ deny all;
+
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_pass http://cloud.lab.starship-factory.ch:8090/;
+ proxy_read_timeout 30;
+ }
+ }
+
+***Hinweis:*** Aus Sicherheitsgründen wurde der Zugriff auf die LAP-Konfigurationsoberflächen auf das lokale Netzwerk begrenzt.
+
+Die SSL-Zertifikate wurden mittels des Let's Encrypt *certbot* erstellt und werden regelmässig erneuert. Hier zu ist das folgende Skript hinterlegt:
+
+**/etc/cron.monthly/renew-certificates**
+
+ #!/bin/bash
+
+ # Renew all let's encrypt certificates
+ /usr/bin/certbot renew -n
+
+## Backup
+
+Zur Sicherung aller Daten wurde eine externe Sicherung mittels *BackupPC* eingerichtet. Die Sicherung erfolgt auf dem Backup-Server *rueblitorte.de*, welcher sich physikalisch in D-79576 Weil am Rhein, Deutschland befindet. Der Server wird von Bernd Kalbfuss (aka Langweiler) betrieben.
+
+Für den Zugriff mittels SSH wurde der Benutzer *backuppc* angelegt und der Gruppe *ssh* hinzugefügt. Die Authentifizierung erfolgt mittels eines Schlüsselpaares. Dem Benutzer wurden beschränkte sudo-Rechte eingeräumt:
+
+**/etc/sudoers**
+
+ ...
+ # Allow backuppc user to run rsync with root privileges
+ backuppc ALL=(root) NOPASSWD: /usr/bin/rsync, /usr/local/bin/backup-mode, /usr/local/bin/production-mode
+ ...
+
+Um den Rechner in einen für das Backup sicheren Modus zu bringen und im Anschluss wieder zu reaktivieren, wurden zwei Skripte erstellt. Diese werden von BackupPC vor und nach dem Backup ausgeführt.
+
+**/usr/local/bin/backup-mode**
+
+ #!/bin/bash
+
+ echo "Switching host to backup mode."
+
+ # Pause critical docker containers
+ /usr/bin/docker pause nextcloud
+ /usr/bin/docker pause database
+
+**/usr/local/bin/production-mode**
+
+```3
+#!/bin/bash
+
+echo "Switching host to production mode."
+
+# Unpause critical docker containers
+/usr/bin/docker unpause database
+/usr/bin/docker unpause nextcloud
+```
+
+Um zu verhindern, dass der Server nach einem fehlgeschlagenen/abgebrochenen Backup im Backup-Modus verbleibt, wurde das *crontab* um den folgenden Eintrag erweitert:
+
+**/etc/crontab**
+
+ ...
+ # Unpause docker containers in case of failed backup
+ 00 5 * * * root /usr/local/bin/production-mode >/dev/null 2>&1
+ ...
+
+## LDAP
+
+Zur Benutzerverwaltung und Authentifizierung wurde auf dem Cloud-Server ein *OpenLDAP*-Server sowie die Konfigurationsoberflächen *LDAP Account Manager* und *phpldapadmin* installiert.
+
+Der LDAP-Server kann via *ldap* über der Port 389 unverschlüsselt sowie via *ldaps* über den Port 636 verschlüsselt angesprochen werden. *STARTTLS* auf dem Port 389 wurde bisher **nicht** konfiguriert.
+
+Die Konfigurationsoberfläche *LDAP Account Manager* ist über den Reverse Proxy unter der Adresse https://ldap.lab.starship-factory.ch/ zu erreichen, die Konfigurationsoberfläche *phpldapadmin* unter der der Adresse https://ldap.lab.starship-factory.ch/phpldapadmin/.
+
+Im Normallfall sollte die Konfigurationsoberfläche *LDAP Account Manager* verwendet werden, da diese einen wesentlich höheren Komfort bietet. Für Spezialfälle (z.B. die Verwaltung der Gruppen für die Administratoren und System-Benutzer) muss phpldapadmin verwendet werden, da der LDAP Account Manager entsprechende Funktionen in der freien Version nicht unterstützt.
+
+### Docker
+
+Der *OpenLDAP*-Server sowie die Administrationsoberflächen *LDAP Account Manager* und *phpldapadmin* wurden mittels *Docker* eingerichtet. Konkret wurden hierfür die folgenden Abbilder von *hub.docker.com* mittels `docker pull` bezogen:
+
+| Repository | Tag | Image ID | Size |
+| ---------------------- | ------ | ------------ | ----- |
+| osixia/phpldapadmin | latest | dbb580facde3 | 309MB |
+| osixia/openldap | latest | 31d1d6e16394 | 257MB |
+| ldapaccountmanager/lam | stable | 8b4da396b5eb | 384MB |
+
+Die Container wurden mittels `docker-compose` anhand der folgenden Datei erstellt:
+
+**docker-compose.yml**
+
+ version: '3'
+
+ volumes:
+ db:
+ conf:
+ certs:
+ admin:
+ lam:
+
+ services:
+ ldap:
+ image: osixia/openldap
+ container_name: openldap
+ restart: always
+ ports:
+ - "389:389"
+ - "636:636"
+ volumes:
+ - db:/var/lib/ldap
+ - conf:/etc/ldap
+ - certs:/container/service/slapd/assets/certs
+ environment:
+ - LDAP_ORGANISATION=starship-factory
+ - LDAP_DOMAIN=starship-factory.ch
+ - LDAP_ADMIN_PASSWORD=<Passwort>
+ - LDAP_TLS_CRT_FILENAME=cert.pem
+ - LDAP_TLS_KEY_FILENAME=privkey.pem
+ - LDAP_TLS_CA_CRT_FILENAME=chain.pem
+ - LDAP_TLS_VERIFY_CLIENT=try
+
+ phpldapamin:
+ image: osixia/phpldapadmin
+ container_name: phpldapadmin
+ restart: always
+ volumes:
+ - adminhinzufügt:/var/www/phpldapadmin
+ links:
+ - ldap:ldap-host
+ ports:
+ - "8090:80"
+ - "8091:443"
+ environment:
+ - PHPLDAPADMIN_LDAP_HOSTS=ldap-host
+ - PHPLDAPADMIN_HTTPS=false
+
+ lam:
+ image: ldapaccountmanager/lam:stable
+ container_name: lam
+ restart: always
+ volumes:
+ - lam:/var/lib/ldap-account-manager/config
+ ports:
+ - "8100:80"
+ environment:
+ - LDAP_DOMAIN=starship-factory.ch
+ - LDAP_ORGANISATION="Starship Factory"
+ - LDAP_BASE_DN=dc=starship-factory,dc=ch
+ - LDAP_USERS_DN=ou=users,dc=starship-factory,dc=ch
+ - LDAP_GROUPS_DN=ou=groups,dc=starship-factory,dc=ch
+ - LDAP_SERVER=ldaps://ldap.lab.starship-factory.ch:636
+ - LAM_DISABLE_TLS_CHECK=false
+ - LDAP_USER=cn=admin,dc=starship-factory,dc=ch
+ - LAM_PASSWORD=<Passwort>
+ - LAM_LANG=de_DE
+
+***Hinweis:*** Wird der OpenLDAP-Container mittels `docker-compose down` und im Anschluss `docker-compose up -d` erneut erstellt, so kommt es zu einer Fehlermeldung, da die Datei *ldap.conf* im Volumen *ldap_conf* fehlt. Es besteht lediglich ein symbolischer Link auf eine Datei, welche nicht mehr existiert. Der LDAP-Server startet in diesem Fall nicht, wie mittels `docker logs -f openldap` nachvollzogen werden kann. Um den Fehler zu beheben, muss die Datei aus dem Ordner *ldap_conf.bak* ergänzt werden.
+
+### Konfiguration
+
+Um die mit dem Let's Encrypt *certbot* erstellten Zertifikate dem LDAP-Server verfügbar zu machen, wurde das Skript `renew-certificates` wie erfolgt erweitert:
+
+**/etc/cron.monthly/renew-certificates**
+
+```33
+#!/bin/bash
+
+LDAP_CONTAINER=openldap
+SRC_PATH=/etc/letsencrypt/live/cloud.lab.starship-factory.ch
+DST_PATH=/container/service/slapd/assets/certs
+
+...
+
+# Copy certificates to openldap docker container
+docker cp -L ${SRC_PATH}/cert.pem ${LDAP_CONTAINER}:${DST_PATH}
+docker cp -L ${SRC_PATH}/privkey.pem ${LDAP_CONTAINER}:${DST_PATH}
+docker cp -L ${SRC_PATH}/chain.pem ${LDAP_CONTAINER}:${DST_PATH}
+# Restart openldap docker container
+docker restart ${LDAP_CONTAINER}
+```
+
+Weiterhin wurden in der Konfiguration des *OpenLDAP*-Servers der Gruppe *cn=ldap-admins,ou=groups,dc=starship-factory,dc=ch* vollständige Schreibrechte eingeräumt sowie der Gruppe *cn=ldap-auth-users,ou=groups,dc=starship-factory,dc=ch* vollständge Leserechte.
+
+**openldap:/etc/ldap/slapd.d/cn=config/olcDatabase=\{1\}mdb.ldif**
+
+ ...
+ olcAccess: {0}to *
+ by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage
+ by * break
+ olcAccess: {1}to attrs=userPassword,shadowLastChange,mail,labeledURI
+ by self write
+ by dn="cn=admin,dc=example,dc=org" write
+ by group.exact="cn=ldap-admins,ou=groups,dc=starship-factory,dc=ch" write
+ by anonymous auth
+ by * none
+ olcAccess: {2}to *
+ by dn="cn=admin,dc=example,dc=org" write
+ by group.exact="cn=ldap-admins,ou=groups,dc=starship-factory,dc=ch" write
+ by group.exact="cn=ldap-auth-users,ou=groups,dc=starship-factory,dc=ch" read
+ by self read
+ by * none
+ ...
+
+Die erste Gruppe dient zur Verwaltung der Administratoren, die zweite Gruppe zur Anlage von System-Nutzern, welche zur Authentifizierung gegen den LDAP-Server benötigt werden.
+
+***Hinweis:*** Die Datei *olcDatabase=\{1\}mdb.ldif* befindet sich im Docker-Volumen *ldap_conf*, welches im Verzeichnis */srv/dev-disk-by-id-md-name-debian-1/docker/volumes/ldap_conf/* gespeichert ist. Die Modifikation der *OpenLDAP*-Konfiguration sollte im Normalfall mittels des Befehls `ldapmodify` erfolgen. Da alle Versuche, die Zugriffsrechte mittels `ldapmodify` zu manipulieren scheiterten, wurde letztendlich der Weg der direkten Manipulation der Konfigurationsdatei gewählt.
+
+Die Konfiguration von *phpldapadmin* wurde mit den folgenden Einträgen ergänzt, um sicherzustellen, dass der sichere Hash-Algorithmus *SSHA* verwendet wird und die Nummerierung der Benztzer und Gruppen im Bereich >10000 liegt.
+
+**phpldapadmin:/var/www/phpldapadmin/config/config.php**
+
+ ...
+ /* Default password hashing algorithm. One of md5, ssha, sha, md5crpyt, smd5,
+ blowfish, crypt or leave blank for now default algorithm. */
+ $servers->setValue('appearance','pla_password_hash','ssha');
+
+ /* This feature allows phpLDAPadmin to automatically determine the next
+ available uidNumber for a new entry. */
+ $servers->setValue('auto_number','enable',true);
+
+ /* The minimum number to use when searching for the next available number
+ (only when 'search' is used for auto_number. */
+ $servers->setValue('auto_number','min',array('uidNumber'=>10000,'gidNumber'=>10000));
+
+Die erweiterte Konfiguration des *LDAP Account Manager* wurde mittels der Web-Oberfläche durchgeführt und ist im Folgenden nicht weiter beschrieben.
+
+## NextCloud
+
+Zum Austausch von Dateien und Informationen zwischen den Mitgliedern der Starship Factory wurde auf dem Cloud-Server eine *NextCloud*-Intanz installiert. Die *NextCloud* ist über den Reverse Proxy unter der Adresse https://cloud.lab.starship-factory.ch/ zu erreichen.
+
+### Docker
+
+Die *NextCloud* wurde mittels *Docker* eingerichtet. Konkret wurden hierfür die folgenden Abbilder von *hub.docker.com* mittels `docker pull` bezogen:
+
+| Repository | Tag | Image ID | Size |
+| ---------- | ------ | ------------ | ----- |
+| nextcloud | latest | a7a0780a23a7 | 835MB |
+| mariadb | latest | e27cf5bc24fe | 401MB |
+
+Die Container wurden mittels `docker-compose` anhand der folgenden Datei erstellt:
+
+**docker-compose.yml**
+
+ version: '3'
+
+ networks:
+ nextcloud:
+
+ volumes:
+ nextcloud:
+ db:
+
+ services:
+ db:
+ image: mariadb
+ container_name: database
+ restart: always
+ command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
+ volumes:
+ - db:/var/lib/mysql
+ networks:
+ - nextcloud
+ environment:
+ - MYSQL_ROOT_PASSWORD=<Passwort>
+ - MYSQL_PASSWORD=<Passwort>
+ - MYSQL_DATABASE=nextcloud
+ - MYSQL_USER=<Passwort>
+ app:
+ image: nextcloud
+ container_name: nextcloud
+ restart: always
+ ports:
+ - 8080:80
+ links:
+ - db
+ volumes:
+ - nextcloud:/var/www/html
+ networks:
+ - nextcloud
+ environment:
+ - MYSQL_PASSWORD=<Passwort>
+ - MYSQL_DATABASE=nextcloud
+ - MYSQL_USER=nextcloud
+ - MYSQL_HOST=db
+ - NEXTCLOUD_TRUSTED_DOMAINS=cloud.lab.starship-factory.ch
+
+### Konfiguration
+
+Damit integrierte Apps, insbesondere *OnlyOffice* in Kombination mit dem inversen Proxy und der Weiterleitung von *http* auf *https* funktionieren, wurde in der Datei *config.php* der Eintrag *overwrite.cli.url* auf '' und die Einstellung *overwriteprotocol* auf 'https' gesetzt. Außerdem wurde der vollständige Name des Hosts unter *trusted_domains* eingetragen.
+
+**nextcloud:/var/www/html/config/config.php**
+
+ ...
+ 'trusted_domains' =>
+ array (
+ 0 => 'cloud.lab.starship-factory.ch',
+ ),
+ 'overwrite.cli.url' => '',
+ 'overwriteprotocol' => 'https',
+ ...
+
+***Hinweis:*** Die Datei *config.php* befindet sich im Docker-Volumen *nextcloud_nextcloud*, welches im Verzeichnis */srv/dev-disk-by-id-md-name-debian-1/docker/volumes/nextcloud_nextcloud/* gespeichert ist.
+
+Das *crontab* wurde um den folgenden Eintrag erweitert, damit Hintegrundaufgaben in der *NextCloud* zuverlässig ausgeführt werden:
+
+**/etc/crontab**
+
+ ...
+ # Execute NextCloud background jobs in docker container
+ */5 * * * * root /usr/bin/docker exec nextcloud runuser -u www-data -- php -f /var/www/html/cron.php >/dev/null 2>&1
+ ...
+
+### Authenitifizierung via LDAP
+
+In den Einstellungen unter "LDAP / AD Integration" wurde die Authentifizierung gegen den lokal installierten *LDAP*-Server aktiviert:
+
+[[!img ldap-config.png align="left" alt="LDAP configuration screenshot"]]
+
+Der System-Benutzer *nextcloud-ldap-user* wurde zuvor im LDAP-Verzeichnis angelegt und in die Gruppe *ldap-admins* aufgenommen, um ihm Schreibrechte auf das LDAP-Verzeichnis zu gewähren.
+
+***Hinweis***: Auf Grund einer Beschränkung in der LDAP-Implementierung in Nextcloud ist es aktuell notwendig, dass der LDAP-Benutzer Schreibrechte auf das Verzeichnis hat, um Benutzern das Ändern ihrer Passwörter zu ermöglichen.
+
+***Warnung:*** Eine inkorrekte LDAP-Konfiguration - insbesondere die unsachgemäße Manipulation einer existierenden Konfiguration - kann dazu führen, dass die NextCloud-Instanz nicht mehr startet.
+
+
+### Apps
+
+Die folgenden Apps wurden in NextCloud deaktiviert, da sie mit der Anwendung OnlyOffice kollidieren:
+
+* Collabora Online - Built-in CODE Server
+* Collabora Online
+
+Die folgenden Anwendungen wurden zusätzlich installiert und aktiviert:
+
+* Community Document Server
+* ONLYOFFICE
+* Group Folders
+* Decks
+* Tasks
+* Circles
+* Announcements
+* Notes