diff --git a/.gitignore b/.gitignore index 204d0a0..9d92498 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ -ansible.cfg hosts -proxmox.* \ No newline at end of file +proxmox.* +.vscode diff --git a/ansible.cfg b/ansible.cfg new file mode 100644 index 0000000..b2eabc1 --- /dev/null +++ b/ansible.cfg @@ -0,0 +1,3 @@ +[defaults] +host_key_checking = False +roles_path = ./roles:/etc/ansible/roles \ No newline at end of file diff --git a/playbooks/hardening/manage-ssh-keys.yml b/playbooks/hardening/manage-ssh-keys.yml new file mode 100644 index 0000000..8098838 --- /dev/null +++ b/playbooks/hardening/manage-ssh-keys.yml @@ -0,0 +1,6 @@ +- hosts: all + vars: + good_keys: "{{ lookup('env', 'good_keys') | from_json }}" + bad_keys: "{{ lookup('env', 'bad_keys') | from_json }}" + roles: + - role: manage-ssh-keys \ No newline at end of file diff --git a/roles/manage-ssh-keys/defaults/main.yml b/roles/manage-ssh-keys/defaults/main.yml new file mode 100644 index 0000000..6ff24ad --- /dev/null +++ b/roles/manage-ssh-keys/defaults/main.yml @@ -0,0 +1,14 @@ +--- +ssh_user: "root" +authorized_keys_file: >- + {{ "/root/.ssh/authorized_keys" if ssh_user == "root" else "/home/{{ ssh_user }}/.ssh/authorized_keys" }} + +# Liste der erwünschten (Good) Keys +good_keys: + - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL/XwF0Na+YH7lRqGtwEcyIMVGTQZetNDrC9sZ8ofjC5 niklas@Linkman-PC" + - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINPHSP1qvaoJDwMtka6UV9aOw24cKHBOa2Eyx7JBmhEg dennis@DESKTOP-V99ARL9" + +# Liste der unerwünschten (Bad) Keys +bad_keys: + - "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCgNIBhFlWa82Q0f2EnPcpHsP5JmmGpxyWVUhfpWV3KLvNkl63aGBRZW1gEoda1P5j/ESkwHntVeen8vHjqlQ/ZB9Bs3XtWwsvtS8gfyCoRqgQVQ31T52KVT3QL8/ep0RYwG+3VbE9yvQgeELJETzpXWoyY9+RrPG1gMdArML5cO1NCizShsxNKgHe75+GjCdEe3HMUuCcfJ23JqxPqgA5HoGW1mGsbI1LnLn1fqgmywSKET5LpkKHtHjrXFtQi2NKEnZ3RNxgh60v4amvMKLsxBk1vAn40X+ZeLJwNMpMHep2IzvO67inlj9iWaY5VXjZznLXzd85zhTO3eDv+yAp9 linkman-pc-2022" + # - "ssh-rsa AAAAB3... badkey2" \ No newline at end of file diff --git a/roles/manage-ssh-keys/handlers/main.yml b/roles/manage-ssh-keys/handlers/main.yml new file mode 100644 index 0000000..7b4ade6 --- /dev/null +++ b/roles/manage-ssh-keys/handlers/main.yml @@ -0,0 +1,13 @@ +--- + - name: Cleanup Comments + lineinfile: + path: "{{ authorized_keys_file }}" + state: absent + regexp: '^#.*$' + + - name: Add Comment + blockinfile: + path: "{{ authorized_keys_file }}" + marker: "" + block: | + # Modified by Ansible on {{ ansible_date_time.date }} at {{ ansible_date_time.time }} \ No newline at end of file diff --git a/roles/manage-ssh-keys/tasks/add-goodkeys.yml b/roles/manage-ssh-keys/tasks/add-goodkeys.yml new file mode 100644 index 0000000..f725dc6 --- /dev/null +++ b/roles/manage-ssh-keys/tasks/add-goodkeys.yml @@ -0,0 +1,11 @@ +--- +- name: Good Keys hinzufügen + lineinfile: + path: "{{ authorized_keys_file }}" + line: "{{ item }}" + create: yes + state: present + with_items: "{{ good_keys }}" + notify: + - Cleanup Comments + - Add Comment \ No newline at end of file diff --git a/roles/manage-ssh-keys/tasks/main.yml b/roles/manage-ssh-keys/tasks/main.yml new file mode 100644 index 0000000..90551d8 --- /dev/null +++ b/roles/manage-ssh-keys/tasks/main.yml @@ -0,0 +1,12 @@ +--- +# Haupt-Task der Rolle: Modularer Aufbau mit Subtasks +- name: Validiere SSH Keys + import_tasks: validate-authorized-keys.yml + +- name: Füge Good Keys hinzu + import_tasks: add-goodkeys.yml + when: good_keys + +- name: Entferne Bad Keys + import_tasks: remove-badkeys.yml + when: bad_keys \ No newline at end of file diff --git a/roles/manage-ssh-keys/tasks/remove-badkeys.yml b/roles/manage-ssh-keys/tasks/remove-badkeys.yml new file mode 100644 index 0000000..78ceb5c --- /dev/null +++ b/roles/manage-ssh-keys/tasks/remove-badkeys.yml @@ -0,0 +1,10 @@ +--- +- name: Bad Keys entfernen + lineinfile: + path: "{{ authorized_keys_file }}" + line: "{{ item }}" + state: absent + with_items: "{{ bad_keys }}" + notify: + - Cleanup Comments + - Add Comment \ No newline at end of file diff --git a/roles/manage-ssh-keys/tasks/validate-authorized-keys.yml b/roles/manage-ssh-keys/tasks/validate-authorized-keys.yml new file mode 100644 index 0000000..b6e4e60 --- /dev/null +++ b/roles/manage-ssh-keys/tasks/validate-authorized-keys.yml @@ -0,0 +1,8 @@ +--- +- name: Stelle sicher, dass das .ssh-Verzeichnis existiert + file: + path: "{{ authorized_keys_file | dirname }}" + state: directory + owner: "{{ ssh_user }}" + group: "{{ ssh_user }}" + mode: '0700' \ No newline at end of file diff --git a/roles/os-updates/defaults/main.yml b/roles/os-updates/defaults/main.yml new file mode 100644 index 0000000..d0d03c2 --- /dev/null +++ b/roles/os-updates/defaults/main.yml @@ -0,0 +1,9 @@ +# Standardwerte, die überschrieben werden können +os_update_auto_upgrade: true +os_also_update_mirror: false +os_update_mirrors: + # Role needs two mirros to use for the sources.list.j2 Template + - "http://mirror.tinc.gmbh/debian" # Enter a main mirror here (not security) + - "http://mirror.tinc.gmbh/debian-security" # Enter a security mirror here +os_update_major_version: false # Can either be true or false | To toggle if systems need to be upgraded to newer codename +os_update_version_codename: "{{ ansible_distribution_release }}" # KEEP UNTOUCHED!! | Used for jinja2 Template fill in as it determines the current codename of system where ansible is run on \ No newline at end of file diff --git a/roles/os-updates/handlers/main.yml b/roles/os-updates/handlers/main.yml new file mode 100644 index 0000000..8295fe2 --- /dev/null +++ b/roles/os-updates/handlers/main.yml @@ -0,0 +1,11 @@ +- name: apt cleanup + apt: + clean: yes + autoclean: yes + +- name: Reboot system + command: /sbin/reboot + async: 1 + poll: 0 + ignore_errors: true + when: reboot_required.stdout == "yes" \ No newline at end of file diff --git a/roles/os-updates/tasks/main.yml b/roles/os-updates/tasks/main.yml new file mode 100644 index 0000000..0554922 --- /dev/null +++ b/roles/os-updates/tasks/main.yml @@ -0,0 +1,12 @@ +- name: Update mirrors if necessary + when: os_also_update_mirror |bool + include_tasks: update_mirrors.yml + ignore_errors: true + +- name: Upgrade to new major version if enabled + when: os_update_major_version + include_tasks: update_major_version.yml + ignore_errors: true + +- name: Upgrade all packages + include_tasks: upgrade_packages.yml \ No newline at end of file diff --git a/roles/os-updates/tasks/update_major_version.yml b/roles/os-updates/tasks/update_major_version.yml new file mode 100644 index 0000000..0378f21 --- /dev/null +++ b/roles/os-updates/tasks/update_major_version.yml @@ -0,0 +1,34 @@ +- name: Backup existing sources in /etc/apt + copy: + src: "{{ item }}" + dest: "{{ item }}.bak" + remote_src: yes + loop: "{{ lookup('ansible.builtin.fileglob', '/etc/apt/sources.list.d/*.list') + ['/etc/apt/sources.list'] }}" + when: item | file + +- name: Update sources.list for new major version + template: + src: sources.list.j2 + dest: /etc/apt/sources.list + vars: + os_update_version_codename: "{{ new_version_codename }}" # Variable gets passed by main.yml task + +- name: Update additional repositories in /etc/apt/sources.list.d + lineinfile: + path: "{{ item }}" + regexp: '^(deb .* )({{ os_update_version_codename }})' + line: '\1{{ new_version_codename }}' + loop: "{{ lookup('ansible.builtin.fileglob', '/etc/apt/sources.list.d/*.list') }}" + when: item | file + +- name: Update apt cache + apt: + update_cache: yes + +- name: Perform distribution upgrade + apt: + upgrade: yes + allow_unauthenticated: yes + notify: + - Reboot system + - apt cleanup \ No newline at end of file diff --git a/roles/os-updates/tasks/update_mirrors.yml b/roles/os-updates/tasks/update_mirrors.yml new file mode 100644 index 0000000..b2e18e3 --- /dev/null +++ b/roles/os-updates/tasks/update_mirrors.yml @@ -0,0 +1,16 @@ +- name: Backup existing sources.list + copy: + src: /etc/apt/sources.list + dest: /etc/apt/sources.list.bak + remote_src: yes + force: yes + + +- name: Update sources.list with new mirrors + template: + src: sources.list.j2 + dest: /etc/apt/sources.list + +- name: Update apt cache + apt: + update_cache: yes \ No newline at end of file diff --git a/roles/os-updates/tasks/upgrade_packages.yml b/roles/os-updates/tasks/upgrade_packages.yml new file mode 100644 index 0000000..cd0f54f --- /dev/null +++ b/roles/os-updates/tasks/upgrade_packages.yml @@ -0,0 +1,23 @@ +- name: Upgrade all installed packages + apt: + upgrade: full + update_cache: yes + notify: + - apt cleanup + +- name: Check if a kernel update is available + shell: | + dpkg -l | grep -E 'linux-image-[0-9]' | awk '{print $2}' | sort | tail -n 1 + register: latest_kernel + +- name: Check if running kernel matches the latest installed kernel + shell: uname -r | grep -c "{{ latest_kernel.stdout }}" + register: kernel_match + changed_when: false + +- name: Mark reboot required if a new kernel is installed + set_fact: + reboot_required: "yes" + notify: + - Reboot system + when: kernel_match.stdout == "0" \ No newline at end of file diff --git a/update-to-deb12/update-to-deb12.yaml b/update-to-deb12/update-to-deb12.yaml deleted file mode 100644 index 090f21f..0000000 --- a/update-to-deb12/update-to-deb12.yaml +++ /dev/null @@ -1,25 +0,0 @@ ---- -- name: Update to Debian 12 - hosts: all - tasks: - - name: Run Pre Update and Upgrade before Dist Upgrade - apt: - update_cache: yes - upgrade: yes - when: ansible_distribution == 'Debian' - - - name: Replace "bullseye" with "bookworm" in sources.list - replace: - backup: yes - path: /etc/apt/sources.list - regexp: 'bullseye' - replace: 'bookworm' - when: ansible_distribution == 'Debian' - - - name: Replace "bullseye" with "bookworm" in sources.list.d/docker - replace: - backup: yes - path: /etc/apt/sources.list.d/docker.list - regexp: 'bullseye' - replace: 'bookworm' - when: ansible_distribution == 'Debian' diff --git a/upgrade-alpine/upgrade-alpine.yaml b/upgrade-alpine/upgrade-alpine.yaml deleted file mode 100644 index 1a4c3b2..0000000 --- a/upgrade-alpine/upgrade-alpine.yaml +++ /dev/null @@ -1,16 +0,0 @@ -- name: Update to newest Alpine - hosts: all - tasks: - - name: Run APK update - apk: - update_cache: yes - upgrade: true - when: ansible_distribution == 'Alpine' - - - name: Update Alpine versions - replace: - backup: yes - path: "/etc/apk/repositories" - regexp: 'v\d+\.\d+' - replace: 'v3.20' - when: ansible_distribution == 'Alpine' \ No newline at end of file