=====Mit Ansible eine Konfigurationsdatei Zeilenweise bearbeiten==== **Aufgabe**: In einer Datei wie der sshd.sshd_config soll ein Parameter erweitert werden. In diesem Fall soll der Ansible User mit in die Liste der "AllowUsers" aufgenommen werden. Siehe bzgl. Bedeutung der Parameter (Restricting Access to an SSH Server by Account) => https://www.oreilly.com/library/view/linux-security-cookbook/0596003919/ch03s14.html D.h. wir benötigen den Parameter AllowUsers , falls dieser nicht existiert setzen wir den Parameter auf "AllowUsers root ansible", falls dieser existiert,erweitern wir den Parameter um den User "ansible" wie z.B. auf "AllowUsers root oracle grid ansible". Für das zeilenweise Auslesen und Ändern von Text Dateien seht das "lineinfile" BuildIn zur Verfügung, siehe dazu => https://docs.ansible.com/ansible/latest/collections/ansible/builtin/lineinfile_module.html . ---- ==== Test Playbooks erstellen ==== Im ersten Schritt erstmal die sshd_config nach Temp Kopieren zum üben: cp /etc/ssh/sshd_config /tmp chmod 666 /tmp/sshd_config chown ansible:ansible /tmp/sshd_config grep AllowUsers /tmp/sshd_config #Parameter noch nicht vorhanden === Parameter ist noch nicht vorhanden - neu anlegen === Anlegen des Tasks setzen des Parameter falls noch nicht existiert --- - name: configure sshd conf to restrict user access hosts: localhost tasks: - name: Add parameter if missing ansible.builtin.lineinfile: path: /tmp/sshd_config line: "AllowUsers root ansible" state: present ansible-playbook edit_conf.yml --syntax-check # wenn ok # im ersten Schritt mit Debug starten ansible-playbook edit_conf.yml -vvv grep AllowUsers /tmp/sshd_config #Parameter eingefügt! ===Parameter erweitern um den ansible User=== Dazu benötigen wir vorab einen RegEx Ausdruck, diese üben wir erstmal: # wir suchen diesen Ausdruck # AllowUsers abc cde efg usw # Testweise in /tmp/sshd_config einfügen # Zeilenanfang mit AllowUsers und ohne ansible in der Zeile # Zeilen Anfang bis Ende # Backref auf die gesamte Zeile mit () # Zeile muss mit AllowUsers anfangen # Nicht in String Suche mit ((?!ansible).) # grep -P '^(AllowUsers((?!ansible).)*)$' /tmp/sshd_config AllowUsers abc cde efg usw Playbook, falls eine Zeile gefunden wurde am Ende den Managemement User anhängen: - name: configure sshd conf to restrict user access hosts: localhost tasks: - name: Add User to parameter if exits ansible.builtin.lineinfile: path: /tmp/sshd_config regexp: '^(AllowUsers((?!ansible).)*)$' line: '\g<1> ansible' backrefs: yes ---- ==== Die Endversion ==== Zuerst muss geprüft werden ob des die gewünschte Zeile schon gibt. Falls JA => Führe den Task aus um zu prüfen ob es schon eine Zeile mit dem Ansible User gibt, wenn nein diesen zu der Zeile hinzufügen Dazu mit einem RegEx prüfen ob die Zeile "AllowUsers" exisiert ohne das der ansible user enthalten ist, falls ja über eine Back Referenz wird die alte Zeile im Orginal geholt und mit dem Usernamen ergänzt Falls NEIN => Der Neue Eintrag wird hinzugefügt, in der Schleife mit dem with_items Wird dann pro Text Zeile das durchgeführt, damit beim ersten Einfügen ein Kommentar in der Config Datei steht. Nach jedem Schritt wird geprüft ob die Daten noch valide ist, falls ja läuft das Playbook weiter und startet den SSHD Service neu. --- - name: configure sshd conf to restrict user access hosts: all become: yes become_user: root vars: config_file: /etc/ssh/sshd_config mon_user: ansible tasks: - name: Check if parameter exits command: grep "AllowUsers" "{{ config_file }}" register: checkParameter ignore_errors: True changed_when: False - name: Add User to parameter if exits ansible.builtin.lineinfile: path: "{{ config_file }}" backup: True regexp: '^(AllowUsers((?!{{ mon_user }}).)*)$' line: '\g<1> {{ mon_user }}' backrefs: yes validate: "sshd -t -f %s" when: checkParameter.rc == 0 register: changeParam - name: Add parameter if missing ansible.builtin.lineinfile: path: "{{ config_file }}" backup: true line: "{{ item }}" state: present validate: "sshd -t -f %s" with_items: - '#Parameter added with ansible' - 'AllowUsers root {{ mon_user }}' when: not checkParameter.rc == 0 register: addNewParam - name : restart sshd ansible.builtin.service: name: sshd state: restarted when: (addNewParam.changed == true) or (changeParam.changed == true) In Produktion wird dann noch der Ansible Username als Parameter ergänzt. ---- ==== Quellen ==== Web: * https://www.middlewareinventory.com/blog/ansible-lineinfile-examples/#Example_1_Validate_if_a_line_is_present_in_the_file_without_any_modification * https://stackoverflow.com/questions/56436906/how-to-cleanly-edit-sshd-config-for-basic-security-options-in-an-ansible-playboo * https://stackoverflow.com/questions/406230/regular-expression-to-match-a-line-that-doesnt-contain-a-word * http://www.handverdrahtet.org/2016/01/ansible-using-numbered-backreference.html * https://stackoverflow.com/questions/39834862/ansible-lineinfile-add-new-line-with-path-or-append-to-existing-line-with