Autorenarchiv: Jörg Kastning

Datenpanne im Internet – Bin ich betroffen?

Sie passieren ständig – Datenpannen[1. Wikipedia: Datenpanne] im Internet. Und die Abstände zwischen ihnen werden gefühlt immer kürzer. In diesem Artikel möchte ich euch einen Weg aufzeigen, wie ihr selbst schnell und einfach feststellen könnt, ob ihr selbst von einer Datenpanne betroffen seid. Im Gegensatz zu vielen anderen Artikeln auf diesem Blog versuche ich dabei auf technische Details so weit wie möglich zu verzichten, um den Artikel allgemeinverständlich zu gestalten.

Datenpannen sind Verstöße, gegen die Datensicherheit und den Datenschutz, bei denen Staatsgeheimnisse, Betriebsgeheimnisse oder personenbezogene Daten Unberechtigten vermutlich oder erwiesenermaßen bekannt geworden sind. – Quelle: Deutschsprachige Wikipedia: Datenpanne

Und Datenpannen können überall passieren. Im Online-Shop, dem Online-Auktionsportal, im Online-Banking, in Tauschbörsen, in sozialen Netzwerken und auch im Cloud-Speicher-Dienst, dem wir unsere Dateien anvertrauen. Wikipedia listet einige bedeutende Vorfälle[2. Wikipedia: Bedeutende Datenpannen], die in den vergangenen Jahren bekannt wurden.

Doch wie kann man nun überprüfen, ob man selbst von einer solchen Panne betroffen ist? Eine erfreulich einfache Möglichkeit bietet die Webseite https://haveibeenpwned.com/.[3. ‚;–have i been pwned? {en}] [4. Wikipedia: Have I Been Pwned? {en}]

https://haveibeenpwned.com

https://haveibeenpwned.com – Prüfe, ob einer deiner Accounts durch eine Datenpanne kompromittiert wurde.

Die Bedienung der Seite ist, wie bereits erwähnt, erfreulich einfach. Man trägt den zu überprüfenden Benutzernamen bzw. E-Mail-Adresse in das Suchfeld ein und startet die Suche. Das Ergebnis gibt Auskunft darüber, ob der Benutzername bzw. die E-Mail-Adresse von einer Datenpanne betroffen ist und bei welchem Dienst die Informationen stammen. Die folgenden beiden Screenshots zeigen zwei Beispiele. Das erste Beispiel zeigt einen Fall, bei dem die Kompromittierung eines Benutzernamens bis heute nicht bekannt geworden ist. Das zweite Beispiel zeigt die Abfrage einer E-Mail-Adresse, die mit anderen Daten bei einem Datenleck beim Cloud-Speicheranbieter Dropbox abgegriffen wurden.

username-not-compromised

Keine Kompromittierung des Benutzernamens bekannt

compromised-mailaddress

Die kompromittierte E-Mail-Adresse stammt aus einem Datenleck bei Dropbox

Neben der manuellen Überprüfung bietet die Webseite auch die Möglichkeit, eine E-Mail-Adresse zu hinterlegen. Taucht diese E-Mail-Adresse in einem öffentlich bekannt gewordenen Datenbestand auf, erhält man hierüber eine Nachricht an die hinterlegte E-Mail-Adresse.

Jetzt auch als deutschsprachiges Angebot: Der E-Mail Leak Check

Janis von Bleichert wies mich via E-Mail auf den E-Mail Leak Check hin, welcher unter der URL https://www.experte.de/email-check erreichbar ist. Herr Bleichert hat hier ein Angebot für deutschsprachige Benutzer geschaffen. Dazu hat her Bleichert eigenen Angaben zufolge Informationen zu mehr als 300 Daten-Leaks auf Deutsch übersetzt und ein Tool programmiert, mit welchem Benutzer ebenfalls überprüfen können, ob ihre E-Mail-Adresse von einem Datenleck betroffen ist.

easy check of mail address

Quelle: https://www.experte.de/email-check

Funktion, Nutzung, Datenschutzhinweis und Antworten auf häufige Fragen, werden in einfachem und verständlichem Deutsch gegeben.

Ich möchte Herrn Bleichert an dieser Stelle für den Hinweis auf diesen Dienst danken.

Was tun, wenn ich betroffen bin?

Stellt man nun fest, dass die geprüften Benutzerdaten kompromittiert sind, sollte man umgehend handeln. Es ist dringend empfohlen, in diesem Fall

  1. die Zugangsdaten (Benutzername, E-Mail-Adressse, Passwort) beim betroffenen Dienst zu ändern.
  2. die Zugangsdaten (Benutzername, E-Mail-Adressse, Passwort) bei allen sonstigen Diensten zu ändern, bei denen die gleichen Zugangsdaten verwendet wurden.

Mit dem zweiten Schritt soll sichergestellt werden, dass mit den kompromittierten Benutzerinformationen noch weitere Benutzerkonten bei anderen Online-Diensten gekapert werden können.

Um den Umgang und die Verwaltung von Benutzernamen und Passwörtern so komfortabel wie möglich zu gestalten, empfehle ich die Verwendung eines Passwortmanagers wie z.B. KeePass.[5. Wikipedia: KeePass] [6. KeePass Password Safe] [7. The Official KeePassX Homepage]

Der eigene Mailserver – TLS-Migration zu Let’s Encrypt

Durch die Ankündigung von Mozilla, den Zertifizierungsstellen StartCom und WoSign das Vertrauen entziehen zu wollen,[1. Golem: Mozilla will Startcom und Wosign das Vertrauen entziehen] [2. Mozilla’s proposed conclusion for community discussion, regarding the matter of WoSign and StartCom. {en}] entstand für mich Handlungsbedarf. Denn ich wollte die Zertifikate dieser Anbieter nun so schnell wie möglich loswerden.

In Teil 2 meiner Artikelreihe „Der eigene Mailserver“ wird ein TLS/SSL-Zertifikat von StartSSL verwendet, um dieses zur Absicherung von Postfix, Dovecot und dem Webmailer Roundcube zu verwenden. An dieser Stelle halte ich nun die Umstellung auf TLS-Zertifikate von Let’s Encrypt fest.

Für die Bereitstellung und automatisierte Erneuerung der Zertifikate verwende ich certbot-auto.[3. Automatically enable HTTPS on your website with EFF’s Certbot, deploying Let’s Encrypt certificates. {en}] Dessen Installation und Nutzung wird in Abschnitt 3.6.1 TLS-Kochbuch[4. TLS-Kochbuch – Rezepte für die Verwendung von OpenSSL, HTTP Strict Transport Security (HSTS) und HTTP Public Key Pinning (HPKP)] beschrieben.

Das von cerbot-auto erzeugte Zertifikat und der dazugehörige private Schlüssel werden unter dem Pfad /etc/letsencrypt/live/ abgelegt. Um das Zertifikat in die gewünschten Dienste einzubinden, ist der Pfad zum Zertifikat in den Konfigurationsdateien der Dienste zu aktualisieren. Das folgende Listing gibt den Namen der Konfigurationsdateien und der anzupassenden Parameter wieder:

# /etc/nginx/sites-available/roundcube
ssl_certificate /etc/letsencrypt/live/FQDN/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/FQDN/privkey.pem;

# /etc/postfix/main.cf
smtpd_tls_cert_file = /etc/letsencrypt/live/FQDN/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/FQDN/privkey.pem

# /etc/dovecot/conf.d/99-mail-stack-delivery.conf
ssl_cert =

Die Konfiguration der Dienste muss anschließend neu geladen werden. Um dies bei zukünftigen Erneuerungen des Zertifikats zu automatisieren, habe ich ein kleines Skript renew_certs.sh erstellt, welches täglich via Cron ausgeführt wird.

#!/bin/sh
/home/USERNAME/certbot/certbot-auto renew --quiet --no-self-upgrade
sudo service nginx reload
sudo service postfix reload
sudo service dovecot reload

certbot-auto renew erneuert das Zertifikat, sobald die Gültigkeitsdauer kleiner 30 Tage ist. Durch die tägliche Ausführung soll sichergestellt werden, dass die Aktualisierung auch dann rechtzeitig gelingt, sollte die Schnittstelle von Let’s Encrypt vorübergehend nicht erreichbar sein.

Ansible: Patch-Management für Red Hat Systeme

Als Linux-Distribution für den Betrieb im Rechenzentrum fiel unsere Wahl vor einiger Zeit auf Red Hat Enterprise Linux. Zu meinen Aufgaben gehört es, ein Patch-Management für diese Systeme zu entwickeln, welches die folgenden Anforderungen erfüllt:

  1. Die zu aktualisierenden Hosts werden in Gruppen im Ansible Inventory verwaltet. Eine Gruppe entspricht dabei einer Stage/Phase für das Patch-Management.
  2. An definierten Stichtagen sollen automatisiert fehlende Sicherheitsaktualisierungen auf den Systemen in den verschiedenen Stages/Phasen eingespielt werden können.
  3. Dabei sollen ausschließlich Pakete aktualisiert werden, für die Red Hat Security Advisory veröffentlicht wurden.
  4. Wenn Pakete aktualisiert wurden, soll der Host anschließend neugestartet werden.

Ich habe mich entschieden, diese Anforderungen durch die Verwendung von Ansible zu erfüllen. Wem Ansible noch kein Begriff ist, möge einen Blick in die Quellen am Ende des Artikels werfen.[1. Ansible – IT-Automation für Jedermann] [2. Ansible Documentation {en}] [3. Linux-Benutzerkonten mit Ansible verwalten] [4. Das Modul yum_repository] [5. Die Module copy und cron]

Mit den Anregungen meines Arbeitskollegen habe ich dazu das folgende Playbook erstellt, welches die Rolle rhel-patchmanagement auf allen Hosts mit einem Red Hat Betriebssystem ausführt:

---
- hosts: all

  tasks:
    - name: Group by OS
      group_by: key=os_{{ ansible_distribution }}
      changed_when: False

- hosts: os_RedHat
  roles:
    - rhel-patchmanagement

Die Rolle rhel-patchmanagement besteht aus den beiden folgenden Dateien:

  • roles/patch_rhel/tasks/main.yml
  • roles/patch_rhel/vars/main.yml

roles/patch_rhel/vars/main.yml:

---
rhsa_to_install: RHSA-2016:1626,RHSA-2016:1628,RHSA-2016:1633

Obiges Listing gibt ein kurzes Beispiel, wie die Red Hat Security Advisory (RHSA) Nummern einer Variablen zugewiesen werden können. Die Variable rhsa_to_install wird dann in der Task-Datei verwendet.

roles/patch_rhel/tasks/main.yml:

---
  - name: Install Red Hat Security Advisory (RHSA)
    command: yum -y update-minimal --advisory {{ rhsa_to_install }}
    register: yum_output
  - debug: var=yum_output

  - name: Reboot Host if packages were updated
    shell: sleep 2 && shutdown -r now "Ansible updates triggered"
    async: 1
    poll: 0
    ignore_errors: true
    when: ('"Complete!" in "{{ yum_output.stdout_lines[-1] }}"') or
          ('"Komplett!" in "{{ yum_output.stdout_lines[-1] }}"')

  - name: waiting for access server
    local_action: wait_for
      host={{ inventory_hostname }}
      state=started
      port=22
      delay=30
      timeout=300
      connect_timeout=15

Zuerst wird das Kommando zur Aktualisierung der zu den angegebenen RHSA gehörenden Pakete auf den Hosts ausgeführt. Dabei wird die Ausgabe des Kommandos yum auf den Hosts der Variable yum_output zugewiesen.[6. Registered Variables] Diese Variable wird im nächsten Schritt ausgewertet, um zu ermitteln, ob Pakete aktualisiert wurden. Ist dies der Fall, wird der Host neugestartet.

Erklärung: Wurden Pakete aktualisiert, steht in der letzten Zeile der YUM-Ausgabe der Ausdruck „Complete!“. "{{ yum_output.stdout_lines[-1] }}" dereferenziert die Variable und liefert die Ausgabe des YUM-Kommandos als Liste zurück. Dabei wird in diesem Fall auf das letzte Element der Liste zugegriffen. Enthält diese Zeile den genannten Ausdruck, wird der Host neugestartet. Hinweis: Die zweite Zeile der when-Bedingung aus dem oberen Listing dient der Behandlung einer deutschsprachigen Ausgabe. In diesem Fall wird das Schlüsselwort „Komplett!“ ausgegeben und in der Variable gespeichert.

Der letzte Task wartet 30 Sekunden ab, um dem Host Zeit für den Neustart zu geben und prüft, ob eine Verbindung hergestellt werden kann. Damit soll sichergestellt werden, dass der Host nach dem Neustart wieder korrekt hochfährt.

Damit sind die Anforderungen aus Punkt 2 und 3 erfüllt. Um auch noch die Anforderung aus Punkt 1 zu erfüllen, setze ich folgendes Wrapper-Skript ein, welches das Playbook zu den definierten Stichtagen ausführen soll:

#!/bin/sh

DOM=`date +%d`
DOW=`date +%w`
LOG="/var/log/ansible/patch_run_`date +%Y-%m-%d`.log"
SETUP_LOG="/var/log/ansible/setup_patch_run_`date +%Y-%m-%d`.log"
SSH_KEY="/pfad/zum/ssh-key"
PLAYBOOK="/data/ansible/patch_rhel.yml"
CREATEVARS="/pfad/zu/roles/rhel-patchmanagement/create_vars.sh"

# Run Patch-Management ad-hoc in the specified phase.
# Example: './run_rhel_patch_mgmt.sh NOW rhel-patch-phase1'
if [ "${1}" = "NOW" ] && [ -n "${2}" ]
then
  ansible-playbook $PLAYBOOK --private-key=$SSH_KEY --limit="${2}" >>$LOG 2>&1
  exit
fi

if [ "${1}" = "NOW" ] && [ -z "${2}" ]
then
  echo "ERROR: Second argument is missing."
  echo "Example: './run_rhel_patch_mgmt.sh NOW rhel-patch-phase1'"
  exit
fi

# Setup the next patchcycle
if [ "$DOW" = "2" ] && [ "$DOM" -gt 0 ] && [ "$DOM" -lt 8 ]
then
    $CREATEVARS > $SETUP_LOG 2>&1
fi

# Patchcycle of the rhel-patch-phase1 on the second Tuesday of a month
if [ "$DOW" = "2" ] && [ "$DOM" -gt 7 ] && [ "$DOM" -lt 15 ]
then
    ansible-playbook $PLAYBOOK --private-key=$SSH_KEY --limit=rhel-patch-phase1 > $LOG 2>&1
fi

# Patchcycle of the rhel-patch-phase2 on the third Tuesday of a month
if [ "$DOW" = "2" ] && [ "$DOM" -gt 14 ] && [ "$DOM" -lt 22 ]
then
    ansible-playbook $PLAYBOOK --private-key=$SSH_KEY --limit=rhel-patch-phase2 > $LOG 2>&1
fi

# Patchcycle of the rhel-patch-phase3 on the fourth Tuesday of a month
if [ "$DOW" = "2" ] && [ "$DOM" -gt 21 ] && [ "$DOM" -lt 29 ]
then
    ansible-playbook $PLAYBOOK --private-key=$SSH_KEY --limit=rhel-patch-phase3 > $LOG 2>&1
fi

# Patchcycle of the rhel-patch-phase4 on the fourth Wednesday of a month
if [ "$DOW" = "3" ] && [ "$DOM" -gt 21 ] && [ "$DOM" -lt 30 ]
then
    ansible-playbook $PLAYBOOK --private-key=$SSH_KEY --limit=rhel-patch-phase4 > $LOG 2>&1
fi

Mit diesem Wrapper-Skript möchte ich dafür sorgen, dass an jedem 2. Dienstag im Monat die RSHA-Aktualisierungen auf den Hosts in der rhel-patch-phase1, jeden 3. Dienstag in der rhel-patch-phase2, jeden 4. Dienstag in der rhel-patch-phase3 und jeden 4. Mittwoch in rhel-patch-phase4 installiert werden.

So kann sichergestellt werden, dass die Informationen aus den RHSA alle Hosts erreichen. Gleichzeitig wird den Betreibern der Hosts die Gelegegnheit gegeben, die Aktualisierungen bis zu den genannten Stichtagen selbst einzuspielen. Damit sollte ich auch an Punkt 1 einen Haken dran machen können.

Die Ansible-Rolle und dazugehörende Skripte und Beispiel-Dateien findet ihr auf:

Fragen zur Anwendung, Konfiguration und Nutzung des RHEL-Patchmanagements könnt ihr gerne auf GitHub oder hier in den Kommentaren stellen.

Aktualisiert am: 07.09.2018

Kurz vorgestellt: Mozilla SSL Configuration Generator

In diesem Artikel möchte ich euch kurz den Mozilla SSL Configuration Generator vorstellen, auf den mich ein Kollege aufmerksam machte.

mozilla_ssl_configuration_generator

Mozilla SSL Configuration Generator

Es handelt sich dabei um eine Seite, die dabei hilft, valide Konfigurationen für verschiedene Webserver wie Apache, NGINX, Lighttpd, HAProxy oder AWS ELB zu erstellen. Man gibt dazu den verwendeten Webserver, dessen Version und die OpenSSL Version an. Die Seite erstellt daraufhin die Konfiguration, welche per Copy&Paste übernommen werden kann. Lediglich die enthaltenen Pfadinformationen sind an die eigenen Bedürfnisse anzupassen.

mozilla_ssl_configuration_generator_nginx

Konfiguration für nginx 1.4.6 | modern profile | OpenSSL 1.0.1e

Neben der Konfiguration erhält man auch noch die Information dazu geliefert, welche Browser mit der erstellten Version kompatibel sind.

In einer ersten Stichprobe scheint die Seite ganz brauchbare Ergebnisse zu liefern. Ich freue mich über eure Meinungen und Erfahrungen zu diesem Dienst.

Bei positiver Resonanz nehme ich einen Hinweis auf diesen Dienst in eine kommende Version meines TLS-Kochbuchs auf.

Installation von Seafile auf einem Ubuntu/Debian Server

Diese Anleitung beschreibt, wie die Software Seafile[1. Wikipedia Artikel zu Seafile}] auf einem Ubuntu Server installiert werden kann. Sie gilt prinzipiell auch für Debian. Jedoch müssen einzelne Schritte ggf. angepasst werden.

Hinweis zu Seafile Version 6.2: Bitte beachten Sie bei der Installation von Seafile in Version 6.2 den Kommentar von Christoph weiter unten. Ich Danke Christoph für diesen Hinweis.

Getestete Versionen

BetriebssystemUbuntu 14.04 LTS Server
WebserverNGINX 1.4.6
DatenbankserverMySQL 5.6
Seafile5.1.4 64bit

Einleitung

Seafile ist eine freie Software, um Dateien zentral auf einem eigenen Server zu speichern (Filehosting). Benutzer können auf ihre Daten über eine Webschnittstelle zugreifen oder über Desktop-Clients synchronisieren. Quelle: Wikipedia {de}

Seafile[2. Seafile Homepage {en}] bildet damit einen Teil des Funktionsumfangs bekannter Open Source Projekte wie ownCloud und Nextcloud ab, konzentriert sich dabei jedoch auf die „Sync+Share“-Funktion für Dateien. Jan Karres hat in seinem Blog einen schönen Artikel über den Vergleich ownCloud vs Seafile geschrieben, welcher die Eigenschaften sowie die Vor- und Nachteile beider Projekte erläutert.

Bei dem hier vorliegenden Anwendungsfall habe ich mich für Seafile entschieden, da die einzige Anforderung im Sync+Share von Dateien besteht. Seafile bietet im Gegensatz zu ownCloud auf diesem Gebiet auch clientseitige Verschlüsselung[3. How to Use Encrypted Libraries] an. Die zukünftigen Anwender sind im Umgang bereits geübt und die Sync-Clients bereits auf den meisten ihrer Endgeräte installiert.

Um dieser Anleitung folgen zu können, werden grundlegende Kenntnisse in der Administration eines Linuxservers vorausgesetzt.

Anleitung

Die folgende Anleitung wurde auf Basis der Artikel von Jan Karres[4. Raspberry Pi: Owncloud-Alternative Seafile Server installieren] und André P.[5. Seafile 4.0.x mit Nginx und MySQL-Backend auf Debian/Ubuntu] erstellt.

Voraussetzungen

Folgende Dienste müssen auf dem Server installiert und funktionsfähig sein, um Seafile installieren zu können:

Als Servername wird im Folgenden stets seafile verwendet. Dieser ist an den gewünschten Servernamen der eigenen Installation anzupassen.

Installation und Konfiguration

Zuerst werden die von Seafile benötigten Abhängigkeiten installiert:

sudo apt-get install python2.7 python-setuptools python-simplejson python-imaging python-mysqldb

Im zweiten Schritt wird ein Systembenutzer[9. Der Unterschied zwischen einem Systembenutzer und einem normalen Benutzer] erstellt, dessen Home-Verzeichnis die gesamte Seafile-Installation aufnehmen wird. Der Benutzername kann dabei frei gewählt werden.

sudo adduser --system --group BENUTZERNAME

Mit den folgenden Befehlen wird der Benutzer gewechselt, die benötigte Verzeichnisstruktur erstellt, die Software heruntergeladen und entpackt.

# Wechselt zum erstellten Systembenutzer für die Seafile-Installation
sudo su - BENUTZERNAME -s /bin/bash

# Erstellen der Verzeichnisstruktur
mkdir -p seafile/installed && cd seafile/installed
wget wget https://download.seafile.de/seafile-server_latest_x86-64.tar.gz

# Archiv in das Zielverzeichnis entpacken und zurück ins Home-Verzeichnis wechseln
tar -xzvf *tar.gz -C ../ && cd ..

Im Home-Verzeichnis sollte die Verzeichnisstruktur nun wie folgt aussehen:

seafile@rs212997:/home/seafile/seafilesrv$ tree -L 2
.
├── installed
│   └── seafile-server_latest_x86-64.tar.gz
└── seafile-server-5.1.3
    ├── check_init_admin.py
    ├── reset-admin.sh
    ├── runtime
    ├── seaf-fsck.sh
    ├── seaf-fuse.sh
    ├── seaf-gc.sh
    ├── seafile
    ├── seafile.sh
    ├── seahub
    ├── seahub.sh
    ├── setup-seafile-mysql.py
    ├── setup-seafile-mysql.sh
    ├── setup-seafile.sh
    └── upgrade

6 directories, 11 files

Nun wechselt man in das Verzeichnis mit der Software (in diesem Fall seafile-server-5.1.3) und führt das Skript setup-seafile-mysql.sh aus. Die Antworten auf die Fragen sind selbstverständlich an die eigene Umgebung anzupassen.

./setup-seafile-mysql.sh 
Checking python on this machine ...
  Checking python module: setuptools ... Done.
  Checking python module: python-imaging ... Done.
  Checking python module: python-mysqldb ... Done.

-----------------------------------------------------------------
This script will guide you to setup your seafile server using MySQL.
Make sure you have read seafile server manual at

        https://github.com/haiwen/seafile/wiki

Press ENTER to continue
-----------------------------------------------------------------


What is the name of the server? It will be displayed on the client.
3 - 15 letters or digits
[ server name ] seafile

What is the ip or domain of the server?
For example: www.mycompany.com, 192.168.1.101
[ This server's ip or domain ] seafile.domain.tld

Where do you want to put your seafile data?
Please use a volume with enough free space
[ default "/home/BENUTZERNAME/seafilesrv/seafile-data" ] 

Which port do you want to use for the seafile fileserver?
[ default "8082" ] 

-------------------------------------------------------
Please choose a way to initialize seafile databases:
-------------------------------------------------------

[1] Create new ccnet/seafile/seahub databases
[2] Use existing ccnet/seafile/seahub databases

[ 1 or 2 ] 1

What is the host of mysql server?
[ default "localhost" ] 

What is the port of mysql server?
[ default "3306" ] 

What is the password of the mysql root user?
[ root password ] 

verifying password of user root ...  done

Enter the name for mysql user of seafile. It would be created if not exists.
[ default "root" ] seafile_user

Enter the password for mysql user "seafile_user":
[ password for seafile_user ] 

Enter the database name for ccnet-server:
[ default "ccnet-db" ] my-ccnet-db

Enter the database name for seafile-server:
[ default "seafile-db" ] my-seafile-db

Enter the database name for seahub:
[ default "seahub-db" ] my-seahub-db

---------------------------------
This is your configuration
---------------------------------

    server name:            seafile
    server ip/domain:       seafile.domain.tld

    seafile data dir:       /home/BENUTZERNAME/seafilesrv/seafile-data
    fileserver port:        8082

    database:               create new
    ccnet database:         my-ccnet-db
    seafile database:       my-seafile-db
    seahub database:        my-seahub-db
    database user:          seafile_user



---------------------------------
Press ENTER to continue, or Ctrl-C to abort
---------------------------------

Generating ccnet configuration ...

done
Successly create configuration dir /home/BENUTZERNAME/seafilesrv/ccnet.
Generating seafile configuration ...

Done.
done
Generating seahub configuration ...

----------------------------------------
Now creating seahub database tables ...

----------------------------------------

creating seafile-server-latest symbolic link ...  done




-----------------------------------------------------------------
Your seafile server configuration has been finished successfully.
-----------------------------------------------------------------

run seafile server:     ./seafile.sh { start | stop | restart }
run seahub  server:     ./seahub.sh  { start  | stop | restart  }

-----------------------------------------------------------------
If you are behind a firewall, remember to allow input/output of these tcp ports:
-----------------------------------------------------------------

port of seafile fileserver:   8082
port of seahub:               8000

When problems occur, Refer to

        https://github.com/haiwen/seafile/wiki

for information.

Möchte man Seafile via HTTPS nutzen, sind noch zwei Dateien anzupassen. Zuerst wird in die Datei ~/seafilesrv/conf/ccnet.conf der Parameter SERVICE_URL wie folgt angepasst:

SERVICE_URL = https://seafile.domain.tld:8000

Die zweite zu bearbeitende Datei ist seahub_settings.py. Hier wird am Ende der Datei die folgende Zeile eingefügt:

FILE_SERVER_ROOT = 'https://seafile.domain.tld/seafhttp'

Durch manuelles Starten der Dienste wird der Administrator-Account erstellt. Das folgende Listing zeigt die auszuführenden Befehle und Abfragen:

:~$ ~/seafilesrv/seafile-server-latest/seafile.sh start

[09/02/16 21:56:00] ../common/session.c(132): using config file /home/BENUTZERNAME/seafilesrv/conf/ccnet.conf
Starting seafile server, please wait ...
Seafile server started

Done.
:~$ ~/seafilesrv/seafile-server-latest/seahub.sh start-fastcgi

LC_ALL is not set in ENV, set to en_US.UTF-8
Starting seahub (fastcgi) at 127.0.0.1:8000 ...

----------------------------------------
It's the first time you start the seafile server. Now let's create the admin account
----------------------------------------

What is the email for the admin account?
[ admin email ] EURE E-MAIL-ADRESSE

What is the password for the admin account?
[ admin password ] SICHERESPASSWORThttp://start.ubuntu.com/16.04/Google/?sourceid=hphttp://start.ubuntu.com/16.04/Google/?sourceid=hp

Enter the password again:
[ admin password again ] SICHERESPASSWORT



----------------------------------------
Successfully created seafile admin
----------------------------------------




Seahub is started

Done.

Zum Abschluss werden die manuell gestarteten Dienste wieder beendet:

:~$ ~/seafilesrv/seafile-server-latest/seafile.sh stop
:~$ ~/seafilesrv/seafile-server-latest/seahub.sh stop

Um sicherzustellen, dass der lokale Seafile-Webdienst nicht aus dem Internet erreichbar ist, sollte folgender Block in der Datei ~/seafilesrv/conf/seafile.conf vorhanden sein:

[fileserver]
host=127.0.0.1
port=8082

An dieser Stelle wird die aktuelle Shell mit exit verlassen. Von nun an kann mit sudo oder als root weitergearbeitet werden.

Konfiguration von NGINX

Für NGINX wird ein neuer VirtualHost für die Domain seafile.domain.tld erstellt. Wird die Konfiguration aus folgendem Listing übernommen, so sind mindestens die Werte für den root-Pfad, server_name, ssl_certificate und ssl_certificate_key an die eigene Konfiguration anzupassen.

server {
        listen       80;
        server_name  seafile.domain.tld;
        rewrite ^/(.*) https://$server_name/$1 permanent;
}
server {
        listen 443; #IPv4
        #listen [::]:443; # IPv6
        ssl on;
        ssl_certificate /etc/nginx/certs/ssl-unified.crt;
        ssl_certificate_key /etc/nginx/certs/ssl.key;
        server_name seafile.domain.tld;

        location / {
                fastcgi_pass    127.0.0.1:8000;
                fastcgi_param   SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_param   PATH_INFO           $fastcgi_script_name;

                fastcgi_param   SERVER_PROTOCOL     $server_protocol;
                fastcgi_param   QUERY_STRING        $query_string;
                fastcgi_param   REQUEST_METHOD      $request_method;
                fastcgi_param   CONTENT_TYPE        $content_type;
                fastcgi_param   CONTENT_LENGTH      $content_length;
                fastcgi_param   SERVER_ADDR         $server_addr;
                fastcgi_param   SERVER_PORT         $server_port;
                fastcgi_param   SERVER_NAME         $server_name;

                fastcgi_param   HTTPS on;
                fastcgi_param   HTTP_SCHEME https;
        }

        location /seafhttp {
                rewrite ^/seafhttp(.*)$ $1 break;
                proxy_pass http://127.0.0.1:8082;
                client_max_body_size 0;
        }

        location /media {
                root /home/BENUTZERNAME/seafilesrv/seafile-server-latest/seahub;
        }
}

Mit der oben stehenden Konfiguration erfolgt automatisch eine Weiterleitung von HTTP auf HTTPS. Wer für die Beantragung und Implementierung des Zertifikats Anleitung benötigt oder die Installation zusätzlich noch mit HSTS und HPKP schützen möchte, sei auf mein TLS-Kochbuch[10. Kapitel 4, TLS-Kochbuch mit Rezepten zur Verwendung von OpenSSL, HTTP Strict Transport Security (HSTS) und HTTP Public Key Pinning (HPKP)] verwiesen.

Konfiguration des Seafile-Dienstes

Zur Konfiguration des Dienstes bediene ich mich der Arbeit aus dem Artikel von André P. Dazu wird die Datei /etc/init.d/seafile mit folgendem Inhalt erstellt. Die Parameter user und seafile_dir sind dabei an die eigene Installation anzupassen.

#!/bin/bash

### BEGIN INIT INFO
# Provides:          seafile
# Required-Start:    $local_fs $remote_fs $network
# Required-Stop:     $local_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Starts Seafile and Seahub
# Description:       starts Seafile and Seahub
### END INIT INFO

#### CONFIG START ####
user=seafile
seafile_dir=/srv/seafile/servername
##### CONFIG END #####

script_path=${seafile_dir}/seafile-server-latest
seafile_init_log=${seafile_dir}/logs/seafile.init.log
seahub_init_log=${seafile_dir}/logs/seahub.init.log
[ -d ${seafile_dir}/logs ] || mkdir ${seafile_dir}/logs && chown $user:$user ${seafile_dir}/logs

# Change the value of fastcgi to true if fastcgi is to be used
fastcgi=true
# Set the port of fastcgi, default is 8000. Change it if you need different.
fastcgi_port=8000

case "$1" in
        start)
                sudo -u ${user} ${script_path}/seafile.sh start >> ${seafile_init_log}
                if [  $fastcgi = true ];
                then
                        sudo -u ${user} ${script_path}/seahub.sh start-fastcgi ${fastcgi_port} >> ${seahub_init_log}
                else
                        sudo -u ${user} ${script_path}/seahub.sh start >> ${seahub_init_log}
                fi
        ;;
        restart)
                sudo -u ${user} ${script_path}/seafile.sh restart >> ${seafile_init_log}
                if [  $fastcgi = true ];
                then
                        sudo -u ${user} ${script_path}/seahub.sh restart-fastcgi ${fastcgi_port} >> ${seahub_init_log}
                else
                        sudo -u ${user} ${script_path}/seahub.sh restart >> ${seahub_init_log}
                fi
        ;;
        stop)
                ${script_path}/seafile.sh $1 >> ${seafile_init_log}
                ${script_path}/seahub.sh $1 >> ${seahub_init_log}
        ;;
        *)
                echo "Usage: /etc/init.d/seafile {start|stop|restart}"
                exit 1
        ;;
esac

Mit den folgenden Kommandos wird das Skript ausführbar gemacht, installiert und der Dienst gestartet:

chmod +x /etc/init.d/seafile
update-rc.d seafile defaults
service seafile start

Ende

Die Installation ist damit abgeschlossen. Die Seafile-Installation kann nun über https://seafile.domain.tld aufgerufen und genutzt werden.

An dieser Stelle möchte ich mich noch einmal bei André P. für seinen Artikel „Seafile 4.0.x mit Nginx und MySQL-Backend auf Debian/Ubuntu bedanken. Er stellt die Basis für diese Anleitung mit der aktuellen Version von Seafile dar.

Solltet ihr Seafile mit dieser Anleitung auch unter anderen Versionen von Ubuntu/Debian, etc. installieren können, freue ich mich über eure Kommentare, um die Tabelle mit den getesteten Versionen ergänzen zu können.

Mein TLS/SSL-Kochbuch

Heutzutage werden immer mehr Kommunikationsverbindungen im Internet mit TLS/SSL-Verbindungen geschützt. Die Verschlüsselung hilft, die Vertraulichkeit der zwischen Sender und Empfänger übertragenen Daten zu schützen und sollte daher standardmäßig aktiviert sein. Doch bereitet der Einsatz von TLS/SSL-Verschlüsselung noch immer vielen Administratoren und Betreibern verschiedenster Anwendungen Kopfschmerzen. Zu undurchsichtig scheint der Dschungel aus Zertifizierungsstellen, Zertifikaten, Zertifikatsanfragen, öffentlichen und privaten Schlüsseln zu sein. Verschiedenste Validierungsverfahren und Dateiformate für Zertifikate tragen nicht gerade dazu bei, den Durchblick zu behalten. Bereits die Erstellung einer Zertifikatsanfrage gerät dabei häufig genug zu einem Problem. Die richtige Konfiguration der zu sichernden Server bzw. Dienste erscheint kompliziert und Fehler in der Konfiguration führen nicht selten zur Nichterreichbarkeit einer Webseite. Die Folge: Immer noch wird viel zu häufig auf den Einsatz von TLS/SSL-Verschlüsselung verzichtet.

Mit meinem TLS-Kochbuch möchte ich dazu beitragen, etwas Licht ins Dunkel zu bringen. Darin finden sich Rezepte mit praktischen Tipps für die Verwendung von TLS/SSL-Verschlüsselung mittels OpenSSL, HTTP Strict Transport Security (HSTS) und HTTP Public Key Pinning (HPKP).

Aus dem Inhalt

Nach der Einleitung führt Kapitel 2 in das Thema ein und definiert die wesentlichen Begriffe. Es bildet die Grundlage für das Verständnis der daran anschießenden Kapitel.

In Kapitel 3 geht es um die Implementierung von TLS/SSL. Hier werden verschiedene Methoden zur Generierung von privaten Schlüsseln und Certificate Signing Requests vorgestellt. Darüber hinaus werden einige Zertifizierungsstellen kurz vorgestellt, bei denen Zertifikate beantragt werden können. Im Folgenden wird auf die Implementierung von TLS/SSL-Zertifikaten in verschiedenen Diensten eingegangen. Hier wird insbesondere die Implementierung von Zertifikaten der recht jungen Zertifizierungsstelle „Let’s Encrypt“ erläutert, mit deren Hilfe sich der Prozess der Zertifikatserneuerung automatisieren lässt.

Der Implementierung des HTTP Public Key Pinning (HPKP) widmet sich Kapitel 4. Das Pinning-Verfahren wird am Beispiel des Webservers NGINX erläutert und getestet.

Zum Schluss werden die in den einzelnen Kapiteln vorgestellten Techniken und Methoden nochmals zusammenfassend an einem konkreten Beispiel in Kapitel 5 verdeutlicht.

Hier geht es zum Text

Mir persönlich hat die Arbeit an folgendem Dokument geholfen, mich detailliert mit der Thematik auseinanderzusetzen und mein Wissen zu erweitern und zu vertiefen. Ich freue mich, wenn mein Kochbuch auch euch dabei hilft, ein besseres Verständnis für das Thema zu entwickeln.

Dies ist die erste Ausgabe meines TLS/SSL-Kochbuchs und es gibt sicher noch viel mehr, was man zu diesem Thema schreiben kann. Fehler sowie Wünsche zum Inhalt zukünftiger Ausgaben können gern an die E-Mail-Adresse tls-rezepte(aet)my-it-brain(Punkt)de gemeldet werden.

Downloads zum Text

Ansible – Die Module copy und cron

In diesem Beitrag zu meiner kleinen Ansible-Reihe beschäftige ich mich mit den Modulen copy[1. Ansible: copy – Copies files to remote locations] und cron[2. Ansible: cron – Manage cron.d and crontab entries].

Hinweis: Die folgende Konfiguration ist nicht zur Nachahmung empfohlen. Es handelt sich dabei um meine ersten Schritte mit Ansible. Es ist daher wahrscheinlich, dass die Konfiguration noch Fehler enthält, nicht optimiert ist und ein großes Verbesserungspotenzial besitzt. Die Nachahmung erfolgt ausdrücklich auf eigene Gefahr. Über Hinweise, wie man es besser machen kann, freue ich mich jederzeit.

Anforderungen

In diesem Szenario sollen Shell-Skripte auf das Zielsystem kopiert werden. Anschließend sind Einträge in der crontab zu erstellen, um diese Shell-Skripte auszuführen. Beim Zielsystem handelt es sich um die Gruppe [i-stage], in der sich aktuell nur ein Host namens host-i1.example.com befindet.

Vorbereitungen

Die zu verteilenden Skripte werden auf der Ansible-Control-Machine im Verzeichnis /root/src/ gesammelt. Anschließend wurde eine Rolle für dieses Vorhaben erstellt. Die auf meiner Spielwiese verwendete Verzeichnisstruktur wurde bereits in den vergangenen Beiträgen[3. Linux-Benutzerkonten mit Ansible verwalten] zu dieser Reihe beschrieben.

Umsetzung

Zur Umsetzung der Anforderungen wird ein Playbook erstellt, welches die geforderten Tasks ausführt. Der folgende Code-Block listet die benötigten Dateien inkl. ihres kommentierten Inhalts auf:

# Begin of file: local_scripts_i-stage.yml
---
- hosts: i-stage
  roles:
    - local_scripts
# End of file ############################

# Begin of file: roles/local_scripts/tasks/main.yml
---
## Copy local script files to target hosts
- copy: src=/root/src/sript1.sh dest=/root/src/sript1.sh owner=root group=root mode=755
- copy: src=/root/src/sript2.sh dest=/root/src/sript2.sh owner=root group=root mode=755

## Create cron jobs for local script files
- cron: name="local script1" minute="10" hour="1" job="/root/src/sript1.sh"
- cron: name="local script2" minute="12" hour="1" job="/root/src/sript2.sh"
# End of file #############################

Nach der Ausführung des Playbooks liegen die Skripte auf dem oder den Zielsystemen im gewünschten Verzeichnis /root/bin/. Lässt man sich die Crontab des Benutzers root anzeigen, so erkennt man die von Ansible hinzugefügten Einträge:

# crontab -l
# DO NOT EDIT THIS FILE - edit the master and reinstall.
# (/tmp/crontabaf5r8i installed on Mon Jul 18 11:52:09 2016)
# (Cronie version 4.2)
#Ansible: local script1
10 1 * * * /root/bin/script1.sh
#Ansible: local script2
12 1 * * * /root/bin/script2.sh

Fazit

Wieder konnte eine Anforderung schnell und einfach mit Ansible umgesetzt werden. Ob dies bereits der Königsweg ist bzw. ob dieser überhaupt existiert, steht jedoch noch nicht fest. Anstatt die Dateien zuerst auf das Ziel zu kopieren und dort Cron-Einträge für die Ausführung zu erstellen, könnte auch das Modul script[4. Ansible: script – Runs a local script on a remote node after transferring it] genutzt werden. Dieses Modul transferiert ein lokales Skript zum Zielsystem und führt es dort aus.

Bisher habe ich mich gegen den Einsatz des script-Moduls entschieden, da mir noch nicht klar ist, ob das Skript auf dem Zielsystem verbleibt oder bei jeder Ausführung erneut übertragen wird. Letzteres wäre bei einer großen Anzahl Zielsysteme nicht unbedingt wünschenswert.

Ansible – Das Modul yum_repository

Das Ansible Modul yum_repositoryist dazu geeignet, Repositories zu RPM-basierten Linux-Distributionen hinzuzufügen bzw. zu entfernen. Es findet z.B. in unserer Umgebung Anwendung, um Repositories von unserem lokalen Spiegelserver anzubinden. Der folgende Text gibt ein Beispiel zur Anwendung dieses Ansible-Moduls.

Auf meiner Spielwiese verwende ich folgende Konfiguration, um zwei Repositories hinzuzufügen.

Hinweis: Die folgende Konfiguration ist nicht zur Nachahmung empfohlen. Es handelt sich dabei um meine ersten Schritte mit Ansible. Es ist daher wahrscheinlich, dass die Konfiguration noch Fehler enthält, nicht optimiert ist und ein großes Verbesserungspotenzial besitzt. Die Nachahmung erfolgt ausdrücklich auf eigene Gefahr. Über Hinweise, wie man es besser machen kann, freue ich mich jederzeit.

Verzeichnisstruktur

Abgeleitet aus den „Best Practices“ von Ansible, verwende ich auf meiner Spielwiese folgende Verzeichnisstruktur:

ansible/
|-- group_vars
|   `-- e-stage               # variables for group e-stage
|-- hosts                     # inventory file
|-- host_vars                 # for system specific variables
|-- roles
|   |-- common                # this hierarchy represents a "role"
|   |   |-- defaults          
|   |   |-- files
|   |   |-- handlers
|   |   |   `-- main.yml      #  handlers file
|   |   |-- meta
|   |   |-- tasks
|   |   |   `-- main.yml      #  tasks file can include smaller files if wanted
|   |   `-- vars
|   `-- std-repos
|       |-- defaults
|       |-- files
|       |-- handlers
|       |-- meta
|       |-- tasks
|       |-- templates
|       `-- vars
|-- set_repos.yml             # playbook which sets the repos
|-- site.yml                  # master playbook file
`-- staging                   # inventory file for staging environment

Das Playbook

Das Playbook ist sehr kurz gehalten und gibt im Wesentlichen nur an, welche Hosts auf welche Rolle gemapped werden sollen.

# set_repos.yml
---
- hosts: all
  roles:
    - std-repos

Das obige Playbook definiert, dass die Tasks aus der Datei roles/e-stage/tasks/main.yml ausgeführt werden sollen, welche wie folgt aufgebaut ist:

---
- name: Add rhel-e-stage-repository
  yum_repository:
    name: "{{ repo_name1 }}"
    description: "{{ repo_description1 }}"
    baseurl: "{{ repo_baseurl1 }}"
    gpgcheck: yes
    gpgkey: file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release

- name: Add my-own-repository
  yum_repository:
    name: "{{ repo_name2 }}"
    description: "{{ repo_description2 }}"
    baseurl: "{{ rebo_baseurl2 }}"
    gpgcheck: no

GroupVars

Nun existieren im Staging-Bereich häufig noch weitere Stages. So gibt es oftmals eine T-, E- und I-Stage. Dabei ist jeder Stage ein eigenes Stage-Repository zugeordnet. Um die Systeme in den unterschiedlichen Stages mit den dazugehörigen Stage-Repositories zu versorgen, werden diese mit Hilfe der group_vars den entsprechenden Gruppen zugewiesen.

Für die Server der Gruppe e-stage wird in der Datei group_vars/e-stage definiert:

# file: group_vars/e-stage
repo_name1: rhel-e-stage
repo_description1: Local RHEL-Repo for E-Stage
repo_baseurl1: http://repo.example.com/rhel-e-stage/

repo_name2: own-e-stage
repo_description2: Local OWN-Repo for E-Stage
repo_baseurl2: http://repo.example.com/own-e-stage/

Nach diesem Beispiel können nun weitere Variablen unter group_vars für andere Stages erstellt werden. Den Hosts in den entsprechenden Hostgruppen, werden auf diesem Wege die passenden Repositories hinzugefügt.

Linux-Benutzerkonten mit Ansible verwalten

Wie bereits in diesem Beitrag erwähnt, beschäftige ich mich aktuell mit der Evaluierung von Ansible.

In diesem Artikel dokumentiere ich ein Beispiel, wie das Modul user zur Administration von Linux-Benutzerkonten verwendet werden kann. Der Link zur offiziellen Dokumentation des user-Moduls befindet sich am Ende dieses Artikels.[1. Ansible Module: user – Manage user accounts {en}]

Hinweis: Die folgende Konfiguration ist nicht zur Nachahmung empfohlen. Es handelt sich dabei um meine ersten Schritte mit Ansible. Es ist daher wahrscheinlich, dass die Konfiguration noch Fehler enthält, nicht optimiert ist und ein großes Verbesserungspotenzial besitzt. Die Nachahmung erfolgt ausdrücklich auf eigene Gefahr. Über Hinweise, wie man es besser machen kann, freue ich mich jederzeit.

Anforderungen

  • Es soll ein lokales Benutzerkonto angelegt werden
  • Der Benutzer soll Mitglied der Gruppe „wheel“ werden
  • Es soll ein initiales Passwort für das Benutzerkonto gesetzt werden
  • Ein öffentlicher SSH-Schlüssel soll in die Datei authorized_keys des zu erstellenden Benutzers eingetragen werden
  • Konfiguration des SSH-Daemons

Vorbereitung

Abgeleitet aus den „Best Practices“[2. Ansible Best Practices – Directory Layout] verwende ich auf meiner Spielwiese folgende Verzeichnisstruktur:

ansible/
|-- autoupdate.txt            # ignore
|-- autoupdate.yml            # ignore
|-- check_reboot.             # playbook which sets the repos
|-- group_vars
|   `-- e-stage               # variables for group e-stage
|-- hosts                     # inventory file
|-- host_vars                 # for system specific variables
|-- roles
|   |-- common                # this hierarchy represents a "role"
|   |   |-- defaults          
|   |   |-- files
|   |   |-- handlers
|   |   |   `-- main.yml      # handlers file
|   |   |-- meta
|   |   |-- tasks
|   |   |   `-- main.yml      # tasks file can include smaller files if warranted
|   |   `-- vars
|   `-- e-stage
|       |-- defaults
|       |-- files
|       |-- handlers
|       |-- meta
|       |-- templates
|       `-- vars
|-- create_johnd.yml          # playbook which creates user johnd
|-- site.yml                  # master playbook file
`-- staging                   # inventory file for staging environment

17 directories, 11 files

Um das Passwort für den neuen Benutzer erstellen zu können, muss zuerst der passende Passwort-Hash generiert werden[3. How do I generate crypted passwords for the user module?]:

python -c "from passlib.hash import sha512_crypt; import getpass; print sha512_crypt.encrypt(getpass.getpass())"

Der generierte Hash wird auf der Standardausgabe ausgegeben. Dieser wird für das Playbook benötigt.

Playbook und Tasks

Das Playbook ist sehr kurz gehalten und gibt im Wesentlichen nur an, welche Hosts auf welche Rolle gemapped werden sollen.

# create_johnd.yml
---
- hosts: all
  roles:
    - common

Bei Verwendung dieses Playbooks werden die Tasks aus der Datei roles/common/tasks/main.yml ausgeführt, welche wie folgt aufgebaut wurde:

---
# Configure sshd_config on target system
- name: Enable Public-Key-Authentication
  lineinfile:
    dest: /etc/ssh/sshd_config
    regexp: "^PubkeyAuthentication"
    line: "PubkeyAuthentication yes"
    state: present
  notify:
    - reload sshd

- name: Set AuthorizedKeyFile
  lineinfile:
    dest: /etc/ssh/sshd_config
    regexp: "^AuthorizedKeysFile"
    line: "AuthorizedKeysFile      .ssh/authorized_keys"
    state: present
  notify:
    - reload sshd

- name: Disable PasswordAuthentication
  lineinfile:
    dest: /etc/ssh/sshd_config
    regexp: "^PasswordAuthentication"
    line: "PasswordAuthentication no"
    state: present
  notify:
    - reload sshd

# Add user johnd with specific uid in group 'wheel'
- user: name=johnd comment="John Doe" uid=100 groups=wheel password="PASSWORDHASH" shell=/bin/bash append=yes state=present
  notify:
    - deploy ssh-pub-keys

Die hier spezifizierten Tasks setzen die folgenden Aufgaben um:

  • Aktivierung der Public-Key-Authentication
  • Spezifikation des Standard-AuthorizedKeysFile
  • Deaktivierung der Password-Authentication

Was in dieser Datei noch nicht zu sehen ist, ist die Verteilung eines öffentlichen SSH-Schlüssels. Dies wird von dem Handler[4. Ansible Handlers – Running Operations On Change] deploy ssh-pub-keys übernommen.

Der Handler ist in der Datei roles/common/handlers/main.yml definiert. Es handelt sich dabei um einen Task, welcher nur ausgeführt wird, wenn der Benutzer erfolgreich erstellt wurde.

Fazit

Soweit zu meinen ersten Gehversuchen mit Ansible Playbooks. Meine Anforderungen können mit dem hier dokumentierten Playbook erfüllt werden.

In dem hier beschriebenen Beispiel habe ich angenommen, dass es sich bei dem zu erstellenden Benutzer um das erste lokale Benutzerkonto neben root handelt. Dieses soll über die Berechtigung verfügen, Kommandos mit sudo auszuführen und primär für die Arbeit auf dem System verwendet werden.

Die Verteilung des SSH-Schlüssels über einen Handler anzustoßen erscheint mir jedoch nicht optimal. Der Handler wird nur dann ausgeführt, wenn durch das user-Modul Änderungen am Zielsystem vorgenommen wurden. Weitere SSH-Schlüssel bzw. Änderungen an bereits vorhandenen SSH-Schlüsseln lassen sich auf diesem Weg nicht vornehmen.

Daher erscheint es mir sinnvoll, die Verteilung von SSH-Schlüsseln über das Modul authorized_key[5. Ansible Module: authorized_key – Adds or removes an SSH authorized key] in ein eigenes Playbook auszulagern.

Ansible – IT-Automation für Jedermann

Ansible[1. Ansible Homepage {en}] ist eine Open-Source-Plattform zur Orchestrierung und allgemeinen Konfiguration und Administration von Computern.[2. Ansible – Wikipedia] Ansible soll dabei helfen, Konfigurationsprozesse zu automatisieren und die Administration multipler Systeme zu vereinfachen. Damit verfolgt Ansible im Wesentlichen die gleichen Ziele wie z.B. Puppet[3. Puppet – Wikipedia], Chef[4. Chef – Wikipedia {en}] und Salt[5. Salt – Wikipedia {en}].

Ansible hat gegenüber den genannten Systemen das Alleinstellungsmerkmal, dass auf den verwalteten Rechnern kein Agent installiert werden muss. Der Zugriff erfolgt ausschließlich über das SSH-Protokoll. Dies ist ein Vorteil, da bei der Einführung von Ansible SSH-Key-Authentifizierungsverfahren genutzt werden können, die häufig schon existieren. Ein weiterer Vorteil ergibt sich in dem Fall, wenn man Ansible nicht mehr nutzen möchte. Es bleiben keine Softwarekomponenten auf den verwalteten Rechnern zurück, die wieder deinstalliert werden müssen.

Mir gefällt auf den ersten Blick, dass mir die Lösung zwei Wege bietet, um meine Systeme zu konfigurieren. Zum einen kann ich Playbooks[6. Ansible – Playbooks {en}] nutzen, welche gewissermaßen das Pendant der Puppet Manifeste darstellen. Zum anderen existiert ein Ad-hoc-Modus, welcher es erlaubt, die Konfiguration von Zielsystemen bei Bedarf anzupassen, ohne zuvor ein Rezept bzw. Playbook erstellt zu haben.

Die Playbooks selbst werden in YAML[7. YAML – Wikipedia]-Syntax verfasst. Dadurch wird eine gute Lesbarkeit sichergestellt. Zudem ist die Syntax recht einfach gehalten und daher schnell zu erlernen.

Für häufige Anwendungsfälle wie z.B. das Anlegen eines Benutzers, die Verteilung von SSH-Keys, die Installation verfügbarer Updates/Patches und noch vieles mehr, bringt Ansible vorgefertigte Module mit. Diese können direkt auf den Zielsystemen oder durch die Verwendung von Playbooks ausgeführt werden.[8. About Modules – Ansible {en}]

Die oben genannten Aspekte motivieren mich, zu evaluieren, ob Ansible für den Einsatz in meinem beruflichen Umfeld geeignet ist. In diesem Blog werden in unregelmäßigen Abständen weitere Artikel erscheinen, in denen ich Erkenntnisse aus meiner Evaluierung festhalte und einige kurze Beispiele zur Nutzung konkreter Module wiedergebe.

Wer dieser Reihe folgt und sich gern mit seinen Erfahrungen einbringen möchte, darf dies gerne tun. Ich freue mich jederzeit über Kommentare, Ideen und Anregungen.

Update vom 17.12.2016: Ich habe die Ansible-Artikel in diesem Blog in einer PDF-Datei zusammengefasst. Die Datei gibt es hier: Ansible-Kochbuch (PDF)