From 71e46ef6a1be8599a03b3fee2f9c1c0e5b188c41 Mon Sep 17 00:00:00 2001
From: Adar Nimrod <nimrod@shore.co.il>
Date: Sun, 13 Dec 2020 00:32:58 +0200
Subject: [PATCH] Debian server role.

Also, some adaptations for Ansible 2.10.
---
 .pre-commit-config.yaml                |  14 +++-
 ansible.cfg                            |   2 +-
 debian_server.yaml                     |   8 ++
 roles/debian_server/files/btrfs-backup |  45 ++++++++++
 roles/debian_server/tasks/main.yml     | 109 +++++++++++++++++++++++++
 5 files changed, 176 insertions(+), 2 deletions(-)
 create mode 100644 debian_server.yaml
 create mode 100755 roles/debian_server/files/btrfs-backup
 create mode 100644 roles/debian_server/tasks/main.yml

diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 8a7187c..08178ea 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -10,27 +10,39 @@ repos:
       - id: check-yaml
       - id: detect-private-key
       - id: trailing-whitespace
+
   - repo: https://git.shore.co.il/ansible/ansible-pre-commit.git
     rev: v0.10.0
     hooks:
       - id: ansible-syntax-check
-        files: bootstrap\.yaml|update\.yaml|renew-certs\.yaml
+        # yamllint disable-line rule:line-length
+        files: bootstrap\.yaml|update\.yaml|renew-certs\.yaml|debian_server\.yaml
         types: [yaml]
+
   - repo: https://github.com/ansible/ansible-lint
     rev: v4.3.7
     hooks:
       - id: ansible-lint
+
   - repo: https://github.com/adrienverge/yamllint
     rev: v1.25.0
     hooks:
       - id: yamllint
+
   - repo: https://github.com/amperser/proselint/
     rev: 0.10.2
     hooks:
       - id: proselint
         types: [markdown]
+
   - repo: https://github.com/Yelp/detect-secrets
     rev: v0.14.3
     hooks:
       - id: detect-secrets
         exclude: Pipfile\.lock
+
+  - repo: https://git.shore.co.il/nimrod/shell-pre-commit.git
+    sha: v0.6.0
+    hooks:
+      - id: shell-lint
+      - id: shellcheck
diff --git a/ansible.cfg b/ansible.cfg
index 778a07e..d8ca0fd 100644
--- a/ansible.cfg
+++ b/ansible.cfg
@@ -1,5 +1,5 @@
 [defaults]
-callback_whitelist = profile_tasks, timer
+callback_whitelist = ansible.posix.profile_tasks, ansible.posix.timer
 command_warnings = True
 deprecation_warnings = True
 fact_caching = jsonfile
diff --git a/debian_server.yaml b/debian_server.yaml
new file mode 100644
index 0000000..1f001ea
--- /dev/null
+++ b/debian_server.yaml
@@ -0,0 +1,8 @@
+---
+- hosts:
+    - ns4
+    - host01
+  roles:
+    - debian_server
+  become: true
+  become_user: root
diff --git a/roles/debian_server/files/btrfs-backup b/roles/debian_server/files/btrfs-backup
new file mode 100755
index 0000000..cb65985
--- /dev/null
+++ b/roles/debian_server/files/btrfs-backup
@@ -0,0 +1,45 @@
+#!/bin/sh
+set -eu
+
+list_subvolumes() {
+    btrfs subvolume list --sort=path "$1" | awk '{print $9}' | uniq
+}
+
+cleanup() {
+    for volume in $(list_subvolumes "$source/.snapshot")
+    do
+        if [ -d "$source/.snapshot/$volume" ]
+        then
+            btrfs subvolume delete "$source/.snapshot/$volume"
+        fi
+    done
+    btrfs subvolume delete "$source/.snapshot"
+    sync --file-system "$source"
+}
+
+if [ "$#" -ne 2 ]
+then
+    echo "Usage: $0 source destination" >&2
+    exit 1
+fi
+
+source="$1"
+destination="$2"
+
+# Before the first snapshot is made.
+subvolumes="$(list_subvolumes "$source")"
+trap 'cleanup' INT QUIT EXIT TERM
+
+# It would be better to take all snapshots atomically, but that's not possible.
+btrfs subvolume snapshot "$source" "$source/.snapshot"
+for volume in $subvolumes
+do
+    rm --dir "$source/.snapshot/$volume"
+    btrfs subvolume snapshot "$source/$volume" "$source/.snapshot/$volume"
+done
+sync --file-system "$source"
+
+rsync --archive \
+      --delete \
+      "$source/.snapshot/" \
+      "$destination"
diff --git a/roles/debian_server/tasks/main.yml b/roles/debian_server/tasks/main.yml
new file mode 100644
index 0000000..d122ecc
--- /dev/null
+++ b/roles/debian_server/tasks/main.yml
@@ -0,0 +1,109 @@
+---
+- name: Verify assertions
+  assert:
+    that:
+      - ansible_distribution == "Debian"
+      - ansible_distribution_major_version|int >= 10
+
+- name: Enable the backports repo
+  loop:
+    - deb
+    - deb-src
+  apt_repository:
+    # yamllint disable-line rule:line-length
+    repo: '{{ item }} http://deb.debian.org/debian {{ ansible_distribution_release }}-backports main contrib non-free'
+    state: present
+    update_cache: true
+
+- name: Install packages
+  apt:
+    cache_valid_time: 3600
+    name:
+      - btrfs-progs
+      - cryptsetup
+      - docker.io
+      - fwupd
+      - fwupdate-signed
+      - intel-microcode
+      - libpam-mount-bin
+      - rsync
+      - tmux
+      - ufw
+    state: present
+
+- name: Rate limit SSH
+  community.general.ufw:
+    rule: limit
+    port: ssh
+    proto: tcp
+
+- name: Enable UFW
+  community.general.ufw:
+    default: reject
+    state: enabled
+
+- name: Allow unprivileged user namespaces
+  ansible.posix.sysctl:
+    name: kernel/unprivileged_userns_clone
+    state: present
+    value: "1"
+
+- name: Allow more inotify watches
+  ansible.posix.sysctl:
+    name: fs.inotify.max_user_watches
+    state: present
+    value: "640000"
+
+- name: Secure SSH
+  with_dict:
+    PermitRootLogin: !!str no
+    PasswordAuthentication: !!str no
+  lineinfile:
+    backup: true
+    line: |-
+      {{ item.key }} {{ item.value }}
+    path: /etc/ssh/sshd_config
+    regexp: |-
+      {{ item.key }}
+    state: present
+    validate: sshd -Tf %s
+
+- name: Make /tmp a tmpfs mount
+  ansible.posix.mount:
+    fstype: tmpfs
+    name: /tmp
+    src: none
+    opts: "defaults,nosuid,nodev"
+    state: present
+
+- name: Disable swap
+  meta: noop
+
+- name: Set UID/GID mapping range
+  loop:
+    - /etc/subgid
+    - /etc/subuid
+  copy:
+    content: |
+      nimrod:100000:65536
+    dest: |-
+      {{ item }}
+    group: root
+    mode: 0o0644
+    owner: root
+
+- name: Create an SSL directory under /var
+  file:
+    group: root
+    mode: 0o0755
+    owner: root
+    path: /var/ssl
+    state: directory
+
+- name: Copy btrfs copy script
+  copy:
+    dest: /usr/local/sbin/btrfs-backup
+    group: root
+    mode: preserve
+    owner: root
+    src: btrfs-backup
-- 
GitLab