One place for hosting & domains

      Einrichten

      Einrichten eines Node-Projekts mit TypeScript


      Einführung

      Node ist eine Laufzeitumgebung, die es ermöglicht, serverseitiges JavaScript zu schreiben. Seit ihrer Veröffentlichung im Jahr 2011 hat sie eine weite Verbreitung gefunden. Das Schreiben von serverseitigem JavaScript kann eine Herausforderung sein, da die Codebasis aufgrund der Art der JavaScript-Sprache – dynamisch und schwach typisiert – wächst.

      Entwickler, die aus anderen Sprachen zu JavaScript kommen, beklagen sich oft über den Mangel an starker statischer Typisierung, aber genau hier kommt TypeScript ins Spiel, um diese Lücke zu schließen.

      TypeScript ist eine typisierte (optionale) Obermenge von JavaScript, die bei der Erstellung und Verwaltung großer JavaScript-Projekte helfen kann. Man kann es sich als JavaScript mit zusätzlichen Funktionen wie starker statischer Typisierung, Kompilierung und objektorientierter Programmierung vorstellen.

      Anmerkung: TypeScript ist technisch gesehen eine Obermenge von JavaScript, wobei der gesamte JavaScript-Code gültiger TypeScript-Code ist.

      Hier sind einige Vorteile der Verwendung von TypeScript:

      1. Optionale statische Typisierung.
      2. Typinferenz.
      3. Fähigkeit zur Verwendung von Schnittstellen.

      In diesem Tutorial richten Sie ein Node-Projekt mit TypeScript ein. Sie werden eine Express-Anwendung mit TypeScript erstellen und diese in einen sauberen und zuverlässigen JavaScript-Code transpilieren.

      Voraussetzungen

      Bevor Sie mit diesem Leitfaden beginnen, muss Node.js auf Ihrem Computer installiert sein. Sie können dies erreichen, indem Sie dem Leitfaden Installieren von Node.js und Erstellen einer lokalen Entwicklungsumgebung für Ihr Betriebssystem folgen.

      Schritt 1 — Initialisieren eines npm-Projekts

      Erstellen Sie zunächst einen neuen Ordner namens node_project und wechseln Sie in dieses Verzeichnis.

      • mkdir node_project
      • cd node_project

      Initialisieren Sie es als npm-Projekt:

      Nach der Ausführung von npm init müssen Sie npm Informationen über Ihr Projekt bereitstellen. Wenn Sie es vorziehen, npm sinnvolle Standardeinstellungen annehmen zu lassen, können Sie das Flag y hinzufügen, um die Eingabeaufforderungen für zusätzliche Informationen zu überspringen:

      Nachdem Ihr Projektraum nun eingerichtet ist, können Sie mit der Installation der erforderlichen Abhängigkeiten fortfahren.

      Schritt 2 — Installieren der Abhängigkeiten

      Wenn ein blankes npm-Projekt initialisiert wurde, besteht der nächste Schritt darin, die Abhängigkeiten zu installieren, die zur Ausführung von TypeScript erforderlich sind.

      Führen Sie die folgenden Befehle aus Ihrem Projektverzeichnis aus, um die Abhängigkeiten zu installieren:

      • npm install -D typescript@3.3.3
      • npm install -D tslint@5.12.1

      Das Flag -D ist die Kurzform für: -save-dev. In der Dokumentation zu npmjs können Sie mehr über dieses Flag erfahren.

      Jetzt ist es an der Zeit, das Express-Framework zu installieren:

      • npm install -S express@4.16.4
      • npm install -D @types/express@4.16.1

      Der zweite Befehl installiert die Express-Typen für die TypeScript-Unterstützung. Typen in TypeScript sind Dateien, normalerweise mit einer Erweiterung von .d.ts. Die Dateien werden verwendet, um Typinformationen über eine API, in diesem Fall das Express-Framework, bereitzustellen.

      Dieses Paket ist erforderlich, da TypeScript und Express unabhängige Pakete sind. Ohne das Paket @types/express gibt es für TypeScript keine Möglichkeit, Informationen über die Typen von Express-Klassen zu erhalten.

      Schritt 3 — Konfigurieren von TypeScript

      In diesem Abschnitt richten Sie TypeScript ein und konfigurieren Linting für TypeScript. TypeScript verwendet eine Datei namens tsconfig.json, um die Compiler-Optionen für ein Projekt zu konfigurieren. Erstellen Sie eine Datei tsconfig.json im Stammverzeichnis des Projektverzeichnisses und fügen Sie das folgende Snippet ein:

      tsconfig.json

      {
        "compilerOptions": {
          "module": "commonjs",
          "esModuleInterop": true,
          "target": "es6",
          "moduleResolution": "node",
          "sourceMap": true,
          "outDir": "dist"
        },
        "lib": ["es2015"]
      }
      

      Sehen wir uns einige der Schlüssel im obigen JSON-Snippet an:

      • module: Gibt die Methode zur Erzeugung des Modulcodes an. Node verwendet commonjs.
      • target: Gibt das Ausgabe-Sprachniveau an.
      • moduleResolution: Dies hilft dem Compiler herauszufinden, worauf sich ein Import bezieht. Der Wert node imitiert den Mechanismus zur Auflösung des Node-Moduls.
      • outDir: Dies ist der Speicherort für die Ausgabe von .js-Dateien nach der Transpilation. In diesem Tutorial speichern Sie sie als dist.

      Eine Alternative zur manuellen Erstellung und Population der Datei tsconfig.json ist die Ausführung des folgenden Befehls:

      Dieser Befehl generiert eine gut kommentierte tsconfig.json-Datei.

      Um mehr über die verfügbaren Schlüsselwertoptionen zu erfahren, bietet die offizielle TypeScript-Dokumentation Erklärungen zu jeder Option.

      Jetzt können Sie TypeScript-Linting für das Projekt konfigurieren. Führen Sie den folgenden Befehl in einem Terminal im Stammverzeichnis Ihres Projektverzeichnisses aus, das in diesem Tutorial als node_project eingerichtet wurde, um eine tslint.json-Datei zu erzeugen:

      • ./node_modules/.bin/tslint --init

      Öffnen Sie die neu erzeugte tslint.json-Datei und fügen Sie die Regel no-console entsprechend hinzu:

      tslint.json

      {
        "defaultSeverity": "error",
        "extends": ["tslint:recommended"],
        "jsRules": {},
        "rules": {
          "no-console": false
        },
        "rulesDirectory": []
      }
      

      Standardmäßig verhindert der TypeScript-Linter die Verwendung von Debugging mittels der Anweisungen console, weshalb der Linter explizit angewiesen werden muss, die standardmäßige Regel no-console zu widerrufen.

      Schritt 4 — Aktualisieren der Datei package.json

      An diesem Punkt im Tutorial können Sie entweder Funktionen im Terminal einzeln ausführen oder ein npm-Skript erstellen, um sie auszuführen.

      In diesem Schritt erstellen Sie ein Skript start, das den TypeScript-Code kompiliert und transpiliert und dann die resultierende Anwendung .js ausführt.

      Öffnen Sie die Datei package.json und aktualisieren Sie sie entsprechend:

      package.json

      {
        "name": "node-with-ts",
        "version": "1.0.0",
        "description": "",
        "main": "dist/app.js",
        "scripts": {
          "start": "tsc && node dist/app.js",
          "test": "echo "Error: no test specified" && exit 1"
        },
        "author": "",
        "license": "ISC",
        "devDependencies": {
          "@types/express": "^4.16.1",
          "tslint": "^5.12.1",
          "typescript": "^3.3.3"
        },
        "dependencies": {
          "express": "^4.16.4"
        }
      }
      

      Im obigen Snippet haben Sie den Pfad main aktualisiert und den Befehl start dem Abschnitt scripts hinzugefügt. Wenn Sie sich den Befehl start ansehen, sehen Sie, dass zuerst der Befehl tsc ausgeführt wird, und dann der Befehl node. Dadurch wird die generierte Ausgabe mit node kompiliert und dann ausgeführt.

      Der Befehl tsc weist TypeScript an, die Anwendung zu kompilieren und die generierte Ausgabe .js im angegebenen Verzeichnis outDir zu platzieren, wie es in der Datei tsconfig.json festgelegt ist.

      Schritt 5 — Erstellen und Ausführen eines einfachen Express-Servers

      Nachdem TypeScript und dessen Linter konfiguriert sind, ist es an der Zeit, einen Node Express-Server zu erstellen.

      Erstellen Sie zunächst einen Ordner src im Stammverzeichnis Ihres Projektverzeichnisses:

      Erstellen Sie dann darin eine Datei namens app.ts:

      An diesem Punkt sollte die Ordnerstruktur wie folgt aussehen:

      ├── node_modules/
      ├── src/
        ├── app.ts
      ├── package-lock.json
      ├── package.json
      ├── tsconfig.json
      ├── tslint.json
      

      Öffnen Sie die Datei app.ts mit einem Texteditor Ihrer Wahl und fügen Sie das folgende Code-Snippet ein:

      src/app.ts

      import express from 'express';
      
      const app = express();
      const port = 3000;
      app.get('/', (req, res) => {
        res.send('The sedulous hyena ate the antelope!');
      });
      app.listen(port, err => {
        if (err) {
          return console.error(err);
        }
        return console.log(`server is listening on ${port}`);
      });
      

      Der obige Code erstellt einen Node-Server, der auf Port 3000 auf Anfragen lauscht. Führen Sie die Anwendung mit dem folgenden Befehl aus:

      Wenn sie erfolgreich ausgeführt wird, wird eine Nachricht im Terminal protokolliert:

      Output

      • server is listening on 3000

      Sie können nun http://localhost:3000 in Ihrem Browser besuchen, und Sie sollten die Nachricht sehen:

      Output

      • The sedulous hyena ate the antelope!

      Browserfenster mit der Nachricht: The sedulous hyena ate the antelope! (Die fleißige Hyäne fraß die Antilope!)

      Öffnen Sie die Datei dist/app.js und Sie finden die transpilierte Version des TypeScript-Codes:

      dist/app.js

      "use strict";
      
      var __importDefault = (this && this.__importDefault) || function (mod) {
          return (mod && mod.__esModule) ? mod : { "default": mod };
      };
      Object.defineProperty(exports, "__esModule", { value: true });
      const express_1 = __importDefault(require("express"));
      const app = express_1.default();
      const port = 3000;
      app.get('/', (req, res) => {
          res.send('The sedulous hyena ate the antelope!');
      });
      app.listen(port, err => {
          if (err) {
              return console.error(err);
          }
          return console.log(`server is listening on ${port}`);
      });
      
      //# sourceMappingURL=app.js.map
      

      An diesem Punkt haben Sie Ihr Node-Projekt erfolgreich für die Verwendung von TypeScript eingerichtet.

      Zusammenfassung

      In diesem Tutorial haben Sie erfahren, warum TypeScript nützlich ist, um zuverlässigen JavaScript-Code zu schreiben. Sie haben auch einige Vorteile der Arbeit mit TypeScript kennengelernt.

      Abschließend haben Sie ein Node-Projekt mit dem Express-Framework eingerichtet, das Projekt jedoch mit TypeScript kompiliert und ausgeführt.



      Source link

      Einrichten und Sichern eines etcd-Clusters mit Ansible unter Ubuntu 18.04


      Der Autor hat die Wikimedia Foundation dazu ausgewählt, im Rahmen des Programms Write for DOnations eine Spende zu erhalten.

      Einführung

      etcd ist ein verteilter Schlüsselwertspeicher, auf den sich viele Plattformen und Tools verlassen, darunter Kubernetes, Vulcand und Doorman. Innerhalb von Kubernetes dient etcd als globaler Konfigurationsspeicher, der den Status des Clusters speichert. Kenntnisse zur Verwaltung von etcd sind unerlässlich für die Verwaltung eines Kubernetes-Clusters. Zwar gibt es viele verwaltete Kubernetes-Produkte (auch als Kubernetes-as-a-Service bekannt), die diese Administrationsaufgaben für Sie übernehmen, doch entscheiden sich viele Unternehmen wegen der damit verbundenen Flexibilität immer noch für selbstverwaltete Kubernetes-Cluster.

      Die erste Hälfte dieses Artikels führt Sie durch die Einrichtung eines etcd-Clusters mit drei Knoten auf Ubuntu 18.04-Servern. In der zweiten Hälfte geht es um das Sichern des Clusters mit Transport Layer Security oder TLS. Um jede Einrichtung automatisiert auszuführen, verwenden wir durchgehend Ansible. Ansible ist ein Konfigurationsmanagement-Tool ähnlich wie Puppet, Chef, und SaltStack; damit können wir die einzelnen Einrichtungsschritte auf deklarative Weise definieren, und zwar in Dateien namens Playbooks.

      Am Ende dieses Tutorials verfügen Sie über einen sicheren etcd-Cluster mit drei Knoten, der auf Ihren Servern ausgeführt wird. Außerdem werden Sie über ein Ansible-Playbook verfügen, mit dem Sie die gleiche Einrichtung auf einem neuen Satz von Servern wiederholt und konsequent nachbilden können.

      Voraussetzungen

      Bevor Sie diese Anleitung beginnen, benötigen Sie Folgendes:

      • Python, pip und das auf Ihrem lokalen Computer installierte pyOpenSSL-Paket. Um zu erfahren, wie Sie Python3, pip und Python-Pakete installieren können, lesen Sie Installieren von Python 3 und Einrichten einer lokalen Programmierumgebung unter Ubuntu 18.04.

      • Drei Ubuntu 18.04-Server im gleichen lokalen Netzwerk mit mindestens 2 GB RAM und root SSH-Zugriff. Außerdem sollten Sie die Server so konfigurieren, dass sie die Hostnamen etcd1, etcd2 und etcd3 tragen. Die in diesem Artikel beschriebenen Schritte würden auf jedem generischen Server funktionieren, nicht nur bei DigitalOcean Droplets. Wenn Sie Ihre Server aber in DigitalOcean hosten möchten, können Sie dem Leitfaden Erstellen eines Droplets über das DigitalOcean Control Panel folgen, um diese Anforderung zu erfüllen. Beachten Sie, dass Sie bei der Erstellung Ihres Droplets die Option Private Networking aktivieren müssen. Um für vorhandene Droplets private Netzwerke zu aktivieren, lesen Sie Aktivieren von Private Networking in Droplets.

      Warnung: Da der Zweck dieses Artikels darin besteht, eine Einführung in das Einrichten eines etcd-Clusters in einem privaten Netzwerk zu liefern, wurden die drei Ubuntu 18.04-Server in dieser Einrichtung nicht mit einer Firewall getestet und als root user aufgerufen. In einer Produktionsumgebung würde jeder dem öffentlichen Internet ausgesetzte Knoten eine Firewall und einen Sudo-Benutzer erfordern, damit sich bewährte Sicherheitspraktiken einhalten lassen. Weitere Informationen finden Sie im Tutorial Ersteinrichtung des Servers mit Ubuntu 18.04.

      • Ein SSH-Schlüsselpaar, das Ihrem lokalen Rechner Zugriff auf die Server etcd1, etcd2 und etcd3 erlaubt. Wenn Sie nicht wissen, was SSH ist oder über kein SSH-Schlüsselpaar verfügen, können Sie hier mehr darüber erfahren: SSH Essentials: Working with SSH Servers, Clients, and Keys (SSH-Grundlagen: Arbeiten mit SSH-Servern, -Clients und -Schlüsseln).

      • Auf Ihrem lokalen Rechner installiertes Ansible. Wenn Sie beispielsweise Ubuntu 18.04 ausführen, können Sie Ansible installieren, indem Sie Schritt 1 des Artikels Installieren und Konfigurieren von Ansible unter Ubuntu 18.04 befolgen. Dadurch werden die Befehle ansible und ansible-playbook auf Ihrem Computer verfügbar. Vielleicht möchten Sie auch How to Use Ansible: A Reference Guide (Verwenden von Ansible: Ein Referenzhandbuch) parat halten. Die Befehle in diesem Tutorial sollten mit Ansible v2.x funktionieren; wir haben sie in Ansible v2.9.7 unter Ausführung von Python v3.8.2 getestet.

      Schritt 1 — Konfigurieren von Ansible für den Steuerknoten

      Ansible ist ein Tool, das zum Verwalten von Servern dient. Die Server, die Ansible verwaltet, werden verwaltete Knoten genannt. Das Gerät, auf dem Ansible ausgeführt wird, wird als Steuerknoten bezeichnet. Ansible arbeitet mit SSH-Schlüsseln im Steuerknoten, um Zugriff auf die verwalteten Knoten zu erhalten. Sobald eine SSH-Sitzung eingerichtet ist, führt Ansible eine Reihe von Skripten aus, um die verwalteten Knoten bereitzustellen und zu konfigurieren. In diesem Schritt testen wir, ob wir Ansible zur Verbindungsherstellung mit den verwalteten Knoten verwenden und den Befehl hostname ausführen können.

      Ein typischer Tag für einen Systemadministrator kann das Verwalten verschiedener Sätze von Knoten beinhalten. Beispielsweise können Sie Ansible verwenden, um neue Server bereitzustellen; später aber verwenden Sie es, um einen anderen Satz von Servern neu zu konfigurieren. Um Administratoren eine bessere Organisation des Satzes von verwalteten Knoten zu ermöglichen, verfügt Ansible über das Konzept des Hostinventars (oder kurz Inventar). Sie können jeden Knoten, den Sie mit Ansible verwalten möchten, in einer Inventardatei definieren und in Gruppen anordnen. Wenn Sie dann die Befehle ansible und ansible-playbook ausführen, können Sie angeben, für welche Hosts oder Gruppen der Befehl gelten soll.

      Standardmäßig liest Ansible die Inventardatei von /etc/ansible/hosts; wir können jedoch eine andere Inventardatei angeben, indem wir das Flag --inventory (oder kurz -i) verwenden.

      Erstellen Sie zunächst ein neues Verzeichnis auf Ihrem lokalen Rechner (dem Steuerknoten), in dem alle Dateien für dieses Tutorial installiert werden:

      • mkdir -p $HOME/playground/etcd-ansible

      Rufen Sie dann das gerade erstellte Verzeichnis auf:

      • cd $HOME/playground/etcd-ansible

      Erstellen und öffnen Sie im Verzeichnis mit Ihrem Editor eine leere Inventardatei namens hosts:

      • nano $HOME/playground/etcd-ansible/hosts

      Listen Sie in der Datei hosts alle Ihre verwalteten Knoten im folgenden Format auf und ersetzen Sie die markierten öffentlichen IP-Adressen durch die wahren öffentlichen IP-Adressen Ihrer Server:

      ~/playground/etcd-ansible/hosts

      [etcd]
      etcd1 ansible_host=etcd1_public_ip  ansible_user=root
      etcd2 ansible_host=etcd2_public_ip  ansible_user=root
      etcd3 ansible_host=etcd3_public_ip  ansible_user=root
      

      Die Zeile [etcd] definiert eine Gruppe namens etcd. Unter der Gruppendefinition listen wir alle unsere verwalteten Knoten auf. Jede Zeile beginnt mit einem Alias (z. B. etcd1), mit dem wir unter Verwendung eines leicht zu merkenden Namens anstelle einer langen IP-Adresse auf jeden einzelnen Host verweisen können. Die Variablen ansible_host und ansible_user sind Ansible-Variablen. In diesem Fall dienen sie zur Bereitstellung von Ansible mit den öffentlichen IP-Adressen und SSH-Benutzernamen, die beim Herstellen einer Verbindung über SSH verwendet werden.

      Um zu prüfen, ob Ansible eine Verbindung mit unseren verwalteten Knoten herstellen kann, testen wir mithilfe von Ansible durch Ausführung des Befehls hostname auf den einzelnen Hosts in der Gruppe etcd die Konnektivität:

      • ansible etcd -i hosts -m command -a hostname

      Lassen Sie uns diesen Befehl genauer ansehen, um zu erfahren, was die einzelnen Teile bedeuten:

      • etcd: gibt das Hostmuster an, mit dem ermittelt wird, welche Hosts aus dem Inventar mit diesem Befehl verwaltet werden. Hier verwenden wir den Gruppennamen als Hostmuster.
      • -i hosts: gibt die zu verwendende Inventardatei an.
      • -m command: Die Funktionalität hinter Ansible wird von Modulen bereitgestellt. Das command-Modul nimmt das übergebene Argument und führt es als Befehl auf den einzelnen verwalteten Knoten aus. Im Verlauf dieses Tutorials werden noch einige weitere Ansible-Module eingeführt.
      • -a hostname: das Argument, das an das Modul übergeben wird. Die Zahl und Arten von Argumenten hängen vom Modul ab.

      Nach Ausführung des Befehls sehen Sie die folgende Ausgabe, was bedeutet, dass Ansible richtig konfiguriert wurde:

      Output

      etcd2 | CHANGED | rc=0 >> etcd2 etcd3 | CHANGED | rc=0 >> etcd3 etcd1 | CHANGED | rc=0 >> etcd1

      Jeder Befehl, den Ansible ausführt, wird als Aufgabe bezeichnet. Die Verwendung von ansible in der Befehlszeile zum Ausführen von Aufgaben wird Ausführung von ad-hoc-Befehlen genannt. Der Vorteil von Ad-hoc-Befehlen besteht darin, dass sie schnell sind und wenig Einrichtung benötigen; der Nachteil ist, dass sie manuell ausgeführt werden und sich somit nicht für ein Versionskontrollsystem wie Git verwenden lassen.

      Eine kleine Verbesserung wäre es, ein Shell-Skript zu schreiben und unsere Befehle mit dem script-Modul von Ansible auszuführen. So könnten wir die Konfigurationsschritte, die wir ergriffen haben, in die Versionskontrolle aufnehmen. Allerdings sind Shell-Skripte imperativ. Das bedeutet, dass wir die auszuführenden Befehle (die „wie“s) ermitteln müssen, um das System mit Blick auf den gewünschten Zustand zu konfigurieren. Ansible hingegen setzt auf einen deklarativen Ansatz, bei dem wir definieren, „was“ der gewünschte Zustand unseres Servers in Konfigurationsdateien sein sollte. Ansible ist dafür verantwortlich, den Server in den gewünschten Zustand zu bringen.

      Der deklarative Ansatz wird bevorzugt, da die Absicht der Konfigurationsdatei sofort übermittelt wird, was bedeutet, dass er leichter zu verstehen und zu verwalten ist. Außerdem wird dabei die Verantwortung für die Bearbeitung von Edge-Fällen vom Administrator auf Ansible übertragen, was uns eine Menge Arbeit spart.

      Nachdem Sie nun den Ansible-Steuerknoten zur Kommunikation mit den verwalteten Knoten konfiguriert haben, stellen wir Ihnen im nächsten Schritt Ansible-Playbooks vor, mit denen Sie Aufgaben deklarativ angeben können.

      Schritt 2 — Abrufen der Hostnamen von verwalteten Knoten mit Ansible Playbooks

      In diesem Schritt werden wir replizieren, was wir in Schritt 1 getan haben: das Ausdrucken der Hostnamen der verwalteten Knoten. Anstatt Ad-hoc-Aufgaben auszuführen, werden wir die einzelnen Aufgaben jedoch deklarativ als Ansible-Playbook definieren und ausführen. Ziel dieses Schritt ist es, zu zeigen, wie Ansible Playbooks funktionieren. Wir werden mit Playbooks in späteren Schritten noch deutlich umfangreichere Aufgaben ausführen.

      Erstellen Sie in Ihrem Projektverzeichnis mit Ihrem Editor eine neue Datei namens playbook.yaml:

      • nano $HOME/playground/etcd-ansible/playbook.yaml

      Fügen Sie in playbook.yaml die folgenden Zeilen hinzu:

      ~/playground/etcd-ansible/playbook.yaml

      - hosts: etcd
        tasks:
          - name: "Retrieve hostname"
            command: hostname
            register: output
          - name: "Print hostname"
            debug: var=output.stdout_lines
      

      Schließen und speichern Sie die Datei playbook.yaml, indem Sie Strg+X drücken, gefolgt von J.

      Das Playbook enthält eine Liste von Plays; jedes Play enthält eine Liste von Aufgaben, die auf allen Hosts ausgeführt werden sollen, die mit dem vom Schlüssel hosts angegebenen Hostmuster übereinstimmen. In diesem Playbook verfügen wir über ein Play, das zwei Aufgaben enthält. Die erste Aufgabe führt den Befehl hostname mit dem command-Modul aus und registriert die Ausgabe in einer Variable namens output. In der zweiten Aufgabe verwenden wir das debug-Modul, um die Eigenschaft stdout_lines der output-Variablen auszugeben.

      Wir können dieses Playbook nun mit dem Befehl ansible-playbook ausführen:

      • ansible-playbook -i hosts playbook.yaml

      Sie erhalten die folgende Ausgabe, was bedeutet, dass Ihr Playbook ordnungsgemäß funktioniert:

      Output

      PLAY [etcd] *********************************************************************************************************************** TASK [Gathering Facts] ************************************************************************************************************ ok: [etcd2] ok: [etcd3] ok: [etcd1] TASK [Retrieve hostname] ********************************************************************************************************** changed: [etcd2] changed: [etcd3] changed: [etcd1] TASK [Print hostname] ************************************************************************************************************* ok: [etcd1] => { "output.stdout_lines": [ "etcd1" ] } ok: [etcd2] => { "output.stdout_lines": [ "etcd2" ] } ok: [etcd3] => { "output.stdout_lines": [ "etcd3" ] } PLAY RECAP ************************************************************************************************************************ etcd1 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 etcd2 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 etcd3 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

      Anmerkung: ansible-playbook verwendet zum Teil cowsay als verspielte Methode zur Ausgabe der Überschriften. Wenn Sie in Ihrem Terminal viele ASCII-artige Kühe sehen, wissen Sie jetzt warum. Um diese Funktion zu deaktivieren, setzen Sie die Umgebungsvariable ANSIBLE_NOCOWS vor dem Ausführen von ansible-playbook auf 1, indem Sie in Ihrer Shell export ANSIBLE_NOCOWS=1 ausführen.

      In diesem Schritt sind wir von der Ausführung von imperativen Ad-hoc-Aufgaben zum Ausführen von deklarativen Playbooks übergegangen. Im nächsten Schritt ersetzen wir diese beiden Vorführaufgaben durch Aufgaben, die für die Einrichtung unseres etcd-Clusters sorgen werden.

      Schritt 3 — Installieren von etcd in den verwalteten Knoten

      In diesem Schritt zeigen wir Ihnen die Befehle zur manuellen Installation von etcd und demonstrieren, wie Sie die gleichen Befehle in unserem Ansible-Playbook in Aufgaben übersetzen können.

      etcd und dessen Client etcdctl sind als Binärdateien verfügbar, die wir herunterladen, extrahieren und in einem Verzeichnis platzieren werden, das Teil der PATH-Umgebungsvariablen ist. Bei manueller Konfiguration sind dies die Schritte, die wir auf jedem der verwalteten Knoten ausführen würden:

      • mkdir -p /opt/etcd/bin
      • cd /opt/etcd/bin
      • wget -qO- https://storage.googleapis.com/etcd/v3.3.13/etcd-v3.3.13-linux-amd64.tar.gz | tar --extract --gzip --strip-components=1
      • echo 'export PATH="$PATH:/opt/etcd/bin"' >> ~/.profile
      • echo 'export ETCDCTL_API=3" >> ~/.profile

      Die ersten vier Befehle sorgen dafür, dass die Binärdateien heruntergeladen und im Verzeichnis /opt/etcd/bin/ extrahiert werden. Standardmäßig nutzt der etcdctl-Client API v2 zur Kommunikation mit dem etcd-Server. Da wir etcd v3.x ausführen, setzt der letzte Befehl die Umgebungsvariable ETCDCTL_API auf 3.

      Anmerkung: Hier verwenden wir etcd v3.3.13, was für Rechner mit Prozessoren entwickelt wurde, die das AMD64-Anweisungsset verwenden. Auf der offiziellen GitHub Release-Seite finden Sie Binärdateien für andere Systeme und Versionen.

      Um die gleichen Schritte in einer standardisierten Form zu replizieren, können wir unserem Playbook Aufgaben hinzufügen. Öffnen Sie die Playbook-Datei playbook.yaml in Ihrem Editor:

      • nano $HOME/playground/etcd-ansible/playbook.yaml

      Ersetzen Sie die gesamte Datei playbook.yaml durch folgende Inhalte:

      ~/playground/etcd-ansible/playbook.yaml

      - hosts: etcd
        become: True
        tasks:
          - name: "Create directory for etcd binaries"
            file:
              path: /opt/etcd/bin
              state: directory
              owner: root
              group: root
              mode: 0700
          - name: "Download the tarball into the /tmp directory"
            get_url:
              url: https://storage.googleapis.com/etcd/v3.3.13/etcd-v3.3.13-linux-amd64.tar.gz
              dest: /tmp/etcd.tar.gz
              owner: root
              group: root
              mode: 0600
              force: True
          - name: "Extract the contents of the tarball"
            unarchive:
              src: /tmp/etcd.tar.gz
              dest: /opt/etcd/bin/
              owner: root
              group: root
              mode: 0600
              extra_opts:
                - --strip-components=1
              decrypt: True
              remote_src: True
          - name: "Set permissions for etcd"
            file:
              path: /opt/etcd/bin/etcd
              state: file
              owner: root
              group: root
              mode: 0700
          - name: "Set permissions for etcdctl"
            file:
              path: /opt/etcd/bin/etcdctl
              state: file
              owner: root
              group: root
              mode: 0700
          - name: "Add /opt/etcd/bin/ to the $PATH environment variable"
            lineinfile:
              path: /etc/profile
              line: export PATH="$PATH:/opt/etcd/bin"
              state: present
              create: True
              insertafter: EOF
          - name: "Set the ETCDCTL_API environment variable to 3"
            lineinfile:
              path: /etc/profile
              line: export ETCDCTL_API=3
              state: present
              create: True
              insertafter: EOF
      

      Jede Aufgabe nutzt ein Modul; für diesen Satz von Aufgaben verwenden wir folgende Module:

      • file: zum Erstellen des Verzeichnisses /opt/etcd/bin und zum späteren Festlegen der Dateiberechtigungen für die Binärdateien etcd und etcdctl.
      • get_url: zum Herunterladen des gzip-ten Tarball auf die verwalteten Knoten.
      • unarchive: zum Extrahieren und Entpacken der Binärdateien etcd und etcdctl aus dem gzip-ten Tarball.
      • lineinfile: zum Hinzufügen eines Eintrags in die Datei .profile.

      Um diese Änderungen anzuwenden, schließen und speichern Sie die Datei playbook.yaml, indem Sie Strg+X drücken, gefolgt von J. Führen Sie dann im Terminal den gleichen Befehl ansible-playbook erneut aus:

      • ansible-playbook -i hosts playbook.yaml

      Der Abschnitt PLAY RECAP der Ausgabe wird nur ok und changed anzeigen:

      Output

      ... PLAY RECAP ************************************************************************************************************************ etcd1 : ok=8 changed=7 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 etcd2 : ok=8 changed=7 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 etcd3 : ok=8 changed=7 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

      Um die ordnungsgemäße Installation von etcd zu prüfen, stellen Sie manuell eine SSH-Verbindung zu einem der verwalteten Knoten her und führen Sie etcd und etcdctl aus:

      etcd1_public_ip ist die öffentliche IP-Adresse des Servers namens etcd1. Sobald Sie sich SSH-Zugriff verschafft haben, führen Sie etcd --version aus, um die installierte Version von etcd auszudrucken:

      Sie werden eine Ausgabe erhalten, die in etwa der folgenden ähnelt. Das bedeutet, dass die Binärdatei etcd erfolgreich installiert wurde:

      Output

      etcd Version: 3.3.13 Git SHA: 98d3084 Go Version: go1.10.8 Go OS/Arch: linux/amd64

      Um sich zu vergewissern, dass etcdctl erfolgreich installiert wurde, führen Sie etcdctl version aus:

      Sie werden eine Ausgabe sehen, die etwa folgendermaßen aussieht:

      Output

      etcdctl version: 3.3.13 API version: 3.3

      Beachten Sie, dass die Ausgabe API version: 3.3 lautet, wodurch bestätigt wird, dass unsere Umgebungsvariable ETCDCTL_API richtig festgelegt wurde.

      Beenden Sie den etcd1-Server, um zu Ihrer lokalen Umgebung zurückzukehren.

      Wir haben etcd und etcdctl nun erfolgreich auf allen unseren verwalteten Knoten installiert. Im nächsten Schritt fügen wir unserem Play zusätzliche Aufgaben hinzu, sodass etcd als Hintergrunddienst ausgeführt wird.

      Schritt 4 — Erstellen einer Unit-Datei für etcd

      Die schnellste Methode zur Ausführung von etcd mit Ansible scheint die Verwendung des command-Moduls zur Ausführung von /opt/etcd/bin/etcd zu sein. Das funktioniert jedoch nicht, da etcd dadurch als Vordergrundprozess ausgeführt wird. Durch die Verwendung des command-Moduls wird Ansible hängenbleiben, da es auf die Rückgabe des Befehl etcd wartet, was nie geschehen wird. In diesem Schritt werden wir unser Playbook also so aktualisieren, dass stattdessen unsere Binärdatei etcd als Hintergrunddienst ausgeführt wird.

      Ubuntu 18.04 verwendet systemd als sein init-System. Das bedeutet, dass wir neue Dienste erstellen können, indem wir Unit-Dateien schreiben und im Verzeichnis /etc/systemd/system/ platzieren.

      Erstellen Sie zunächst in Ihrem Projektverzeichnis ein neues Verzeichnis namens files/:

      Erstellen Sie dann in diesem Verzeichnis mit Ihrem Editor eine neue Datei namens etcd.service:

      Kopieren Sie als Nächstes den folgenden Codeblock in die Datei files/etcd.service:

      ~/playground/etcd-ansible/files/etcd.service

      [Unit]
      Description=etcd distributed reliable key-value store
      
      [Service]
      Type=notify
      ExecStart=/opt/etcd/bin/etcd
      Restart=always
      

      Diese Unit-Datei definiert einen Dienst, der die ausführbare Datei unter /opt/etcd/bin/etcd ausführt, systemd benachrichtigt, sobald die Initialisierung beendet ist, und immer neu startet, sollte sie je beendet werden.

      Anmerkung: Wenn Sie mehr über systemd und Unit-Dateien erfahren möchten oder die Unit-Datei an Ihre Bedürfnisse anpassen möchten, lesen Sie den Leitfaden Understanding Systemd Units and Unit Files (systemd-Units und Unit-Dateien verstehen).

      Schließen und speichern Sie die Datei files/etcd.service, indem Sie Strg+X drücken, gefolgt von Y.

      Als Nächstes müssen wir eine Aufgabe in unserem Playbook hinzufügen, die die lokale Datei files/etcd.service für die einzelnen verwalteten Knoten in das Verzeichnis /etc/systemd/system/etcd.service kopiert. Wir können dies mit dem copy-Modul tun.

      Öffnen Sie Ihr Playbook:

      • nano $HOME/playground/etcd-ansible/playbook.yaml

      Fügen Sie am Ende der bestehenden Aufgaben die folgende hervorgehobene Aufgabe an:

      ~/playground/etcd-ansible/playbook.yaml

      - hosts: etcd
        become: True
        tasks:
          ...
          - name: "Set the ETCDCTL_API environment variable to 3"
            lineinfile:
              path: /etc/profile
              line: export ETCDCTL_API=3
              state: present
              create: True
              insertafter: EOF
          - name: "Create a etcd service"
            copy:
              src: files/etcd.service
              remote_src: False
              dest: /etc/systemd/system/etcd.service
              owner: root
              group: root
              mode: 0644
      

      Durch Kopieren der Unit-Datei in /etc/systemd/system/etcd.service wird nun ein Dienst definiert.

      Speichern und schließen Sie das Playbook.

      Führen Sie den gleichen Befehl ansible-playbook erneut aus, um die neuen Änderungen anzuwenden:

      • ansible-playbook -i hosts playbook.yaml

      Um zu prüfen, ob die Änderungen angewendet wurden, stellen Sie zunächst eine SSH-Verbindung mit einem der verwalteten Knoten her:

      Führen Sie dann systemctl status etcd aus, um systemd über den Status des Diensts etcd abzufragen:

      Sie erhalten die folgende Ausgabe, in der angegeben wird, dass der Dienst geladen wurde:

      Output

      ● etcd.service - etcd distributed reliable key-value store Loaded: loaded (/etc/systemd/system/etcd.service; static; vendor preset: enabled) Active: inactive (dead) ...

      Anmerkung: Die letzte Zeile (Active: inactive (dead)) der Ausgabestatus gibt an, dass der Dienst inaktiv ist. Das bedeutet, dass er beim Starten des Systems nicht automatisch ausgeführt würde. Dies ist zu erwarten und kein Fehler.

      Drücken Sie q, um zur Shell zurückzukehren, und führen Sie dann exit aus, um den verwalteten Knoten zu verlassen und zu Ihrer lokalen Shell zurückzukehren:

      In diesem Schritt haben wir unser Playbook so aktualisiert, das es die Binärdatei etcd als systemd-Dienst ausführt. Im nächsten Schritt werden wir etcd weiter einrichten, indem wir Platz zur Speicherung seiner Daten zur Verfügung stellen.

      Schritt 5 — Konfigurieren des Datenverzeichnisses

      etcd ist ein Datenspeicher für Schlüsselwerte. Das bedeutet, dass wir ihm Platz zur Speicherung seiner Daten zur Verfügung stellen müssen. In diesem Schritt werden wir unser Playbook so aktualisieren, dass ein dediziertes Datenverzeichnis zur Verwendung durch etcd definiert wird.

      Öffnen Sie Ihr Playbook:

      • nano $HOME/playground/etcd-ansible/playbook.yaml

      Fügen Sie am Ende der Liste der Aufgaben die folgende Aufgabe an:

      ~/playground/etcd-ansible/playbook.yaml

      - hosts: etcd
        become: True
        tasks:
          ...
          - name: "Create a etcd service"
            copy:
              src: files/etcd.service
              remote_src: False
              dest: /etc/systemd/system/etcd.service
              owner: root
              group: root
              mode: 0644
          - name: "Create a data directory"
            file:
              path: /var/lib/etcd/{{ inventory_hostname }}.etcd
              state: directory
              owner: root
              group: root
              mode: 0755
      

      Hier verwenden wir /var/lib/etcd/hostname.etcd als Datenverzeichnis, wobei hostname der Hostname des aktuellen verwalteten Knotens ist. inventory_hostname ist eine Variable, die den Hostnamen des aktuellen verwalteten Knoten darstellt; ihr Wert wird automatisch von Ansible ausgefüllt. Die Syntax mit geschweiften Klammern (d. h. {{ inventory_hostname }}) wird zur Variablenersetzung genutzt, unterstützt durch die Jinja2-Vorlagen-Engine, die die standardmäßige Vorlagen-Engine für Ansible ist.

      Schließen Sie den Texteditor und speichern Sie die Datei.

      Als Nächstes müssen wir etcd anweisen, dieses Datenverzeichnis zu verwenden. Dazu übergeben wir den Parameter data-dir an etcd. Zum Festlegen von etcd-Parametern können wir eine Kombination aus Umgebungsvariablen, Befehlszeilen-Flags und Konfigurationsdateien verwenden. In diesem Tutorial verwenden wir eine Konfigurationsdatei, da es deutlich eleganter ist, alle Konfigurationen in einer Datei zu isolieren, anstatt die Konfiguration über unser ganzes Playbook zu verteilen.

      Erstellen Sie in Ihrem Projektverzeichnis ein neues Verzeichnis namens templates/:

      Erstellen Sie dann in dem Verzeichnis mit Ihrem Editor eine neue Datei namens etcd.conf.yaml.j2:

      • nano templates/etcd.conf.yaml.j2

      Kopieren Sie als Nächstes die folgende Zeile und fügen Sie sie in die Datei ein:

      ~/playground/etcd-ansible/templates/etcd.conf.yaml.j2

      data-dir: /var/lib/etcd/{{ inventory_hostname }}.etcd
      

      Diese Datei verwendet die gleiche Jinja2-Variablenersetzungssyntax wie unser Playbook. Um die Variablen zu ersetzen und das Ergebnis in die einzelnen verwalteten Hosts hochzuladen, können wir das template-Modul verwenden. Es funktioniert auf ähnliche Weise wie copy, nimmt vor dem Upload jedoch eine Variablenersetzung vor.

      Beenden Sie etcd.conf.yaml.j2 und öffnen Sie dann Ihr Playbook:

      • nano $HOME/playground/etcd-ansible/playbook.yaml

      Fügen Sie der Liste der Aufgaben die folgenden Aufgaben an, um ein Verzeichnis zu erstellen und die vorlagenbasierte Konfigurationsdatei darin hochzuladen:

      ~/playground/etcd-ansible/playbook.yaml

      - hosts: etcd
        become: True
        tasks:
          ...
          - name: "Create a data directory"
            file:
              ...
              mode: 0755
          - name: "Create directory for etcd configuration"
            file:
              path: /etc/etcd
              state: directory
              owner: root
              group: root
              mode: 0755
          - name: "Create configuration file for etcd"
            template:
              src: templates/etcd.conf.yaml.j2
              dest: /etc/etcd/etcd.conf.yaml
              owner: root
              group: root
              mode: 0600
      

      Speichern und schließen Sie diese Datei.

      Da wir diese Änderung vorgenommen haben, müssen wir nun die Unit-Datei unseres Diensts aktualisieren, damit ihr der Speicherort unserer Konfigurationsdatei übergeben wird (d. h. /etc/etcd/etcd.conf.yaml).

      Öffnen Sie die Datei etcd.service auf Ihrem lokalen Rechner:

      Aktualisieren Sie die Datei files/etcd.service, indem Sie das im Folgenden hervorgehobene Flag --config-file hinzufügen:

      ~/playground/etcd-ansible/files/etcd.service

      [Unit]
      Description=etcd distributed reliable key-value store
      
      [Service]
      Type=notify
      ExecStart=/opt/etcd/bin/etcd --config-file /etc/etcd/etcd.conf.yaml
      Restart=always
      

      Speichern und schließen Sie die Datei.

      In diesem Schritt haben wir unser Playbook zur Bereitstellung eines Datenverzeichnisses für etcd zum Speichern seiner Daten verwendet. Im nächsten Schritt werden wir noch einige Aufgaben hinzufügen, um den etcd-Dienst neu zu starten und für ein Ausführen beim Systemstart zu sorgen.

      Schritt 6 — Aktivieren und Starten des etcd-Diensts

      Jedes Mal wenn wir Änderungen an der Unit-Datei eines Diensts vornehmen, müssen wir diesen Dienst neu starten, damit die Änderungen wirksam werden. Wir können dazu den Befehl systemctl restart etcd ausführen. Damit der etcd-Dienst beim Systemstart automatisch gestartet wird, müssen wir systemctl enable etcd ausführen. In diesem Schritt werden wir mit dem Playbook diese beiden Befehle ausführen.

      Um Befehle auszuführen, können wir das command-Modul verwenden:

      • nano $HOME/playground/etcd-ansible/playbook.yaml

      Fügen Sie am Ende der Aufgabenliste die folgenden Aufgaben an:

      ~/playground/etcd-ansible/playbook.yaml

      - hosts: etcd
        become: True
        tasks:
          ...
          - name: "Create configuration file for etcd"
            template:
              ...
              mode: 0600
          - name: "Enable the etcd service"
            command: systemctl enable etcd
          - name: "Start the etcd service"
            command: systemctl restart etcd
      

      Speichern und schließen Sie die Datei.

      Führen Sie ansible-playbook -i hosts playbook.yaml erneut aus:

      • ansible-playbook -i hosts playbook.yaml

      Um zu überprüfen, ob der Dienst etcd neu gestartet und aktiviert wurde, stellen Sie eine SSH-Verbindung zu einem der verwalteten Knoten her:

      Führen Sie dann systemctl status etcd aus, um den Status des etcd-Diensts zu überprüfen:

      Sie werden im Folgenden enabled und active (running) als hervorgehoben sehen; das bedeutet, dass die Änderungen, die wir in unserem Playbook vorgenommen haben, wirksam geworden sind:

      Output

      ● etcd.service - etcd distributed reliable key-value store Loaded: loaded (/etc/systemd/system/etcd.service; static; vendor preset: enabled) Active: active (running) Main PID: 19085 (etcd) Tasks: 11 (limit: 2362)

      In diesem Schritt haben wir das command-Modul zur Ausführung von systemctl-Befehlen verwendet, die den Dienst etcd neu starten und auf unseren verwalteten Knoten aktivieren. Nachdem wir eine etcd-Installation eingerichtet haben, testen wir nun im nächsten Schritt ihre Funktionalität durch Ausführung von CRUD-Operationen zum Erstellen, Lesen, Aktualisieren und Löschen.

      Schritt 7 — Testen von etcd

      Zwar verfügen wir über eine funktionierende etcd-Installation, doch ist diese unsicher und noch nicht bereit für den Produktionseinsatz. Bevor wir aber unsere etcd-Installation in späteren Schritten sichern, sollten wir zunächst wissen, was etcd für Funktionen bietet. In diesem Schritt werden wir manuell Anfragen an etcd senden, um Daten hinzuzufügen, abzurufen, zu aktualisieren und zu löschen.

      Standardmäßig macht etcd eine API verfügbar, die an Port 2379 auf Client-Kommunikation lauscht. Das bedeutet, dass wir mit einem HTTP-Client rohe API-Anfragen an etcd senden können. Es ist jedoch schneller, den offiziellen etcd-Client etcdctl zu verwenden. Damit können Sie Schlüsselwertpaare mit den Unterbefehlen put, get bzw. del erstellen/aktualisieren, abrufen und löschen.

      Stellen Sie sicher, dass Sie sich noch im verwalteten Knoten etcd1 befinden, und führen Sie die folgenden etcdctl-Befehle aus, um sich zu vergewissern, dass Ihre etcd-Installation richtig funktioniert.

      Erstellen Sie zunächst mit dem Unterbefehl put einen neuen Eintrag.

      Der Unterbefehl put weist die folgende Syntax auf:

      etcdctl put key value
      

      Führen Sie für etcd1 folgenden Befehl aus:

      Der Befehl, den wir gerade ausgeführt haben, weist etcd an, den Wert "bar" im Speicher in den Schlüssel foo zu schreiben.

      Dann werden Sie OK in der Ausgabe sehen, was angibt, dass die Daten persistiert wurden:

      Output

      OK

      Wir können diesen Eintrag dann mit dem Unterbefehl get abrufen, der die Syntax etcdctl get key hat:

      Sie werden diese Ausgabe finden, die den Schlüssel in der ersten Zeile und den Wert anzeigt, den Sie zuvor in der zweiten Zeile eingefügt haben:

      Output

      foo bar

      Wir können den Eintrag mit dem Unterbefehl del löschen, der die Syntax etcdctl del key hat:

      Sie werden die folgende Ausgabe sehen, die die Anzahl der gelöschten Einträge angibt:

      Output

      1

      Lassen Sie uns nun den Unterbefehl get erneut ausführen, um zu versuchen, ein gelöschtes Schlüssel-Wert-Paar abzurufen:

      Sie erhalten keine Ausgabe, was bedeutet, dass etcdctl das Schlüssel-Wert-Paar nicht abrufen kann. Dadurch wird bestätigt, dass der Eintrag nach dem Löschen nicht mehr abgerufen werden kann.

      Nachdem Sie die grundlegenden Operationen von etcd und etcdctl getestet haben, verlassen wir nun unseren verwalteten Knoten und kehren zurück zu der lokalen Umgebung:

      In diesem Schritt haben wir den etcdctl-Client zum Senden von Anfragen an etcd verwendet. An diesem Punkt führen wir drei separate Instanzen von etcd aus, die jeweils unabhängig voneinander agieren. Jedoch ist etcd als verteilter Schlüssel-Wert-Speicher konzipiert; das bedeutet, dass sich mehrere etcd-Instanzen gruppieren können, um einen einzelnen Cluster zu bilden; jede Instanz wird dann ein Member (Mitglied) des Clusters. Nach der Einrichtung eines Clusters könnten Sie ein Schlüssel-Wert-Paar abrufen, das von einem anderen Memberknoten des Clusters eingefügt wurde. Im nächsten Schritt werden wir unser Playbook verwenden, um unsere drei 1-Node-Cluster in einen einzigen 3-Node-Cluster zu verwandeln.

      Schritt 8 — Erstellen eines Clusters mit statischer Erkennung

      Um anstelle von drei 1-Node-Clustern einen 3-Node-Cluster zu erstellen, müssen wir die etcd-Installationen so konfigurieren, dass sie miteinander kommunizieren. Das bedeutet, dass alle die IP-Adressen der anderen kennen müssen. Dieser Prozess wird Erkennung genannt. Erkennung kann entweder mit statischer Konfiguration oder mit einer dynamischen Diensterkennung erfolgen. In diesem Schritt werden wir den Unterschied zwischen den beiden erörtern sowie unser Playbook aktualisieren, um einen etcd-Cluster mit statischer Erkennung einzurichten.

      Erkennung mit statischer Konfiguration ist die Methode, die die geringste Einrichtung erfordert; hier werden die Endpunkte der einzelnen Memberknoten in den Befehl etcd übergeben, bevor er ausgeführt wird. Um statische Konfiguration zu verwenden, müssen vor der Initialisierung des Clusters folgende Bedingungen erfüllt sein:

      • die Anzahl der Memberknoten ist bekannt
      • die Endpunkte der einzelnen Memberknoten sind bekannt
      • die IP-Adressen für alle Endpunkte sind statisch

      Wenn sich diese Bedingungen nicht erfüllen lassen, können Sie einen dynamischen Erkennungsdienst verwenden. Bei der dynamischen Diensterkennung würden sich alle Instanzen beim Erkennungsdienst registrieren, damit jeder Memberknoten Informationen über den Ort anderer Memberknoten abrufen kann.

      Da wir wissen, dass wir einen 3-Node-etcd-Cluster nutzen möchten und alle unsere Server über statische IP-Adressen verfügen, werden wir statische Erkennung verwenden. Um unseren Cluster mit statischer Erkennung zu initiieren, müssen wir unserer Konfigurationsdatei mehrere Parameter hinzufügen. Verwenden Sie einen Editor, um die Vorlagendatei templates/etcd.conf.yaml.j2 zu öffnen:

      • nano templates/etcd.conf.yaml.j2

      Fügen Sie dann die folgenden hervorgehobenen Zeilen hinzu:

      ~/playground/etcd-ansible/templates/etcd.conf.yaml.j2

      data-dir: /var/lib/etcd/{{ inventory_hostname }}.etcd
      name: {{ inventory_hostname }}
      initial-advertise-peer-urls: http://{{ hostvars[inventory_hostname]['ansible_facts']['eth1']['ipv4']['address'] }}:2380
      listen-peer-urls: http://{{ hostvars[inventory_hostname]['ansible_facts']['eth1']['ipv4']['address'] }}:2380,http://127.0.0.1:2380
      advertise-client-urls: http://{{ hostvars[inventory_hostname]['ansible_facts']['eth1']['ipv4']['address'] }}:2379
      listen-client-urls: http://{{ hostvars[inventory_hostname]['ansible_facts']['eth1']['ipv4']['address'] }}:2379,http://127.0.0.1:2379
      initial-cluster-state: new
      initial-cluster: {% for host in groups['etcd'] %}{{ hostvars[host]['ansible_facts']['hostname'] }}=http://{{ hostvars[host]['ansible_facts']['eth1']['ipv4']['address'] }}:2380{% if not loop.last %},{% endif %}{% endfor %}
      

      Schließen und speichern Sie die Datei templates/etcd.conf.yaml.j2, indem Sie Strg+X drücken, gefolgt von J.

      Hier ist eine kurze Erläuterung der einzelnen Parameter:

      • name – ein menschenlesbarer Name für den Memberknoten. Standardmäßig verwendet etcd eine eindeutige, zufällig generierte ID zur Identifizierung der einzelnen Memberknoten; ein menschlich lesbarer Name erleichtert jedoch in Konfigurationsdateien und in der Befehlszeile das Verweisen darauf. Hier werden wir die Hostnamen als Membernamen (d. h. etcd1, etcd2 und etcd3) verwenden.
      • initial-advertise-peer-urls – eine Liste mit IP-Adress-/Port-Kombinationen, die andere Memberknoten zur Kommunikation mit diesem Memberknoten verwenden können. Neben dem API-Port (2379) macht etcd auch Port 2380 für Peer-Kommunikation zwischen etcd-Memberknoten verfügbar, sodass sie Nachrichten aneinander senden und Daten austauschen können. Beachten Sie, dass diese URLs von ihren Peers erreichbar sein müssen (und keine lokalen IP-Adressen sein dürfen).
      • listen-peer-urls – eine Liste mit IP-Adress-/Port-Kombinationen, bei denen der aktuelle Memberknoten auf Kommunikation von anderen Memberknoten lauscht. Sie muss alle URLs aus dem Flag --initial-advertise-peer-urls enthalten, aber auch lokale URLs wie 127.0.0.1:2380. Die Ziel-IP-Adresse/der Port eingehender Peer-Nachrichten müssen mit einer der hier aufgeführten URLs übereinstimmen.
      • advertise-client-urls – eine Liste mit IP-Adress-/Port-Kombinationen, die Clients zur Kommunikation mit diesem Memberknoten verwenden sollen. Diese URLs müssen vom Client erreichbar sein (und dürfen keine lokalen Adressen sein). Wenn der Client über das öffentliche Internet auf den Cluster zugreift, muss dies eine öffentliche IP-Adresse sein.
      • listen-client-urls – eine Liste mit IP-Adress-/Port-Kombinationen, bei denen der aktuelle Memberknoten auf Kommunikation von Clients lauscht. Sie muss alle URLs aus dem Flag --advertise-client-urls enthalten, aber auch lokale URLs wie 127.0.0.1:2379. Die Ziel-IP-Adresse/der Port eingehender Client-Nachrichten müssen mit einer der hier aufgeführten URLs übereinstimmen.
      • initial-cluster – eine Liste mit Endpunkten für jeden Memberknoten des Clusters. Jeder Endpunkt muss mit einer der initial-advertise-peer-urls-URLs des entsprechenden Memberknotens übereinstimmen.
      • initial-cluster-state – entweder new oder existing.

      Zur Gewährleistung der Konsistenz kann etcd nur Entscheidungen treffen, wenn eine Mehrheit der Knoten integer ist. Dies wird als Einrichten eines Quorum bezeichnet. Mit anderen Worten,: In einem Cluster mit drei Memberknoten wird das Quorum erreicht, wenn zwei oder mehr der Mitglieder integer sind.

      Wenn der Parameter initial-cluster-state auf new gesetzt ist, weiß etcd, dass dies ein neuer Cluster ist, für den Bootstrapping ausgeführt wird; so können Memberknoten parallel gestartet werden, ohne dass auf das Erreichen des Quorums gewartet werden muss. Konkret: Nachdem das erste Mitglied gestartet wurde, wird kein Quorum erreicht, da ein Drittel (33,33 %) nicht mehr als 50 % ist. Normalerweise wird etcd anhalten und sich weigern, weitere Aktionen zu übergeben; der Cluster wird nie erstellt. Wenn der initial-cluster-state jedoch auf new gesetzt ist, wird das anfängliche Fehlen des Quorums ignoriert.

      Wenn der Wert auf existing gesetzt ist, wird der Memberknoten versuchen, einem vorhandenen Cluster beizutreten, und erwarten, dass das Quorum bereits eingerichtet wurde.

      Anmerkung: Weitere Details zu allen unterstützten Konfigurations-Flags finden Sie im Abschnitt Konfiguration der etcd-Dokumentation.

      In der aktualisierten Vorlagendatei templates/etcd.conf.yaml.j2 gibt es einige Instanzen von hostvars. Wenn Ansible ausgeführt wird, erfassen sie Variablen aus verschiedenen Quellen. Wir haben bereits die Variable inventory_hostname verwendet, aber es gibt noch viel mehr. Diese Variablen sind verfügbar unter hostvars[inventory_hostname]['ansible_facts']. Hier extrahieren wir die privaten IP-Adressen der einzelnen Knoten und nutzen Sie zur Erstellung unseres Parameterwerts.

      Anmerkung: Da wir bei der Erstellung unserer Server die Option Private Networking aktiviert haben, würde jeder Server über drei IP-Adressen verfügen, die mit ihm verknüpft sind:

      • Eine Loopback-IP-Adresse – eine Adresse, die nur im gleichen Rechner gültig ist. Sie wird vom Rechner verwendet, um sich auf sich zu verweisen, z. B. 127.0.0.1.
      • Eine öffentliche IP-Adresse – eine Adresse, die über das öffentliche Internet routingfähig ist, z. B. 178.128.169.51.
      • Eine private IP-Adresse – eine Adresse, die nur im privaten Netzwerk routingfähig ist; im Fall von DigitalOcean Droplets gibt es in jedem Rechenzentrum ein privates Netzwerk, z. B. 10.131.82.225.

      Jede dieser IP-Adressen ist mit einer anderen Netzwerkschnittstelle verbunden: Die Loopback-Adresse ist mit der lo-Schnittstelle verbunden, die öffentliche IP-Adresse mit der eth0-Schnittstelle und die private IP-Adresse mit der eth1-Schnittstelle. Wir verwenden die eth1-Schnittstelle, damit der gesamte Datenverkehr im privaten Netzwerk bleibt, ohne je das Internet zu erreichen.

      Für diesen Artikel ist kein Verständnis von Netzwerkschnittstellen erforderlich; wenn Sie jedoch mehr erfahren möchten, ist An Introduction to Networking Terminology, Interfaces, and Protocols( Eine Einführung in Netzwerkbegriffe, Schnittstellen und Protokolle) ein guter Ausgangspunkt.

      Die Jinja2-Syntax {% %} definiert die for-Schleifenstruktur, die über jeden Knoten in der Gruppe etcd iteriert, um die Zeichenfolge initial-cluster in einem Format zu erstellen, das etcd benötigt.

      Um den neuen Cluster mit drei Memberknoten zu erstellen, müssen Sie zunächst den etcd-Dienst stoppen und das Datenverzeichnis löschen, bevor Sie den Cluster starten. Verwenden Sie einen Editor, um die Datei playbook.yaml auf Ihrem lokalen Rechner zu öffnen:

      • nano $HOME/playground/etcd-ansible/playbook.yaml

      Fügen Sie dann vor der Aufgabe „Create a Data directory“ eine Aufgabe hinzu, um den etcd-Dienst anzuhalten:

      ~/playground/etcd-ansible/playbook.yaml

      - hosts: etcd
        become: True
        tasks:
          ...
              group: root
              mode: 0644
          - name: "Stop the etcd service"
            command: systemctl stop etcd
          - name: "Create a data directory"
            file:
          ...
      

      Aktualisieren Sie als Nächstes die Aufgabe "Create a Data directory", um das Datenverzeichnis zunächst zu löschen und dann neu zu erstellen:

      ~/playground/etcd-ansible/playbook.yaml

      - hosts: etcd
        become: True
        tasks:
          ...
          - name: "Stop the etcd service"
            command: systemctl stop etcd
          - name: "Create a data directory"
            file:
              path: /var/lib/etcd/{{ inventory_hostname }}.etcd
              state: "{{ item }}"
              owner: root
              group: root
              mode: 0755
            with_items:
              - absent
              - directory
          - name: "Create directory for etcd configuration"
            file:
          ...
      

      Die Eigenschaft with_items definiert eine Liste von Zeichenfolgen, über die diese Aufgabe iterieren wird. Es ist genauso, als würden Sie die gleiche Aufgabe zweimal wiederholen, aber mit verschiedenen Werten für die Eigenschaft state. Hier iterieren wir über die Liste mit Elementen absent und directory, was gewährleistet, dass das Datenverzeichnis zunächst gelöscht und danach neu erstellt wird.

      Schließen und speichern Sie die Datei playbook.yaml, indem Sie Strg+X drücken, gefolgt von J. Führen Sie dann ansible-playbook erneut aus. Ansible erstellt nun einen einzelnen etcd-Cluster mit drei Memberknoten:

      • ansible-playbook -i hosts playbook.yaml

      Sie können dies überprüfen, indem Sie eine SSH-Verbindung zu einem beliebigen etcd-Memberknoten herstellen:

      Führen Sie dann etcdctl endpoint health --cluster aus:

      • etcdctl endpoint health --cluster

      Dadurch wird der Zustand der einzelnen Memberknoten im Cluster aufgelistet:

      Output

      http://etcd2_private_ip:2379 is healthy: successfully committed proposal: took = 2.517267ms http://etcd1_private_ip:2379 is healthy: successfully committed proposal: took = 2.153612ms http://etcd3_private_ip:2379 is healthy: successfully committed proposal: took = 2.639277ms

      Wir haben nun erfolgreich einen etcd-Cluster mit drei Knoten erstellt. Wir können dies prüfen, indem wir auf einem Memberknoten einen Eintrag zu etcd hinzufügen und diesen dann auf einem anderen Memberknoten abrufen. Führen Sie auf einem der Memberknoten etcdctl put aus:

      Verwenden Sie dann ein neues Terminal, um eine SSH-Verbindung zu einem anderen Memberknoten herzustellen:

      Versuchen Sie als Nächstes, mit folgendem Schlüssel den gleichen Eintrag abzurufen:

      Sie können den Eintrag abrufen, was beweist, dass der Cluster funktioniert:

      Output

      foo bar

      Verlassen Sie abschließend die einzelnen verwalteten Knoten und kehren Sie zurück zu Ihrem lokalen Rechner:

      In diesem Schritt haben wir einen neuen Cluster mit drei Knoten bereitgestellt. Derzeit erfolgt die Kommunikation zwischen etcd-Memberknoten sowie ihren Peers und Clients über HTTP. Das bedeutet, dass die Kommunikation unverschlüsselt ist und jede Person, die den Verkehr abfangen kann, auch die entsprechenden Nachrichten lesen kann. Dies ist kein großes Problem, wenn der etcd-Cluster und die Clients alle in einem privaten Netzwerk oder einem virtuellen privaten Netzwerk (VPN) bereitgestellt werden, das Sie vollständig kontrollieren. Wenn jedoch Teile des Datenverkehrs über ein freigegebenes Netzwerk (privat oder öffentlich) übertragen werden, sollten Sie sicherstellen, dass dieser Datenverkehr verschlüsselt ist. Außerdem muss für Clients oder Peers ein Mechanismus eingerichtet werden, der die Authentizität des Servers überprüft.

      Im nächsten Schritt werden wir uns ansehen, wie wir Client-to-Server- sowie Peer-Kommunikation mit TLS sichern können.

      Schritt 9 — Abrufen der privaten IP-Adressen von verwalteten Knoten

      Um Nachrichten zwischen Memberknoten zu verschlüsseln, verwendet etcd Hypertext Transfer Protocol Secure oder HTTPS, was eine Ebene über der Transport Layer Security oder dem TLS-Protokoll ist. TLS nutzt ein System aus privaten Schlüsseln, Zertifikaten und vertrauenswürdigen Entitäten namens Zertifizierungsstellen (CAs) zum Authentifizieren und gegenseitigen Senden verschlüsselter Nachrichten.

      In diesem Tutorial muss jeder Memberknoten ein Zertifikat generieren, um sich selbst zu identifizieren, und von einer Zertifizierungsstelle signieren lassen. Wir werden konfigurieren alle Memberknoten so, dass sie dieser Zertifizierungsstelle vertrauen und somit auch Zertifikaten vertrauen, die von ihr signiert wurden. Dadurch können sich Mitgliedsknoten gegenseitig authentifizieren.

      Das Zertifikat, das ein Memberknoten generiert, muss es anderen Memberknoten erlauben, sich selbst zu identifizieren. Alle Zertifikate umfassen den Common Name (CN) der Entität, mit der sie verknüpft sind. Dies wird oft als Identität der Entität verwendet. Bei der Prüfung eines Zertifikats können Clientimplementierungen jedoch vergleichen, ob die von ihnen erfassten Informationen über die Entität mit dem übereinstimmen, was im Zertifikat angegeben wurde. Wenn beispielsweise ein Client das TLS-Zertifikat mit dem Betreff CN=foo.bar.com herunterlädt, der Client in Wahrheit aber mit einer IP-Adresse (z. B. 167.71.129.110) verbunden ist, gibt es einen Konflikt und der Client vertraut dem Zertifikat ggf. nicht. Indem Sie im Zertifikat einen Subject Alternative Name (SAN) angeben, erfährt der Überprüfer, dass beide Namen zur gleichen Entität gehören.

      Da unsere etcd-Memberknoten über ihre privaten IP-Adressen Peering betreiben, müssen wir diese privaten IP-Adressen, wenn wir unsere Zertifikate definieren, als alternative Antragstellernamen (SANs) angeben.

      Um die private IP-Adresse eines verwalteten Knoten zu erfahren, stellen Sie eine SSH-Verbindung damit her:

      Führen Sie dann den folgenden Befehl aus:

      • ip -f inet addr show eth1

      Sie sehen eine Ausgabe, die den folgenden Zeilen ähnelt:

      Output

      3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 inet 10.131.255.176/16 brd 10.131.255.255 scope global eth1 valid_lft forever preferred_lft forever

      In unserer Beispielausgabe ist 10.131.255.176 die private IP-Adresse des verwalteten Knotens und die einzige Information, an der wir interessiert sind. Um alles mit Ausnahme der privaten IP-Adresse herauszufiltern, können wir die Ausgabe des Befehls ip an das Dienstprogramm sed übergeben, das zum Filtern und Umformen von Text dient.

      • ip -f inet addr show eth1 | sed -En -e 's/.*inet ([0-9.]+).*/1/p'

      Die einzige Ausgabe ist nun die private IP-Adresse selbst:

      Output

      10.131.255.176

      Sobald Sie damit zufrieden sind, dass der vorhergehende Befehl funktioniert, verlassen Sie den verwalteten Knoten:

      Um die vorherigen Befehle in Ihr Playbook aufzunehmen, öffnen Sie zunächst die Datei playbook.yaml:

      • nano $HOME/playground/etcd-ansible/playbook.yaml

      Fügen Sie dann vor dem vorhandenen Play ein neues Play mit einer einzelnen Aufgabe hinzu:

      ~/playground/etcd-ansible/playbook.yaml

      ...
      - hosts: etcd
        tasks:
          - shell: ip -f inet addr show eth1 | sed -En -e 's/.*inet ([0-9.]+).*/1/p'
            register: privateIP
      - hosts: etcd
        tasks:
      ...
      

      Die Aufgabe verwendet das shell-Modul, um die Befehle ip und sed auszuführen, wodurch die private IP-Adresse des verwalteten Knoten abgerufen wird. Dann registriert sie den Rückgabewert des Shell-Befehls in einer Variable namens privateIP, die wir später verwenden werden.

      In diesem Schritt haben wir dem Playbook eine Aufgabe hinzugefügt, um die private IP-Adresse der verwalteten Knoten zu erhalten. Im nächsten Schritt werden wir diese Informationen verwenden, um für jeden der Knoten ein Zertifikat zu generieren und die Zertifikate von einer Zertifizierungsstelle (CA) signieren zu lassen.

      Schritt 10 — Erstellen der privaten Schlüssel und CSRs von etcd-Memberknoten

      Damit ein Memberknoten verschlüsselten Datenverkehr erhält, muss der Absender den öffentlichen Schlüssel des Memberknotens verwenden, um die Daten zu verschlüsseln. Der Memberknoten muss den privaten Schlüssel nutzen, um den verschlüsselten Text zu entschlüsseln und die Originaldaten abzurufen. Der öffentliche Schlüssel ist in einem Zertifikat verpackt und wurde von einer CA signiert, um sicherzustellen, dass er echt ist.

      Daher müssen wir für jeden etcd-Memberknoten einen privaten Schlüssel und eine Zertifikatsignaturanforderung (CSR) generieren. Um es einfacher zu machen, erstellen wir alle Schlüsselpaare und signieren alle Zertifikate lokal auf dem Steuerknoten und kopieren die entsprechenden Dateien dann auf die verwalteten Hosts.

      Erstellen Sie zunächst ein Verzeichnis namens artifacts/, in dem Sie die in dem Prozess generierten Dateien (Schlüssel und Zertifikate) platzieren werden. Öffnen Sie die Datei playbook.yaml mit einem Editor:

      • nano $HOME/playground/etcd-ansible/playbook.yaml

      Verwenden Sie darin das file-Modul, um das Verzeichnis artifacts/ zu erstellen:

      ~/playground/etcd-ansible/playbook.yaml

      ...
          - shell: ip -f inet addr show eth1 | sed -En -e 's/.*inet ([0-9.]+).*/1/p'
            register: privateIP
      - hosts: localhost
        gather_facts: False
        become: False
        tasks:
          - name: "Create ./artifacts directory to house keys and certificates"
            file:
              path: ./artifacts
              state: directory
      - hosts: etcd
        tasks:
      ...
      

      Fügen Sie als Nächstes am Ende des Plays eine weitere Aufgabe hinzu, um den privaten Schlüssel zu generieren:

      ~/playground/etcd-ansible/playbook.yaml

      ...
      - hosts: localhost
        gather_facts: False
        become: False
        tasks:
              ...
          - name: "Generate private key for each member"
            openssl_privatekey:
              path: ./artifacts/{{item}}.key
              type: RSA
              size: 4096
              state: present
              force: True
            with_items: "{{ groups['etcd'] }}"
      - hosts: etcd
        tasks:
      ...
      

      Das Erstellen von privaten Schlüsseln und CSRs kann mit den Modulen openssl_privatekey bzw. openssl_csr erfolgen.

      Das Attribut force: True stellt sicher, dass der private Schlüssel jedes Mal neu generiert wird, auch wenn er bereits existiert.

      Fügen Sie nun die folgende neue Aufgabe demselben Play an, um die CSRs für die einzelnen Memberknoten zu generieren; nutzen Sie dazu das Modul openssl_csr:

      ~/playground/etcd-ansible/playbook.yaml

      ...
      - hosts: localhost
        gather_facts: False
        become: False
        tasks:
          ...
          - name: "Generate private key for each member"
            openssl_privatekey:
              ...
            with_items: "{{ groups['etcd'] }}"
          - name: "Generate CSR for each member"
            openssl_csr:
              path: ./artifacts/{{item}}.csr
              privatekey_path: ./artifacts/{{item}}.key
              common_name: "{{item}}"
              key_usage:
                - digitalSignature
              extended_key_usage:
                - serverAuth
              subject_alt_name:
                - IP:{{ hostvars[item]['privateIP']['stdout']}}
                - IP:127.0.0.1
              force: True
            with_items: "{{ groups['etcd'] }}"
      

      Wir geben an, dass sich dieses Zertifikat für den Zweck der Serverauthentifizierung an einem digitalen Signaturmechanismus beteiligen kann. Das Zertifikat ist mit dem Hostnamen (z. B. etcd1) verknüpft; der Überprüfer soll jedoch auch die privaten und lokalen Loopback-IP-Adressen der einzelnen Knoten als alternative Namen behandeln. Beachten Sie, dass wir die Variable privateIP verwenden, die wir im vorherigen Play registriert haben.

      Schließen und speichern Sie die Datei playbook.yaml, indem Sie Strg+X drücken, gefolgt von J. Führen Sie das Playbook dann erneut aus:

      • ansible-playbook -i hosts playbook.yaml

      Wir werden in unserem Projektverzeichnis nun ein neues Verzeichnis namens Artefakte sehen; verwenden Sie ls, um den Inhalt aufzulisten:

      Sie sehen die privaten Schlüssel und CSRs für die einzelnen etcd-Memberknoten:

      Output

      etcd1.csr etcd1.key etcd2.csr etcd2.key etcd3.csr etcd3.key

      In diesem Schritt haben wir verschiedene Ansible-Module verwendet, um für die einzelnen Memberknoten private Schlüssel und öffentliche Schlüsselzertifikate zu generieren. Im nächsten Schritt werden wir uns ansehen, wie eine Zertifikatsignaturanforderung (CSR) signiert wird.

      Schritt 11 — Erstellen von CA-Zertifikaten

      Innerhalb eines etcd-Clusters verschlüsseln Memberknoten Nachrichten mit dem öffentlichen Schlüssel des Empfängers. Um sicherzustellen, dass der öffentliche Schlüssel echt ist, verpackt der Empfänger den öffentlichen Schlüssel in eine Zertifikatsignaturanforderung (CSR) und lässt diese von einer vertrauenswürdigen Entität (d. h. der CA) signieren. Da wir alle Memberknoten und die Zertifizierungstellen, denen sie vertrauen, kontrollieren, müssen wir keine externe CA nutzen und können als eigene CA fungieren. In diesem Schritt werden wir als eigene CA agieren; das bedeutet, dass wir einen privaten Schlüssel und ein selbstsigniertes Zertifikat erstellen müssen, um als CA zu fungieren.

      Öffnen Sie die Datei playbook.yaml mit Ihrem Editor:

      • nano $HOME/playground/etcd-ansible/playbook.yaml

      Fügen Sie dann ähnlich wie im vorherigen Schritt eine Aufgabe im Play localhost an, um einen privaten Schlüssel für die CA zu generieren:

      ~/playground/etcd-ansible/playbook.yaml

      - hosts: localhost
        ...
        tasks:
          ...
        - name: "Generate CSR for each member"
          ...
          with_items: "{{ groups['etcd'] }}"
          - name: "Generate private key for CA"
            openssl_privatekey:
              path: ./artifacts/ca.key
              type: RSA
              size: 4096
              state: present
              force: True
      - hosts: etcd
        become: True
        tasks:
          - name: "Create directory for etcd binaries"
      ...
      

      Als Nächstes verwenden Sie das Modul openssl_csr, um eine neue CSR zu generieren. Dies ähnelt dem vorherigen Schritt; in dieser CSR fügen wir jedoch die Basiseinschränkung und Schlüsselverwendungserweiterung hinzu, um anzugeben, dass dieses Zertifikat als CA-Zertifikat verwendet werden kann:

      ~/playground/etcd-ansible/playbook.yaml

      - hosts: localhost
        ...
        tasks:
          ...
          - name: "Generate private key for CA"
            openssl_privatekey:
              path: ./artifacts/ca.key
              type: RSA
              size: 4096
              state: present
              force: True
          - name: "Generate CSR for CA"
            openssl_csr:
              path: ./artifacts/ca.csr
              privatekey_path: ./artifacts/ca.key
              common_name: ca
              organization_name: "Etcd CA"
              basic_constraints:
                - CA:TRUE
                - pathlen:1
              basic_constraints_critical: True
              key_usage:
                - keyCertSign
                - digitalSignature
              force: True
      - hosts: etcd
        become: True
        tasks:
          - name: "Create directory for etcd binaries"
      ...
      

      Verwenden Sie schließlich das Modul openssl_certificate, um das CSR selbst zu signieren:

      ~/playground/etcd-ansible/playbook.yaml

      - hosts: localhost
        ...
        tasks:
          ...
          - name: "Generate CSR for CA"
            openssl_csr:
              path: ./artifacts/ca.csr
              privatekey_path: ./artifacts/ca.key
              common_name: ca
              organization_name: "Etcd CA"
              basic_constraints:
                - CA:TRUE
                - pathlen:1
              basic_constraints_critical: True
              key_usage:
                - keyCertSign
                - digitalSignature
              force: True
          - name: "Generate self-signed CA certificate"
            openssl_certificate:
              path: ./artifacts/ca.crt
              privatekey_path: ./artifacts/ca.key
              csr_path: ./artifacts/ca.csr
              provider: selfsigned
              force: True
      - hosts: etcd
        become: True
        tasks:
          - name: "Create directory for etcd binaries"
      ...
      

      Schließen und speichern Sie die Datei playbook.yaml, indem Sie Strg+X drücken, gefolgt von J. Führen Sie dann das Playbook erneut aus, um die Änderungen anzuwenden:

      • ansible-playbook -i hosts playbook.yaml

      Außerdem können Sie ls ausführen, um den Inhalt des Verzeichnisses artifacts/ zu überprüfen:

      Sie sehen nun das neu generierte CA-Zertifikat (ca.crt):

      Output

      ca.crt ca.csr ca.key etcd1.csr etcd1.key etcd2.csr etcd2.key etcd3.csr etcd3.key

      In diesem Schritt haben wir einen privaten Schlüssel und ein selbstsigniertes Zertifikat für die CA generiert. Im nächsten Schritt verwenden wir das CA-Zertifikat nutzen, um die CSRs der einzelnen Memberknoten zu signieren.

      Schritt 12 — Signieren der CSRs von etcd-Memberknoten

      In diesem Schritt signieren wir die CSRs der einzelnen Memberknoten. Dies ähnelt der Methode, mit der wir das Modul openssl_certificate verwendet haben, um das CA-Zertifikat selbst zu signieren. Aber anstelle des Anbieters selfsigned nutzen wir den Anbieter ownca, damit wir unsere eigenen CA-Zertifikate signieren können.

      Öffnen Sie Ihr Playbook:

      • nano $HOME/playground/etcd-ansible/playbook.yaml

      Fügen Sie der Aufgabe "Generate self-signed CA certificate" die folgende hervorgehobene Aufgabe an:

      ~/playground/etcd-ansible/playbook.yaml

      - hosts: localhost
        ...
        tasks:
          ...
          - name: "Generate self-signed CA certificate"
            openssl_certificate:
              path: ./artifacts/ca.crt
              privatekey_path: ./artifacts/ca.key
              csr_path: ./artifacts/ca.csr
              provider: selfsigned
              force: True
          - name: "Generate an `etcd` member certificate signed with our own CA certificate"
            openssl_certificate:
              path: ./artifacts/{{item}}.crt
              csr_path: ./artifacts/{{item}}.csr
              ownca_path: ./artifacts/ca.crt
              ownca_privatekey_path: ./artifacts/ca.key
              provider: ownca
              force: True
            with_items: "{{ groups['etcd'] }}"
      - hosts: etcd
        become: True
        tasks:
          - name: "Create directory for etcd binaries"
      ...
      

      Schließen und speichern Sie die Datei playbook.yaml, indem Sie Strg+X drücken, gefolgt von “Y. Führen Sie dann das Playbook erneut aus, um die Änderungen anzuwenden:

      • ansible-playbook -i hosts playbook.yaml

      Listen Sie nun den Inhalt des Verzeichnisses artifacts/ auf:

      Sie finden den privaten Schlüssel, die CSR und das Zertifikat für jeden einzelnen etcd-Memberknoten und die CA:

      Output

      ca.crt ca.csr ca.key etcd1.crt etcd1.csr etcd1.key etcd2.crt etcd2.csr etcd2.key etcd3.crt etcd3.csr etcd3.key

      In diesem Schritt haben wir die CSRs der einzelnen Memberknoten mithilfe des Schlüssels der CA signiert. Im nächsten Schritt kopieren wir die relevanten Dateien in die einzelnen verwalteten Knoten, damit etcd zum Einrichten von TLS-Verbindungen Zugriff auf die entsprechenden Schlüssel und Zertifikate hat.

      Schritt 13 — Kopieren von privaten Schlüsseln und Zertifikaten

      Jeder Knoten muss eine Kopie des selbstsignierten Zertifikats der CA (ca.crt) haben. Jeder etcd-Memberknoten muss auch über einen eigenen privaten Schlüssel und ein Zertifikat verfügen. In diesem Schritt laden wir die Dateien hoch und platzieren sie in einem neuen Verzeichnis namens /etc/etcd/ssl/.

      Öffnen Sie zunächst die Datei playbook.yaml mit Ihrem Editor:

      • nano $HOME/playground/etcd-ansible/playbook.yaml

      Um diese Änderungen an unserem Ansible-Playbook vorzunehmen, aktualisieren Sie zunächst die Eigenschaft path der Aufgabe Create directory for etcd configuration, um das Verzeichnis /etc/etcd/ssl/ zu erstellen:

      ~/playground/etcd-ansible/playbook.yaml

      - hosts: etcd
        ...
        tasks:
          ...
            with_items:
              - absent
              - directory
          - name: "Create directory for etcd configuration"
            file:
              path: "{{ item }}"
              state: directory
              owner: root
              group: root
              mode: 0755
            with_items:
              - /etc/etcd
              - /etc/etcd/ssl
          - name: "Create configuration file for etcd"
            template:
      ...
      

      Fügen Sie dann nach der modifizierten Aufgabe drei weitere Aufgaben hinzu, um die Dateien zu kopieren:

      ~/playground/etcd-ansible/playbook.yaml

      - hosts: etcd
        ...
        tasks:
          ...
          - name: "Copy over the CA certificate"
            copy:
              src: ./artifacts/ca.crt
              remote_src: False
              dest: /etc/etcd/ssl/ca.crt
              owner: root
              group: root
              mode: 0644
          - name: "Copy over the `etcd` member certificate"
            copy:
              src: ./artifacts/{{inventory_hostname}}.crt
              remote_src: False
              dest: /etc/etcd/ssl/server.crt
              owner: root
              group: root
              mode: 0644
          - name: "Copy over the `etcd` member key"
            copy:
              src: ./artifacts/{{inventory_hostname}}.key
              remote_src: False
              dest: /etc/etcd/ssl/server.key
              owner: root
              group: root
              mode: 0600
          - name: "Create configuration file for etcd"
            template:
      ...
      

      Schließen und speichern Sie die Datei playbook.yaml, indem Sie Strg+X drücken, gefolgt von J.

      Führen Sie ansible-playbook erneut aus, um diese Änderungen vorzunehmen:

      • ansible-playbook -i hosts playbook.yaml

      In diesem Schritt haben wir die privaten Schlüssel und Zertifikate erfolgreich in die verwalteten Knoten hochgeladen. Nachdem wir die Dateien kopiert haben, müssen wir nun unsere etcd-Konfigurationsdatei so aktualisieren, dass sie sie nutzt.

      Schritt 14 — Aktivieren von TLS in etcd

      Im letzten Schritt dieses Tutorials werden wir einige Ansible-Konfigurationen aktualisieren, um TLS in einem etcd-Cluster zu aktivieren.

      Öffnen Sie zunächst die Vorlagendatei templates/etcd.conf.yaml.j2 mit Ihrem Editor:

      • nano $HOME/playground/etcd-ansible/templates/etcd.conf.yaml.j2

      Ändern Sie darin alle URLs so, dass sie https als Protokoll anstelle von http verwenden. Fügen Sie außerdem am Ende der Vorlage einen Abschnitt hinzu, um den Speicherort des CA-Zertifikats, des Serverzertifikats und des Serverschlüssels anzugeben:

      ~/playground/etcd-ansible/templates/etcd.conf.yaml.j2

      data-dir: /var/lib/etcd/{{ inventory_hostname }}.etcd
      name: {{ inventory_hostname }}
      initial-advertise-peer-urls: https://{{ hostvars[inventory_hostname]['ansible_facts']['eth1']['ipv4']['address'] }}:2380
      listen-peer-urls: https://{{ hostvars[inventory_hostname]['ansible_facts']['eth1']['ipv4']['address'] }}:2380,https://127.0.0.1:2380
      advertise-client-urls: https://{{ hostvars[inventory_hostname]['ansible_facts']['eth1']['ipv4']['address'] }}:2379
      listen-client-urls: https://{{ hostvars[inventory_hostname]['ansible_facts']['eth1']['ipv4']['address'] }}:2379,https://127.0.0.1:2379
      initial-cluster-state: new
      initial-cluster: {% for host in groups['etcd'] %}{{ hostvars[host]['ansible_facts']['hostname'] }}=https://{{ hostvars[host]['ansible_facts']['eth1']['ipv4']['address'] }}:2380{% if not loop.last %},{% endif %}{% endfor %}
      
      client-transport-security:
        cert-file: /etc/etcd/ssl/server.crt
        key-file: /etc/etcd/ssl/server.key
        trusted-ca-file: /etc/etcd/ssl/ca.crt
      peer-transport-security:
        cert-file: /etc/etcd/ssl/server.crt
        key-file: /etc/etcd/ssl/server.key
        trusted-ca-file: /etc/etcd/ssl/ca.crt
      

      Schließen und speichern Sie die Datei templates/etcd.conf.yaml.j2.

      Führen Sie als Nächstes Ihr Ansible-Playbook aus:

      • ansible-playbook -i hosts playbook.yaml

      Stellen Sie dann eine SSH-Verbindung zu einem der verwalteten Knoten her:

      Führen Sie darauf den Befehl etcdctl endpoint health aus, um zu überprüfen, ob die Endpunkte HTTPS verwenden und ob alle Memberknoten integer sind:

      • etcdctl --cacert /etc/etcd/ssl/ca.crt endpoint health --cluster

      Da unser CA-Zertifikat standardmäßig kein vertrauenswürdiges CA-Stammzertifikat ist, das im Verzeichnis /etc/ssl/certs/ installiert ist, müssen wir es mit dem Flag --cacert an etcdctl übergeben.

      Dadurch erhalten Sie folgende Ausgabe:

      Output

      https://etcd3_private_ip:2379 is healthy: successfully committed proposal: took = 19.237262ms https://etcd1_private_ip:2379 is healthy: successfully committed proposal: took = 4.769088ms https://etcd2_private_ip:2379 is healthy: successfully committed proposal: took = 5.953599ms

      Um zu bestätigen, dass der etcd-Cluster tatsächlich funktioniert, können wir erneut einen Eintrag auf einem etcd-Memberknoten erstellen und ihn dann von einem anderen etcd-Memberknoten abrufen:

      • etcdctl --cacert /etc/etcd/ssl/ca.crt put foo "bar"

      Verwenden Sie ein neues Terminal, um eine SSH-Verbindung zu einem anderen Knoten herzustellen:

      Rufen Sie nun mit dem Schlüssel foo den gleichen Eintrag ab:

      • etcdctl --cacert /etc/etcd/ssl/ca.crt get foo

      Dadurch wird der Eintrag zurückgegeben, der die folgende Ausgabe anzeigt:

      Output

      foo bar

      Sie können das Gleiche mit dem dritten Knoten tun, um zu prüfen, ob alle drei Memberknoten ausgeführt werden.

      Zusammenfassung

      Sie haben nun erfolgreich einen etcd-Cluster mit drei Knoten bereitgestellt, mit TLS gesichert und sich vergewissert, dass er funktioniert.

      etcd ist eine ursprünglich von CoreOS entwickelte Software. Um die Verwendung von etcd in Bezug auf CoreOS zu verstehen, können Sie Folgendes lesen: How To Use Etcdctl and Etcd, CoreOS’s Distributed Key-Value Store. Der Artikel führt Sie außerdem durch die Einrichtung eines dynamischen Erfassungsmodells, das in diesem Tutorial diskutiert, aber nicht vorgeführt wurde.

      Wie am Anfang dieses Tutorials erwähnt, ist etcd ein wichtiger Teil des Kubernetes-Ökosystems. Um mehr über Kubernetes und die Rolle von etcd darin zu erfahren, können Sie An Introduction to Kubernetes (Eine Einführung in Kubernetes) lesen. Wenn Sie etcd als Teil eines Kubernetes-Clusters bereitstellen, sollten Sie wissen, dass es andere Tools gibt, wie z. B. kubespray und kubeadm. Weitere Details dazu finden Sie unter Erstellen eines Kubernetes-Clusters unter Ubuntu 18.04.

      Schließlich wurden in diesem Tutorial auch viele Tools verwendet, die einzeln nicht genau besprochen werden konnten. Im Folgenden finden Sie Links, die Ihnen genauere Informationen zu den einzelnen Tools liefern:



      Source link

      Einrichten eines IKEv2-VPN-Servers mit StrongSwan unter Ubuntu 20.04


      Eine frühere Version dieses Tutorials wurde von Justin Ellingwood und Namo verfasst

      Einführung

      Ein virtuelles privates Netzwerk oder VPN ermöglicht Ihnen die sichere Verschlüsselung des Datenverkehrs auf dem Weg durch nicht vertrauenswürdige Netzwerke, wie z. B. im Café, bei einer Konferenz oder auf einem Flughafen.

      Internet Key Exchange v2 oder IKEv2 ist ein Protokoll, das ein direktes IPSec-Tunneling zwischen Server und Client ermöglicht. In IKEv2-VPN-Implementierungen bietet IPSec eine Verschlüsselung für den Netzwerkverkehr. IKEv2 wird auf einigen Plattformen (OS X 10.11+, iOS 9.1+ und Windows 10) nativ unterstützt, ohne dass zusätzliche Anwendungen erforderlich sind und Client-Hickups werden reibungslos verwaltet.

      In diesem Tutorial richten Sie einen IKEv2-VPN-Server mit StrongSwan auf einem Ubuntu-20.04-Server ein. Anschließend lernen Sie, wie mit Windows-, macOS-, Ubuntu-, iOS- und Android-Clients eine Verbindung zu diesem Server herstellen können.

      Voraussetzungen

      Um diesem Tutorial zu folgen, benötigen Sie:

      Schritt 1 — Installieren von StrongSwan

      Zuerst installieren wir StrongSwan, einen Open-Source-IPSec-Daemon, den wir als unseren VPN-Server konfigurieren werden. Außerdem installieren wir die Komponente „Public Key Infrastructure“ (PKI), sodass wir eine Zertifizierungsstelle (Certificate Authority, CA) erstellen können, die die Anmeldedaten für unsere Infrastruktur bereitstellt.

      Beginnen Sie mit der Aktualisierung des lokalen Paket-Caches:

      Installieren Sie dann die Software durch folgende Eingabe:

      • sudo apt install strongswan strongswan-pki libcharon-extra-plugins libcharon-extauth-plugins

      Das zusätzliche Paket libcharon-extauth-plugins wird verwendet, um sicherzustellen, dass verschiedene Clients sich bei Ihrem Server mit einem gemeinsamen Benutzernamen und einer gemeinsamen Passphrase authentifizieren können.

      Nachdem nun alles installiert ist, fahren wir mit der Erstellung unserer Zertifikate fort.

      Schritt 2 — Erstellen einer Zertifizierungsstelle

      Ein IKEv2-Server erfordert ein Zertifikat, um sich gegenüber Clients zu identifizieren. Um bei der Erstellung des erforderlichen Zertifikats zu helfen, enthält das Paket strongswan-pki ein Dienstprogramm namens pki zur Generierung einer Zertifizierungsstelle und von Serverzertifikaten.

      Zu Beginn erstellen wir einige Verzeichnisse zum Speichern aller Assets, an denen wir arbeiten möchten. Die Verzeichnisstruktur entspricht einigen der Verzeichnisse in /etc/ipsec.d, wohin wir schließlich alle von uns erstellten Objekte verschieben werden:

      • mkdir -p ~/pki/{cacerts,certs,private}

      Dann sperren wir die Berechtigungen, sodass unsere privaten Dateien von anderen Benutzern nicht gesehen werden können:

      Nachdem wir nun über eine Verzeichnisstruktur verfügen, um alles zu speichern, können wir einen Stammschlüssel generieren. Dies wird ein 4096-Bit-RSA-Schlüssel sein, der zum Signieren unserer Stammzertifizierungsstelle verwendet wird.

      Führen Sie diese Befehle zur Generierung des Schlüssels aus:

      • pki --gen --type rsa --size 4096 --outform pem > ~/pki/private/ca-key.pem

      Danach können wir zur Erstellung unserer Stammzertifizierungsstelle übergehen und den gerade generierten Schlüssel zum Signieren des Stammzertifikats verwenden:

      • pki --self --ca --lifetime 3650 --in ~/pki/private/ca-key.pem
      • --type rsa --dn "CN=VPN root CA" --outform pem > ~/pki/cacerts/ca-cert.pem

      Das Flag --lifetime 3650 wird verwendet, um sicherzustellen, dass das Stammzertifikat der Zertifizierungsstelle für 10 Jahre gültig ist. Das Stammzertifikat einer Stelle ändert sich in der Regel nicht, da es an alle Server und Clients, die darauf angewiesen sind, neu verteilt werden müsste. 10 Jahre ist als ein sicherer Standardwert für die Gültigkeitsdauer.

      Sie können den Wert für den unterscheidenden Namen (Distinguished name, DN) in etwas anderes ändern, wenn Sie möchten. Der gewöhnliche Name (Common Name) (CN-Feld) ist hier nur der Indikator, sodass er mit nichts in Ihrer Infrastruktur übereinstimmen muss.

      Nachdem wir nun unsere Stammzertifizierungsstelle eingerichtet haben, können wir ein Zertifikat erstellen, das der VPN-Server verwenden wird.

      Schritt 3 — Erstellen eines Zertifikats für den VPN-Server

      Wir erstellen nun ein Zertifikat und einen Schlüssel für den VPN-Server. Dieses Zertifikat ermöglicht es dem Client, die Authentifizierung des Servers mit dem gerade generierten CA-Zertifikat zu überprüfen.

      Erstellen Sie zunächst einen privaten Schlüssel für den VPN-Server mit dem folgenden Befehl:

      • pki --gen --type rsa --size 4096 --outform pem > ~/pki/private/server-key.pem

      Erstellen und signieren Sie nun das VPN-Serverzertifikat mit dem Schlüssel der Zertifizierungsstelle, den Sie im vorherigen Schritt erstellt haben. Führen Sie den folgenden Befehl aus, ändern Sie jedoch den Common Name (CN) und das Feld Subject Alternate Name (SAN) in den DNS-Namen oder die IP-Adresse Ihres VPN-Servers:

      • pki --pub --in ~/pki/private/server-key.pem --type rsa
      • | pki --issue --lifetime 1825
      • --cacert ~/pki/cacerts/ca-cert.pem
      • --cakey ~/pki/private/ca-key.pem
      • --dn "CN=server_domain_or_IP" --san server_domain_or_IP
      • --flag serverAuth --flag ikeIntermediate --outform pem
      • > ~/pki/certs/server-cert.pem

      Anmerkung: Wenn Sie anstelle eines DNS-Namens eine IP-Adresse verwenden, müssen mehrere --san Einträge angegeben werden. Die Zeile im vorherigen Befehlsblock, in dem Sie den Distinguished Name (--dn ...) angeben, muss mit dem zusätzlichen Eintrag wie die folgende Auszugszeile modifiziert werden:

      --dn "CN=IP address --san @IP_address --san IP_address 
      

      Der Grund für diesen zusätzlichen Eintrag --san @IP_address ist, dass einige Clients prüfen, ob das TLS-Zertifikat sowohl über einen DNS-Eintrag als auch einen IP-Adressen-Eintrag für einen Server verfügt, wenn sie seine Identität überprüfen.

      Die Option –--flag serverAuth wird verwendet, um anzugeben, dass das Zertifikat explizit für die Serverauthentifizierung verwendet wird, bevor der verschlüsselte Tunnel hergestellt wird. Die Option --flag ikeIntermediate wird zur Unterstützung älterere MacOS-Clients verwendet.

      Nachdem wir nun alle TLS/SSL-Dateien erzeugt haben, die StrongSwan benötigt, können wir die Dateien in das Verzeichnis /etc/ipsec.d verschieben, indem wir Folgendes eingeben:

      • sudo cp -r ~/pki/* /etc/ipsec.d/

      In diesem Schritt haben wir ein Zertifikatpaar erstellt, das zur Sicherung der Kommunikation zwischen dem Client und dem Server verwendet wird. Wir haben die Zertifikate auch mit dem CA-Schlüssel signiert, sodass der Client die Authentifizierung des VPN-Servers mit dem CA-Zertifikat überprüfen kann. Nachdem nun alle diese Zertifikate fertig sind, gehen wir zur Konfiguration der Software über.

      Schritt 4 — Konfigurieren von StrongSwan

      StrongSwan hat eine Standardkonfigurationsdatei mit einigen Beispielen, aber wir werden die Konfiguration größtenteils selbst vornehmen müssen. Lassen Sie uns die Datei als Referenz sichern, bevor wir von Grund auf starten:

      • sudo mv /etc/ipsec.conf{,.original}

      Erstellen und öffnen Sie eine neue leere Konfigurationsdatei mit Ihrem bevorzugten Texteditor. Wir verwenden hier nano:

      • sudo nano /etc/ipsec.conf

      Anmerkung: Während Sie diesen Abschnitt zur Konfiguration des Serverteils Ihres VPNs durcharbeiten, werden Sie auf Einstellungen stoßen, die sich auf die linke und die rechte Seite einer Verbindung beziehen. Bei der Arbeit mit IPSec bezieht sich die linke Seite per Konvention auf das lokale System, das Sie konfigurieren, in diesem Fall den Server. Die Anweisungen der rechten Seite in diesen Einstellungen beziehen sich auf entfernte Clients wie Telefone und andere Computer.

      Wenn Sie später in diesem Tutorial mit der Konfiguration von Clients fortfahren, beziehen sich die Client-Konfigurationsdateien mit verschiedenen linken Anweisungen auf sich selbst, und der Server wird mit der Terminologie der rechten Seite bezeichnet.

      Zuerst weisen wir StrongSwan an, den Daemon-Status zur Fehlersuche zu protokollieren und doppelte Verbindungen zulassen. Fügen Sie der Datei diese Zeilen hinzu:

      /etc/ipsec.conf

      config setup
          charondebug="ike 1, knl 1, cfg 0"
          uniqueids=no
      

      Dann erstellen wir einen Konfigurationsabschnitt für unser VPN. Außerdem weisen wir StrongSwan an, IKEv2 VPN-Tunnel zu erstellen und diesen Konfigurationsabschnitt automatisch beim Starten zu laden. Fügen Sie der Datei folgende Zeilen an:

      /etc/ipsec.conf

      . . .
      conn ikev2-vpn
          auto=add
          compress=no
          type=tunnel
          keyexchange=ikev2
          fragmentation=yes
          forceencaps=yes
      

      Wir konfigurieren ebenfalls die Dead-Peer-Erkennung, um alle „unreferenzierten“ Verbindungen zu löschen, falls der Client die Verbindung unerwartet trennt. Fügen Sie diese Zeilen hinzu:

      /etc/ipsec.conf

      . . .
      conn ikev2-vpn
          . . .
          dpdaction=clear
          dpddelay=300s
          rekey=no
      

      Als Nächstes konfigurieren wir die IPSec-Parameter der „linken“ Seite des Servers. Jede der folgenden Parameter stellt sicher, dass der Server für die Annahme von Verbindungen von Clients und für seine korrekte Identifizierung konfiguriert ist. Sie fügen jede dieser Einstellungen der Datei /etc/ipsec.conf hinzu, sobald Sie sich damit vertraut gemacht haben, was sie sind und warum sie verwendet werden:

      • left =%any Der Wert %any stellt sicher, dass der Server die Netzwerkschnittstelle, an der er eingehende Verbindungen empfängt, für die nachfolgende Kommunikation mit Clients verwendet. Wenn Sie beispielsweise einen Client über ein privates Netzwerk verbinden, verwendet der Server für den Rest der Verbindung die private IP-Adresse, an der er den Datenverkehr empfängt.
      • leftid=@server_domain_or_IP Diese Option steuert den Namen, den der Server den Clients präsentiert. In Kombination mit der nächsten Option leftcert, stellt die Option leftid sicher, dass der konfigurierte Name des Servers und der im öffentlichen Zertifikat enthaltene Dinstinguished Name (DN) übereinstimmen.
      • leftcert=server-cert.pem Diese Option ist der Pfad zum öffentlichen Zertifikat für den Server, den Sie in Schritt 3 konfiguriert haben. Ohne ihn kann sich der Server nicht bei Clients authentifizieren und die Aushandlung der IKEv2-Einrichtung nicht beenden.
      • leftsendcert=always Der Wert always stellt sicher, dass jeder Client, der sich mit dem Server verbindet, als Teil des anfänglichen Verbindungsaufbaus immer eine Kopie des öffentlichen Zertifikats des Servers erhält.
      • leftsubnet=0.0.0.0/0 Die letzte Option der „linken“ Seite, die Sie hinzufügen werden, informiert Clients über die Subnetze, die hinter dem Server erreichbar sind. In diesem Fall wird 0.0.0.0/0 verwendet, um den gesamten Satz der IPv4-Adressen zu repräsentieren, was bedeutet, dass der Server Clients standardmäßig anweist, ihren gesamten Datenverkehr über das VPN zu senden.

      Nachdem Sie nun mit jeder der entsprechenden Optionen der „linken“ Seite vertraut sind, fügen Sie sie alle wie folgt zur Datei hinzu:

      /etc/ipsec.conf

      . . .
      conn ikev2-vpn
          . . .
          left=%any
          leftid=@server_domain_or_IP
          leftcert=server-cert.pem
          leftsendcert=always
          leftsubnet=0.0.0.0/0
      

      Anmerkung: Geben Sie bei der Konfiguration der Server-ID (leftid) das @-Zeichen nur dann an, wenn Ihr VPN-Server durch einen Domänennamen identifiziert werden soll:

      /etc/ipsec.conf

          . . .    leftid=@vpn.example.com
          . . .
      

      Wenn der Server durch seine IP-Adresse identifiziert werden soll, geben Sie einfach die IP-Adresse ein:

      /etc/ipsec.conf

          . . .
          leftid=your_server_ip
          . . .
      

      Als Nächstes können wir die IPSec-Parameter der „rechten“ Seite des Clients konfigurieren. Jede der folgenden Parameter teilt dem Server mit, wie Verbindungen von Clients akzeptiert werden sollen, wie sich Clients beim Server authentifizieren sollen und welche privaten IP-Adressbereiche und DNS-Server diese Clients verwenden werden. Fügen Sie jede dieser Einstellungen der Datei /etc/ipsec.conf hinzu, sobald Sie sich damit vertraut gemacht haben, was sie sind und warum sie verwendet werden:

      • right=%any Die Option %any für die rechte Seite der Verbindung weist den Server an, eingehende Verbindungen von jedem Remote-Client anzunehmen.
      • rightid=%any Diese Option stellt sicher, dass der Server keine Verbindungen von Clients ablehnt, die eine Identität angeben, bevor der verschlüsselte Tunnel hergestellt ist.
      • rightauth=eap-mschapv2 Diese Option konfiguriert die Authentifizierungsmethode, die Clients zur Authentifizierung gegenüber dem Server verwenden werden. eap-mschapv2 wird hier für eine breite Kompatibilität verwendet, um Clients wie Windows-, MacOS- und Android-Geräte zu unterstützen.
      • rightsourceip=10.10.10.0/24 Diese Option weist den Server an, Clients private IP-Adressen aus dem angegebenen IP-Pool 10.10.10.0/24 zuzuweisen.
      • rightdns=8.8.8.8,8.8.4.4 Diese IP-Adressen sind die öffentlichen DNS-Auflöser von Google. Sie können geändert werden, um andere öffentliche Auflöser, die Auflösung des VPN-Servers oder einen anderen Auflöser zu verwenden, den die Clients erreichen können.
      • rightsendcert=never Diese Option weist den Server an, dass Clients kein Zertifikat senden müssen, um sich selbst zu authentifizieren.

      Nachdem Sie nun mit den erforderlichen Optionen der „rechten“ Seite vertraut sind, fügen Sie die folgenden Zeilen in /etc/ipsec.conf ein:

      /etc/ipsec.conf

      . . .
      conn ikev2-vpn
          . . .
          right=%any
          rightid=%any
          rightauth=eap-mschapv2
          rightsourceip=10.10.10.0/24
          rightdns=8.8.8.8,8.8.4.4
          rightsendcert=never
      

      Nun werden wir StrongSwan anweisen, den Client beim Verbindungsaufbau nach den Anmeldedaten der Benutzer zu fragen:

      /etc/ipsec.conf

      . . .
      conn ikev2-vpn
          . . .
          eap_identity=%identity
      

      Zum Schluss fügen Sie die folgenden Zeilen hinzu, um Linux-, Windows-, macOS-, iOS- und Android-Clients zu unterstützen. Diese Zeilen spezifizieren die verschiedenen Schlüsselaustausch-, Hashing-, Authentifizierungs- und Verschlüsselungsalgorithmen (allgemein als Cipher Suites bezeichnet), die StrongSwan den verschiedenen Clients zur Verfügung stellt:

      /etc/ipsec.conf

      . . .
      conn ikev2-vpn
          . . .
          ike=chacha20poly1305-sha512-curve25519-prfsha512,aes256gcm16-sha384-prfsha384-ecp384,aes256-sha1-modp1024,aes128-sha1-modp1024,3des-sha1-modp1024!
          esp=chacha20poly1305-sha512,aes256gcm16-ecp384,aes256-sha256,aes256-sha1,3des-sha1!
      

      Jede unterstützte Cipher Suite wird durch ein Komma von den anderen abgegrenzt. Beispielsweise ist chacha20poly1305-sha512-curve25519-prfsha512 eine Suite, und aes256gcm16-sha384-prfsha384-ecp384 ist eine andere. Die hier aufgelisteten Cipher Suits sind so ausgewählt, dass sie die größtmögliche Kompatibilität zwischen Windows-, macOS-, iOS-, Android- und Linux-Clients gewährleisten.

      Die vollständige Konfigurationsdatei sollte wie folgt aussehen:

      /etc/ipsec.conf

      config setup
          charondebug="ike 1, knl 1, cfg 0"
          uniqueids=no
      
      conn ikev2-vpn
          auto=add
          compress=no
          type=tunnel
          keyexchange=ikev2
          fragmentation=yes
          forceencaps=yes
          dpdaction=clear
          dpddelay=300s
          rekey=no
          left=%any
          leftid=@server_domain_or_IP
          leftcert=server-cert.pem
          leftsendcert=always
          leftsubnet=0.0.0.0/0
          right=%any
          rightid=%any
          rightauth=eap-mschapv2
          rightsourceip=10.10.10.0/24
          rightdns=8.8.8.8,8.8.4.4
          rightsendcert=never
          eap_identity=%identity
          ike=chacha20poly1305-sha512-curve25519-prfsha512,aes256gcm16-sha384-prfsha384-ecp384,aes256-sha1-modp1024,aes128-sha1-modp1024,3des-sha1-modp1024!
          esp=chacha20poly1305-sha512,aes256gcm16-ecp384,aes256-sha256,aes256-sha1,3des-sha1!
      

      Speichern und schließen Sie die Datei, nachdem Sie überprüft haben, dass Sie jede Zeile korrekt hinzugefügt haben. Wenn Sie nano verwendet haben, drücken Sie STRG+X, Y, dann die EINGABETASTE.

      Nachdem wir nun die VPN-Parameter konfiguriert haben, gehen wir zur Erstellung eines Kontos über, damit unsere Benutzer eine Verbindung zum Server herstellen können.

      Schritt 5 — Konfigurieren der VPN-Authentifizierung

      Unser VPN-Server ist nun so konfiguriert, dass er Client-Verbindungen akzeptiert, aber wir haben noch keine Anmeldedaten konfiguriert. Wir müssen einige Dinge in einer speziellen Konfigurationsdatei namens ipsec.secrets konfigurieren:

      • Wir müssen StrongSwan mitteilen, wo der private Schlüssel für unser Serverzertifikat zu finden ist, damit sich der Server gegenüber den Clients authentifizieren kann.
      • Außerdem müssen wir eine Liste von Benutzern erstellen, die eine Verbindung mit dem VPN herstellen dürfen.

      Öffnen wie die Datei „Secrets“ zum Bearbeiten:

      • sudo nano /etc/ipsec.secrets

      Zuerst teilen wir StrongSwan mit, wo unser privater Schlüssel zu finden ist:

      /etc/ipsec.secrets

      : RSA "server-key.pem"
      

      Dann definieren wir die Anmeldedaten des Benutzers. Sie können jede beliebige Kombination von Benutzername und Passwort zusammenstellen, die Ihnen gefällt:

      /etc/ipsec.secrets

      your_username : EAP "your_password"
      

      Speichern und schließen Sie die Datei. Nachdem wir die Arbeit mit den VPN-Parametern beendet haben, starten wir den VPN-Dienst neu, damit unsere Konfiguration übernommen wird:

      • sudo systemctl restart strongswan-starter

      Nachdem der VPN-Server nun sowohl mit den Serveroptionen als auch mit den Anmeldedaten der Benutzer vollständig konfiguriert ist, ist es an der Zeit, mit der Konfiguration des wichtigsten Teils fortzufahren: der Firewall.

      Schritt 6 — Konfigurieren der Firewall & Kernel-IP-Weiterleitung

      Nachdem die Konfiguration von StrongSwan abgeschlossen ist, müssen wir die Firewall so konfigurieren, dass sie VPN-Verkehr durchlässt und weiterleitet.

      Wenn Sie dem Tutorial zur Ersteinrichtung des Servers gefolgt sind, sollten Sie eine UFW-Firewall aktiviert haben. Wenn Sie UFW noch nicht konfiguriert haben, sollten Sie zunächst mit dem Hinzufügen einer Regel beginnen, um SSH-Verbindungen durch die Firewall zuzulassen, damit Ihre aktuelle nicht geschlossen wird, wenn Sie UFW aktivieren:

      Aktivieren Sie dann die Firewall durch folgende Eingabe:

      Fügen Sie dann eine Regel hinzu, um den UDP-Verkehr zu den IPSec-Standardports 500 und 4500 zulassen:

      • sudo ufw allow 500,4500/udp

      Als Nächstes öffnen wir eine der Konfigurationsdateien von UFW, um einige niedrigstufige Richtlinien für das Routing und die Weiterleitung von IPSec-Paketen hinzuzufügen. Zuvor müssen wir jedoch herausfinden, welche Netzwerkschnittstelle auf unserem Server für den Internetzugang verwendet wird. Finden Sie diese Schnittstelle, indem Sie das mit der Standardroute verknüpfte Gerät abfragen:

      Ihre öffentliche Schnittstelle sollte dem Wort „dev“ folgen. Dieses Ergebnis zeigt beispielsweise die im folgenden Beispiel hervorgehobene Schnittstelle eth0 an:

      Output

      default via your_server_ip dev eth0 proto static

      Wenn Sie Ihre öffentliche Netzwerkschnittstelle haben, öffnen Sie die Datei /etc/ufw/before.rules in Ihrem Texteditor. Die Regeln in dieser Datei werden der Firewall vor den übrigen üblichen Eingabe- und Ausgaberegeln hinzugefügt. Sie werden verwendet, um die Netzwerkadressübersetzung (Network Address Translation, NAT) zu konfigurieren, damit der Server Verbindungen zu und von Clients und dem Internet korrekt weiterleiten kann.

      • sudo nano /etc/ufw/before.rules

      Fügen Sie am Anfang der Datei (vor der Zeile *filter) den folgenden Konfigurationsblock hinzu. Ändern Sie jede Instanz von eth0 in der obigen Konfiguration so, dass sie mit dem Schnittstellennamen übereinstimmt, den Sie mit ip route gefunden haben. Die Zeilen *nat erstellen Regeln, damit die Firewall den Datenverkehr zwischen den VPN-Clients und dem Internet korrekt weiterleiten und manipulieren kann. Die Zeile *mangle passt die maximale Paketsegmentgröße an, um potenzielle Probleme mit bestimmten VPN-Clients zu verhindern:

      /etc/ufw/before.rules

      *nat
      -A POSTROUTING -s 10.10.10.0/24 -o eth0 -m policy --pol ipsec --dir out -j ACCEPT
      -A POSTROUTING -s 10.10.10.0/24 -o eth0 -j MASQUERADE
      COMMIT
      
      *mangle
      -A FORWARD --match policy --pol ipsec --dir in -s 10.10.10.0/24 -o eth0 -p tcp -m tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1361:1536 -j TCPMSS --set-mss 1360
      COMMIT
      
      *filter
      :ufw-before-input - [0:0]
      :ufw-before-output - [0:0]
      :ufw-before-forward - [0:0]
      :ufw-not-local - [0:0]
      . . .
      

      Fügen Sie als Nächstes nach den Zeilen *filter und Kettendefinitionen einen weiteren Konfigurationsblock hinzu:

      /etc/ufw/before.rules

      . . .
      *filter
      :ufw-before-input - [0:0]
      :ufw-before-output - [0:0]
      :ufw-before-forward - [0:0]
      :ufw-not-local - [0:0]
      
      -A ufw-before-forward --match policy --pol ipsec --dir in --proto esp -s 10.10.10.0/24 -j ACCEPT
      -A ufw-before-forward --match policy --pol ipsec --dir out --proto esp -d 10.10.10.0/24 -j ACCEPT
      

      Diese Zeilen weisen die Firewall an, den ESP-Datenverkehr (Encapsulating Security Payload-Datenverkehr) weiterzuleiten, sodass die VPN-Clients eine Verbindung herstellen können. ESP bietet für unsere VPN-Pakete zusätzliche Sicherheit, da sie nicht vertrauenswürdige Netzwerke durchqueren.

      Wenn Sie fertig sind, speichern und schließen Sie die Datei, nachdem Sie überprüft haben, dass Sie jede Zeile korrekt hinzugefügt haben. Wenn Sie nano verwendet haben, drücken Sie STRG+X, Y, dann die EINGABETASTE.

      Vor dem Neustart der Firewall werden wir einige Netzwerk-Kernel-Parameter ändern, um die Weiterleitung von einer Schnittstelle zu einer anderen zu ermöglichen. Die Datei, die diese Einstellungen steuert, heißt /etc/ufw/sysctl.conf. In dieser Datei müssen wir einige Dinge konfigurieren.

      Zuerst muss die IPv4-Paketweiterleitung eingeschaltet werden, damit der Datenverkehr zwischen dem VPN und den öffentlich zugänglichen Netzwerkschnittstellen auf dem Server ausgetauscht werden kann. Als Nächstes deaktivieren wir die Path-MTU-Erkennung, um Probleme mit der Paketfragmentierung zu verhindern. Abschließend werden wir weder ICMP-Weiterleitungen akzeptieren noch ICMP-Weierleitungen senden, um Man-in-the-Middle-Angriffe zu verhindern.

      Öffnen Sie die Konfigurationsdatei der UFW-Kernel-Parameter in nano oder Ihrem bevorzugten Texteditor:

      • sudo nano /etc/ufw/sysctl.conf

      Fügen Sie nun am Ende der Datei die folgende Einstellung net/ipv4/ip_forward=1 hinzu, um die Weiterleitung von Paketen zwischen Schnittstellen zu ermöglichen:

      /etc/ufw/sysctl.conf

      . . .
      net/ipv4/ip_forward=1
      

      Blockieren Sie als Nächstes das Senden und Empfangen von ICMP-Umleitungspaketen, indem Sie die folgenden Zeilen am Ende der Datei hinzufügen:

      /etc/ufw/sysctl.conf

      . . .
      net/ipv4/conf/all/accept_redirects=0
      net/ipv4/conf/all/send_redirects=0
      

      Deaktivieren Sie abschließend die Path-MTU-Erkennung, indem Sie diese Zeile am Ende der Datei hinzufügen:

      /etc/ufw/sysctl.conf

      . . .
      net/ipv4/ip_no_pmtu_disc=1
      

      Speichern Sie die Datei, wenn Sie fertig sind. Jetzt können wir alle unsere Änderungen durch Deaktivieren und erneutes Aktivieren der Firewall aktivieren, da UFW diese Einstellungen bei jedem Neustart anwendet:

      • sudo ufw disable
      • sudo ufw enable

      Sie werden dazu aufgefordert, den Vorgang zu bestätigen. Geben Sie Y ein, um UFW mit den neuen Einstellungen erneut zu aktivieren.

      Schritt 7 — Testen der VPN-Verbindung unter Windows, macOS, Ubuntu, iOS und Android

      Nachdem nun alles eingerichtet ist, ist es Zeit, es auszuprobieren. Zuerst müssen Sie das von Ihnen erstellte CA-Zertifikat kopieren und auf Ihrem/Ihren Client-Gerät(en) installieren, das/die sich mit Ihrem Server verbindet/verbinden. Am einfachsten geht das, indem Sie sich bei Ihrem Server anmelden und den Inhalt der Zertifikatsdatei ausgeben:

      • cat /etc/ipsec.d/cacerts/ca-cert.pem

      Sie sehen eine Ausgabe, die dieser ähnelt:

      Output

      -----BEGIN CERTIFICATE----- MIIFNDCCAxygAwIBAgIIHCsidG5mXzgwDQYJKoZIhvcNAQEMBQAwODELMAkGA1UE . . . H2YUdz8XNHrJHvMQKWFpi0rlEcMs+MSXPFWE3Q7UbaZJ/h8wpSldSUbQRUlphExJ dJ4PX+MUJO/vjG1/ie6Kh25xbBAc3qNq8siiJZDwrg6vjEK7eiZ1rA== -----END CERTIFICATE-----

      Kopieren Sie diese Ausgabe auf Ihren Computer, einschließlich der Zeilen --BEGIN CERTIFICATE---- und --END CERTIFICATE--, und speichern Sie sie in einer Datei mit einem erkennbaren Namen wie ca-cert.pem. Stellen Sie sicher, dass die von Ihnen erstellte Datei die Erweiterung .pem hat.

      Alternativ können Sie SFTP verwenden, um die Datei auf Ihren Computer zu übertragen.

      Sobald die Datei ca-cert.pem auf Ihren Computer heruntergeladen haben, können Sie die Verbindung zum VPN einrichten.

      Herstellen der Verbindung von Windows

      Es gibt mehrere Möglichkeiten, das Stammzertifikat zu importieren und Windows für die Verbindung mit einem VPN zu konfigurieren. Die erste Methode verwendet grafische Tools für jeden Schritt. Die zweite Methode verwendet PowerShell-Befehle, die in Skripts geschrieben und an Ihre VPN-Konfiguration angepasst werden können.

      Anmerkung: Diese Anweisungen wurden in Windows 10-Installationen getestet, die die Versionen 1903 und 1909 ausführen.

      Konfigurieren von Windows mit grafischen Tools

      Importieren Sie zunächst das Stammzertifikat, indem Sie die folgenden Schritte ausführen:

      1. Drücken Sie WINDOWS+R, um das Dialogfeld Ausführen aufzurufen, und geben Sie mmc.exe zum Starten der Windows Managementkonsole ein.
      2. Navigieren Sie im Menü Datei zu Snap-In hinzufügen oder entfernen, wählen Sie aus der Liste der verfügbaren Snap-Ins Zertifikate aus und klicken Sie auf Hinzufügen.
      3. Wir wollen, dass das VPN mit jedem Benutzer funktioniert, daher wählen wir Computerkonto und klicken auf Weiter.
      4. Wir konfigurieren Dinge auf dem lokalen Computer, daher wählen wir Lokaler Computer und klicken auf Fertigstellen.
      5. Erweitern Sie unter dem Knoten Konsolenstamm den Eintrag Zertifikate (Lokaler Computer), erweitern Sie Vertrauenswürdige Stammzertifizierungsstellen und wählen Sie dann den Eintrag** Zertifikate**: Zertifikatsansicht.

      6. Wählen Sie im Menü Aktion Alle Aufgaben aus und klicken Sie auf Improtieren, um den Assistenten für den Zertifikatimport anzuzeigen. Klicken Sie auf Weiter, um die Einführung zu überspringen.

      7. Klicken Sie auf dem Bildschirm Zu importierende Datei die Schaltfläche Durchsuchen, stellen Sie sicher, dass Sie den Dateityp von „X.509-Zertifikat (.cer;.crt)“ in „Alle Dateien (.)“ ändern und wählen Sie die Datei ca-cert.pem, die Sie gespeichert haben. Klicken Sie dann auf Weiter.

      8. Stellen Sie sicher, dass der Zertifikatspeicher auf Vertrauenswürdige Stammzertifizierungsstellen eingestellt ist und klicken Sie auf Weiter.

      9. Klicken Sie auf Fertigstellen, um das Zertifikat zu importieren.

      Konfigurieren Sie das VPN dann mit diesen Schritten:

      1. Starten Sie die Systemsteuerung, navigieren Sie dann zum Netzwerk- und Freigabecenter.
      2. Klicken Sie auf Einrichten einer neuen Verbindung oder eines neuen Netzwerks und wählen Sie Mit einem Arbeitsplatz verbinden.
      3. Wählen Sie Meine Internetverbindung (VPN) verwenden.
      4. Geben Sie die Details des VPN-Servers ein. Geben Sie den Domänennamen oder die IP-Adresse des Servers in das Feld Internetadresse ein und geben Sie dann den Zielnamen mit einer Beschreibung Ihrer VPN-Verbindung ein. Klicken Sie dann auf Fertig.

      Konfigurieren von Windows mit PowerShell

      Um das Stamm-CA-Zertifikat mit PowerShell zu importieren, öffnen Sie zunächst eine PowerShell-Eingabeaufforderung mit Administratorberechtigungen. Klicken Sie dazu mit der rechten Maustaste auf das Symbol im Startmenü und wählen Sie Windows PowerShell (Admin). Sie können auch eine Eingabeaufforderung als Administrator öffnen und powershell eingeben.

      Als Nächstes importieren wir das Zertifikat mit dem Powershell cmdlet Import-Certificate. Im folgenden Befehl wird mit dem ersten Argument -CertStoreLocation sichergestellt, dass das Zertifikat in dem Speicher der Vertrauenswürdigen Stammzertifizierungsstelle des Computers importiert wird, damit alle Programme und Benutzer das Zertifikat des VPN-Servers überprüfen können. Das Argument -FilePath sollte auf den Speicherort verweisen, in den Sie das Zertifikat kopiert haben. Im folgenden Beispiel lautet der Pfad C:UserssammyDocumentsca-cert.pem. Stellen Sie sicher, dass Sie den Befehl so bearbeiten, dass er mit dem von Ihnen verwendeten Speicherort übereinstimmt.

      • Import-Certificate `
      • -CertStoreLocation cert:LocalMachineRoot `
      • -FilePath C:userssammyDocumentsca-cert.pem

      Der Befehl gibt etwas wie das Folgende aus:

      Output

      PSParentPath: Microsoft.PowerShell.SecurityCertificate::LocalMachineRoot Thumbprint Subject ---------- ------- DB00813B4087E9367861E8463A60CEA0ADC5F002 CN=VPN root CA

      Um nun das VPN mit PowerShell zu konfigurieren, führen Sie den folgenden Befehl aus. Ersetzen Sie den DNS-Namen oder die IP-Adresse Ihres Servers in der Zeile -Serveraddress. Die verschiedenen Flags stellen sicher, dass Windows korrekt mit den entsprechenden Sicherheitsparametern konfiguriert wird, die den Optionen entsprechen, die Sie in /etc/ipsec.conf festgelegt haben.

      • Add-VpnConnection -Name "VPN Connection" `
      • -ServerAddress "server_domain_or_IP" `
      • -TunnelType "IKEv2" `
      • -AuthenticationMethod "EAP" `
      • -EncryptionLevel "Maximum" `
      • -RememberCredential `

      Wenn der Befehl erfolgreich ist, gibt es keine Ausgabe. Um zu bestätigen, dass das VPN richtig konfiguriert ist, verwenden Sie das cmdlet Get-VPNConnection:

      • Get-VpnConnection -Name "VPN Connection"

      Sie erhalten eine Ausgabe wie die folgende:

      Output

      Name : VPN Connection ServerAddress : your_server_ip AllUserConnection : False Guid : {B055A1AB-175C-4028-B4A8-D34309A2B20E} TunnelType : Ikev2 AuthenticationMethod : {Eap} EncryptionLevel : Maximum L2tpIPsecAuth : UseWinlogonCredential : False EapConfigXmlStream : #document ConnectionStatus : Disconnected RememberCredential : True SplitTunneling : False DnsSuffix : IdleDisconnectSeconds : 0

      Standardmäßig wählt Windows ältere und langsamere Algorithmen. Führen Sie das cmdlet Set-VpnConnectionIPsecConfiguration aus, um die Verschlüsselungsparameter zu aktualisieren, die Windows für den IKEv2-Schlüsselaustausch verwendet und um Pakete zu verschlüsseln:

      • Set-VpnConnectionIPsecConfiguration -Name "VPN Connection" `
      • -AuthenticationTransformConstants GCMAES256 `
      • -CipherTransformConstants GCMAES256 `
      • -DHGroup ECP384 `
      • -IntegrityCheckMethod SHA384 `
      • -PfsGroup ECP384 `
      • -EncryptionMethod GCMAES256

      Anmerkung: Wenn Sie die VPN-Verbindung löschen und mit verschiedenen Optionen neu konfigurieren möchten, können Sie das cmdlet Remove-VpnConnection ausführen.

      • Remove-VpnConnection -Name "VPN Connection" -Force

      Das Flag -Force wird übersprungen und Sie werden aufgefordert, das Entfernen zu bestätigen. Wenn Sie versuchen, die VPN-Verbindung mit diesem Befehl zu entfernen, müssen Sie vom VPN getrennt sein.

      Herstellen einer Verbindung mit dem VPN

      Sobald Sie das Zertifikat importiert und das VPN mit einer der beiden Methoden konfiguriert haben, wird Ihre neue VPN-Verbindung unter der Liste der Netzwerke sichtbar. Wählen Sie das VPN und klicken Sie auf Verbinden. Sie werden zur Eingabe Ihres Benutzernamens und Ihres Passworts aufgefordert. Geben Sie sie ein, klicken Sie auf OK, und Sie werden verbunden.

      Herstellen einer Verbindung von macOS

      Folgen Sie diesen Schritten, um das Zertifikat zu importieren:

      1. Doppelklicken Sie auf die Zertifikatsdatei. Keychain Access wird mit einem Dialogfeld eingeblendet, in dem es heißt „Keychain Access is trying to modify the system keychain. Enter your password to allow this.“ (Keychain Access versucht die System-Keychain zu ändern. Geben Sie Ihr Passwort ein, um dies zuzulassen).
      2. Geben Sie Ihr Passwort ein, klicken Sie dann auf Modify Keychain (Keychain ändern)
      3. Doppelklicken Sie auf das neu importierte VPN-Zertifikat. Dadurch wird ein kleines Eigenschaftenfenster eingeblendet, in dem Sie die Vertrauensstufen angeben können. Setzen Sie IP Security (IPSec) auf Always Trust (Immer vertrauen) und Sie werden erneut zur Eingabe Ihres Passworts aufgefordert. Diese Einstellung wird nach der Eingabe des Passworts automatisch gespeichert.

      Nachdem das Zertifikat importiert und vertrauenswürdig ist, konfigurieren Sie die VPN-Verbindung nun mit diesen Schritten:

      1. Gehen Sie zu Systemeinstellungen und wählen Sie Netzwerk.
      2. Klicken Sie auf die kleine „Plus“-Schaltfläche unten links in der Liste der Netzwerke.
      3. Stellen Sie in dem angezeigten Popup-Fenster Schnittstelle auf VPN, setzen Sie den VPN-Typ auf IKEv2 und geben Sie der Verbindung einen Namen.
      4. Geben Sie im Feld Server und Remote ID den Domänennamen oder die IP-Adresse des Servers ein. Lassen Sie Lokale ID leer.
      5. Klicken Sie auf Authentifizierungseinstellungen, wählen Sie Bentuzername und geben Sie Ihren Benutzernamen und Ihr Passwort ein, das Sie für Ihren VPN-Benutzer konfiguriert haben. Klicken Sie dann auf OK.

      Klicken Sie abschließend auf Verbinden, um sich mit dem VPN zu verbinden. Sie sollten nun mit dem VPN verbunden sein.

      Herstellen einer Verbindung von Ubuntu

      Um eine Verbindung von einem Ubuntu-Rechner herzustellen, können Sie StrongSwan als Dienst einrichten und verwalten oder bei jeder gewünschten Verbindung einen einmaligen Befehl verwenden. Für beides stehen Anweisungen zur Verfügung.

      Verwalten von StrongSwan als Dienst

      Um StrongSwan als Dienst zu verwalten, müssen Sie die folgenden Konfigurationsschritte durchführen.

      Aktualisieren Sie zunächst Ihren lokalen Paket-Cache mit apt

      Installieren Sie als Nächstes StrongSwan und die erforderlichen Plugins für die Authentifizierung:

      • sudo apt install strongswan libcharon-extra-plugins

      Jetzt benötigen Sie im Verzeichnis /etc/ipsec.d/cacerts eine Kopie des CA-Zertifikats, damit Ihr Client die Identität des Servers überprüfen kann. Führen Sie den folgenden Befehl aus, um die Datei ca-cert.pem in den richtigen Speicherort zu kopieren:

      • sudo cp /tmp/ca-cert.pem /etc/ipsec.d/cacerts

      Um sicherzustellen, dass das VPN nur bei Bedarf ausgeführt wird, deaktivieren Sie mit systemctl die automatische Ausführung von StrongSwan:

      • sudo systemctl disable --now strongswan-starter

      Konfigurieren Sie als Nächstes den Benutzernamen und das Passwort, das Sie zur Authentifizierung auf dem VPN-Server verwenden werden. Bearbeiten Sie /etc/ipsec.secrets mit nano oder Ihrem bevorzugten Editor:

      • sudo nano /etc/ipsec.conf

      Fügen Sie die folgende Zeile hinzu und bearbeiten Sie die hervorgehobenen Werte für Benutzername und Passwort, damit sie mit denen übereinstimmen, die Sie auf dem Server konfiguriert haben:

      /etc/ipsec.conf

      your_username : EAP "your_password"
      

      Bearbeiten Sie abschließend die Datei /etc/ipsec.conf, um Ihren Client so zu konfigurieren, dass er mit der Konfiguration des Servers übereinstimmt:

      /etc/ipsec.conf

      config setup
      
      conn ikev2-rw
          right=server_domain_or_IP
          # This should match the `leftid` value on your server's configuration
          rightid=server_domain_or_IP
          rightsubnet=0.0.0.0/0
          rightauth=pubkey
          leftsourceip=%config
          leftid=username
          leftauth=eap-mschapv2
          eap_identity=%identity
          auto=start
      

      Um sich mit dem VPN zu verbinden, geben Sie Folgendes ein:

      • sudo systemctl start strongswan-starter

      Um sich wieder zu trennen, geben Sie Folgendes ein:

      • sudo systemctl stop strongswan-starter

      Verwenden des Clients charon-cmd für einmalige Verbindungen

      Um StrongSwan als Dienst zu verwalten, müssen Sie die folgenden Konfigurationsschritte durchführen.

      Aktualisieren Sie zunächst Ihren lokalen Paket-Cache mit apt

      Installieren Sie als Nächstes StrongSwan und die erforderlichen Plugins für die Authentifizierung:

      • sudo apt install strongswan libcharon-extra-plugins

      Jetzt benötigen Sie im Verzeichnis /etc/ipsec.d/cacerts eine Kopie des CA-Zertifikats, damit Ihr Client die Identität des Servers überprüfen kann. Führen Sie den folgenden Befehl aus, um die Datei ca-cert.pem in den richtigen Speicherort zu kopieren:

      • sudo cp /tmp/ca-cert.pem /etc/ipsec.d/cacerts

      Zu diesem Zeitpunkt können Sie sich mit charon-cmd unter Verwendung des CA-Zertifikats des Servers, der IP-Adresse des VPN-Servers und des von Ihnen konfigurierten Benutzernamens mit dem VPN-Server verbinden.

      Führen Sie den folgenden Befehl aus, wann immer Sie eine Verbindung mit dem VPN herstellen möchten:

      • sudo charon-cmd --cert ca-cert.pem --host vpn_domain_or_IP --identity your_username

      Geben Sie, wenn Sie dazu aufgefordert werden, das Passwort des VPN-Benutzers ein und Sie werden mit dem VPN verbunden. Um die Verbindung zu trennen, drücken Sie im Terminal Strg+C und warten Sie, bis die Verbindung geschlossen wird.

      Herstellen einer Verbindung von iOS

      Führen Sie die folgenden Schritte aus, um die VPN-Verbindung auf einem iOS-Gerät zu konfigurieren:

      1. Senden Sie sich selbst eine E-Mail mit dem Stammzertifikat im Anhang.
      2. Öffnen Sie die E-Mail auf Ihrem iOS-Gerät und tippen Sie auf die angehängte Zertifikatdatei, tippen Sie dann auf Installieren und geben Sie Ihren Passcode ein. Sobald diese installiert ist, tippen Sie auf Fertig.
      3. Gehen Sie zu Einstellungen, Allgemein, VPN und tippen Sie auf VPN-Konfiguration hinzufügen. Daraufhin wird der Bildschirm zur Konfiguration der VPN-Verbindung angezeigt.
      4. Tippen Sie auf Typ und wählen Sie IKEv2.
      5. Geben Sie im Feld Beschreibung einen kurzen Namen für die VPN-Verbindung ein. Dieser Name kann beliebig sein.
      6. Geben Sie im Feld Server und Remote ID den Domänennamen oder die IP-Adresse des Servers ein. Das Feld Lokale ID kann leer gelassen werden.
      7. Geben Sie Ihren Benutzernamen und Ihr Passwort in den Abschnitt Authentifizierung ein, und tippen Sie dann auf Fertig.
      8. Wählen Sie die gerade erstellte VPN-Verbindung, tippen Sie auf die Schaltfläche oben auf der Seite und schon sind Sie verbunden.

      Herstellen einer Verbindung von Android

      Folgen Sie diesen Schritten, um das Zertifikat zu importieren:

      1. Senden Sie sich selbst eine E-Mail mit dem CA-Zertifikat im Anhang. Speichern Sie das CA-Zertifikat in Ihrem Download-Ordner.
      2. Laden Sie den StrongSwan VPN-Client aus dem Play-Store herunter.
      3. Öffnen Sie die App. Tippen Sie auf das Symbol “Mehr” () in der rechten oberen Ecke und wählen Sie CA-Zertifikate.
      4. Tippen Sie erneut auf das Symbol “Mehr” () in der rechten oberen Ecke. Wählen Sie Zertifikat importieren.
      5. Navigieren Sie zu der CA-Zertifikatsdatei in Ihrem Donwload-Ordner und wählen Sie sie aus, um sie in die Anwendung zu importieren.

      Nachdem das Zertifikat nun in die StrongSwan-Anwendung importiert wurde, können Sie die VPN-Verbindung mit diesen Schritten konfigurieren:

      1. Tippen Sie oben in der App auf VPN-PROFIL HINZUFÜGEN.
      2. Geben Sie bei Server den Domänennamen oder die öffentliche IP-Adresse Ihres VPN-Servers ein.
      3. Stellen Sie sicher, dass IKEv2 EAP (Benutzername/Passwort) als VPN-Typ ausgewählt ist.
      4. Geben Sie bei Benutzername und Passwort die Anmeldedaten ein, die Sie auf dem Server definiert haben.
      5. Deaktivieren Sie Automatisch auswählen im Abschnitt CA-Zertifikat und klicken Sie auf CA-Zertifikat auswählen.
      6. Tippen Sie auf die Registerkarte IMPORTIERT oben auf dem Bildschirm und wählen Sie die von Ihnen importierte CA (sie heißt „VPN root CA“ wenn Sie den „DN“ nicht zuvor geändert haben).
      7. Wenn Sie möchten, können Sie den Profilnamen (optional) mit einem aussagekräftigeren Namen ausfüllen.

      Wenn Sie eine Verbindung mit dem VPN herstellen möchten, klicken Sie auf das Profil, das Sie gerade in der Anwendung StrongSwan erstellt haben.

      Fehlerbehebung bei Verbindungen

      Wenn Sie das Zertifikat nicht importieren können, stellen Sie sicher, dass die Datei die Erweiterung .pem und nicht .pem.txt hat.

      Wenn Sie keine Verbindung mit dem VPN herstellen können, überprüfen Sie den von Ihnen verwendeten Servernamen oder die IP-Adresse. Der Domänenname oder die IP-Adresse des Servers muss mit dem übereinstimmen, was Sie bei der Erstellung des Zertifikats als Common Name (CN) konfiguriert haben. Wenn sie nicht übereinstimmen, funktioniert die VPN-Verbindung nicht. Wenn Sie beispielsweise ein Zertifikat mit dem CN von vpn.example.com einrichten, müssen Sie vpn.example.com verwenden, wenn Sie die VPN-Serverdetails eingeben. Überprüfen Sie den Befehl, den Sie zum Generieren des Zertifikats verwendet haben, und die Werte, die Sie bei der Erstellung Ihrer VPN-Verbindung verwendet haben.

      Abschließend überprüfen Sie die VPN-Konfiguration, um sicherzustellen, dass der Wert leftid mit dem Symbol @ konfiguriert ist, wenn Sie einen Domänennamen verwenden:

      /etc/ipsec.conf

          leftid=@vpn.example.com
      

      Wenn Sie eine IP-Adresse verwenden, stellen Sie sicher, dass das Symbol @ ausgelassen ist. Stellen Sie außerdem sicher, dass Sie beim Generieren der Datei server-cert.pem die beiden Flags --san @IP_address und --san IP_address eingefügt haben.

      Zusammenfassung

      In diesem Tutorial haben Sie einen VPN-Server erstellt, der das IKEv2-Protokoll verwendet. Sie haben sich mit den Anweisungen vertraut gemacht, die die linke und die rechte Seite einer Verbindung sowohl auf dem Server als auch auf den Clients steuern. Außerdem haben Sie einen Windows-, macOS-, iOS-, Android- oder Linux-Client für die Verbindung mit dem VPN konfiguriert.

      Um Benutzer hinzuzufügen oder zu entfernen, führen Sie erneut Schritt 5 aus. Jede Zeile in /etc/ipsec.secrets ist für einen Benutzer, sodass das Hinzufügen oder Entfernen von Benutzern oder das Ändern von Passwörtern nur die Bearbeitung der Datei erfordert.

      Jetzt können Sie sicher sein, dass Ihre Online-Aktivitäten überall und mit jedem Gerät, das Sie für den Zugang zum Internet benutzen, geschützt bleiben.



      Source link