diff --git a/.gitignore b/.gitignore index 9d92498..b4da087 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ hosts proxmox.* .vscode +inventory +.vault_pass \ No newline at end of file diff --git a/ansible.cfg b/ansible.cfg index b2eabc1..1c7f2b4 100644 --- a/ansible.cfg +++ b/ansible.cfg @@ -1,3 +1,7 @@ [defaults] host_key_checking = False -roles_path = ./roles:/etc/ansible/roles \ No newline at end of file +roles_path = ./roles:/etc/ansible/roles +group_vars = ./group_vars + +[ssh_connection] +ssh_args = -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \ No newline at end of file diff --git a/bootstrap.yml b/bootstrap.yml index e69de29..84a0f61 100644 --- a/bootstrap.yml +++ b/bootstrap.yml @@ -0,0 +1,18 @@ +- hosts: all + become: true + user: admin + tasks: + - name: Verify if system is Debian + debug: + msg: "This playbook is running on a Debian system." + when: ansible_facts['os_family'] == "Debian" + + - name: Stop playbook if system is not Debian + fail: + msg: "This playbook only supports Debian." + when: ansible_facts['os_family'] != "Debian" + + - name: Include Bootstrap role + import_role: + name: bootstrap + when: ansible_facts['os_family'] == "Debian" \ No newline at end of file diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 0000000..e80355c --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,31 @@ +FROM debian:trixie-slim +ARG DEBIAN_FRONTEND=noninteractive +ENV TZ=Europe/Berlin +ENV ANSIBLE_MAJOR_VERSION=2.18 +ENV PIP_BREAK_SYSTEM_PACKAGES=1 + +RUN apt update && apt install -y --no-install-recommends \ + nano \ + git \ + wget \ + unzip \ + curl \ + python3-pip \ + tzdata \ + openssh-client \ + && rm -rf /var/lib/apt/lists/* + +RUN mkdir -p /etc/ssh/ssh_config.d \ + && printf 'Host *\n StrictHostKeyChecking no\n UserKnownHostsFile /dev/null\n' > /etc/ssh/ssh_config.d/99-no-hostkey-check.conf + +RUN pip3 install --no-cache-dir --upgrade \ + ansible-core~=${ANSIBLE_MAJOR_VERSION} + +RUN mkdir -p /root/.bashrc.d +COPY ansible-functs.sh /root/.bashrc.d/ansible-functs.sh +RUN chmod +x /root/.bashrc.d/ansible-functs.sh \ + && printf '\n[ -f /root/.bashrc.d/ansible-functs.sh ] && . /root/.bashrc.d/ansible-functs.sh\n' >> /root/.bashrc + +WORKDIR /ansible + +CMD ["ansible-playbook", "--version"] \ No newline at end of file diff --git a/docker/ansible-functs.sh b/docker/ansible-functs.sh new file mode 100644 index 0000000..ab29df3 --- /dev/null +++ b/docker/ansible-functs.sh @@ -0,0 +1,11 @@ +#!/bin/bash +# Useful bashrc functions for ansible in docker + +alias ll='ls -alF' +alias la='ls -A' +alias l='ls -CF' + +alias ap='ansible-playbook' +alias ag='ansible-galaxy' +alias av='ansible-vault' + diff --git a/execute.sh b/execute.sh new file mode 100644 index 0000000..c6b2be2 --- /dev/null +++ b/execute.sh @@ -0,0 +1,43 @@ +#!/bin/bash + +defaultimage="ansible:deb13" + +export ANSIBLE_HOST_KEY_CHECKING=False +export ANSIBLE_SSH_ARGS='-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null' +export ANSIBLE_CONFIG=./ansible.cfg + +# Ermittle den nächsten freien Container-Namen +base_name="ansible" +counter=1 +while docker ps -a --format '{{.Names}}' | grep -q "^${base_name}-${counter}$"; do + counter=$((counter + 1)) +done +container_name="${base_name}-${counter}" + +docker run --rm -dit \ + --name "$container_name" \ + --hostname "$container_name" \ + -e ANSIBLE_HOST_KEY_CHECKING=False \ + -e ANSIBLE_SSH_ARGS='-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null' \ + -e ANSIBLE_CONFIG=./ansible.cfg \ + -v "$(pwd):/ansible" \ + -v ansible_ssh_keys:/root/.ssh \ + -w /ansible \ + $defaultimage \ + "/bin/bash" + +docker exec "$container_name" sh -lc "mkdir -p /root/.ssh && chmod 700 /root/.ssh && printf 'Host *\n StrictHostKeyChecking no\n UserKnownHostsFile /dev/null\n' > /root/.ssh/config && chmod 600 /root/.ssh/config" + +container_ip=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "$container_name" 2>/dev/null) +container_os=$(docker exec "$container_name" sh -c 'grep PRETTY_NAME /etc/os-release 2>/dev/null | cut -d= -f2 | tr -d "\"" 2>/dev/null') + +echo "-----------------------------------" +echo "Container Name : $container_name" +echo "Container IP : ${container_ip:-n/a}" +echo "Container OS : ${container_os:-n/a}" +echo "-----------------------------------" + +docker attach "$container_name" + + + diff --git a/playbooks/docker.yml b/playbooks/docker.yml new file mode 100644 index 0000000..9b567a9 --- /dev/null +++ b/playbooks/docker.yml @@ -0,0 +1,18 @@ +- hosts: all + user: admin + become: true + tasks: + - name: Verify if system is Debian + debug: + msg: "This playbook is running on a Debian system." + when: ansible_facts['os_family'] == "Debian" + + - name: Stop playbook if system is not Debian + fail: + msg: "This playbook only supports Debian." + when: ansible_facts['os_family'] != "Debian" + + - name: Include Docker setup role + import_role: + name: docker + when: ansible_facts['os_family'] == "Debian" \ No newline at end of file diff --git a/playbooks/hardening/manage-ssh-keys.yml b/playbooks/hardening/manage-ssh-keys.yml index e6c7be9..de71c49 100644 --- a/playbooks/hardening/manage-ssh-keys.yml +++ b/playbooks/hardening/manage-ssh-keys.yml @@ -2,5 +2,6 @@ # vars: # good_keys: "{{ lookup('env', 'good_keys') | from_json }}" # bad_keys: "{{ lookup('env', 'bad_keys') | from_json }}" + user: admin roles: - role: manage-ssh-keys \ No newline at end of file diff --git a/playbooks/os-updates-deb.yml b/playbooks/os-updates-deb.yml index c3f6ace..d25aeea 100644 --- a/playbooks/os-updates-deb.yml +++ b/playbooks/os-updates-deb.yml @@ -1,17 +1,18 @@ - hosts: all + user: admin become: true tasks: - name: Verify if system is Debian debug: msg: "This playbook is running on a Debian system." - when: ansible_os_family == "Debian" + when: ansible_facts['os_family'] == "Debian" - name: Stop playbook if system is not Debian fail: msg: "This playbook only supports Debian." - when: ansible_os_family != "Debian" + when: ansible_facts['os_family'] != "Debian" - name: Include OS update role include_role: name: os-updates - when: ansible_os_family == "Debian" \ No newline at end of file + when: ansible_facts['os_family'] == "Debian" \ No newline at end of file diff --git a/roles/bootstrap/defaults/main.yml b/roles/bootstrap/defaults/main.yml new file mode 100644 index 0000000..5c3a2bc --- /dev/null +++ b/roles/bootstrap/defaults/main.yml @@ -0,0 +1,13 @@ +--- +# SSH authorized keys for admin user +# Format: key and optional comment +admin_authorized_keys: + - key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL/XwF0Na+YH7lRqGtwEcyIMVGTQZetNDrC9sZ8ofjC5 niklas@Linkman-PC" + comment: "Niklas - Linkman-PC" + - key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINPHSP1qvaoJDwMtka6UV9aOw24cKHBOa2Eyx7JBmhEg dennis@DESKTOP-V99ARL9" + comment: "Dennis - DESKTOP-V99ARL9" + - key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA+EvtGavPlXfv7b00jSYsXX2+IEsqFWupEs6Rzf5z9q root@ansible" + comment: "Generic Ansible Key" + +# Admin user password (hashed with SHA-512) +admin_password: "$6$NmIxM3ZbJDsbC1E6$BO8ag1ZyBqbhELjk0ppKV0CLnYXhHDp9oZc.jmkc62N9hjwbXihF1FmvsYgMKKINVcwaE73u2dRO8pnE6yEGH/" diff --git a/roles/bootstrap/handlers/main.yml b/roles/bootstrap/handlers/main.yml new file mode 100644 index 0000000..c597d7b --- /dev/null +++ b/roles/bootstrap/handlers/main.yml @@ -0,0 +1,9 @@ +--- +- name: Restart sshd + service: + name: "{{ ssh_service_name | default('sshd') }}" + state: restarted + +- name: Reload keyboard layout + shell: setupcon + ignore_errors: yes diff --git a/roles/bootstrap/tasks/add-ssh-keys.yml b/roles/bootstrap/tasks/add-ssh-keys.yml new file mode 100644 index 0000000..673e8d2 --- /dev/null +++ b/roles/bootstrap/tasks/add-ssh-keys.yml @@ -0,0 +1,17 @@ +--- +- name: Create .ssh directory for admin user + file: + path: /home/admin/.ssh + state: directory + owner: admin + group: admin + mode: '0700' + +- name: Deploy authorized SSH keys for admin user + template: + src: authorized_keys.j2 + dest: /home/admin/.ssh/authorized_keys + owner: admin + group: admin + mode: '0600' + when: admin_authorized_keys is defined and admin_authorized_keys | length > 0 diff --git a/roles/bootstrap/tasks/configure-ssh.yml b/roles/bootstrap/tasks/configure-ssh.yml new file mode 100644 index 0000000..c84308b --- /dev/null +++ b/roles/bootstrap/tasks/configure-ssh.yml @@ -0,0 +1,10 @@ +--- +- name: Configure SSH daemon + template: + src: sshd.conf.j2 + dest: /etc/ssh/sshd_config + owner: root + group: root + mode: '0600' + validate: /usr/sbin/sshd -T -f %s + notify: Restart sshd diff --git a/roles/bootstrap/tasks/create-admin-user.yml b/roles/bootstrap/tasks/create-admin-user.yml index 3b83165..4e49719 100644 --- a/roles/bootstrap/tasks/create-admin-user.yml +++ b/roles/bootstrap/tasks/create-admin-user.yml @@ -6,10 +6,20 @@ shell: /bin/bash createhome: yes state: present + password: "{{ admin_password }}" + password_lock: no + +- name: Create sudoers.d directory if not exists + file: + path: /etc/sudoers.d + state: directory + mode: '0755' - name: Set sudo privileges for admin user - lineinfile: - path: /etc/sudoers.d/10-admin - line: "admin ALL=(ALL) NOPASSWD:ALL" - validate: 'visudo -cf %s' - state: present \ No newline at end of file + template: + src: sudoers-admin.j2 + dest: /etc/sudoers.d/10-admin + owner: root + group: root + mode: '0440' + validate: 'visudo -cf %s' \ No newline at end of file diff --git a/roles/bootstrap/tasks/install-basicpackages.yml b/roles/bootstrap/tasks/install-basicpackages.yml new file mode 100644 index 0000000..da52524 --- /dev/null +++ b/roles/bootstrap/tasks/install-basicpackages.yml @@ -0,0 +1,19 @@ +--- +- name: Install basic packages + ansible.builtin.apt: + name: + - fastfetch + - htop + - curl + - wget + - git + - sudo + - console-setup + - qemu-guest-agent + - cron + - net-tools + - tcpdump + - locales-all + update_cache: yes + install_recommends: no + state: present \ No newline at end of file diff --git a/roles/bootstrap/tasks/install-openssh.yml b/roles/bootstrap/tasks/install-openssh.yml new file mode 100644 index 0000000..4b28828 --- /dev/null +++ b/roles/bootstrap/tasks/install-openssh.yml @@ -0,0 +1,13 @@ +--- +- name: Remove openssh-client if ssh package is installed + package: + name: ssh + state: absent + +- name: Install OpenSSH server + ansible.builtin.apt: + name: + - openssh-server + - openssh-client + update_cache: yes + state: present diff --git a/roles/bootstrap/tasks/install-sudo.yml b/roles/bootstrap/tasks/install-sudo.yml deleted file mode 100644 index 4011a9b..0000000 --- a/roles/bootstrap/tasks/install-sudo.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -- name: Install sudo - apt: - name: sudo - state: present - become: yes \ No newline at end of file diff --git a/roles/bootstrap/tasks/main.yml b/roles/bootstrap/tasks/main.yml new file mode 100644 index 0000000..cd271cd --- /dev/null +++ b/roles/bootstrap/tasks/main.yml @@ -0,0 +1,21 @@ +--- +- import_tasks: install-basicpackages.yml + +- import_tasks: create-admin-user.yml + +- import_tasks: set-motd.yml + tags: motd + +- import_tasks: set-keyboardlayout.yml + +- import_tasks: install-openssh.yml + tags: ssh + +- import_tasks: configure-ssh.yml + tags: ssh + +- import_tasks: add-ssh-keys.yml + tags: ssh + +- import_tasks: setup-bashrc.yml + tags: bashrc \ No newline at end of file diff --git a/roles/bootstrap/tasks/set-keyboardlayout.yml b/roles/bootstrap/tasks/set-keyboardlayout.yml new file mode 100644 index 0000000..f9bc4e6 --- /dev/null +++ b/roles/bootstrap/tasks/set-keyboardlayout.yml @@ -0,0 +1,9 @@ +--- +- name: Set keyboard layout to QWERTZ + template: + src: keyboard.j2 + dest: /etc/default/keyboard + owner: root + group: root + mode: '0644' + notify: Reload keyboard layout diff --git a/roles/bootstrap/tasks/set-motd.yml b/roles/bootstrap/tasks/set-motd.yml new file mode 100644 index 0000000..ce54890 --- /dev/null +++ b/roles/bootstrap/tasks/set-motd.yml @@ -0,0 +1,16 @@ +- name: Set MOTD to display fastfetch on login + copy: + content: | + #!/bin/bash + # Managed by Ansible - Do not edit manually + fastfetch -s os:kernel:uptime:packages:shell:disk:cpu:memory:localip:colors + dest: /etc/profile.d/motd.sh + owner: root + group: root + mode: '0755' + +- name: Remove default MOTD file if it exists + file: + path: /etc/motd + state: absent + \ No newline at end of file diff --git a/roles/bootstrap/tasks/setup-bashrc.yml b/roles/bootstrap/tasks/setup-bashrc.yml new file mode 100644 index 0000000..794c987 --- /dev/null +++ b/roles/bootstrap/tasks/setup-bashrc.yml @@ -0,0 +1,46 @@ +--- +- name: Get all regular users from /etc/passwd (including root) + shell: | + getent passwd | awk -F: '($3 >= 1000 && $3 < 65534 && $7 !~ /nologin|false/) || $3 == 0 {print $1":"$6}' + register: system_users + changed_when: false + +- name: Create user list with home directories + set_fact: + user_list: "{{ system_users.stdout_lines | map('split', ':') | list }}" + +- name: Ensure .bashrc exists for all users + file: + path: "{{ item[1] }}/.bashrc" + state: touch + owner: "{{ item[0] }}" + mode: '0644' + modification_time: preserve + access_time: preserve + loop: "{{ user_list }}" + when: item[1] is defined and item[1] != "" + +- name: Add useful aliases to .bashrc + blockinfile: + path: "{{ item[1] }}/.bashrc" + marker: "# {mark} ANSIBLE MANAGED ALIASES" + block: | + # Useful Aliases + alias ll='ls -la' + alias la='ls -A' + alias l='ls -CF' + alias ..='cd ..' + alias ...='cd ../..' + alias grep='grep --color=auto' + alias fgrep='fgrep --color=auto' + alias egrep='egrep --color=auto' + + # Additional useful shortcuts + alias df='df -h' + alias du='du -h' + alias free='free -h' + owner: "{{ item[0] }}" + mode: '0644' + create: no + loop: "{{ user_list }}" + when: item[1] is defined and item[1] != "" diff --git a/roles/bootstrap/templates/authorized_keys.j2 b/roles/bootstrap/templates/authorized_keys.j2 new file mode 100644 index 0000000..0b767d0 --- /dev/null +++ b/roles/bootstrap/templates/authorized_keys.j2 @@ -0,0 +1,8 @@ +# {{ ansible_managed }} +# This file is managed by Ansible. Do not edit it manually. +{% for key_entry in admin_authorized_keys %} +{% if key_entry.comment is defined %} +# {{ key_entry.comment }} +{% endif %} +{{ key_entry.key }} +{% endfor %} diff --git a/roles/bootstrap/templates/keyboard.j2 b/roles/bootstrap/templates/keyboard.j2 new file mode 100644 index 0000000..9ca016c --- /dev/null +++ b/roles/bootstrap/templates/keyboard.j2 @@ -0,0 +1,8 @@ +# {{ ansible_managed }} +# This file is managed by Ansible. Do not edit it manually. +XKBMODEL="pc105" +XKBLAYOUT="de" +XKBVARIANT="" +XKBOPTIONS="" + +BACKSPACE="guess" diff --git a/roles/bootstrap/templates/sshd.conf.j2 b/roles/bootstrap/templates/sshd.conf.j2 new file mode 100644 index 0000000..ac34988 --- /dev/null +++ b/roles/bootstrap/templates/sshd.conf.j2 @@ -0,0 +1,42 @@ +# {{ ansible_managed }} +# This file is managed by Ansible. Do not edit it manually. +# This is the ssh server system-wide configuration file. +# See sshd_config(5) for more information. + +Port 22 +AddressFamily any +ListenAddress 0.0.0.0 +ListenAddress :: + +# HostKeys +HostKey /etc/ssh/ssh_host_ed25519_key +HostKey /etc/ssh/ssh_host_rsa_key + +# Authentication +PermitRootLogin no +PubkeyAuthentication yes +PasswordAuthentication no +PermitEmptyPasswords no +AuthenticationMethods publickey +MaxAuthTries 3 + +# SFTP +Subsystem sftp /usr/lib/openssh/sftp-server + +# Security +X11Forwarding no +PermitTunnel no +AllowAgentForwarding no +AllowTcpForwarding yes +PermitOpen any +ClientAliveInterval 300 +ClientAliveCountMax 2 +Compression no +UseDNS no + +# Logging +SyslogFacility AUTH +LogLevel VERBOSE + +# Accept locale-related environment variables +AcceptEnv LANG LC_* \ No newline at end of file diff --git a/roles/bootstrap/templates/sudoers-admin.j2 b/roles/bootstrap/templates/sudoers-admin.j2 new file mode 100644 index 0000000..f8e6aa7 --- /dev/null +++ b/roles/bootstrap/templates/sudoers-admin.j2 @@ -0,0 +1,5 @@ +# Sudoers configuration for admin user +# {{ ansible_managed }} +# This file is managed by Ansible. Do not edit it manually. + +admin ALL=(ALL) NOPASSWD:ALL diff --git a/roles/docker/defaults/main.yml b/roles/docker/defaults/main.yml new file mode 100644 index 0000000..f0493f3 --- /dev/null +++ b/roles/docker/defaults/main.yml @@ -0,0 +1,8 @@ +docker_mirror: https://download.docker.com/linux/debian +os_version_codename: "{{ ansible_lsb.codename }}" +docker_packages: + - docker-ce + - docker-ce-cli + - containerd.io + - docker-buildx-plugin + - docker-compose-plugin \ No newline at end of file diff --git a/roles/docker/handlers/main.yml b/roles/docker/handlers/main.yml new file mode 100644 index 0000000..d093e27 --- /dev/null +++ b/roles/docker/handlers/main.yml @@ -0,0 +1,17 @@ +--- +- name: Restart Docker + ansible.builtin.systemd: + name: docker + state: restarted + daemon_reload: yes + +- name: Reload Docker + ansible.builtin.systemd: + name: docker + state: reloaded + +- name: Start Docker + ansible.builtin.systemd: + name: docker + state: started + enabled: yes diff --git a/roles/docker/tasks/install-docker.yml b/roles/docker/tasks/install-docker.yml new file mode 100644 index 0000000..e725cc4 --- /dev/null +++ b/roles/docker/tasks/install-docker.yml @@ -0,0 +1,40 @@ +--- +- name: Update apt cache + ansible.builtin.apt: + update_cache: yes + cache_valid_time: 3600 + +- name: Install required packages + ansible.builtin.apt: + name: + - ca-certificates + - curl + state: present + +- name: Create keyrings directory + ansible.builtin.file: + path: /etc/apt/keyrings + state: directory + mode: '0755' + +- name: Download Docker GPG key + ansible.builtin.get_url: + url: "{{ docker_mirror }}/gpg" + dest: /etc/apt/keyrings/docker.asc + mode: '0644' + +- name: Add Docker repository + ansible.builtin.template: + src: sources.list.j2 + dest: /etc/apt/sources.list.d/docker.sources + mode: '0644' + +- name: Update apt cache after adding repository + ansible.builtin.apt: + update_cache: yes + +- name: Install Docker packages + ansible.builtin.apt: + name: "{{ docker_packages }}" + state: present + notify: Start Docker \ No newline at end of file diff --git a/roles/docker/tasks/main.yml b/roles/docker/tasks/main.yml new file mode 100644 index 0000000..14303d2 --- /dev/null +++ b/roles/docker/tasks/main.yml @@ -0,0 +1,2 @@ +- name: Include Docker installation tasks + ansible.builtin.include_tasks: install-docker.yml diff --git a/roles/docker/templates/sources.list.j2 b/roles/docker/templates/sources.list.j2 new file mode 100644 index 0000000..68b1ab4 --- /dev/null +++ b/roles/docker/templates/sources.list.j2 @@ -0,0 +1,7 @@ +# {{ ansible_managed }} +# Package sources for Docker for Codename {{ os_version_codename }}. This file is generated by Ansible using the docker role. +Types: deb +URIs: {{ docker_mirror }} +Suites: {{ os_version_codename }} +Components: stable +Signed-By: /etc/apt/keyrings/docker.asc \ No newline at end of file diff --git a/roles/manage-ssh-keys/defaults/main.yml b/roles/manage-ssh-keys/defaults/main.yml index 6ff24ad..c77322d 100644 --- a/roles/manage-ssh-keys/defaults/main.yml +++ b/roles/manage-ssh-keys/defaults/main.yml @@ -1,12 +1,11 @@ --- -ssh_user: "root" -authorized_keys_file: >- - {{ "/root/.ssh/authorized_keys" if ssh_user == "root" else "/home/{{ ssh_user }}/.ssh/authorized_keys" }} +ssh_user: "admin" # Liste der erwünschten (Good) Keys good_keys: - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL/XwF0Na+YH7lRqGtwEcyIMVGTQZetNDrC9sZ8ofjC5 niklas@Linkman-PC" - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINPHSP1qvaoJDwMtka6UV9aOw24cKHBOa2Eyx7JBmhEg dennis@DESKTOP-V99ARL9" + - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA+EvtGavPlXfv7b00jSYsXX2+IEsqFWupEs6Rzf5z9q root@ansible" # Liste der unerwünschten (Bad) Keys bad_keys: diff --git a/roles/manage-ssh-keys/tasks/main.yml b/roles/manage-ssh-keys/tasks/main.yml index 90551d8..6a1e452 100644 --- a/roles/manage-ssh-keys/tasks/main.yml +++ b/roles/manage-ssh-keys/tasks/main.yml @@ -5,8 +5,8 @@ - name: Füge Good Keys hinzu import_tasks: add-goodkeys.yml - when: good_keys + when: good_keys.defined and good_keys | length > 0 - name: Entferne Bad Keys import_tasks: remove-badkeys.yml - when: bad_keys \ No newline at end of file + when: bad_keys.defined and bad_keys | length > 0 \ 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 index b6e4e60..22dafef 100644 --- a/roles/manage-ssh-keys/tasks/validate-authorized-keys.yml +++ b/roles/manage-ssh-keys/tasks/validate-authorized-keys.yml @@ -1,8 +1,8 @@ --- -- name: Stelle sicher, dass das .ssh-Verzeichnis existiert +- name: Prüfe das .ssh-Verzeichnis des eingeloggten Users file: - path: "{{ authorized_keys_file | dirname }}" + path: "{{ ansible_env.HOME }}/.ssh" state: directory - owner: "{{ ssh_user }}" - group: "{{ ssh_user }}" + owner: "{{ ansible_user_id }}" + group: "{{ ansible_user_gid | default(ansible_user_id) }}" mode: '0700' \ No newline at end of file diff --git a/roles/os-updates/defaults/main.yml b/roles/os-updates/defaults/main.yml index e697faa..903d1b0 100644 --- a/roles/os-updates/defaults/main.yml +++ b/roles/os-updates/defaults/main.yml @@ -5,5 +5,9 @@ os_update_mirrors: # Role needs two mirros to use for the sources.list.j2 Template - "http://deb.debian.org/debian" # Enter a main mirror here (not security) - "http://security.debian.org/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 +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 +os_update_debian_codenames: + # Only these suites are considered Debian codenames and will be rewritten in sources.list.d + - trixie + - bookworm + - bullseye \ No newline at end of file diff --git a/roles/os-updates/handlers/main.yml b/roles/os-updates/handlers/main.yml index 8295fe2..cf01584 100644 --- a/roles/os-updates/handlers/main.yml +++ b/roles/os-updates/handlers/main.yml @@ -8,4 +8,4 @@ async: 1 poll: 0 ignore_errors: true - when: reboot_required.stdout == "yes" \ No newline at end of file + when: reboot_required == "yes" \ No newline at end of file diff --git a/roles/os-updates/tasks/main.yml b/roles/os-updates/tasks/main.yml index 0554922..4bfc678 100644 --- a/roles/os-updates/tasks/main.yml +++ b/roles/os-updates/tasks/main.yml @@ -3,10 +3,5 @@ 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 deleted file mode 100644 index 03343e8..0000000 --- a/roles/os-updates/tasks/update_major_version.yml +++ /dev/null @@ -1,44 +0,0 @@ -- 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 (deb822 format) - replace: - path: "{{ item }}" - regexp: '^(Suites:.*\s)({{ os_update_version_codename }})(\s|$)' - replace: '\1{{ new_version_codename }}\3' - loop: "{{ lookup('ansible.builtin.fileglob', '/etc/apt/sources.list.d/*.sources') }}" - when: item | file - ignore_errors: true - -- name: Update additional repositories in /etc/apt/sources.list.d (old format fallback) - lineinfile: - path: "{{ item }}" - regexp: '^(deb .* )({{ os_update_version_codename }})' - replace: '\1{{ new_version_codename }}' - loop: "{{ lookup('ansible.builtin.fileglob', '/etc/apt/sources.list.d/*.list') }}" - when: item | file - ignore_errors: true - -- 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 index bdedd13..bf57937 100644 --- a/roles/os-updates/tasks/update_mirrors.yml +++ b/roles/os-updates/tasks/update_mirrors.yml @@ -1,20 +1,66 @@ +- name: Run last dist upgrade before changing codename + apt: + update_cache: yes + upgrade: dist + when: ansible_facts['distribution_release'] != os_update_version_codename + - name: Backup existing sources.list copy: src: /etc/apt/sources.list dest: /etc/apt/sources.list.bak remote_src: yes force: yes + ignore_errors: true + when: ansible_facts['distribution_version'] is version('13', '<=') # Only apply under Debian 13 and newer -- name: Remove existing debian.sources file from LXC image +- name: Remove existing sources.list to avoid conflicts with new deb822 format file: - path: /etc/apt/sources.list.d/debian.sources + path: /etc/apt/sources.list state: absent + when: ansible_facts['distribution_version'] is version('13', '>=') # Only apply for Debian 13 and newer -- name: Update sources.list with new mirrors +- name: Update sources.list.d with new mirrors + template: + src: sources.list-deb822.j2 + dest: /etc/apt/sources.list.d/debian.sources + when: ansible_facts['distribution_version'] is version('13', '>=') # Only apply for Debian 13 and newer + register: cache_update_needed + +- name: Update sources.list with new mirrors for older Debian versions template: src: sources.list.j2 dest: /etc/apt/sources.list + when: ansible_facts['distribution_version'] is version('13', '<') # Only apply for Debian versions older than 13 + register: cache_update_needed + +- name: Find sources list fragments + find: + paths: /etc/apt/sources.list.d + patterns: "*.list,*.sources" + file_type: file + register: apt_sources_list_fragments + +- name: Align suite codenames in sources.list.d for .list files + replace: + path: "{{ item.path }}" + backup: yes + regexp: '^(deb(?:-src)?\s+(?:\[[^\]]+\]\s+)?\S+\s+)({{ os_update_debian_codenames | join("|") }})(-[^\s]+)?(\s+.+)$' + replace: '\1{{ os_update_version_codename }}\3\4' + loop: "{{ apt_sources_list_fragments.files }}" + when: (item.path | regex_search('\.list$')) is not none + register: cache_update_needed + +- name: Align suite codenames in sources.list.d for .sources files + replace: + path: "{{ item.path }}" + backup: yes + regexp: '^(Suites:\s+)({{ os_update_debian_codenames | join("|") }})(-[^\s]+)?(.*)$' + replace: '\1{{ os_update_version_codename }}\3\4' + loop: "{{ apt_sources_list_fragments.files }}" + when: (item.path | regex_search('\.sources$')) is not none + register: cache_update_needed - name: Update apt cache apt: - update_cache: yes \ No newline at end of file + update_cache: yes + when: cache_update_needed is changed \ No newline at end of file diff --git a/roles/os-updates/tasks/upgrade_packages.yml b/roles/os-updates/tasks/upgrade_packages.yml index 67516cf..e7b75c2 100644 --- a/roles/os-updates/tasks/upgrade_packages.yml +++ b/roles/os-updates/tasks/upgrade_packages.yml @@ -16,12 +16,15 @@ echo "{{ latest_kernel.stdout }}" | grep -c $(uname -r) register: kernel_match changed_when: false - ignore_errors: true - when: ansible_virtualization_type != 'lxc' + failed_when: false + when: ansible_facts['virtualization_type'] != 'lxc' - name: Mark reboot required if a new kernel is installed set_fact: reboot_required: "yes" + changed_when: true + notify: + - Reboot system when: - - ansible_virtualization_type != 'lxc' - - kernel_match.stdout == "0" \ No newline at end of file + - ansible_facts['virtualization_type'] != 'lxc' + - (kernel_match.stdout | int) == 0 \ No newline at end of file diff --git a/roles/os-updates/templates/sources.list-deb822.j2 b/roles/os-updates/templates/sources.list-deb822.j2 new file mode 100644 index 0000000..a2c3b73 --- /dev/null +++ b/roles/os-updates/templates/sources.list-deb822.j2 @@ -0,0 +1,26 @@ +# {{ ansible_managed }} +# Package sources for Debian {{ os_update_version_codename }}. This file is generated by Ansible using the os-updates role. +# Using deb822 format for sources.list as it is the new standard in Debian 13 and newer. This file is placed in /etc/apt/sources.list.d/debian.sources to avoid conflicts with older sources.list files and to allow coexistence during transition. +Types: deb +URIs: {{ os_update_mirrors[0] }} +Suites: {{ os_update_version_codename }} +Components: main contrib non-free non-free-firmware +Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg + +Types: deb +URIs: {{ os_update_mirrors[0] }} +Suites: {{ os_update_version_codename }}-updates +Components: main contrib non-free non-free-firmware +Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg + +Types: deb +URIs: {{ os_update_mirrors[0] }} +Suites: {{ os_update_version_codename }}-backports +Components: main contrib non-free non-free-firmware +Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg + +Types: deb +URIs: {{ os_update_mirrors[1] }} +Suites: {{ os_update_version_codename }}-security +Components: main contrib non-free non-free-firmware +Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg \ No newline at end of file diff --git a/roles/os-updates/templates/sources.list.j2 b/roles/os-updates/templates/sources.list.j2 index 4db3da0..ed89802 100644 --- a/roles/os-updates/templates/sources.list.j2 +++ b/roles/os-updates/templates/sources.list.j2 @@ -1,20 +1,8 @@ -# {{ ansible_managed }} -Types: deb -URIs: {{ os_update_mirrors[0] }} -Suites: {{ os_update_version_codename }} -Components: main contrib non-free non-free-firmware +# {{ ansible_managed }} | This file is managed by Ansible. Do not edit it manually. +# Package sources for Debian {{ os_update_version_codename }}. This file is generated by Ansible using the os-updates role. -Types: deb -URIs: {{ os_update_mirrors[0] }} -Suites: {{ os_update_version_codename }}-updates -Components: main contrib non-free non-free-firmware +deb {{ os_update_mirrors[0] }} {{ os_update_version_codename }} main contrib non-free non-free-firmware +deb {{ os_update_mirrors[0] }} {{ os_update_version_codename }}-updates main contrib non-free non-free-firmware +deb {{ os_update_mirrors[0] }} {{ os_update_version_codename }}-backports main contrib non-free non-free-firmware -Types: deb -URIs: {{ os_update_mirrors[0] }} -Suites: {{ os_update_version_codename }}-backports -Components: main contrib non-free non-free-firmware - -Types: deb -URIs: {{ os_update_mirrors[1] }} -Suites: {{ os_update_version_codename }}-security -Components: main contrib non-free non-free-firmware \ No newline at end of file +deb {{ os_update_mirrors[1] }} {{ os_update_version_codename }}-security main contrib non-free non-free-firmware \ No newline at end of file diff --git a/setenv.sh b/setenv.sh new file mode 100644 index 0000000..0b8bcd5 --- /dev/null +++ b/setenv.sh @@ -0,0 +1,5 @@ +export PROXMOX_URL=https://192.168.212.10:8006/ +export PROXMOX_USERNAME=ansible@pve +export PROXMOX_PASSWORD=u0H1GQMsAuSYZJ +export PROXMOX_INVALID_CERT=False +export EXCLUDE_LIST="docker.*;br-*;veth*" diff --git a/vault.yml b/vault.yml new file mode 100644 index 0000000..23dede5 --- /dev/null +++ b/vault.yml @@ -0,0 +1,9 @@ +$ANSIBLE_VAULT;1.1;AES256 +34323331303232653139313063663566323064373330346237653366363965303235376230396534 +3364383031333064336239653661313066383534626565320a666433333038303938333163363030 +65623133356566313263616564626166396635343863353065646538343333383066333839666239 +3739643861393534360a353837636662303065623735373063313937633731636338643631623435 +65613634316432373837393638636165326231616563353765376533313336373165313436353566 +65346536316533343966323531333866626162363837653762383265366632323330646665643635 +62653238353738613937393632336132646364633962646637353331613061363564346234333439 +63356431373962343737