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 [25.09.2022 11:35. ] – [Lösung] django | linux:ansible:playbook_example_08 [01.06.2024 13:48. ] (aktuell) – [Script starten] django | ||
---|---|---|---|
Zeile 18: | Zeile 18: | ||
==== Lösung ==== | ==== Lösung ==== | ||
<WRAP center round tip 80%> | <WRAP center round tip 80%> | ||
- | Der ungeduldigen Leser kann auch direkt zur Tat schreiten und das manuelle Anlegen des Verzeichnisses und des Ansible-Scriptes | + | Der ungeduldigen Leser kann auch direkt zur Tat schreiten und das manuelle Anlegen des Verzeichnisses und des Ansible-Scripts |
< | < | ||
- | Anschließend | + | Anschliessend |
</ | </ | ||
=== Script anlegen === | === Script anlegen === | ||
Zeile 281: | 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** ausschliesslich mit Schlüsseln, | + | - Die Anmeldung an remote Hosts erfolgt mit Hilfe der **SSH** ausschliesslich mit Schlüsseln, |
- 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 **'' | ||
Zeile 294: | Zeile 294: | ||
</ | </ | ||
- | 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 305: | Zeile 305: | ||
- Installation und Konfiguration des Passwortmanagers **'' | - Installation und Konfiguration des Passwortmanagers **'' | ||
- Hinterlegen des Ansible Become Passwortes in einem Ansible-Vault. | - Hinterlegen des Ansible Become Passwortes in einem Ansible-Vault. | ||
+ | - 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. | ||
Zeile 312: | Zeile 313: | ||
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: | 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 Variable | + | Anschliessend kann man, nachdem man die Variablen wie z.B. **'' |
</ | </ | ||
=== Script anlegen === | === Script anlegen === | ||
Zeile 322: | 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 }}/.ansible.cfg" | + | |
- | 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: "playbooks/"} | + | |
- | - {directory: " | + | |
- | - {directory: " | + | |
- | - {directory: " | + | |
- | - {directory: " | + | |
- | - {directory: " | + | |
- | - {directory: " | + | |
- | - {directory: " | + | |
- | - {directory: " | + | |
- | - {directory: " | + | |
- | - {directory: " | + | |
- | - {directory: " | + | |
- | - {directory: " | + | |
- | - {directory: " | + | |
- | - {directory: " | + | |
- | + | ||
- | - name: " | + | |
- | ansible.builtin.file: | + | |
- | path: '/ | + | |
- | 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: | | + | |
- | # Generated by Ansible on {{ ansible_date_time.date }}, do not edit manually! | + | |
- | ansible_become_pass: | + | |
- | owner: '{{ admin_user }}' | + | |
- | group: '{{ admin_user }}' | + | |
- | mode: ' | + | |
- | + | ||
- | - name: " | + | |
- | become_user: | + | |
- | become: true | + | |
- | shell: | | + | |
- | ansible-vault encrypt /home/{{ admin_user }}/ | + | |
- | changed_when: | + | |
- | + | ||
- | - name: " | + | |
- | ansible.builtin.file: | + | |
- | path: '/ | + | |
- | state: absent | + | |
- | + | ||
- | - name: " | + | |
- | ansible.builtin.copy: | + | |
- | dest: '/ | + | |
- | content: | | + | |
- | # Generated by Ansible on {{ ansible_date_time.date }}, do not edit manually! | + | |
- | ansible_become: | + | |
- | ansible_become_method: | + | |
- | ansible_become_user: | + | |
- | ansible_become_ask_pass: | + | |
- | owner: '{{ admin_user }}' | + | |
- | group: '{{ admin_user }}' | + | |
- | mode: ' | + | |
- | + | ||
- | ... # 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 571: | 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 **'' | ||
Zeile 578: | Zeile 357: | ||
- Ansible-Vault Datei, die zuvor angelegt wurde, mit dem Ansible-Vault-Passwort sicher verschlüsseln. | - Ansible-Vault Datei, die zuvor angelegt wurde, mit dem Ansible-Vault-Passwort sicher verschlüsseln. | ||
- Im Inventory die Definitionen zu privilege_escalation anlegen und auch hier ggf. ein bereits existierende Konfigurationsdatei vorher löschen. | - 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/ |
- | + | ||
- | < | + | |
- | <pre class=" | + | |
- | <font style=" | + | |
- | <font style=" | + | |
- | [WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match ' | + | |
- | <font style=" | + | |
- | Retype password for password-store?: | + | |
- | Enter become-password for sudo?: | + | |
- | Retype become-password for sudo?: | + | |
- | + | ||
- | PLAY [ansible_grundconfig_v2.yml] ************************************************************************************************* | + | |
- | + | ||
- | TASK [Gathering Facts] ************************************************************************************************************</ | + | |
- | <font style=" | + | |
- | <font style=" | + | |
- | TASK [Playbooklauf abbrechen sofern die beiden eigegebenen Passwörter nicht übereinstimmen!] **************************************</ | + | |
- | <font style=" | + | |
- | <font style=" | + | |
- | TASK [Playbooklauf abbrechen sofern die beiden eigegebenen Passwörter nicht übereinstimmen!] **************************************</ | + | |
- | <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={' | + | |
- | 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={' | + | |
- | 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=" | + | |
- | TASK [Passwort-Manager pass installieren] ***********************************************************************************</ | + | |
- | <font style=" | + | |
- | <font style=" | + | |
- | TASK [Verzeichnis ~/bin anlegen] ********************************************************************************************</ | + | |
- | <font style=" | + | |
- | <font style=" | + | |
- | TASK [vault-Wrapperscript anlegen] ******************************************************************************************</ | + | |
- | <font style=" | + | |
- | <font style=" | + | |
- | TASK [Sicherstellen dass das pass Store-Verzeichnis nicht existiert] ********************************************************</ | + | |
- | <font style=" | + | |
- | <font style=" | + | |
- | TASK [Pass-Store Passwort ablegen] ******************************************************************************************</ | + | |
- | <font style=" | + | |
- | <font style=" | + | |
- | TASK [Sicherstellen dass das File für das verschlüsselte become-password noch nicht existiert] ******************************</ | + | |
- | <font style=" | + | |
- | <font style=" | + | |
- | TASK [Ansible Become Password für sudo Rechteerweiterung anlegen] ***********************************************************</ | + | |
- | <font style=" | + | |
- | <font style=" | + | |
- | TASK [Ansible Become Password mit ansible-vault verschlüsseln] **************************************************************</ | + | |
- | <font style=" | + | |
- | <font style=" | + | |
- | TASK [Sicherstellen dass das File mit der Ansible-Konfiguration nicht existiert] ********************************************</ | + | |
- | <font style=" | + | |
- | <font style=" | + | |
- | TASK [Ansible Konfigurationsdatei mit den Definitionen zu privilege_escalation anlegen] *************************************</ | + | |
- | <font style=" | + | |
- | <font style=" | + | |
- | PLAY RECAP ********************************************************************************************************************</ | + | |
- | <font style=" | + | |
- | + | ||
- | </ | + | |
- | </ | + | |
{{ : | {{ : |