From bc4c5deec4bf2e0b60a0bbb5906af1211a210e46 Mon Sep 17 00:00:00 2001
From: Ben Sturmfels <ben@sturm.com.au>
Date: Fri, 15 Sep 2023 21:49:19 +1000
Subject: [PATCH] Extend Ansible config

---
 deploy/ansible/20auto-upgrades     |   4 -
 deploy/{ansible => }/install.yml   | 115 +++++++++++++++++++++--------
 deploy/{ansible => }/inventory.ini |   0
 deploy/postfix/main.cf             |  52 +++++++++++++
 4 files changed, 138 insertions(+), 33 deletions(-)
 delete mode 100644 deploy/ansible/20auto-upgrades
 rename deploy/{ansible => }/install.yml (66%)
 rename deploy/{ansible => }/inventory.ini (100%)
 create mode 100644 deploy/postfix/main.cf

diff --git a/deploy/ansible/20auto-upgrades b/deploy/ansible/20auto-upgrades
deleted file mode 100644
index f29c25ff..00000000
--- a/deploy/ansible/20auto-upgrades
+++ /dev/null
@@ -1,4 +0,0 @@
-APT::Periodic::Update-Package-Lists "1";
-APT::Periodic::Unattended-Upgrade "1";
-Unattended-Upgrade::Automatic-Reboot "true";
-Unattended-Upgrade::Automatic-Reboot-Time "02:00";
diff --git a/deploy/ansible/install.yml b/deploy/install.yml
similarity index 66%
rename from deploy/ansible/install.yml
rename to deploy/install.yml
index 195a50bb..5f97bb39 100644
--- a/deploy/ansible/install.yml
+++ b/deploy/install.yml
@@ -1,12 +1,10 @@
----
-# Run this with:
-#  ansible-playbook -i deploy/ansible/inventory.ini --become --ask-become-pass deploy/ansible/install.yml
-
-# Other useful commands:
-# ansible all -i [HOST], -u user -m ping
-# ansible all -i [HOST], -u user -a /bin/date
-# scp -3 -v [OLDHOST]:backup/backup.gz [HOST]:tmp/
+# Ansible playbook for basic web server configuration.
+#
+# Run with:
+# ANSIBLE_STDOUT_CALLBACK=debug ansible-playbook deploy/install.yml -i deploy/inventory.ini --verbose
 
+# Notes:
+#
 # /etc/apache2 uses OS defaults aside from "site-available", "sites-enabled" and
 # "conservancy.conf".
 #
@@ -16,37 +14,84 @@
 # SQLite database lives at /var/lib/www/database.
 #
 # Disabled Rackspace CDN videos.
-#
-# No mail as yet.
-#
-# No etckeeper as yet.
-#
-# a2enmod ssl rewrite
 
  - name: Configure web server
    hosts: web
-   # remote_user:
-   # become_user:
-   # become_method:
-
+   become: true
+   vars:
+     ansible_ssh_pipelining: true
    tasks:
      - name: Install unattended upgrades
        apt:
          name: unattended-upgrades
 
-     - name: Configure unattended upgrades
+     - name: Configure unattended upgrades overrides
+       # See defaults in 50unattended-upgrades.
        copy:
-         src: 20auto-upgrades
          dest: /etc/apt/apt.conf.d/20auto-upgrades
+         content: |
+           APT::Periodic::Update-Package-Lists "1";
+           APT::Periodic::Unattended-Upgrade "1";
+           Unattended-Upgrade::Automatic-Reboot "true";
+           Unattended-Upgrade::Automatic-Reboot-Time "02:00";
+           Unattended-Upgrade::Mail "root";
+
+     - name: Add extensive history logging
+       blockinfile:
+         path: /etc/bash.bashrc
+         block: |
+           # Write to history file immediately (rather than only when shell is
+           # closed). For setting history length see HISTSIZE and HISTFILESIZE in
+           # bash(1).
+           shopt -s histappend
+           PROMPT_COMMAND='history -a'
+           HISTSIZE=1000000
+           HISTFILESIZE=1000000
+         insertafter: EOF
 
      - name: Install Apache
        apt:
          name: apache2,libapache2-mod-wsgi-py3
 
+     - apache2_module:
+         state: present
+         name: ssl
+
+     - apache2_module:
+         state: present
+         name: rewrite
+
      - name: Install Postfix
        apt:
-         # libsasl2-modules fixes "SASL authentication failure: No worthy mechs found"
-         name: postfix,libsasl2-modules,mailutils
+         pkg:
+           - postfix
+           # libsasl2-modules fixes "SASL authentication failure: No worthy mechs found"
+           - libsasl2-modules
+           - mailutils
+
+     # # Commented because you only want this on first run ever.
+     # - name: Add file for SMTP credentials
+     #   copy:
+     #     dest: /etc/postfix/sasl_passwd
+     #     content: |-
+     #       # After updating, run `sudo postmap hash:/etc/postfix/sasl_passwd`.
+     #       [mail.sfconservancy.org]:587 conference@sfconservancy.org:PASSWORD
+           
+     - name: Configure Postfix for relaying
+       copy:
+         src: postfix/main.cf
+         dest: /etc/postfix/main.cf
+       notify:
+         - restart postfix
+
+     - name: Alias mail to root
+       copy:
+         dest: /etc/aliases
+         content: |-
+           postmaster: root
+           root: sysadmin@sfconservancy.org, sysadmin@sturm.com.au
+       notify:
+         - restart postfix
 
      - name: Install Certbot
        apt:
@@ -71,8 +116,8 @@
      - name: Disable SSH password authentication
        lineinfile:
          path: /etc/ssh/sshd_config
-         regexp: '^#?PasswordAuthentication '
          line: 'PasswordAuthentication no'
+         regexp: 'PasswordAuthentication '
        notify:
          - restart sshd
 
@@ -88,6 +133,13 @@
          group: www-data
          mode: '0755'
 
+     - name: Git checkout
+       ansible.builtin.git:
+         repo: 'https://k.sfconservancy.org/website'
+         dest: /var/www/website
+         version: master
+         remote: upstream
+
      - name: Create the database directory
        file:
          path: /var/lib/www/database
@@ -96,12 +148,6 @@
          group: www-data
          mode: '0755'
 
-     - name: Git checkout
-       ansible.builtin.git:
-         repo: 'https://k.sfconservancy.org/website'
-         dest: /var/www/website
-         version: master
-
      - name: Create static dir
        file:
          path: /var/www/website/conservancy/static
@@ -110,6 +156,12 @@
          group: www-data
          mode: '0755'
 
+     - name: Install `netfilter-persistent` && `iptables-persistent` packages
+       apt:
+         pkg:
+           - iptables-persistent
+           - netfilter-persistent
+
      - name: Install iptables  # May need kernel reload/reboot
        apt:
          name: iptables,iptables-netflow-dkms
@@ -225,3 +277,8 @@
        service:
          name: ssh
          state: reloaded
+
+     - name: restart postfix
+       service:
+         name: postfix
+         state: reloaded
diff --git a/deploy/ansible/inventory.ini b/deploy/inventory.ini
similarity index 100%
rename from deploy/ansible/inventory.ini
rename to deploy/inventory.ini
diff --git a/deploy/postfix/main.cf b/deploy/postfix/main.cf
new file mode 100644
index 00000000..b07529e7
--- /dev/null
+++ b/deploy/postfix/main.cf
@@ -0,0 +1,52 @@
+# See /usr/share/postfix/main.cf.dist for a commented, more complete version
+
+
+# Debian specific:  Specifying a file name will cause the first
+# line of that file to be used as the name.  The Debian default
+# is /etc/mailname.
+#myorigin = /etc/mailname
+
+smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU)
+biff = no
+
+# appending .domain is the MUA's job.
+append_dot_mydomain = no
+
+# Uncomment the next line to generate "delayed mail" warnings
+#delay_warning_time = 4h
+
+readme_directory = no
+
+# See http://www.postfix.org/COMPATIBILITY_README.html -- default to 3.6 on
+# fresh installs.
+compatibility_level = 3.6
+
+
+
+# TLS parameters
+smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
+smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
+smtpd_tls_security_level=may
+
+smtp_tls_CApath=/etc/ssl/certs
+smtp_tls_security_level=secure
+smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
+
+
+smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
+myhostname = hickory.sfconservancy.org
+alias_maps = hash:/etc/aliases
+alias_database = hash:/etc/aliases
+myorigin = /etc/mailname
+mydestination = $myhostname, hickory, localhost
+relayhost = [mail.sfconservancy.org]:587
+mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
+mailbox_size_limit = 0
+recipient_delimiter = +
+inet_interfaces = loopback-only
+inet_protocols = all
+
+# Relay authentication
+smtp_sasl_auth_enable = yes
+smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
+smtp_sasl_security_options = noanonymous
\ No newline at end of file