imfreedom/email-ansible

Add basic system configuration
draft
2020-05-15, Richard Laager
e3de5f00bc98
Parents a54cdf109597
Children aac15f33ef6a
Add basic system configuration
--- a/ansible.cfg Fri May 15 14:55:44 2020 -0500
+++ b/ansible.cfg Fri May 15 16:09:19 2020 -0500
@@ -33,7 +33,7 @@
# smart - gather by default, but don't regather if already gathered
# implicit - gather by default, turn off with gather_facts: False
# explicit - do not gather by default, must say gather_facts: True
-#gathering = implicit
+gathering = smart
# This only affects the gathering done by a play's gather_facts directive,
# by default gathering retrieves all facts subsets
@@ -240,13 +240,13 @@
# wanting to use, for example, IP information from one group of servers
# without having to talk to them in the same playbook run to get their
# current IP information.
-#fact_caching = memory
+fact_caching = jsonfile
#This option tells Ansible where to cache facts. The value is plugin dependent.
#For the jsonfile plugin, it should be a path to a local directory.
#For the redis plugin, the value is a host:port:database triplet: fact_caching_connection = localhost:6379:0
-#fact_caching_connection=/tmp
+fact_caching_connection=/tmp
@@ -338,9 +338,9 @@
#unparsed_is_failed=False
[privilege_escalation]
-#become=True
+become=True
#become_method=sudo
-#become_user=root
+become_user=root
#become_ask_pass=False
[paramiko_connection]
--- a/inventories/pidgin/vault.yaml Fri May 15 14:55:44 2020 -0500
+++ b/inventories/pidgin/vault.yaml Fri May 15 16:09:19 2020 -0500
@@ -1,14 +1,29 @@
$ANSIBLE_VAULT;1.1;AES256
-63336432616637393630373235326464323661393138333230346136323433356261343732313836
-3336613534343332613731383837623762646231316362650a356537653635633562386232613965
-36316465666230323939623238323561613730666538653836343365633632376666333039623433
-3235323566396262310a333763616633363835393663343536366431633462363136313035656661
-62616439303133396236613766363831643034323337323831383062386464363836663366396462
-66356464316438383930353237323238666232616639613938363438336237353632313334656434
-34303138323936666563613430653931303737393036386137303130623937356664306439383334
-31613231346264343431303231636235646137643161336435336562373835343837663637383061
-61623136613062376137616435666636356431336635356239623733333661353434663735663230
-61333130386332643132623565353132663438663539663763666465373063313866356637383261
-32303766346437383232383263616261343662393261313637363631373732626638356635346135
-33616339366138366537663737303465373132306334366331386134353462353564666632613664
-3565
+35663038626561353262303230373339383932343139666161376432623937306361626136663937
+3530333631633938393061626639366466363332376362620a343833316335653164313938663363
+64633164633930613763613832636438643839616465383432343131306238313439353432633738
+3934366462336437380a633030366137366636653335303236373538653961326534643465623637
+31616266366563333431346563356237333033636230383530396161363465656563656465343038
+39626461616633646334336632363736663333663362613131633065333437376165303861356230
+63613139336366386138643830333064623933346462666263393834383433356534316131366631
+65386466633137396437323630376337383065326164643730653735326562653261343162633232
+31383932616135643138623437303464633161343566393465653033346165623233373336373462
+33353130326334643530313339636263376336393433316334306536373962643764313231663438
+35613830376466633535333935366535326138363461393264386161303962653335323338626165
+63663265326535633133613930316261623462383035363666393833313437656263643361646437
+61396338626666313663393831376336333034313865353832653137363362663131323435393935
+34343161646339656238623336363233316564396461323330373736343231383033303736373135
+63613836333033353064373932666439333533343738623431313161636230386539373866346235
+61356134646534666464313234633561316161643930386166353364303463396666376632626339
+31646665623066333230616239363830653733313365626330613432343638653032393834373635
+64333230356131386366653164313262616530656234636263616162323538373635303035386638
+32323130303863326662636538383239633735623233323062626530313862633363363563643765
+62393830663032313938373862333063373063316438343733343838623539643664323932653933
+39393430363263313966313231346231623964613237356164636362653735386337326634373263
+31396637356132363766353836373635313063623766373066633735643735363038363738643461
+31616132623635656432643630323137623064663234313730613365376461336435646361306330
+38626138363232366335323234353533656530366331613435313536653231326234366430653664
+35323562373232623230303935366362643432613761613038323631313236313264313736343265
+30323561333863623839653231306166626133306438663333353662376633646135393737396338
+66303565333439386565643538363637323831303862616236623162353862363030363239343339
+63666666643662643735
--- a/mail_servers.yaml Fri May 15 14:55:44 2020 -0500
+++ b/mail_servers.yaml Fri May 15 16:09:19 2020 -0500
@@ -1,6 +1,3 @@
- hosts: mail_servers
- become: yes
- become_user: root
- gather_facts: smart
roles:
- mail
--- a/roles/common/meta/main.yaml Fri May 15 14:55:44 2020 -0500
+++ b/roles/common/meta/main.yaml Fri May 15 16:09:19 2020 -0500
@@ -1,1 +1,7 @@
-dependencies: []
+dependencies:
+ # These need to be first and in this order:
+ - sources
+ - update
+
+ - firewall
+ - ntp
--- a/roles/common/tasks/common.yaml Fri May 15 14:55:44 2020 -0500
+++ b/roles/common/tasks/common.yaml Fri May 15 16:09:19 2020 -0500
@@ -12,3 +12,13 @@
password: "{{ common_root_password_hash }}"
tags:
- user
+
+- name: set root's .ssh/authorized_keys
+ authorized_key:
+ user: root
+ path: "/root/.ssh/authorized_keys"
+ key: "{{ common_root_ssh_keys }}"
+ exclusive: yes
+ tags:
+ - ssh
+ - ssh_key
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/roles/firewall/files/60-firewall.conf Fri May 15 16:09:19 2020 -0500
@@ -0,0 +1,3 @@
+# This should "(among other things) help catch ACK-floods":
+# http://rhelblog.redhat.com/2014/04/11/mitigate-tcp-syn-flood-attacks-with-red-hat-enterprise-linux-7-beta/
+net.netfilter.nf_conntrack_tcp_loose=0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/roles/firewall/handlers/main.yaml Fri May 15 16:09:19 2020 -0500
@@ -0,0 +1,2 @@
+- name: reload ufw
+ command: ufw reload
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/roles/firewall/tasks/main.yaml Fri May 15 16:09:19 2020 -0500
@@ -0,0 +1,18 @@
+# We intentionally do not have a handler to apply this. We let it apply on
+# reboot to avoid breaking any untracked connections in progress.
+- name: disable loose connection tracking
+ copy:
+ src: 60-firewall.conf
+ dest: /etc/sysctl.d/
+ tags:
+ - firewall
+ - sysctl
+
+- include_tasks: ufw.yaml
+ args:
+ apply:
+ tags:
+ - firewall
+ - ufw
+ tags:
+ - always
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/roles/firewall/tasks/ufw.yaml Fri May 15 16:09:19 2020 -0500
@@ -0,0 +1,80 @@
+- name: install ufw
+ apt:
+ name: ufw
+ state: present
+ force_apt_get: yes
+ tags:
+ - apt
+
+- name: disable ufw logging
+ ufw:
+ # This takes a string, not a boolean, so "off" must be quoted.
+ logging: "off"
+ # This will fail if ufw is not installed.
+ ignore_errors: "{{ ansible_check_mode }}"
+
+- name: enable ufw with a default deny policy
+ ufw:
+ state: enabled
+ direction: incoming
+ policy: deny
+ # This will fail if ufw is not installed.
+ ignore_errors: "{{ ansible_check_mode }}"
+
+- name: exempt certain networks from the SSH rate-limit
+ ufw:
+ rule: allow
+ name: OpenSSH
+ src: "{{ item }}"
+ loop: "{{ firewall_ssh_exempt_networks }}"
+ when: firewall_ssh_exempt_networks | length > 0
+ # This will fail if ufw is not installed.
+ ignore_errors: "{{ ansible_check_mode }}"
+ tags:
+ - ssh
+
+- name: allow and rate-limit SSH
+ ufw:
+ rule: limit
+ name: OpenSSH
+ # This will fail if ufw is not installed.
+ ignore_errors: "{{ ansible_check_mode }}"
+ tags:
+ - ssh
+
+# The default behavior of a TCP stack (e.g. with ufw disabled) is to reply to
+# invalid TCP packets with a reset (RST). Since ufw uses connection tracking
+# and drops (-j DROP) packets with a "ctstate" of "INVALID", this does not
+# happen. Invalid TCP packets are simply dropped. This is problematic if the
+# TCP packet corresponds to a previous connection and the server has rebooted
+# (or a VIP has migrated to a different server). The remote client has to
+# timeout, which can take a long time.
+#
+# This change adds an additional iptables rule to reject these with TCP resets
+# (-j REJECT --reject-with tcp-reset). Note that this is subtly different
+# from letting the TCP stack reply with an RST. This happens earlier in
+# packet processing. I'm not sure if that actually matters, but if it does,
+# it will be helpful rather than hurtful.
+#
+# This does make a system a bit less "steathly", as you can use invalid TCP
+# packets to elicit a response. That is not a concern on servers, since they
+# respond on well-known ports anyway.
+#
+# This should not create any opportunity for an amplification attack.
+- name: send TCP resets for invalid connections
+ lineinfile:
+ path: "/etc/ufw/before{{ item }}.rules"
+ insertbefore: >-
+ ^-A ufw{{ item }}-before-input -m conntrack --ctstate INVALID -j DROP
+ line: >-
+ -A ufw{{ item }}-before-input -m conntrack --ctstate INVALID -p tcp
+ -j REJECT --reject-with tcp-reset
+ notify:
+ - reload ufw
+ loop:
+ - ""
+ - "6"
+ loop_control:
+ label: "ip{{ item }}"
+ # This will fail if ufw is not installed because the files will not exist.
+ ignore_errors: "{{ ansible_check_mode }}"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/roles/ntp/files/restart.conf Fri May 15 16:09:19 2020 -0500
@@ -0,0 +1,2 @@
+[Service]
+Restart=on-failure
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/roles/ntp/handlers/main.yaml Fri May 15 16:09:19 2020 -0500
@@ -0,0 +1,9 @@
+- name: restart apparmor
+ systemd:
+ name: apparmor
+ state: restarted
+
+- name: restart ntpd
+ systemd:
+ name: ntpsec
+ state: restarted
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/roles/ntp/meta/main.yaml Fri May 15 16:09:19 2020 -0500
@@ -0,0 +1,2 @@
+dependencies:
+ - systemd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/roles/ntp/tasks/main.yaml Fri May 15 16:09:19 2020 -0500
@@ -0,0 +1,16 @@
+- include_tasks: software.yaml
+ args:
+ apply:
+ tags:
+ - apt
+ - ntp
+ tags:
+ - always
+
+- include_tasks: ntp.yaml
+ args:
+ apply:
+ tags:
+ - ntp
+ tags:
+ - always
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/roles/ntp/tasks/ntp.yaml Fri May 15 16:09:19 2020 -0500
@@ -0,0 +1,43 @@
+# This removes -g and adds -N.
+#
+# -N means to run ntpd at the highest priority. The idea is that this can
+# improve accuracy.
+#
+# It is not necessary to use -g (which allows the initial offset to be more
+# than 1000 seconds, which is 16 minutes and 40 seconds). For VMs, the clock
+# will be very close from the host, which uses NTP. For physical machines,
+# the real-time clock should be close to correct, and initially, the clock is
+# set in the installer. Skipping -g is more secure, especially since we
+# configure ntpd to restart on failure.
+
+- name: adjust ntpd command-line options
+ lineinfile:
+ path: "/etc/default/ntpsec"
+ regexp: ^NTPD_OPTS=.*
+ line: 'NTPD_OPTS="-N"'
+ notify:
+ - restart ntpd
+ # This will fail if ntp is not installed, as the file will not exist.
+ ignore_errors: "{{ ansible_check_mode }}"
+
+- name: create ntp.conf
+ template:
+ src: ntp.conf.j2
+ dest: "/etc/ntpsec/ntp.conf"
+ mode: 0644
+ notify:
+ - restart ntpd
+ tags:
+ - ntp_conf
+
+- name: configure ntpd to restart on failure
+ copy:
+ src: restart.conf
+ dest: "/etc/systemd/system/ntpsec.service.d/"
+ mode: 0644
+ notify:
+ - reload systemd
+ - restart ntpd
+ tags:
+ - systemd
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/roles/ntp/tasks/software.yaml Fri May 15 16:09:19 2020 -0500
@@ -0,0 +1,25 @@
+- name: install software
+ apt:
+ name: "{{ ntp_packages }}"
+ state: present
+ force_apt_get: yes
+ vars:
+ ntp_packages:
+ - apparmor
+ - ntpsec
+ - tzdata
+ tags:
+ - apt
+
+# Installing ntpsec removes ntp, but it does not purge it. If ntp has been
+# removed but not purged, then its /etc/init.d/ntp will still exist, which
+# means two things will try to start ntpd on boot.
+- name: purge ntp
+ apt:
+ name: ntp
+ state: absent
+ autoremove: yes
+ purge: yes
+ force_apt_get: yes
+ tags:
+ - apt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/roles/ntp/templates/ntp.conf.j2 Fri May 15 16:09:19 2020 -0500
@@ -0,0 +1,56 @@
+# /etc/ntpsec/ntp.conf, configuration for ntpd; see ntp.conf(5) for help
+
+driftfile /var/lib/ntpsec/ntp.drift
+leapfile /usr/share/zoneinfo/leap-seconds.list
+
+# To enable Network Time Security support as a server, obtain a certificate
+# (e.g. with Let's Encrypt), configure the paths below, and uncomment:
+# nts cert CERT_FILE
+# nts key KEY_FILE
+# nts enable mintls TLS1.3
+
+# You must create /var/log/ntpsec (owned by ntpsec:ntpsec) to enable logging.
+#statsdir /var/log/ntpsec/
+#statistics loopstats peerstats clockstats
+#filegen loopstats file loopstats type day enable
+#filegen peerstats file peerstats type day enable
+#filegen clockstats file clockstats type day enable
+
+# This should be maxclock 7, but the pool entries count towards maxclock.
+tos maxclock 11
+
+# Comment this out if you have a refclock and want it to be able to discipline
+# the clock by itself (e.g. if the system is not connected to the network).
+tos minclock 4 minsane 3
+
+# Specify one or more NTP servers.
+
+# Public NTP servers supporting Network Time Security:
+# server time.cloudflare.com:1234 nts
+
+server time.cloudflare.com:1234 nts iburst
+server clock.nyc.he.net iburst
+server c.time.steadfast.net iburst
+server ntp1.wiktel.com nts iburst
+
+# pool.ntp.org maps to about 1000 low-stratum NTP servers. Your server will
+# pick a different set every time it starts up. Please consider joining the
+# pool: <https://www.pool.ntp.org/join.html>
+pool 0.debian.pool.ntp.org iburst
+pool 1.debian.pool.ntp.org iburst
+pool 2.debian.pool.ntp.org iburst
+pool 3.debian.pool.ntp.org iburst
+
+# Access control configuration; see /usr/share/doc/ntpsec-doc/html/accopt.html
+# for details.
+#
+# Note that "restrict" applies to both servers and clients, so a configuration
+# that might be intended to block requests from certain clients could also end
+# up blocking replies from your own upstream servers.
+
+# By default, exchange time with everybody, but don't allow configuration.
+restrict default kod nomodify nopeer noquery limited
+
+# Local users may interrogate the ntp server more closely.
+restrict 127.0.0.1
+restrict ::1
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/roles/sources/handlers/main.yaml Fri May 15 16:09:19 2020 -0500
@@ -0,0 +1,4 @@
+- name: update apt cache
+ apt:
+ update_cache: yes
+ force_apt_get: yes
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/roles/sources/meta/main.yaml Fri May 15 16:09:19 2020 -0500
@@ -0,0 +1,1 @@
+dependencies: []
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/roles/sources/tasks/debian.yaml Fri May 15 16:09:19 2020 -0500
@@ -0,0 +1,19 @@
+- name: install debian-backports preferences
+ template:
+ src: debian-backports.preferences.j2
+ dest: /etc/apt/preferences.d/debian-backports
+ notify:
+ - update apt cache
+
+- name: install sources
+ template:
+ src: "{{ item }}.list.j2"
+ dest: "/etc/apt/sources.list.d/{{ item }}.list"
+ mode: 0644
+ loop:
+ - debian
+ - debian-backports
+ - debian-security
+ - debian-updates
+ notify:
+ - update apt cache
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/roles/sources/tasks/main.yaml Fri May 15 16:09:19 2020 -0500
@@ -0,0 +1,22 @@
+- include_tasks: debian.yaml
+ args:
+ apply:
+ tags:
+ - apt
+ - sources
+ tags:
+ - always
+
+- name: replace /etc/apt/sources.list with empty file
+ copy:
+ content: ""
+ dest: /etc/apt/sources.list
+ mode: 0644
+ tags:
+ - apt
+ - sources
+
+# Force handlers to fire now. If changes were made in this role, we need the
+# handlers to run now so that subsequent roles can install packages from the
+# sources configured here.
+- meta: flush_handlers
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/roles/sources/templates/debian-backports.list.j2 Fri May 15 16:09:19 2020 -0500
@@ -0,0 +1,2 @@
+deb http://mirrors.digitalocean.com/debian {{ ansible_facts["distribution_release"] }}-backports main contrib non-free
+deb-src http://mirrors.digitalocean.com/debian {{ ansible_facts["distribution_release"] }}-backports main contrib non-free
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/roles/sources/templates/debian-backports.preferences.j2 Fri May 15 16:09:19 2020 -0500
@@ -0,0 +1,11 @@
+# The backports sources default to a priority of 100. To install a particular
+# backported package, set its priority to 500:
+# Package: PACKAGE_NAME
+# Pin: release a={{ ansible_facts["distribution_release"] }}-backports
+# Pin-Priority: 500
+
+{% if ansible_facts["distribution_major_version"] == "10" %}
+Package: ntpsec ntpsec-ntpdate ntpsec-ntpviz ntpsec-doc python3-ntp
+Pin: release a={{ ansible_facts["distribution_release"] }}-backports
+Pin-Priority: 500
+{% endif %}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/roles/sources/templates/debian-security.list.j2 Fri May 15 16:09:19 2020 -0500
@@ -0,0 +1,11 @@
+{% if ansible_facts["distribution_major_version"]|int <= 10 %}
+deb http://mirror.steadfast.net/debian-security {{ ansible_facts["distribution_release"] }}/updates main contrib non-free
+deb-src http://mirror.steadfast.net/debian-security {{ ansible_facts["distribution_release"] }}/updates main contrib non-free
+deb http://security.debian.org/debian-security {{ ansible_facts["distribution_release"] }}/updates main contrib non-free
+deb-src http://security.debian.org/debian-security {{ ansible_facts["distribution_release"] }}/updates main contrib non-free
+{% else %}
+deb http://mirror.steadfast.net/debian {{ ansible_facts["distribution_release"] }}-security main contrib non-free
+deb-src http://mirror.steadfast.net/debian {{ ansible_facts["distribution_release"] }}-security main contrib non-free
+deb http://security.debian.org/debian-security {{ ansible_facts["distribution_release"] }}-security main contrib non-free
+deb-src http://security.debian.org/debian-security {{ ansible_facts["distribution_release"] }}-security main contrib non-free
+{% endif %}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/roles/sources/templates/debian-updates.list.j2 Fri May 15 16:09:19 2020 -0500
@@ -0,0 +1,2 @@
+deb http://ftp.us.debian.org/debian {{ ansible_facts["distribution_release"] }}-updates main contrib non-free
+deb-src http://ftp.us.debian.org/debian {{ ansible_facts["distribution_release"] }}-updates main contrib non-free
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/roles/sources/templates/debian.list.j2 Fri May 15 16:09:19 2020 -0500
@@ -0,0 +1,2 @@
+deb http://mirrors.digitalocean.com/debian {{ ansible_facts["distribution_release"] }} main contrib non-free
+deb-src http://mirrors.digitalocean.com/debian {{ ansible_facts["distribution_release"] }} main contrib non-free
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/roles/systemd/handlers/main.yaml Fri May 15 16:09:19 2020 -0500
@@ -0,0 +1,3 @@
+- name: reload systemd
+ systemd:
+ daemon_reload: yes
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/roles/systemd/meta/main.yaml Fri May 15 16:09:19 2020 -0500
@@ -0,0 +1,1 @@
+dependencies: []
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/roles/update/defaults/main.yaml Fri May 15 16:09:19 2020 -0500
@@ -0,0 +1,1 @@
+update: false
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/roles/update/meta/main.yaml Fri May 15 16:09:19 2020 -0500
@@ -0,0 +1,1 @@
+dependencies: []
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/roles/update/tasks/main.yaml Fri May 15 16:09:19 2020 -0500
@@ -0,0 +1,17 @@
+- name: enable package updates
+ set_fact:
+ update: yes
+ when: not update|bool
+ tags:
+ - never
+ - update
+
+- name: update packages
+ apt:
+ upgrade: dist
+ autoremove: yes
+ update_cache: yes
+ force_apt_get: yes
+ when: update|bool
+ tags:
+ - update