- name: Playbook to Provision / Re-configure Node hosts: all vars: users: - name: arya password: "{{arya_encrypted_pass}}" - name: devrand password: "{{devrand_encrypted_pass}}" - name: midou password: "{{midou_encrypted_pass}}" - name: ansiblerunner password: "{{ansiblerunner_encrypted_pass}}" tasks: - name: Enable backports ansible.builtin.apt_repository: repo: deb http://deb.debian.org/debian bookworm-backports main contrib state: present - name: Get Knot GPG keys ansible.builtin.get_url: url: https://deb.knot-dns.cz/apt.gpg dest: /usr/share/keyrings/knot.gpg mode: '0644' - name: Enable knot repo ansible.builtin.apt_repository: repo: deb [signed-by=/usr/share/keyrings/knot.gpg] https://deb.knot-dns.cz/knot-latest/ bookworm main state: present - name: Get GoAccess GPG keys ansible.builtin.get_url: url: https://deb.goaccess.io/gnugpg.key dest: /usr/share/keyrings/goaccess.asc mode: '0644' - name: Enable goaccess repo ansible.builtin.apt_repository: repo: deb [signed-by=/usr/share/keyrings/goaccess.asc arch=amd64] https://deb.goaccess.io/ bookworm main state: present - name: Install Required Programs / APT ansible.builtin.apt: name: # Misc - sudo - chrony - tmux - nala - apt-file - fail2ban - tree # Monitoring - htop - gdu - btop - iotop - vnstat - neofetch - prometheus-node-exporter - goaccess # Text Editing - vim - neovim - curl - wget # Backups - borgbackup - rsync # Basic Networking - net-tools - nmap # Python3 - python3-pip - python3-passlib # Ansible User Creation - python3-pyroute2 # for smart-ipv6-rotator - python3-requests # for smart-ipv6-rotator # Speed Tests - iperf3 - speedtest-cli # Security - ufw - name: Enable VNStat service ansible.builtin.service: name: vnstat enabled: true state: started - name: Enable Chrony (NTP) service ansible.builtin.service: name: chrony enabled: true state: started - name: Enable Prometheus Node Exporter service ansible.builtin.service: name: prometheus-node-exporter enabled: true state: started - name: Enable UFW service ansible.builtin.service: name: ufw enabled: true state: started - name: Enable Fail2Ban service ansible.builtin.service: name: fail2ban enabled: true state: started - name: Disable dmesg logging to console ansible.posix.sysctl: name: kernel.printk value: "3 4 1 3" state: present sysctl_set: true - name: Allow binding to non-local IPs / IPv6 ansible.posix.sysctl: name: net.ipv6.ip_nonlocal_bind value: "1" state: present sysctl_set: true - name: Allow IP forwarding / IPv4 ansible.posix.sysctl: name: net.ipv4.ip_forward value: "1" state: present sysctl_set: true - name: Allow IP forwarding / IPv6 ansible.posix.sysctl: name: net.ipv6.conf.all.forwarding value: "1" state: present sysctl_set: true - name: Swappiness ansible.posix.sysctl: name: vm.swappiness value: "60" state: present sysctl_set: true - name: Bashrc skel ansible.builtin.template: src: templates/bashrc.j2 dest: /etc/skel/.bashrc mode: preserve - name: Profile skel ansible.builtin.template: src: templates/profile.j2 dest: /etc/skel/.profile mode: preserve - name: Bash_aliases skel ansible.builtin.template: src: templates/bash_aliases.j2 dest: /etc/skel/.bash_aliases mode: preserve - name: Prompt skel ansible.builtin.template: src: templates/prompt.j2 dest: /etc/skel/.prompt mode: preserve - name: Bashrc root ansible.builtin.template: src: templates/bashrc.j2 dest: /root/.bashrc mode: preserve - name: Profile root ansible.builtin.template: src: templates/profile.j2 dest: /root/.profile mode: preserve - name: Bash_aliases root ansible.builtin.template: src: templates/bash_aliases.j2 dest: /root/.bash_aliases mode: preserve - name: Prompt root ansible.builtin.template: src: templates/prompt.j2 dest: /root/.prompt mode: preserve - name: Add user ansible.builtin.user: name: "{{ item.name }}" group: users groups: users,sudo password: "{{ item.password }}" shell: /bin/bash update_password: always with_items: - "{{ users }}" - name: "Add authorized keys" ansible.posix.authorized_key: user: "{{ item.name }}" key: "{{ lookup('file', 'files/' + item.name + '.pub') }}" with_items: - "{{ users }}" - name: "Allow admin users to sudo without a password" ansible.builtin.lineinfile: dest: "/etc/sudoers" # path: in version 2.3 state: "present" regexp: "^%sudo" line: "%sudo ALL=(ALL) NOPASSWD: ALL" - name: "Sshd configuration file update" ansible.builtin.template: src: templates/sshd_config.j2 dest: /etc/ssh/sshd_config backup: true owner: 0 group: 0 mode: "0644" validate: "/usr/sbin/sshd -T -f %s" notify: - Restart sshd - name: "Remove useless passphrase line (runs after borgmatic role)" ansible.builtin.lineinfile: dest: "/etc/borgmatic/config.yaml" state: "absent" regexp: "^.*encryption_passphrase" handlers: - name: Restart sshd ansible.builtin.service: name: ssh enabled: true state: restarted roles: - role: geerlingguy.docker docker_install_compose_plugin: true docker_compose_package: docker-compose-plugin docker_compose_package_state: present - role: artis3n.tailscale # Future Sysadmin seeing this: if this fails; it is because the key is only valid for 365 days (from Jan 6 2024) tailscale_authkey: "{{tailscale_authkey}}" tailscale_args: "--login-server https://hs.projectsegfau.lt --accept-dns=false" - role: borgbase.ansible_role_borgbackup borg_repository: - ssh://zh3117@zh3117.rsync.net/data1/home/zh3117/backups/{{rsyncnet_slug}} borg_source_directories: "{{bkp_source_directories}}" borg_exclude_patterns: "{{bkp_exclude_patterns}}" borg_remote_path: /usr/local/bin/borg_1.2.4/borg1 borgmatic_hooks: postgresql_databases: "{{bkp_postgresql_databases}}" healthchecks: ping_url: https://healthchecks.projectsegfau.lt/ping/{{bkp_hc_uuid}} states: - finish borg_retention_policy: keep_daily: 7 keep_weekly: 4 keep_monthly: 3 # very secure I know; it has to be plain text anyway for automated backups, unless there is a better way (in which case please email me@aryak.me) borg_encryption_passcommand: "cat /etc/borgmatic/passphrase" - name: UFW Firewall Configuration hosts: eu,us # IN is behind router so no f/w is needed tasks: - name: Enable UFW community.general.ufw: state: enabled policy: deny - name: Allow all in from tailscale community.general.ufw: rule: allow interface: tailscale0 direction: in - name: Allow all in from wg (if its there) community.general.ufw: rule: allow interface: wg0 direction: in # For some reason in order for a docker container to connect to postgres on host it needs this - name: Allow all in from bogon ranges community.general.ufw: rule: allow src: "{{ item }}" direction: in loop: - 10.0.0.0/8 - 172.16.0.0/12 - 192.168.0.0/16 - name: Deny rules community.general.ufw: rule: allow port: "{{ item.port }}" proto: "{{ item.proto }}" with_items: - "{{ ufw_allow_rules }}"