summaryrefslogtreecommitdiff
path: root/tasks
diff options
context:
space:
mode:
Diffstat (limited to 'tasks')
-rw-r--r--tasks/apt_packages.yaml11
-rw-r--r--tasks/harden.yaml161
-rw-r--r--tasks/hugo_setup.yaml24
-rw-r--r--tasks/icecast2_setup.yaml38
-rw-r--r--tasks/nginx_setup.yaml47
-rw-r--r--tasks/preflight.yaml16
6 files changed, 297 insertions, 0 deletions
diff --git a/tasks/apt_packages.yaml b/tasks/apt_packages.yaml
new file mode 100644
index 0000000..c67f043
--- /dev/null
+++ b/tasks/apt_packages.yaml
@@ -0,0 +1,11 @@
+- name: upgrade apt packages
+ apt:
+ upgrade: dist
+
+- name: install apt packages
+ apt:
+ name: "{{ apt_packages }}"
+ state: present
+ update_cache: true
+ environment:
+ DEBIAN_FRONTEND: noninteractive
diff --git a/tasks/harden.yaml b/tasks/harden.yaml
new file mode 100644
index 0000000..3fad047
--- /dev/null
+++ b/tasks/harden.yaml
@@ -0,0 +1,161 @@
+- name: clear /etc/issue and /etc/motd
+ copy:
+ content: ""
+ dest: "{{ item }}"
+ loop:
+ - /etc/issue
+ - /etc/motd
+
+- name: check if /etc/update-motd.d directory exists
+ stat:
+ path: /etc/update-motd.d
+ register: motd_dir
+
+- name: find files in /etc/update-motd.d
+ find:
+ paths: /etc/update-motd.d
+ file_type: file
+ register: motd_files
+ when: motd_dir.stat.exists
+
+- name: remove execute permissions from all files in /etc/update-motd.d
+ file:
+ path: "{{ item.path }}"
+ mode: u-x,g-x,o-x
+ loop: "{{ motd_files.files }}"
+ when: motd_dir.stat.exists
+
+- name: enforce root-only cron/at
+ file:
+ path: "{{ item }}"
+ state: touch
+ owner: root
+ group: root
+ mode: '0600'
+ loop:
+ - /etc/cron.allow
+ - /etc/at.allow
+
+- name: remove deny files for cron and at
+ file:
+ path: "{{ item }}"
+ state: absent
+ loop:
+ - /etc/cron.deny
+ - /etc/at.deny
+
+- name: backup sshd_config
+ copy:
+ src: /etc/ssh/sshd_config
+ dest: "/etc/ssh/sshd_config.bak_{{ ansible_date_time.iso8601_basic }}"
+ remote_src: true
+
+- name: harden sshd_config
+ copy:
+ dest: /etc/ssh/sshd_config
+ content: |
+ Port 22
+ Banner /etc/issue
+ UsePAM yes
+ Protocol 2
+ Subsystem sftp /usr/lib/openssh/sftp-server
+ LogLevel verbose
+ PrintMotd no
+ #AcceptEnv LANG LC_*
+ MaxSessions 5
+ StrictModes yes
+ Compression no
+ MaxAuthTries 3
+ IgnoreRhosts yes
+ PrintLastLog yes
+ AddressFamily inet
+ X11Forwarding no
+ PermitRootLogin yes
+ AllowTcpForwarding yes
+ ClientAliveInterval 1200
+ AllowAgentForwarding no
+ PermitEmptyPasswords no
+ ClientAliveCountMax 0
+ GSSAPIAuthentication no
+ KerberosAuthentication no
+ IgnoreUserKnownHosts yes
+ PermitUserEnvironment no
+ ChallengeResponseAuthentication no
+ MACs hmac-sha2-512,hmac-sha2-256
+ Ciphers aes128-ctr,aes192-ctr,aes256-ctr
+
+- name: regenerate SSH host keys
+ shell: |
+ rm -f /etc/ssh/ssh_host_*key*
+ ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N ""
+ ssh-keygen -t rsa -b 4096 -f /etc/ssh/ssh_host_rsa_key -N ""
+ args:
+ creates: /etc/ssh/ssh_host_ed25519_key
+
+- name: restart ssh
+ systemd:
+ name: ssh
+ state: restarted
+ enabled: true
+ when: ansible_service_mgr == 'systemd'
+
+- name: enable unattended-upgrades
+ shell: dpkg-reconfigure --priority=low unattended-upgrades
+ args:
+ creates: /etc/apt/apt.conf.d/50unattended-upgrades
+
+- name: restart unattended-upgrades
+ systemd:
+ name: unattended-upgrades
+ state: restarted
+ enabled: true
+ when: ansible_service_mgr == 'systemd'
+
+- name: disable ipv6 in grub
+ lineinfile:
+ path: /etc/default/grub
+ regexp: '^GRUB_CMDLINE_LINUX='
+ line: 'GRUB_CMDLINE_LINUX="ipv6.disable=1"'
+
+- name: update grub
+ command: update-grub
+
+- name: create sshd fail2ban jail
+ copy:
+ src: fail2ban/jail.d/sshd.local
+ dest: "{{ fail2ban_jail_dir }}/sshd.local"
+ owner: root
+ group: root
+ mode: '0644'
+
+- name: copy fail2ban jail configuration
+ copy:
+ src: /etc/fail2ban/jail.conf
+ dest: /etc/fail2ban/jail.local
+ remote_src: true
+ mode: '0644'
+
+- name: allow ssh port and enable ufw
+ ufw:
+ rule: allow
+ port: 22
+ proto: tcp
+
+- name: restart fail2ban
+ systemd:
+ name: fail2ban
+ state: restarted
+ enabled: true
+ when: ansible_service_mgr == 'systemd'
+
+- name: enable ufw
+ ufw:
+ state: enabled
+ policy: deny
+
+- name: restart ufw
+ systemd:
+ name: ufw
+ state: restarted
+ enabled: true
+ when: ansible_service_mgr == 'systemd'
diff --git a/tasks/hugo_setup.yaml b/tasks/hugo_setup.yaml
new file mode 100644
index 0000000..475dc8c
--- /dev/null
+++ b/tasks/hugo_setup.yaml
@@ -0,0 +1,24 @@
+- name: download latest hugo .deb
+ shell: |
+ curl -sSL https://api.github.com/repos/gohugoio/hugo/releases |
+ awk -F '"' '/browser_download_url/ {print $4}' |
+ grep -i 'extended' |
+ grep -i 'linux-amd64' |
+ head -1
+ register: latest_hugo_url
+
+- name: download hugo .deb package
+ get_url:
+ url: "{{ latest_hugo_url.stdout }}"
+ dest: /tmp/hugo.deb
+ mode: '0644'
+
+- name: install hugo package
+ apt:
+ deb: /tmp/hugo.deb
+ state: present
+
+- name: remove hugo .deb package
+ file:
+ path: /tmp/hugo.deb
+ state: absent
diff --git a/tasks/icecast2_setup.yaml b/tasks/icecast2_setup.yaml
new file mode 100644
index 0000000..ee8342d
--- /dev/null
+++ b/tasks/icecast2_setup.yaml
@@ -0,0 +1,38 @@
+- name: ensure {{ radio_music_dir }} directory exists
+ file:
+ path: "{{ radio_music_dir }}"
+ state: directory
+ owner: icecast2
+ group: icecast
+ mode: '0700'
+
+- name: deploy icecast.xml from template
+ template:
+ src: icecast2/icecast.xml.j2
+ dest: /etc/icecast2/icecast.xml
+ owner: root
+ group: root
+ mode: '0644'
+
+- name: deploy ices-playlist.xml.j2 from template
+ template:
+ src: icecast2/ices-playlist.xml.j2
+ dest: /etc/icecast2/ices-playlist.xml
+ owner: root
+ group: root
+ mode: '0644'
+
+- name: deploy mp3-to-ogg.sh from template
+ template:
+ src: icecast2/mp3-to-ogg.sh.j2
+ dest: /etc/icecast2/mp3-to-ogg.sh
+ owner: root
+ group: root
+ mode: '0744'
+
+- name: restart icecast2
+ systemd:
+ name: icecast2
+ state: restarted
+ enabled: true
+ when: ansible_service_mgr == 'systemd'
diff --git a/tasks/nginx_setup.yaml b/tasks/nginx_setup.yaml
new file mode 100644
index 0000000..604db6d
--- /dev/null
+++ b/tasks/nginx_setup.yaml
@@ -0,0 +1,47 @@
+- name: remove /etc/nginx/sites-enabled directory
+ file:
+ path: /etc/nginx/sites-enabled
+ state: absent
+
+- name: remove /etc/nginx/sites-available directory
+ file:
+ path: /etc/nginx/sites-available
+ state: absent
+
+- name: ensure /var/www/html directory exists and is empty
+ file:
+ path: /var/www/html
+ state: directory
+ mode: '0755'
+ owner: www-data
+ group: www-data
+
+- name: clean /var/www/html contents
+ file:
+ path: /var/www/html
+ state: absent
+ become: true
+ ignore_errors: true
+
+- name: recreate /var/www/html directory
+ file:
+ path: /var/www/html
+ state: directory
+ mode: '0755'
+ owner: www-data
+ group: www-data
+
+- name: deploy nginx.conf from template
+ template:
+ src: nginx/nginx.conf.j2
+ dest: /etc/nginx/nginx.conf
+ owner: root
+ group: root
+ mode: '0644'
+
+- name: restart nginx
+ systemd:
+ name: nginx
+ state: restarted
+ enabled: true
+ when: ansible_service_mgr == 'systemd'
diff --git a/tasks/preflight.yaml b/tasks/preflight.yaml
new file mode 100644
index 0000000..3358d46
--- /dev/null
+++ b/tasks/preflight.yaml
@@ -0,0 +1,16 @@
+- name: ensure script is run as root
+ assert:
+ that:
+ - ansible_effective_user_id == 0
+ fail_msg: "this playbook must be run as root"
+
+- name: check if system is debian-based
+ command: dpkg -l
+ register: dpkg_check
+ changed_when: false
+ failed_when: false
+
+- name: fail if not debian-based
+ fail:
+ msg: "distribution not Debian-based"
+ when: dpkg_check.rc != 0