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/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..5eeb047 --- /dev/null +++ b/roles/bootstrap/handlers/main.yml @@ -0,0 +1,11 @@ +--- +- name: Restart sshd + service: + name: "{{ ssh_service_name | default('sshd') }}" + state: restarted + remote_user: admin + +- name: Reload keyboard layout + shell: setupcon + ignore_errors: yes + remote_user: admin 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/configure-sysctl.yml b/roles/bootstrap/tasks/configure-sysctl.yml new file mode 100644 index 0000000..d8c7bf0 --- /dev/null +++ b/roles/bootstrap/tasks/configure-sysctl.yml @@ -0,0 +1,9 @@ +--- +- name: Configure swappiness to reduce swap usage + become: yes + ansible.posix.sysctl: + name: vm.swappiness + value: 10 + state: present + reload: yes + when: ansible_facts['virtualization_type'] != "lxc" \ No newline at end of file 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..58c1d8a --- /dev/null +++ b/roles/bootstrap/tasks/main.yml @@ -0,0 +1,32 @@ +--- +- 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 + +- import_tasks: configure-sysctl.yml + tags: sysctl + +- import_role: + name: docker + when: not skip_docker | default(false) + +- import_role: + name: monitoring + when: not skip_monitoring | default(false) \ 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..19c57de --- /dev/null +++ b/roles/bootstrap/tasks/set-motd.yml @@ -0,0 +1,19 @@ +- name: Set MOTD to display fastfetch on login + copy: + content: | + #!/bin/bash + # Managed by Ansible - Do not edit manually + if [[ -z "${FASTFETCH_MOTD_SHOWN:-}" && -z "${SUDO_USER:-}" ]]; then + fastfetch -s os:kernel:uptime:packages:shell:disk:cpu:memory:localip:colors + export FASTFETCH_MOTD_SHOWN=1 + fi + 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