{"id":937,"date":"2026-01-13T09:24:37","date_gmt":"2026-01-13T08:24:37","guid":{"rendered":"https:\/\/whoami.lausitz-event.info\/?p=937"},"modified":"2026-01-14T14:35:27","modified_gmt":"2026-01-14T13:35:27","slug":"ansible-in-jail-mit-cisco-nexus-backup-und-ssh-authentication","status":"publish","type":"post","link":"https:\/\/whoami.lausitz-event.info\/?p=937","title":{"rendered":"Ansible in Jail mit Cisco Nexus und IOSXE Backup und SSH Authentication und Sicherung in Gitea"},"content":{"rendered":"\n\n<p>M\u00f6chte man mit Ansible seine Cisco Nexus Konfigurationsdaten sichern, sollte man den Gedanken Security nicht au\u00dfer acht lassen. Welche Anforderungen haben wir also?<\/p>\n\n\n\n\n\n<ul>\n  <li> Ansible Nutzer darf auf dem Wirtssystem keine Root Rechte haben <\/li>\n  <li> Ansible Nutzer darf keine Login Shell haben, um Angriffe von Au\u00dfen zu eliminieren <\/li>\n  <li> Ansible Nutzer muss eine keybasierte Authentifizierung auf unseren Nexus Switches haben <\/li>\n  <li> Ansible Nutzer darf auf unseren Switches nur bestimmte Show Commands ausf\u00fchren <\/li>\n  <li> Ansible Nutzer muss nach erfolgter Sicherung die Konfiguration in ein GIT Repository schreiben <\/li>\n<\/ul>\n\n\n\n\n\n<p>Auf unserem Linux System sind die folgenden Schritte notwendig. Wir gehen in unserem Beispiel davon aus das die Ansible Directory Struktur sich unterhalb von \/opt\/ansible befindet.<\/p>\n\n\n\n\n\n<p><strong>Anlegen der Keys f\u00fcr unsere Switches. Wir erzeugen f\u00fcr jeden Switch ein eigenes Public\/Private Keypair.<\/strong><\/p>\n\n\n\n\n\n<pre class=\"wp-block-code\"><code>mkdir -p \/opt\/ansible\/keys\nssh-keygen -t ed25519 -f \/opt\/ansible\/keys\/SW001_ed25519 -C \"ansible_backup@SW001\"\nssh-keygen -t ed25519 -f \/opt\/ansible\/keys\/SW002_ed25519 -C \"ansible_backup@SW002\"\nssh-keygen -t ed25519 -f \/opt\/ansible\/keys\/SW003_ed25519 -C \"ansible_backup@SW003\"\nssh-keygen -t ed25519 -f \/opt\/ansible\/keys\/SW004_ed25519 -C \"ansible_backup@SW004\"<\/code><\/pre>\n\n\n\n\n\n<p><strong>Cisco IOSXE hat sich ein wenig scheckig wenn es um die Keyl\u00e4nge geht, hier k\u00f6nnen wir nur mit 1024 Bit L\u00e4nge arbeiten.<\/strong><\/p>\n\n\n\n\n\n<pre class=\"wp-block-code\"><code>ssh-keygen -t rsa -b 1024 -f \/opt\/ansible\/keys\/SW007_ansible_rsa -C \"ansible_backup@Ansible-Device\"<\/code><\/pre>\n\n\n\n\n\n<p><strong>Anlegen eines Backup User f\u00fcr unseren Ansible Backup Job<\/strong><\/p>\n\n\n\n\n\n<pre class=\"wp-block-code\"><code>useradd -r -m -d \/var\/lib\/ansible_backup -s \/usr\/sbin\/nologin ansible_backup\nchown ansible_backup:ansible_backup -R \/opt\/ansible\/*\nmkdir -p \/opt\/ansible\/keys\nchmod 700 \/opt\/ansible\/keys<\/code><\/pre>\n\n\n\n\n\n<p><strong>\/opt\/ansible\/inventory.cfg<\/strong><\/p>\n\n\n\n\n\n<pre class=\"wp-block-code\"><code>all:\n  children:\n    switches:\n      hosts:\n         SW001:\n          ansible_connection: network_cli\n          ansible_network_os: cisco.nxos.nxos\n          ansible_host: 192.168.1.11\n          ansible_user: ansible_backup\n          ansible_ssh_private_key_file: \/opt\/ansible\/keys\/SW001_ansible_ed25519\n         SW002:\n          ansible_connection: network_cli\n          ansible_network_os: cisco.nxos.nxos\n          ansible_host: 192.168.1.12\n          ansible_user: ansible_backup\n          ansible_ssh_private_key_file: \/opt\/ansible\/keys\/SW002_ansible_ed25519\n        SW003:\n          ansible_connection: network_cli\n          ansible_network_os: cisco.nxos.nxos\n          ansible_host: 192.168.1.13\n          ansible_user: ansible_backup\n          ansible_ssh_private_key_file: \/opt\/ansible\/keys\/SW003_ansible_ed25519\n        SW004:\n          ansible_connection: network_cli\n          ansible_network_os: cisco.nxos.nxos\n          ansible_host: 192.168.1.14\n          ansible_user: ansible_backup\n          ansible_ssh_private_key_file: \/opt\/ansible\/keys\/SW004_ansible_ed25519\n<\/code><\/pre>\n\n\n\n\n\n<p><strong>\/opt\/ansible\/playbooks\/netzwerk_backup.yml<\/strong><\/p>\n\n\n\n\n\n<pre class=\"wp-block-code\"><code>---\n- name: Backup Nexus Config\n  hosts: switches\n  gather_facts: no\n  vars:\n    ansible_network_os: cisco.nxos.nxos\n    ansible_connection: network_cli\n\n    backup_dir: \/opt\/backup-config\n    backup_timestamp: \"{{ lookup('pipe', 'date +%Y%m%d-%H-%M-%S') }}\"\n    backup_keep: 60\n\n  tasks:\n    - name: Backup running config\n      cisco.nxos.nxos_config:\n        backup: yes\n        backup_options:\n          filename: \"{{ inventory_hostname }}.cfg\"\n          dir_path: \"\/opt\/ansible\/playbooks\/files\"\n    - name: Remove dynamic NX-OS headers from config\n      ansible.builtin.replace:\n        path: \"\/opt\/ansible\/playbooks\/files\/{{ inventory_hostname }}.cfg\"\n        regexp: '^!(Time|Running configuration last done at|Last configuration change at|NVRAM config last updated at|Command|Device):.*$'\n        replace: ''\n\n\n- name: Check files into Gitea via HTTP + Token\n  hosts: localhost\n  vars:\n    gitea_domain: \"192.168.10.30:3000\"\n    repo_name: \"konfigurationssicherung\"\n    repo_user: \"config\"\n    gitea_token: \"1234567890\"\n    repo_url: \"http:\/\/{{ gitea_domain }}\/{{ repo_user }}\/{{ repo_name }}.git\"\n    repo_dest: \"\/opt\/backup-config\/{{ repo_name }}\"\n    git_branch: \"master\"\n    commit_msg: \"Automated commit via Ansible\"\n    files_to_add:\n      - { src: \"SW001.cfg\", dest: \"SW001.cfg\" }\n      - { src: \"SW002.cfg\", dest: \"SW002.cfg\" }\n      - { src: \"SW003.cfg\", dest: \"SW003.cfg\" }\n      - { src: \"SW004.cfg\", dest: \"SW004.cfg\" }\n\n  tasks:\n    - name: Ensure git is installed\n      ansible.builtin.package:\n        name: git\n        state: present\n\n    - name: Check if Git repo already exists\n      ansible.builtin.stat:\n        path: \"{{ repo_dest }}\/.git\"\n      register: git_repo_present\n\n    - name: Clone repo if missing\n      git:\n        repo: \"{{ repo_url }}\"\n        dest: \"{{ repo_dest }}\"\n        version: \"{{ git_branch }}\"\n        force: no\n      when: not git_repo_present.stat.exists\n\n    - name: Set git user.name\n      command: git config user.name \"pfconfig\"\n      args:\n        chdir: \"{{ repo_dest }}\"\n\n    - name: Set git user.email\n      command: git config user.email \"pfconfig@lkosl.local\"\n      args:\n        chdir: \"{{ repo_dest }}\"\n\n    - name: Copy backup files\n      copy:\n        src: \"{{ item.src }}\"\n        dest: \"{{ repo_dest }}\/{{ item.dest }}\"\n      loop: \"{{ files_to_add }}\"\n\n    - name: Git add files\n      command: git add .\n      args:\n        chdir: \"{{ repo_dest }}\"\n\n    - name: Commit changes (if any)\n      command: git commit -m \"Automated commit via Ansible\"\n      args:\n        chdir: \"{{ repo_dest }}\"\n      register: git_commit\n      failed_when: git_commit.rc != 0 and \"'nothing to commit'\" not in git_commit.stderr\n\n    - name: Ensure branch matches remote\n      command: git branch -M {{ git_branch }}\n      args:\n        chdir: \"{{ repo_dest }}\"\n\n    - name: Ensure origin remote uses token authentication\n      ansible.builtin.command: &gt;\n        git remote set-url origin {{ repo_url }}\n      args:\n        chdir: \"{{ repo_dest }}\"\n\n    - name: Push changes to Gitea using token header\n      ansible.builtin.command: &gt;\n        git -c http.extraHeader=\"Authorization: Bearer {{ gitea_token }}\"\n        push -u origin {{ git_branch }}\n      args:\n        chdir: \"{{ repo_dest }}\"<\/code><\/pre>\n\n\n\n\n\n<p><strong>Auf unserem Nexus Switch:<\/strong><\/p>\n\n\n\n\n\n<pre class=\"wp-block-code\"><code>! Anlegen einer Rolle mit restriktiven Commands\nrole name ansible_backup\n  rule 10 permit command terminal length 0\n  rule 20 permit command terminal width 511\n  rule 30 permit command show running-config\n  rule 40 permit command show version\n  rule 50 permit command show hostname\n  rule 60 permit command read\n  rule 70 permit command show inventory\n\nusername ansible_backup password 1234567890 role ansible_backup\nusername ansible_backup sshkey ssh-dsa ...<\/code><\/pre>\n\n\n\n\n\n<p><strong>Auf unserem IOSXE Switch:<\/strong><\/p>\n\n\n\n\n\n<pre class=\"wp-block-code\"><code>username ansible_backup secret XXXXXXXX\nconf t\nip ssh pubkey-chain\n username ansible_backup\n  key-string\n   ssh-rsa 5AQ5pQCZEopy5ErOUD\/fzf1g2BZIPOBqHB18otNLy5uU6lfJCV78agChymfmeP77GrFdXMpewj0fH9EPoPp59FSHmoZeScGqJ+HrmJEgTkp\/yU4FNps0uH1YyrOBJdXBEXf90BKva76RUzaM8Cdp8S\/dhNk73E365I+zgl6Q== ansible_backup@Ansible-Device\n  exit\n exit\nend<\/code><\/pre>\n\n\n","protected":false},"excerpt":{"rendered":"<p>M\u00f6chte man mit Ansible seine Cisco Nexus Konfigurationsdaten sichern, sollte man den Gedanken Security nicht au\u00dfer acht lassen. Welche Anforderungen haben wir also? Ansible Nutzer darf auf dem Wirtssystem keine Root Rechte haben Ansible Nutzer darf keine Login Shell haben, um Angriffe von Au\u00dfen zu eliminieren Ansible Nutzer muss eine keybasierte Authentifizierung auf unseren Nexus [&hellip;]<\/p>","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"default","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"set","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[1,7,15,3,23,13,4,11],"tags":[],"class_list":["post-937","post","type-post","status-publish","format-standard","hentry","category-allgemein","category-ansible","category-cisco","category-it","category-netzwerk","category-netzwerke","category-scripts","category-security"],"_links":{"self":[{"href":"https:\/\/whoami.lausitz-event.info\/index.php?rest_route=\/wp\/v2\/posts\/937","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/whoami.lausitz-event.info\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/whoami.lausitz-event.info\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/whoami.lausitz-event.info\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/whoami.lausitz-event.info\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=937"}],"version-history":[{"count":10,"href":"https:\/\/whoami.lausitz-event.info\/index.php?rest_route=\/wp\/v2\/posts\/937\/revisions"}],"predecessor-version":[{"id":957,"href":"https:\/\/whoami.lausitz-event.info\/index.php?rest_route=\/wp\/v2\/posts\/937\/revisions\/957"}],"wp:attachment":[{"href":"https:\/\/whoami.lausitz-event.info\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=937"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/whoami.lausitz-event.info\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=937"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/whoami.lausitz-event.info\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=937"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}