Beide Seiten der vorigen Revision Vorhergehende Überarbeitung Nächste Überarbeitung | Vorhergehende Überarbeitung |
linux:ansible:playbook_example_07 [16.09.2022 17:48. ] – django | linux:ansible:playbook_example_07 [26.03.2025 16:06. ] (aktuell) – [Hilfeseite des Scripts] Typofixing django |
---|
Beim ersten Playbook-Beispiel **[[linux:ansible:playbook_example_01|Benutzer anlegen]]** ist uns bereits ein wesentlicher Umstand ins Auge gestossen. Das Ablegen von Passwörtern in einem Playbook ist alles andere als sicher: | Beim ersten Playbook-Beispiel **[[linux:ansible:playbook_example_01|Benutzer anlegen]]** ist uns bereits ein wesentlicher Umstand ins Auge gestossen. Das Ablegen von Passwörtern in einem Playbook ist alles andere als sicher: |
| |
<WRAP center round alert 80%>Doch **Achtung**: Es zeigt sehr anschaulich, dass es __keine gute Idee__ sein kann, Passworte und ähnliches direkt in einem Playbook und/oder Inventory unverschlüsselt vorzuhalten - kann doch so jeder, der Zugriff auf das Playbook/Inventory hat, unberechtigter Weise Kenntnis von vertraulichen Informationen erlangen!</WRAP> | <WRAP center round alert 80%>Doch **Achtung**: Es zeigt sehr anschaulich, dass es __keine gute Idee__ sein kann, Passworte und ähnliches direkt in einem Playbook und/oder Inventory unverschlüsselt vor zuhalten - kann doch so jeder, der Zugriff auf das Playbook/Inventory hat, unberechtigter Weise Kenntnis von vertraulichen Informationen erlangen!</WRAP> |
| |
Das Passwort **''M31nP4p4157d3r4113r83573!''** des Nutzers **''ruben''** ist in diesem Beispiel für jedermann lesbar in dem Playbook gespeichert. Das ist natürlich alles andere als sicher! Jeder oder jede, die auf diese Datei lesend zugreifen kann, kennt nun das Passwort dieses Users. :-? Was also tun? Nun, im Grunde verfahren wir wie sonst auch: | Das Passwort **''M31nP4p4157d3r4113r83573!''** des Nutzers **''ruben''** ist in diesem Beispiel für jedermann lesbar in dem Playbook gespeichert. Das ist natürlich alles andere als sicher! Jeder oder jede, die auf diese Datei lesend zugreifen kann, kennt nun das Passwort dieses Users. :-? Was also tun? Nun, im Grunde verfahren wir wie sonst auch: |
| |
===== Dokumentation - Beschreibung ===== | ===== Dokumentation - Beschreibung ===== |
Was das **[[https://www.python.org/download/releases/3.0/|Python3-Script]]** **''ansible-vault''** nun alles kann und leistet, entnehmen wir einfach den Hilfe-Optionen des Scripts bzw. der zugehörigen Manpage | Was das **[[https://www.python.org/download/releases/3.0/|Python3-Script]]** **''ansible-vault''** nun alles kann und leistet, entnehmen wir einfach den Hilfe-Optionen des Scripts bzw. der zugehörigen Manpage. |
| |
==== Hilfeseite des Scripts ==== | ==== Hilfeseite des Scripts ==== |
Rufen wir das Script **''ansible-vault''** mit der Option **''-h''** bzw **''--help''** auf, erhalten wir eine entsprechende Kurzbeschreibung. | Rufen wir das Script **''ansible-vault''** mit der Option **''-h''** bzw **''--help''** auf, erhalten wir eine entsprechende Kurzbeschreibung. |
$ ansible-vault --help | $ ansible-vault --help |
| ++++ Ausgabe des Befehls ansible-vault --help | |
<code>usage: ansible-vault [-h] [--version] [-v] {create,decrypt,edit,view,encrypt,encrypt_string,rekey} ... | <code>usage: ansible-vault [-h] [--version] [-v] {create,decrypt,edit,view,encrypt,encrypt_string,rekey} ... |
| |
| |
See 'ansible-vault <command> --help' for more information on a specific command.</code> | See 'ansible-vault <command> --help' for more information on a specific command.</code> |
| ++++ |
| |
Wollen wir eine Kurz-Hilfe z.B. zur Option **''encrypt''**, fragen wir entsprechend nnach dessen beschreibende Option bzw. Kurz-Hilfe. | Wollen wir eine Kurz-Hilfe z.B. zur Option **''encrypt''**, fragen wir entsprechend nach dessen beschreibende Option bzw. Kurz-Hilfe. |
$ ansible-vault encrypt --help | $ ansible-vault encrypt --help |
| ++++ Ausgabe des Befehls ansible-vault encrypt --help | |
<code>usage: ansible-vault encrypt [-h] [--vault-id VAULT_IDS] [--ask-vault-password | --vault-password-file VAULT_PASSWORD_FILES] [-v] | <code>usage: ansible-vault encrypt [-h] [--vault-id VAULT_IDS] [--ask-vault-password | --vault-password-file VAULT_PASSWORD_FILES] [-v] |
[--output OUTPUT_FILE] [--encrypt-vault-id ENCRYPT_VAULT_ID] | [--output OUTPUT_FILE] [--encrypt-vault-id ENCRYPT_VAULT_ID] |
the vault id used to encrypt (required if more than one vault-id is provided) | the vault id used to encrypt (required if more than one vault-id is provided) |
</code> | </code> |
| ++++ |
==== Manpage ==== | ==== Manpage ==== |
Werfen wir nun also auch noch einen Blick in die Manpage von **''ansible-vault''**. | Werfen wir nun also auch noch einen Blick in die Manpage von **''ansible-vault''**. |
$ man ansible-vault | $ man ansible-vault |
| ++++ Manual-Page des Befehls ansible-vault | |
<code>ANSIBLE-VAULT(1) System administration commands ANSIBLE-VAULT(1) | <code>ANSIBLE-VAULT(1) System administration commands ANSIBLE-VAULT(1) |
| |
| |
Ansible 2.9.6 ANSIBLE-VAULT(1) </code> | Ansible 2.9.6 ANSIBLE-VAULT(1) </code> |
| ++++ |
| |
===== ansible-vault - Praxis-Beispiele ===== | ===== ansible-vault - Praxis-Beispiele ===== |
Nehmen wir in nachfolgendem Beispiel an, dass Passwort **''Früh übt sich, wer ein Meister werden will!''** des Admin-Users **''christoph''** legen wir im Inventory ab: | Nehmen wir in nachfolgendem Beispiel an, dass Passwort **''Früh übt sich, wer ein Meister werden will!''** des Admin-Users **''christoph''** legen wir im Inventory ab: |
$ echo "admin_password: Frueh_uebt_51ch_wer_31n_Meister_werden_will!" > ~/ansible/inventory/produktion/group_vars/all/secrets | $ echo "admin_password: Frueh_uebt_51ch_wer_31n_Meister_werden_will!" > ~/ansible/inventory/produktion/group_vars/all/secrets.yml |
| |
Wir haben also eine Datei, mit folgendem Inhalt, die jeder (aus-)lesen kann der Zugriff auf unseren Rechner hat: | Wir haben also eine Datei, mit folgendem Inhalt, die jeder (aus-)lesen kann der Zugriff auf unseren Rechner hat: |
$ cat ~/ansible/inventory/produktion/group_vars/all/secrets | $ cat ~/ansible/inventory/produktion/group_vars/all/secrets |
| |
Früh_übt_sich_wer_ein_Meister_werden_will! | admin_password: Frueh_uebt_51ich_wer_31n_Meister_werden_will! |
| |
==== Inhalte/Datei Verschlüsseln ==== | ==== Inhalte/Datei Verschlüsseln ==== |
Wir wollen also diese Datei mit Hilfe von **''ansible-vault''** verschlüsseln, dazu rufen wir folgenden Befehl auf: | Wir wollen also diese Datei mit Hilfe von **''ansible-vault''** verschlüsseln, dazu rufen wir folgenden Befehl auf: |
$ ansible-vault encrypt ~/ansible/inventory/produktion/group_vars/all/secrets | $ ansible-vault encrypt ~/ansible/inventory/produktion/group_vars/all/secrets.yml |
| |
Wir werden nun nach einem hinreichend sicheren Passwort **2x** gefragt - hier geben wir also **''Schleichi, der aufstrebende Stern am Ansible-Himmel!''** ein. | Wir werden nun nach einem hinreichend sicheren Passwort **2x** gefragt - hier geben wir also **''Schleichi, der aufstrebende Stern am Ansible-Himmel!''** ein. |
==== Inhalte anzeigen ==== | ==== Inhalte anzeigen ==== |
Wie wir gerade gesehen haben, kommen wir nun nicht mehr so ohne weiteres an die verborgene Information. Wollen wir den Inhalt einsehen, benutzen wir die Option **''view''** beim Aufruf von **''ansible-vault''**. | Wie wir gerade gesehen haben, kommen wir nun nicht mehr so ohne weiteres an die verborgene Information. Wollen wir den Inhalt einsehen, benutzen wir die Option **''view''** beim Aufruf von **''ansible-vault''**. |
$ ansible-vault view ~/ansible/inventory/produktion/group_vars/all/secrets | $ ansible-vault view ~/ansible/inventory/produktion/group_vars/all/secrets.yml |
| |
Wir werden nun aufgefordert unser Vault-Passphrase/-Passwort einzugeben, damit für die Anzeige der Datei diese temporär entschlüsselt werden kann. Wir geben also hier **''Schleichi, der aufstrebende Stern am Ansible-Himmel!''** ein. | Wir werden nun aufgefordert unser Vault-Passphrase/-Passwort einzugeben, damit für die Anzeige der Datei diese temporär entschlüsselt werden kann. Wir geben also hier **''Schleichi, der aufstrebende Stern am Ansible-Himmel!''** ein. |
| |
Die Datei selbst ist immer noch verschlüsselt: | Die Datei selbst ist immer noch verschlüsselt: |
$ less ~/ansible/inventory/produktion/group_vars/all/secrets | $ less ~/ansible/inventory/produktion/group_vars/all/secrets.yml |
<code>$ANSIBLE_VAULT;1.1;AES256 | <code>$ANSIBLE_VAULT;1.1;AES256 |
39303364346439623430643364306438353034663962646364376362626665373862623335323361 | 39303364346439623430643364306438353034663962646364376362626665373862623335323361 |
==== Inhalte editieren ==== | ==== Inhalte editieren ==== |
Möchten wir eine Anpassung am Inhalt der Datei vornehmen, nutzen wir einfach die Option **''edit''**. | Möchten wir eine Anpassung am Inhalt der Datei vornehmen, nutzen wir einfach die Option **''edit''**. |
$ ansible-vault view ~/ansible/inventory/produktion/group_vars/all/secrets | $ ansible-vault view ~/ansible/inventory/produktion/group_vars/all/secrets.yml |
| |
Wir werden auch hiernun aufgefordert unser Vault-Passphrase/-Passwort einzugeben, damit die Datei entschlüsselt und im **''vim''** zum editieren angeboten werden kann. Wir geben also hier wiederum unsere Passphrase **''Schleichi, der aufstrebende Stern am Ansible-Himmel!''** ein. | Wir werden auch hier nun aufgefordert unser Vault-Passphrase/-Passwort einzugeben, damit die Datei entschlüsselt und im **''vim''** zum editieren angeboten werden kann. Wir geben also hier wiederum unsere Passphrase **''Schleichi, der aufstrebende Stern am Ansible-Himmel!''** ein. |
Vault password: Schleichi, der aufstrebende Stern am Ansible-Himmel! | Vault password: Schleichi, der aufstrebende Stern am Ansible-Himmel! |
| |
admin_password: Frueh_uebt_51ch_wer_31n_Meister_werden_will! | admin_password: Frueh_uebt_51ch_wer_31n_Meister_werden_will! |
| |
Anschließend verlassen wir den Editor und speichern unsere Änderungen mit dem altbekannten **'':x!''**. Die Datei liegt nun wieder verschlüsselt mit den geänderten Inhalten vor. | Anschliessend verlassen wir den Editor und speichern unsere Änderungen mit dem altbekannten **'':x!''**. Die Datei liegt nun wieder verschlüsselt mit den geänderten Inhalten vor. |
$ less ~/ansible/inventory/produktion/group_vars/all/secrets | $ less ~/ansible/inventory/produktion/group_vars/all/secrets |
<code>$ANSIBLE_VAULT;1.1;AES256 | <code>$ANSIBLE_VAULT;1.1;AES256 |
3963</code> | 3963</code> |
| |
Mit **''view''** können wir uns vergewissern, ob die neunen Inhalte auch wirklich vorliegen. | Mit **''view''** können wir uns vergewissern, ob die neuen Inhalte auch wirklich vorliegen. |
$ ansible-vault view ~/ansible/inventory/produktion/group_vars/all/secrets | $ ansible-vault view ~/ansible/inventory/produktion/group_vars/all/secrets.yml |
| |
Vault password: Frueh_uebt_51ch_wer_31n_Meister_werden_will! | Vault password: Frueh_uebt_51ch_wer_31n_Meister_werden_will! |
==== Inhalte/Datei entschlüsseln ==== | ==== Inhalte/Datei entschlüsseln ==== |
Wollen wir die Verschlüsselung unserer Datei wieder entfernen, entschlüsseln wir diese mit der Option **''decrypt''**. | Wollen wir die Verschlüsselung unserer Datei wieder entfernen, entschlüsseln wir diese mit der Option **''decrypt''**. |
$ ansible-vault decrypt ~/ansible/inventory/produktion/group_vars/all/secrets | $ ansible-vault decrypt ~/ansible/inventory/produktion/group_vars/all/secrets.yml |
| |
Auch hier geben wir unsere Passphrase ein, damit die Datei entschlüsselt werden kann. | Auch hier geben wir unsere Passphrase ein, damit die Datei entschlüsselt werden kann. |
| |
Die Datei liegt nun wieder entschlüsselt in plaintext vor. | Die Datei liegt nun wieder entschlüsselt in plaintext vor. |
$ cat ~/ansible/inventory/produktion/group_vars/all/secrets | $ cat ~/ansible/inventory/produktion/group_vars/all/secrets.yml |
| |
admin_user: christoph | admin_user: christoph |
| |
<WRAP center round info 80%> | <WRAP center round info 80%> |
Bei der Verschlüsselung von Inhalten sind wir keinesfalls auf Datei-(Variabl)en beschränkt. Wir könnten bei Bedarf auch jedwede Projeketdateien, wie //Playbooks//, //Rollen//, //Templates// oder auch ganze //Inventories// verschlüsseln! | Bei der Verschlüsselung von Inhalten sind wir keinesfalls auf Dateien und Variabeln beschränkt. Wir könnten bei Bedarf auch jedwede Projeketdateien, wie //Playbooks//, //Rollen//, //Templates// oder auch ganze //Inventories// verschlüsseln! |
</WRAP> | </WRAP> |
| |
| |
<WRAP center round tip 80%> | <WRAP center round tip 80%> |
Aus dem Blickwinkel **Sicherheit** haben wir nun zum einen erreicht, dass schützenswerte Informationen nicht mehr als plain-text in unserer Ansible-Entwicklungsumgebnung ungeschützt herumliegen. Darüber hinaus haben wir nun quasi einen **//zweiten Faktor//** bei der Abarbeitung unserer Ansible-Playbooks eingeführt - genauer gesagt sind es ja eher drei Dinge, über die der Admin verfügen muss: | Aus dem Blickwinkel **Sicherheit** haben wir nun zum einen erreicht, dass schützenswerte Informationen nicht mehr als plain-text in unserer Ansible-Entwicklungsumgebnung ungeschützt herumliegen. Darüber hinaus haben wir nun quasi einen **//zweiten Faktor//** bei der Abarbeitung unserer Ansible-Playbooks eingeführt - genauer gesagt sind es ja eher drei Dinge, über die der Admin verfügen muss: |
- Der Admin muss den SSH-Privat-Key besitzen und von dessen Passphrase Kenntnis haben. | - Der Admin muss den SSH-Privat-Key besitzen und von dessen Passphrase Kenntnis haben. |
- Der Admin muss das **''BECOME password:''** kennen, mit dessen Hilfe die Rechteerweiterung, gemäß unserer **[[first#mit_abfrage_eines_passwortes|initialen Konfiguration zur Rechteerweiterung mit Passwort]]** auf den Zielsystemen erlangt werden kann. | - Der Admin muss das **''BECOME password:''** kennen, mit dessen Hilfe die Rechteerweiterung, gemäss unserer **[[first#mit_abfrage_eines_passwortes|initialen Konfiguration zur Rechteerweiterung mit Passwort]]** auf den Zielsystemen erlangt werden kann. |
- Der Administrator muss nun auch noch **''Vault password:''** eingeben, damit die verschlüsselten Inhalte, die im Inventory abgelegt sind, entschlüsselt werden können und das bzw. die Playbooks auch ordnungsgemäss und vollständig abgearbeitet werden können. | - Der Administrator muss nun auch noch **''Vault password:''** eingeben, damit die verschlüsselten Inhalte, die im Inventory abgelegt sind, entschlüsselt werden können und das bzw. die Playbooks auch ordnungsgemäss und vollständig abgearbeitet werden können. |
| |
Ja, es gäbe auch die Option **''%%--%%vault-password-file''**, aber diese Option streichen wir gleich mal aus unserem Gedächtnis, da es erwiesener Maßen keine gute Idee sein kann, das zum Entschlüsseln von vertraulichen Informationen benötigte Passwort, in Dateisystem wieder für alle lesbar abzulegen! \\ | Ja, es gäbe auch die Option **''%%--%%vault-password-file''**, aber diese Option streichen wir gleich mal aus unserem Gedächtnis, da es erwiesener Maßen keine gute Idee sein kann, das zum Entschlüsseln von vertraulichen Informationen benötigte Passwort, in Dateisystem wieder für alle lesbar abzulegen! \\ |
| |
**Nein**, so 'was machen wir hier **__definitiv nicht__**! | **Nein**, so 'was machen wir hier **__definitiv nicht__**! Never ever! Ein absolutes **no go**! |
</WRAP> | </WRAP> |
| |
Will oder muss man **''ansible-playbook''** öfters und mehrmals ausführen, ist es doch zuweilen mehr als mühsam, bei jedem Aufruf neben dem **become** (früher auch bekannt als sudo) bei Verwendung von **''ansible-vault''** nunmehr zusätzlich das **ansible-vault**-Passwort einzugeben. | Will oder muss man **''ansible-playbook''** öfters und mehrmals ausführen, ist es doch zuweilen mehr als mühsam, bei jedem Aufruf neben dem **become** (früher auch bekannt als sudo) bei Verwendung von **''ansible-vault''** nunmehr zusätzlich das **ansible-vault**-Passwort einzugeben. |
| |
Wie im vorangegenagenen [[#vault-password-file|Abschnitt]] bereits angeschitten, verwerfen wir die Option "Übergabe der Passworte auf der Kommandozeile" bzw. "Vorhalten von Passworten in (Konfig-)Files" **__sofort__** wieder. | Wie im vorangegangenen [[#vault-password-file|Abschnitt]] bereits angeschnitten, verwerfen wir die Option "Übergabe der Passworte auf der Kommandozeile" bzw. "Vorhalten von Passworten in (Konfig-)Files" **__sofort__** wieder. |
| |
=== Vorüberlegungen === | === Vorüberlegungen === |
Was wir nun brauchen ist zum einen eine Möglichkeit das Vault-Passwort sicher zu speichern bzw. vorzuhalten und zum anderen bei Bedarf eine Möglichkeit das Vault-Passwort irgendwie zu "cachen", so dass man Ansible schnell ausführen kann, ohne die Anmeldedaten für kleine Änderungen im Playbook erneut eingeben zu müssen. | Was wir nun brauchen ist zum einen eine Möglichkeit das Vault-Passwort sicher zu speichern bzw. vor zuhalten und zum anderen bei Bedarf eine Möglichkeit das Vault-Passwort irgendwie zu "cachen", so dass man Ansible schnell ausführen kann, ohne die Anmeldedaten für kleine Änderungen im Playbook erneut eingeben zu müssen. |
| |
<WRAP center round alert 80%> | <WRAP center round alert 80%> |
| |
=== Passwortmanager pass === | === Passwortmanager pass === |
Als erstes befassen wir uns mit dem Standard UNIX Passwort-Manager **[[https://www.passwordstore.org/|pass]]**. Der Passwort-Manager **''pass''** haben wir ein einfach zu bedienendes wie auch strukturiertes Tool. Bei **''pass''** wird jedes Passwort in einer gpg-verschlüsselten Datei abgelegt, deren Dateiname der Titel der Website oder Ressource ist, für die das Passwort benötigt wird. Diese verschlüsselten Dateien können in sinnvollen Ordnerhierarchien organisiert, bei Bedarf von Host zu Host kopiert und im Allgemeinen mit Standard-Kommandozeilen-Dienstprogrammen für die Dateiverwaltung bearbeitet werden. Ferner kann der Passwortmanager einfach über sein **CLI** angesprochen und bedient werden. | Als erstes befassen wir uns mit dem Standard UNIX Passwort-Manager **[[https://www.passwordstore.org/|pass]]**. Der Passwort-Manager **''pass''** haben wir ein einfach zu bedienendes wie auch strukturiertes Tool. Bei **''pass''** wird jedes Passwort in einer PGP-verschlüsselten Datei abgelegt, deren Dateiname der Titel der Website oder Ressource ist, für die das Passwort benötigt wird. Diese verschlüsselten Dateien können in sinnvollen Ordnerhierarchien organisiert, bei Bedarf von Host zu Host kopiert und im Allgemeinen mit Standard-Kommandozeilen-Dienstprogrammen für die Dateiverwaltung bearbeitet werden. Ferner kann der Passwortmanager einfach über sein **CLI** angesprochen und bedient werden. |
| |
Bei der Nutzung von **''pass''** gehen wir davon aus, dass man bereits über einen eigneen PGP-Key verfügt und mit dessen Verwendung vertraut ist. Falls nicht, wird in diesem **[[centos:openpgp_beim_mua#openpgp_in_der_praxis|Kapitel]]** die Erstellung und Verwendung ausführlich beschrieben. Besonders sicheheitsbewußten Administratoren ist auch die Verwendung einer Kryptographie-Hardware z.B. eines **[[https://shop.nitrokey.com/de_DE/shop/product/nksa-nitrokey-start-6|Nitrokey Start]]** empfohlen. Die Erstellung von passenden Schlüsselmaterial wie ECDSA-basierten SSH-Schlüssel und PGP-Schlüssel ist z.B. in diesem **[[suse:nitrokey:start#nitrokey_start_und_gnupg|Kapitel in Djangos WIKI]]** ausführlich beschrieben und erklärt. | Bei der Nutzung von **''pass''** gehen wir davon aus, dass man bereits über einen eigenen PGP-Key verfügt und mit dessen Verwendung vertraut ist. Falls nicht, wird in diesem **[[centos:openpgp_beim_mua#openpgp_in_der_praxis|Kapitel]]** die Erstellung und Verwendung ausführlich beschrieben. Besonders sicherheitsbewussten Administratoren ist auch die Verwendung einer Kryptographie-Hardware z.B. eines **[[https://shop.nitrokey.com/de_DE/shop/product/nksa-nitrokey-start-6|Nitrokey Start]]** empfohlen. Die Erstellung von passenden Schlüsselmaterial wie ECDSA-basierten SSH-Schlüssel und PGP-Schlüssel ist z.B. in diesem **[[suse:nitrokey:start#nitrokey_start_und_gnupg|Kapitel in Djangos WIKI]]** ausführlich beschrieben und erklärt. |
| |
Bevor wir uns nun eingehender mit **''pass''** beschäftigen installieren wir das Programm-Paket mit Hilfe des Paketverwaltungs-Tools unserer Distribution. | Bevor wir uns nun eingehender mit **''pass''** beschäftigen installieren wir das Programm-Paket mit Hilfe des Paketverwaltungs-Tools unserer Distribution. |
* **Ubuntu / Debian** : <code> $ sudo apt-get install pass</code> | * **Ubuntu / Debian** : <code> $ sudo apt-get install pass</code> |
| |
Was das Programm **''pass''** alles an Befehlsoptionen mitbringt, offenbart uns die der Programmaufruf mit der Option ***''help''**. | Was das Programm **''pass''** alles an Befehlsoptionen mitbringt, offenbart uns die der Programmaufruf mit der Option **''help''**. |
$ pass --help | $ pass --help |
| ++++ Ausgabe des Befehls pass --help | |
<code>============================================ | <code>============================================ |
= pass: the standard unix password manager = | = pass: the standard unix password manager = |
| |
More information may be found in the pass(1) man page.</code> | More information may be found in the pass(1) man page.</code> |
| ++++ |
| |
Zunächst müssen wir einmalig den Passwort-Safe initialisieren. Wichtig ist dabei, dass wir hier (der dritte Wert beim Aufruf) genau den Namen angeben, den wir bei der Generierung des PGP-Schlüssels verwendet hatten. Im folgenden Konfigurationsbeispiel gehen wir davon aus, dass hier die eMail-Adresse **''christoph@mailserver.guru''** unseres Admins **christoph** verwendet wird. | Zunächst müssen wir einmalig den Passwort-Safe initialisieren. Wichtig ist dabei, dass wir hier (der dritte Wert beim Aufruf) genau den Namen angeben, den wir bei der Generierung des PGP-Schlüssels verwendet hatten. Im folgenden Konfigurationsbeispiel gehen wir davon aus, dass hier die eMail-Adresse **''christoph@nausch.org''** unseres Admins **christoph** verwendet wird. |
$ pass init christoph@mailserver.guru | $ pass init christoph@nausch.org |
| |
Anschließend hinterlegen wir das Vault-Passwort **''Schleichi, der aufstrebende Stern am Ansible-Himmel!''** mit welchem wir unsere zu schützende Datei **''~/ansible/inventory/produktion/group_vars/all/secrets''** **[[#inhalte_datei_verschluesseln|verschlüsselt]]** hatten. | Anschliessend hinterlegen wir das Vault-Passwort **''Schleichi, der aufstrebende Stern am Ansible-Himmel!''** mit welchem wir unsere zu schützende Datei **''~/ansible/inventory/produktion/group_vars/all/secrets''** **[[#inhalte_datei_verschluesseln|verschlüsselt]]** hatten. |
$ pass insert ansible-vault-password | $ pass insert ansible-vault-password |
| |
| |
Im Homeverzeichnis unseres Admins findet sich nun das zugehörige verschlüsselte Dokument. | Im Homeverzeichnis unseres Admins findet sich nun das zugehörige verschlüsselte Dokument. |
<code>/home/chrsitoph/.password-store/ | <code>/home/christoph/.password-store/ |
└── ansible-vault-password.gpg</code> | └── ansible-vault-password.gpg</code> |
| |
/usr/bin/pass show ansible-vault-password</file> | /usr/bin/pass show ansible-vault-password</file> |
| |
Abschließend statten wir das Script mit **''x''**-Rechten aus. | Abschliessend statten wir das Script mit **''x''**-Rechten aus. |
$ chmod +x ~/bin/ansible_vault_password | $ chmod +x ~/bin/ansible_vault_password |
| |
| |
=== Ansible-Playbook === | === Ansible-Playbook === |
Dank unserer Konfiguration wird ab sofort beim Aufruf von **''ansible''**, **''ansible-playbook''** oder auch **''ansible-lint''**, dass Passwort unseres PGP-Schlüssels abgefragt, damit das wiederum mit dem PGP-Schlüssel verschlüsselte Vault-Passwort entschlüsselt und benutzt werden kann. Verwenden wir ein Security-Hardware-Geräte wie z.B. einen **[[https://shop.nitrokey.com/de_DE/shop/product/nksa-nitrokey-start-6|Nitrokey Start]]** werden wir aufgefordert, den Stick anzustecken uns die zugehörige PIN einzugeben. | Dank unserer Konfiguration wird ab sofort beim Aufruf von **''ansible''**, **''ansible-playbook''** oder auch **''ansible-lint''**, dass Passwort unseres PGP-Schlüssels abgefragt, damit das wiederum mit dem PGP-Schlüssel verschlüsselte Vault-Passwort entschlüsselt und benutzt werden kann. \\ |
| {{ :linux:ansible:ansible-krypto-stick.png?nolink&175|Bild: Ansible NitroKey Start}} |
| Verwenden wir ein Security-Hardware-Geräte wie z.B. einen **[[https://shop.nitrokey.com/de_DE/shop/product/nksa-nitrokey-start-6|Nitrokey Start]]** werden wir aufgefordert, den USB-Stick anzustecken uns die zugehörige PIN einzugeben. |
| |
Wie bereits im Abschnitt **[[#ask-vault-pass|ask-vault-pass]]** im Kapitel **[[#ansible-vault_in_verbindung_mit_ansible-playbook|ansible-vault in Verbindung mit ansible-playbook]]** aufgezeigt haben wir nun eine, mit der Security-Brille betrachtete, optimale Lösung gefunden, die natürlich zugegebener Maßen nicht gerade bequem und konfortabel anmuten kann. | Wie bereits im Abschnitt **[[#ask-vault-pass|ask-vault-pass]]** im Kapitel **[[#ansible-vault_in_verbindung_mit_ansible-playbook|ansible-vault in Verbindung mit ansible-playbook]]** aufgezeigt haben wir nun eine, mit der Security-Brille betrachtete, optimale Lösung gefunden, die natürlich zugegebener Maßen nicht gerade bequem und komfortabel anmuten kann. |
| |
Wir werden uns hierzu gleich noch eine Konfiguration ansehen, die in gewisser Art und Weise ähnliche Sicherheit beim doch mehr Bequemlichkeit für den Admin mit sich bringen kann, doch hierzu mehr in nachfolgendem Abschnitt. | Wir werden uns hierzu gleich noch eine Konfiguration ansehen, die in gewisser Art und Weise ähnliche Sicherheit beim doch mehr Bequemlichkeit für den Admin mit sich bringen kann, doch hierzu mehr in nachfolgendem Abschnitt. |
<WRAP center round tip 80%> | <WRAP center round tip 80%> |
Zur Abarbeitung eines Ansible-Playbooks muss der Admin über drei Dinge verfügen: | Zur Abarbeitung eines Ansible-Playbooks muss der Admin über drei Dinge verfügen: |
- Er muss den SSH-Privat-Key besitzen, diesen laden und die zugehörige Pasphrase eingeben. | - Er muss den SSH-Privat-Key besitzen, diesen laden und die zugehörige Passphrase eingeben. |
- Der Admin muss ferner das **''BECOME password:''** beim Starten eines Playbooks eingeben, damit er Root-Rechte auf den Zielsystemen erlangen kann. | - Der Admin muss ferner das **''BECOME password:''** beim Starten eines Playbooks eingeben, damit er Root-Rechte auf den Zielsystemen erlangen kann. |
- Zusätzlich muss er auch noch das **''Vault password:''** eingeben, damit die verschlüsselten Inhalte, die im Inventory abgelegt sind, entschlüsselt werden können und das bzw. die Playbooks auch ordnungsgemäß und vollständig abgearbeitet werden können. | - Zusätzlich muss er auch noch das **''Vault password:''** eingeben, damit die verschlüsselten Inhalte, die im Inventory abgelegt sind, entschlüsselt werden können und das bzw. die Playbooks auch ordnungsgemäss und vollständig abgearbeitet werden können. |
| |
Aus Sicht der **IT-Sicherheit** ein anpeilbares Zielszenario, welches zugegebener Maßen dem Admin einiges an manuellen Tätigkieten abverlangt. | Aus Sicht der **IT-Sicherheit** ein anpeilbares Zielszenario, welches zugegebener Maßen dem Admin einiges an manuellen Tätigkeiten abverlangt. |
</WRAP> | </WRAP> |
| |
| |
| === Beispiel mit nur einer Passwortabfrage === |
| Jede Lösung und Anwendung in der IT-Welt steht und fällt mit der Akzeptanz der Anwender. In unserem speziellen Fall ist das der Admin und für ihn kann es mitunter helfen, wenn man bei der Lösungsfindung eine akzeptable Mischung aus Sicherheit und Bequemlichkeit der Lösung finden kann. Und genau solch ein Beispiel wollen wir uns nun noch abschliessend genauer ansehen. Was werden wir nun machen? Nun, wir verlagern die Information zum **''become_passord''** weg von einer interaktiven Abfrage beim Starten eines Playbooks hin zur Datenvorhaltung in einem ansible-vault! |
=== Beispiel mit nur einer Passwortabfragen === | |
Jede Lösung und Anwendung in der IT-Welt steht und Fällt mit der Akzeptenz der Anwender. In unserem speziellen Fall ist das der Admin und für ihn kann es mitunter helfen, wenn man bei der Lösungsfindung eine akzeptable Mischung aus Sicherheit und Bequemlichkeit der Lösung finden kann. Und genau solch ein Beispiel wollen wir uns nun noch abschließend genauer ansehen. Was werden wir nun machen? Nun, wir verlagern die Information zum **''become_passord''** weg von einer interaktiven Abfrage beim Starten eines Playbooks hin zur Datenvorhaltung in einem ansible-vault! | |
| |
<WRAP center round important 80%> | <WRAP center round important 80%> |
**Nein**, wir werden nicht den Admin-Aser in eine Gruppe **''sudo''** oder **''wheels''** packen und auf den Zielsystemen in der **''sudoers''** auf die Abfrage des Passwortes vrezichten! **''NOPASSWD: ALL''** ist keine erstrebenswerte Idee! Übrigens genau so wenig wie das Vorhaben allen Admins einen direkten **root**-Access auf Zielsystemen zu geben. Aus Sicherheistaspekten quasi der Supergau schlechthin - wenn auch in gewissen Kreisen seit Jahren Usus, aber das ist ein anders Thema ... :-X | **Nein**, wir werden nicht den Admin-Aser in eine Gruppe **''sudo''** oder **''wheels''** packen und auf den Zielsystemen in der **''sudoers''** auf die Abfrage des Passwortes verzichten! **''NOPASSWD: ALL''** ist **__keine__** erstrebenswerte Idee! Übrigens genau so wenig wie das Vorhaben allen Admins einen direkten **root**-Access auf Zielsystemen zu geben. Aus Sicherheitsaspekten quasi der Super-GAU schlechthin - wenn auch in gewissen Kreisen seit Jahren Usus, aber das ist ein anders Thema ... :-X |
</WRAP> | </WRAP> |
| |
| |
Dort hinterlegen wir zunächst die Optionen, die wir früher in der **''ansible.cfg''** vermerkt hatten. | Dort hinterlegen wir zunächst die Optionen, die wir früher in der **''ansible.cfg''** vermerkt hatten. |
$ vim ~/ansible/inventories/production/group_vars/all/ansible_enviroment.yml | $ vim ~/ansible/inventories/production/group_vars/all/ansible_environment.yml |
<file bash ansible_enviroment.yml>ansible_become: True | <file bash ansible_environment.yml>ansible_become: True |
ansible_become_method: sudo | ansible_become_method: sudo |
ansible_become_user: root | ansible_become_user: root |
<file bash vault.yml>ansible_become_pass: Frueh_uebt_51ch_wer_31n_Meister_werden_will!</file> | <file bash vault.yml>ansible_become_pass: Frueh_uebt_51ch_wer_31n_Meister_werden_will!</file> |
| |
Anschließend verschlüsseln wir diese Datei mit dem **Vault-Passwort**, welches wir ja mit Hilfe von **''pass''** mit unserem PGP-Key verschlüsselt vorhalten. | Anschliessend verschlüsseln wir diese Datei mit dem **Vault-Passwort**, welches wir ja mit Hilfe von **''pass''** mit unserem PGP-Key verschlüsselt vorhalten. |
$ ansible-vault encrypt inventories/production/group_vars/all/vault.yml | $ ansible-vault encrypt inventories/production/group_vars/all/vault.yml |
| |
=== Tests === | === Tests === |
Für einen ersten Test bemühen wir das Ansible adhoc Aufruf und Ermitteln mit Hilfe des **''shell''**-Modules wie viele Dateien und Verzeichnisse sich im **''$HOME''**-Verzeichnis des Benutzers **''root''** befinden. Der Test zeigt uns unmittelbar, ob der Zugriff auf die **''vault.yml''**-Datei klappt in dem sich das **''become_pasword''** befindet. | Für einen ersten Test bemühen wir das Ansible adhoc Aufruf und Ermitteln mit Hilfe des **''shell''**-Moduls wie viele Dateien und Verzeichnisse sich im **''$HOME''**-Verzeichnis des Benutzers **''root''** befinden. Der Test zeigt uns unmittelbar, ob der Zugriff auf die **''vault.yml''**-Datei klappt in dem sich das **''become_pasword''** befindet. |
* Aufruf **__ohne PGP Schlüssel__** :DOWN: \\ Im ersten Beispiel wollen wir nun die Anzahl der Verzeichnisse und Dateien im **''$HOME''** Verzeichnis des Benutzers **''root''** erfragen. Hierzu sind natürlich Root-Rechte von nöten, die unser Admin-Account natürlich per se __nicht__ hat. \\ \\ <code> $ ansible localhost -m shell -a "ls -l /root | wc -l"</code> <html><pre class="code"> | * Aufruf **__ohne PGP Schlüssel__** :DOWN: \\ Im ersten Beispiel wollen wir nun die Anzahl der Verzeichnisse und Dateien im **''$HOME''** Verzeichnis des Benutzers **''root''** erfragen. Hierzu sind natürlich Root-Rechte von nöten, die unser Admin-Account natürlich per se __nicht__ hat. \\ \\ <code> $ ansible localhost -m shell -a "ls -l /root | wc -l"</code> <html><pre class="code"> |
<font style="color: rgb(0, 0, 0)">gpg: decryption failed: No secret key</font> | <font style="color: rgb(0, 0, 0)">gpg: decryption failed: No secret key</font> |
</html> Die Abfrage liefert hier natürlich nun das gewünschte Ergebnis, da die Info zu **''ansible_become_pass''** aus dem **Ansible-Vault** erfolgreich mit Hilfe des PGP-Schlüssels temporär entschlüsselt werden konnte. | </html> Die Abfrage liefert hier natürlich nun das gewünschte Ergebnis, da die Info zu **''ansible_become_pass''** aus dem **Ansible-Vault** erfolgreich mit Hilfe des PGP-Schlüssels temporär entschlüsselt werden konnte. |
| |
Beim Aufruf eines Ansible-Playbooks liest das Programm **''ansible-playbook''** alle benötigten Dateien ein. Zum Abarbeiten benötigt Ansible natürlich die temporär entschlüsselten Informationen. Damit Ansible nun die verschlüsselten Informationen herankommt, benötigt Ansible natürlich vorübergehend das Vault-Passwort/-Passphrase, welches sich nun selbst verschlüsselt in einem Ansible-Vault befindet. Durch den Passwortmanager **''pass''** und unserem PGP-Schlüssel kommen wir nun direkt zu dem **Ansible Vault Passwort**. Wir brauchen also nur einmal das für den PGP zugehörige Passwort oder im Falle der Verwendung eines Security-Hardware-Devices wie eines **[[https://shop.nitrokey.com/de_DE/shop/product/nksa-nitrokey-start-6|Nitrokey Start]]**. | |
| {{ :linux:ansible:ansible-krypto-stick.png?nolink&200|Bild: Ansible NitroKey Start}}Beim Aufruf eines Ansible-Playbooks liest das Programm **''ansible-playbook''** alle benötigten Dateien ein inklusive aller Hostdefinitionen aus dem Inventory ein, auch wenn diese gerade nicht zum Abarbeiten des Playbooks benötigt werden. Zum Abarbeiten benötigt Ansible natürlich die temporär entschlüsselten Informationen. Damit Ansible nun die verschlüsselten Informationen herankommt, benötigt Ansible natürlich vorübergehend das Vault-Passwort/-Passphrase, welches sich nun selbst verschlüsselt in einem Ansible-Vault befindet. Durch den Passwortmanager **''pass''** und unserem PGP-Schlüssel kommen wir nun direkt zu dem **Ansible Vault Passwort**. Wir brauchen also nur einmal das für den PGP zugehörige Passwort oder im Falle der Verwendung eines Security-Hardware-Devices wie eines **[[https://shop.nitrokey.com/de_DE/shop/product/nksa-nitrokey-start-6|Nitrokey Start]]**. |
| |
Der Aufruf des Scripts **''01_create-user.ym''** aus **[[linux:ansible:playbook_example_01|Beispiel 1]]** würde dann lauten: | Der Aufruf des Scripts **''01_create-user.ym''** aus **[[linux:ansible:playbook_example_01|Beispiel 1]]** würde dann lauten: |
<WRAP center round tip 80%> | <WRAP center round tip 80%> |
Aus dem Blickwinkel **Sicherheit** haben wir nun zum einen erreicht, dass schützenswerte Informationen nicht mehr als plain-text in unserer Ansible-Entwicklungsumgebnung ungeschützt herumliegen. Darüber hinaus haben wir nun quasi einen **//zweiten Faktor//** bei der Abarbeitung unserer Ansible-Playbooks eingeführt - genauer gesagt sind es ja eher drei Dinge, über die der Admin verfügen muss: | Aus dem Blickwinkel **Sicherheit** haben wir nun zum einen erreicht, dass schützenswerte Informationen nicht mehr als plain-text in unserer Ansible-Entwicklungsumgebnung ungeschützt herumliegen. Darüber hinaus haben wir nun quasi einen **//zweiten Faktor//** bei der Abarbeitung unserer Ansible-Playbooks eingeführt - genauer gesagt sind es ja eher drei Dinge, über die der Admin verfügen muss: |
- Der Admin muss den SSH-Privat-Key besitzen und von dessen Passphrase Kenntnis haben. Wir ein **Nitrokey Start** USB-Schlüssel verwendet, kann bei Bedarf auch der **[[suse:nitrokey:start#nitrokey_start_und_secure_shell|SSH-Key bei Verwendung der SSH]]** benutzt werden. Die Zusätzliche Eingabe einer Passphrase erübrigt sich dadurch auch hier, wenn der SSH-Key auf dem Kryptostick verwendet wird! | - Der Admin muss den SSH-Privat-Key besitzen und von dessen Passphrase Kenntnis haben. Wird ein **Nitrokey Start** USB-Schlüssel verwendet, kann bei Bedarf auch der **[[suse:nitrokey:start#nitrokey_start_und_secure_shell|SSH-Key bei Verwendung der SSH]]** benutzt werden. Die Zusätzliche Eingabe einer Passphrase erübrigt sich dadurch auch hier, wenn der SSH-Key auf dem Kryptostick verwendet wird! |
- Der Administrator muss beim Aufruf der Playbooks nunmehr **__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 **''become_password''** zur Rechteerweiterung. | - Der Administrator muss beim Aufruf der Playbooks nunmehr **__nur noch__** den PGP-Schlüssel durch Eingabe der zugehörigen Passphrase entsperren. Das **''become_password''** Passwort für die Rechteerweiterung wird nun auch von Ansible aus dem Vault gelesen. |
| |
Aus Sicht von **IT-Security** haben wir auch hier 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 auch hier 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. |
| |
===== Fazit und Ausblick ===== | ===== Fazit und Ausblick ===== |
| <WRAP center round info 60%> |
| Wir können nun mit **Ansible-Vault** vertrauliche Informationen in unseren Playbooks bzw. im Inventory ablegen. Diese werden als krypted **AES256** Daten abgelegt und können dadurch auch jederzeit in einem verteiltem Versionskontrollsystem wie **[[ https://git-scm.com/|git]]** vorgehalten werden. Durch Nutzung des Passwort-Manager **''pass''** wird die Handhabung soweit vereinfacht, so dass der Admin auch ohne grosse Not mehrmals hintereinander Ansible-Playbooks ausführen kann, ohne sich durch zigfache Eingabe von Passworten sich selbst das Leben allzu schwer zu machen! |
| </WRAP> |
| |
| All die in diesem WIKI-Artikel aufgezeigten Konfigurationsschritte müssen wir aber nicht manuell nachvollziehen und auf jedem Administrations-Knoten/-Host via //cut'n'paste// nachtragen. Wir werden diese Punkte ganz einfach mit Hilfe von Ansible selbst ausrollen, wie genau das gemacht werden kann, werden wir uns im nächsten Kapitel **[[playbook_example_08#aufgabenstellung_2_-_erweiterte_grund-_basis-installation_fuer_ansible-vault|Ansible mit Hilfe von Ansible einrichten/konfigurieren]]** genauer ansehen. |
| |
| ====== Links ====== |
| * **[[detail|zurück zum Kapitel "Ansible - Erweiterte Konfigurationsbeispiele"]] <= ** |
| * **=> [[playbook_example_08|weiter zum Kapitel "Ansible - erweitertes Konfigurationsbeispiel: Ansible mit Ansible einrichten]]** |
| * **[[start|Zurück zur "Ansible"-Übersicht]]** |
| * **[[wiki:start|Zurück zu >>Projekte und Themenkapitel<<]]** |
| * **[[http://dokuwiki.nausch.org/doku.php/|Zurück zur Startseite]]** |
| |