Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
Beide Seiten der vorigen Revision Vorhergehende Überarbeitung Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
linux:ansible:playbook_example_08 [22.09.2022 12:22. ] – [Script Beschreibung] django | linux:ansible:playbook_example_08 [01.06.2024 13:48. ] (aktuell) – [Script starten] django | ||
---|---|---|---|
Zeile 17: | Zeile 17: | ||
==== Lösung ==== | ==== Lösung ==== | ||
+ | <WRAP center round tip 80%> | ||
+ | Der ungeduldigen Leser kann auch direkt zur Tat schreiten und das manuelle Anlegen des Verzeichnisses und des Ansible-Scripts überspringen. Mit Folgendem Befehl erledigt man dies sozusagen auf einem Rutsch: | ||
+ | |||
+ | < | ||
+ | |||
+ | Anschliessend kann man direkt **[[# | ||
+ | </ | ||
=== Script anlegen === | === Script anlegen === | ||
Zunächst müssen wir manuell einmal das Verzeichnis **'' | Zunächst müssen wir manuell einmal das Verzeichnis **'' | ||
Zeile 119: | Zeile 126: | ||
- {directory: " | - {directory: " | ||
- {directory: " | - {directory: " | ||
+ | - {directory: " | ||
- {directory: " | - {directory: " | ||
- {directory: " | - {directory: " | ||
Zeile 220: | Zeile 228: | ||
ok: [localhost] => (item={' | ok: [localhost] => (item={' | ||
ok: [localhost] => (item={' | ok: [localhost] => (item={' | ||
+ | ok: [localhost] => (item={' | ||
ok: [localhost] => (item={' | ok: [localhost] => (item={' | ||
ok: [localhost] => (item={' | ok: [localhost] => (item={' | ||
Zeile 272: | Zeile 281: | ||
- | ===== Aufgabenstellung 2 - " | + | ===== Aufgabenstellung 2 - " |
<WRAP center round info 80%> | <WRAP center round info 80%> | ||
- | Mit Hinblick auf das all umspannende Thema **Sicherheit in der IT** ist eines unserer | + | Mit Hinblick auf das all umspannende Thema **Sicherheit in der IT** ist eines unserer |
- | Folgende Sicherheitsvorkehrungen wollen wir unseren Admins an die Hand geben: | + | Folgende Sicherheitsvorkehrungen wollen wir unseren Admins |
- | - Die Anmeldung an remote Hosts erfolgt mit Hilfe der **SSH** | + | - Die Anmeldung an remote Hosts erfolgt mit Hilfe der **SSH** |
- Der Administrator soll beim Aufruf der Playbooks **__nur noch__** den PGP-Schlüssel durch Eingabe der zugehörigen Passphrase entsperren. Das Passwort für die Rechteerweiterung wird von Ansible aus dem Vault gelesen, genau so wie das **'' | - Der Administrator soll beim Aufruf der Playbooks **__nur noch__** den PGP-Schlüssel durch Eingabe der zugehörigen Passphrase entsperren. Das Passwort für die Rechteerweiterung wird von Ansible aus dem Vault gelesen, genau so wie das **'' | ||
- | Wir wollen vertrauliche Informationen in unseren Playbooks bzw. im Inventory | + | Wir wollen vertrauliche Informationen in unseren Playbooks bzw. im Inventory |
Aus Sicht von **IT-Security** haben wir somit einen erheblicher Zugewinn an Sicherheit. Die Akzeptanzschwelle ist durch Minimierung von mehrfachen Eingaben diverser Passworte durchaus niedrig, so dass für den Admin durchaus ein Mehrwert bei der täglichen administrativen Tätigkeit ausgemacht werden kann. | Aus Sicht von **IT-Security** haben wir somit einen erheblicher Zugewinn an Sicherheit. Die Akzeptanzschwelle ist durch Minimierung von mehrfachen Eingaben diverser Passworte durchaus niedrig, so dass für den Admin durchaus ein Mehrwert bei der täglichen administrativen Tätigkeit ausgemacht werden kann. | ||
</ | </ | ||
- | Damit wir nun diesen Vorüberlegungen gerecht werden können, benötigen wir eine vordefinierte Grundinstallation und Konfiguration der Ansible-Umgebung für unsere(n) Admin(s). | + | Damit wir nun diesen Vorüberlegungen gerecht werden können, benötigen wir eine vordefinierte Grundinstallation und Konfiguration der Ansible-Umgebung für unsere(n) Admin(s) |
- | Mit Hilfe dieses Playbooks können alle erforderlichen Konfigurationsschritte reproduzierbar und beliebig oft abgesetzt werden. Bei Bedarf ist als also jederzeit ohne grossen Aufwand möglich den Ansible-Controll-Node neu aufzusetzen und das System für spätere Playbook-Rollouts vorzubereiten, | + | Mit Hilfe dieses Playbooks können alle erforderlichen Konfigurationsschritte reproduzierbar und beliebig oft abgesetzt werden. Bei Bedarf ist als also jederzeit ohne grossen Aufwand möglich den Ansible-Controll-Node |
Folgende Schritte sollen von dem playbook abgearbeitet werden: | Folgende Schritte sollen von dem playbook abgearbeitet werden: | ||
Zeile 295: | Zeile 304: | ||
- Ansible Directory Layout anlegen und mit Dummy-Inhalten versorgen. | - Ansible Directory Layout anlegen und mit Dummy-Inhalten versorgen. | ||
- Installation und Konfiguration des Passwortmanagers **'' | - Installation und Konfiguration des Passwortmanagers **'' | ||
- | - Hinterlegen des Ansible Become | + | - Hinterlegen des Ansible Become |
+ | - Für die kompakte Ausgabe der Ansible Rückmeldungen soll der **[[playbook_example_12# | ||
Somit erreichen wir später bequem unser gestecktes Ziel unsere Zeit als Admin effizient zu nutzen und in einer sicheren Umgebung uns zu bewegen. | Somit erreichen wir später bequem unser gestecktes Ziel unsere Zeit als Admin effizient zu nutzen und in einer sicheren Umgebung uns zu bewegen. | ||
==== Lösung ==== | ==== Lösung ==== | ||
+ | <WRAP center round tip 90%> | ||
+ | Der ungeduldigen Leser kann auch direkt zur Tat schreiten und das manuelle Anlegen des Verzeichnisses und des Ansible-Scripts überspringen. Mit Folgendem Befehl erledigt man dies sozusagen auf einem Rutsch: | ||
+ | |||
+ | < | ||
+ | |||
+ | Anschliessend kann man, nachdem man die Variablen wie z.B. **'' | ||
+ | </ | ||
=== Script anlegen === | === Script anlegen === | ||
<WRAP center round important 60%> | <WRAP center round important 60%> | ||
Zeile 306: | Zeile 323: | ||
</ | </ | ||
- | Als erstes legen wir manuell einmal das Verzeichnis **'' | + | Als erstes legen wir manuell einmal das Verzeichnis **'' |
- | $ mkdir -p ~/ | + | $ mkdir -p ~/devel/ |
Hier legen wir nun unser Ansible-Playbook/ | Hier legen wir nun unser Ansible-Playbook/ | ||
$ vim ~/ | $ vim ~/ | ||
- | <file c++ ~/ | + | {{gh> https://gitlab.nausch.org/ |
- | # Ansible Playbook zum initialen Einrichten der Ansible-Umgebung | + | |
- | # | + | |
- | # Aufruf aus dem entsprechenden Arbeits-Verzeichnis via: | + | |
- | # ansible-playbook playbooks/ | + | |
- | + | ||
- | - name: ansible_grundconfig_v2.yml | + | |
- | gather_facts: | + | |
- | hosts: localhost | + | |
- | become: true | + | |
- | vars: | + | |
- | ansible_working_dir: | + | |
- | ansible_config: | + | |
- | admin_user: "{{ lookup(' | + | |
- | admin_mail: django@nausch.org | + | |
- | vars_prompt: | + | |
- | - name: pass_secret | + | |
- | prompt: "Enter password for password-store?" | + | |
- | - name: pass_secret_2nd | + | |
- | prompt: " | + | |
- | - name: become_secret | + | |
- | prompt: "Enter become-password for sudo?" | + | |
- | - name: become_secret_2nd | + | |
- | prompt: " | + | |
- | + | ||
- | tasks: | + | |
- | - name: " | + | |
- | fail: | + | |
- | msg: " | + | |
- | when: | + | |
- | - pass_secret != pass_secret_2nd | + | |
- | + | ||
- | - name: " | + | |
- | fail: | + | |
- | msg: " | + | |
- | when: | + | |
- | - become_secret != become_secret_2nd | + | |
- | + | ||
- | - name: " | + | |
- | ansible.builtin.stat: | + | |
- | path: '{{ ansible_config }}' | + | |
- | register: check_ansible_config | + | |
- | + | ||
- | - name: " | + | |
- | ansible.builtin.fail: | + | |
- | msg: " | + | |
- | when: check_ansible_config.stat.exists != 1 | + | |
- | + | ||
- | - name: " | + | |
- | ansible.builtin.copy: | + | |
- | dest: '/home/{{ admin_user }}/ | + | |
- | group: '{{ admin_user }}' | + | |
- | owner: '{{ admin_user }}' | + | |
- | src: '{{ ansible_config }}' | + | |
- | mode: ' | + | |
- | + | ||
- | | + | |
- | ansible.builtin.lineinfile: | + | |
- | line: "{{ item.line }}" | + | |
- | path: "/home/{{ admin_user }}/ | + | |
- | regexp: "{{ item.regexp }}" | + | |
- | state: present | + | |
- | with_items: | + | |
- | - { | + | |
- | regexp: " | + | |
- | line: " | + | |
- | # default: | + | |
- | } | + | |
- | - { | + | |
- | regexp: " | + | |
- | line: "# Generated by Ansible on {{ ansible_date_time.date }}, do not edit manually!\n\ | + | |
- | # default: # | + | |
- | inventory | + | |
- | } | + | |
- | - { | + | |
- | regexp: " | + | |
- | line: "# Generated by Ansible on {{ ansible_date_time.date }}, do not edit manually!\n\ | + | |
- | # default: # | + | |
- | roles_path | + | |
- | } | + | |
- | - { | + | |
- | regexp: " | + | |
- | line: "# Generated by Ansible on {{ ansible_date_time.date }}, do not edit manually!\n\ | + | |
- | # default: # | + | |
- | vault_password_file = ~/ | + | |
- | } | + | |
- | + | ||
- | - name: " | + | |
- | ansible.builtin.file: | + | |
- | path: '/ | + | |
- | state: directory | + | |
- | owner: '{{ admin_user }}' | + | |
- | group: '{{ admin_user }}' | + | |
- | mode: ' | + | |
- | with_items: | + | |
- | - {directory: " | + | |
- | - {directory: " | + | |
- | - {directory: " | + | |
- | - {directory: " | + | |
- | - {directory: " | + | |
- | - {directory: " | + | |
- | - {directory: " | + | |
- | - {directory: " | + | |
- | - {directory: " | + | |
- | - {directory: " | + | |
- | - {directory: " | + | |
- | - {directory: " | + | |
- | - {directory: " | + | |
- | - {directory: " | + | |
- | - {directory: " | + | |
- | - {directory: " | + | |
- | - {directory: " | + | |
- | + | ||
- | - name: " | + | |
- | ansible.builtin.file: | + | |
- | path: '/home/{{ admin_user }}/{{ ansible_working_dir }}/{{ item.file }}' | + | |
- | state: touch | + | |
- | owner: '{{ admin_user }}' | + | |
- | group: '{{ admin_user }}' | + | |
- | mode: ' | + | |
- | with_items: | + | |
- | - {file: " | + | |
- | - {file: " | + | |
- | - {file: " | + | |
- | - {file: " | + | |
- | - {file: " | + | |
- | - {file: " | + | |
- | - {file: " | + | |
- | - {file: " | + | |
- | - {file: " | + | |
- | - {file: " | + | |
- | - {file: " | + | |
- | - {file: " | + | |
- | - {file: " | + | |
- | - {file: " | + | |
- | - {file: " | + | |
- | - {file: " | + | |
- | - {file: " | + | |
- | - {file: " | + | |
- | - {file: " | + | |
- | + | ||
- | - name: " | + | |
- | ansible.builtin.package: | + | |
- | name: pass | + | |
- | update_cache: | + | |
- | state: latest | + | |
- | + | ||
- | - name: " | + | |
- | ansible.builtin.file: | + | |
- | path: '/ | + | |
- | group: '{{ admin_user }}' | + | |
- | owner: '{{ admin_user }}' | + | |
- | state: directory | + | |
- | mode: ' | + | |
- | + | ||
- | - name: " | + | |
- | ansible.builtin.copy: | + | |
- | dest: '/ | + | |
- | content: | | + | |
- | # | + | |
- | # Ansible generated, do not edit manually! | + | |
- | pass show ansible-vault-password | + | |
- | owner: '{{ admin_user }}' | + | |
- | group: '{{ admin_user }}' | + | |
- | mode: ' | + | |
- | + | ||
- | - name: " | + | |
- | ansible.builtin.file: | + | |
- | path: '/ | + | |
- | state: absent | + | |
- | + | ||
- | - name: " | + | |
- | become_user: | + | |
- | become: true | + | |
- | shell: | | + | |
- | set -o pipefail && pass init '{{ admin_mail }}' && / | + | |
- | changed_when: | + | |
- | args: | + | |
- | executable: /bin/bash | + | |
- | + | ||
- | - name: " | + | |
- | ansible.builtin.file: | + | |
- | path: '/ | + | |
- | state: absent | + | |
- | + | ||
- | - name: " | + | |
- | ansible.builtin.copy: | + | |
- | dest: '/ | + | |
- | content: | | + | |
- | ansible_become_pass: | + | |
- | owner: '{{ admin_user }}' | + | |
- | group: '{{ admin_user }}' | + | |
- | mode: ' | + | |
- | + | ||
- | - name: " | + | |
- | become_user: | + | |
- | become: true | + | |
- | shell: | | + | |
- | ansible-vault encrypt /home/{{ admin_user }}/ | + | |
- | changed_when: | + | |
- | + | ||
- | ... # YML Ende</ | + | |
<WRAP center round important 60%> | <WRAP center round important 60%> | ||
**Wichtig: | **Wichtig: | ||
- | Die Variable | + | Die Variablen wie z.B. **'' |
</ | </ | ||
=== Script Beschreibung === | === Script Beschreibung === | ||
- | Mit Hilfe des Playbooks werden alle wesentlichen Konfigurationsoptionen definiert, die im Kapitel **[[first# | + | Mit Hilfe des Playbooks werden |
Nacheinander werden folgende Punkte abgearbeitet: | Nacheinander werden folgende Punkte abgearbeitet: | ||
- Ermitteln des angemeldeten (Admin-)Usernamens **'' | - Ermitteln des angemeldeten (Admin-)Usernamens **'' | ||
- Abfrage des Passwortes für den **Password-Store** und des **'' | - Abfrage des Passwortes für den **Password-Store** und des **'' | ||
- | - Prüfen, ob die Konfigurationsdatei **''/ | + | - Generieren |
- | - Kopieren | + | |
- Setzen der Ansible-Konfigurationsoptionen | - Setzen der Ansible-Konfigurationsoptionen | ||
* **'' | * **'' | ||
Zeile 535: | Zeile 350: | ||
* **'' | * **'' | ||
- Ansible Directory Layout anlegen und anschliessend | - Ansible Directory Layout anlegen und anschliessend | ||
- | - Ansible Directory Layout mit dummy-files | + | - Ansible Directory Layout mit dummy-files |
- Installation des Passwort-Managers **'' | - Installation des Passwort-Managers **'' | ||
- | - vault-Wrapperscript im **' | + | - vault-Wrapperscript im **'' |
- | - Store-Passwort | + | - Store-Passwort |
- Im Inventory das **'' | - Im Inventory das **'' | ||
- | - Ansible-Vault Datei die zuvor angelegt | + | - Ansible-Vault Datei, die zuvor angelegt |
+ | - Im Inventory die Definitionen zu privilege_escalation anlegen und auch hier ggf. ein bereits existierende Konfigurationsdatei vorher löschen. | ||
+ | - Installation und Konfiguration des Ansible Stdout Compact Logger unter Arch Linux | ||
+ | * **'' | ||
+ | * **'' | ||
=== Script starten === | === Script starten === | ||
Das Ansible-Playbook lässt sich wie folgt auf dem Ansible-Controll-Host bzw. der Admin-Workstation aufrufen: | Das Ansible-Playbook lässt sich wie folgt auf dem Ansible-Controll-Host bzw. der Admin-Workstation aufrufen: | ||
- | $ ansible-playbook ~/ | + | $ ansible-playbook ~/devel/ |
- | < | + | {{ :linux:ansible:ansible-krypto-stick.png? |
- | <pre class=" | + | |
- | <font style=" | + | |
- | <font style=" | + | |
- | [WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'</b></font> | + | |
- | <font style=" | + | |
- | PLAY [ansible_grundconfig_v1.yml] ************************************************************************************************* | + | Der Aufruf des Scripts |
+ | $ ansible-playbook -v 01_create-user.yml --limit=demo | ||
- | TASK [Gathering Facts] | + | Nach der Abfrage des **'' |
- | <font style=" | + | |
- | <font style=" | + | |
- | TASK [Ansible Konfigurationsdatei / | + | |
- | <font style=" | + | |
- | <font style=" | + | |
- | TASK [Fehlerhinweis im Fehlerfall ausgeben] ***************************************************************************************</ | + | |
- | <font style=" | + | |
- | <font style=" | + | |
- | TASK [Ansible Konfigurationsverzeichnis in das User/ | + | |
- | <font style=" | + | |
- | <font style=" | + | |
- | TASK [Ansible Konfiguration anpassen] *********************************************************************************************</ | + | |
- | <font style=" | + | |
- | changed: [localhost] => (item={'regexp': | + | |
- | changed: [localhost] => (item={' | + | |
- | become_method=sudo' | + | |
- | changed: [localhost] => (item={' | + | |
- | changed: [localhost] => (item={' | + | |
- | changed: [localhost] => (item={' | + | |
- | <font style=" | + | |
- | TASK [Ansible Directory Layout anlegen] *******************************************************************************************</ | + | |
- | <font style=" | + | |
- | ok: [localhost] => (item={' | + | |
- | ok: [localhost] => (item={' | + | |
- | ok: [localhost] => (item={' | + | |
- | ok: [localhost] => (item={' | + | |
- | ok: [localhost] => (item={' | + | |
- | ok: [localhost] => (item={' | + | |
- | ok: [localhost] => (item={' | + | |
- | ok: [localhost] => (item={' | + | |
- | ok: [localhost] => (item={' | + | |
- | ok: [localhost] => (item={' | + | |
- | ok: [localhost] => (item={' | + | |
- | ok: [localhost] => (item={' | + | |
- | ok: [localhost] => (item={' | + | |
- | ok: [localhost] => (item={' | + | |
- | ok: [localhost] => (item={' | + | |
- | ok: [localhost] => (item={' | + | |
- | <font style=" | + | |
- | TASK [Ansible Directory Layout mit dummy-files main.yml befüllen] | + | |
- | <font style=" | + | |
- | changed: [localhost] => (item={' | + | |
- | changed: [localhost] => (item={' | + | |
- | changed: [localhost] => (item={' | + | |
- | changed: [localhost] => (item={' | + | |
- | changed: [localhost] => (item={' | + | |
- | changed: [localhost] => (item={' | + | |
- | changed: [localhost] => (item={' | + | |
- | changed: [localhost] => (item={' | + | |
- | changed: [localhost] => (item={' | + | |
- | changed: [localhost] => (item={' | + | |
- | changed: [localhost] => (item={' | + | |
- | changed: [localhost] => (item={' | + | |
- | changed: [localhost] => (item={' | + | |
- | changed: [localhost] => (item={' | + | |
- | changed: [localhost] => (item={' | + | |
- | changed: [localhost] => (item={' | + | |
- | changed: [localhost] => (item={' | + | |
- | changed: [localhost] => (item={' | + | |
- | <font style=" | + | |
- | PLAY RECAP ********************************************************************************************************************</ | + | |
- | <font style=" | + | |
- | </ | + | ===== Fazit und Ausblick ===== |
- | </html> | + | <WRAP center round info 60%> |
- | Für eine einfache Ansible Umgebung | + | Wir haben nun Dank der beiden gezeigten Ansible-Playbooks zur Konfiguration unserer Ansible-Umgebung |
- | $ ansible-playbook ~/ansible/playbooks/ | + | |
- | Wir werden | + | |
- | + | ||
- | <WRAP center round tip 80%> | + | |
- | Da wir aber später vertrauliche Informationen wie Passworte und Schlüssel in unseren Playbooks und im Inventory verwenden wollen, werden wir uns nicht mit dieser Basis-Konfiguration zufrieden geben, sondern eher auf Sicherheit bedacht sein, und daher lieber | + | |
</ | </ | ||
- | + | ====== Links ====== | |
- | + | * **[[detail|zurück zum Kapitel " | |
- | + | * **=> [[playbook_example_09|weiter zum Kapitel " | |
- | + | * **[[start|Zurück zur " | |
- | + | * **[[wiki: | |
- | + | * **[[http:// | |
- | FIXME | + |