Compare commits

...

203 Commits

Author SHA1 Message Date
Alan Orth 41fbc73dd1
host_vars/web22: WordPress 6.4.3 2024-03-20 20:28:13 +03:00
Alan Orth fee794bcf0
Update Pipfile 2024-03-20 20:28:00 +03:00
Alan Orth 8bce1d8b1b
host_vars/web22: WordPress 6.4.1 2023-12-02 22:40:06 +03:00
Alan Orth 6dc2ea36b6
roles/nginx: fix path to php 8.2 socket 2023-09-11 19:55:24 +03:00
Alan Orth af71a9b5f8
roles/php-fpm: remove fmt strings
Ansible confuses them for jinja2 tokens.
2023-09-11 19:52:18 +03:00
Alan Orth 4dd57803e2
roles/php-fpm: fix user/group for php 8.2 configs 2023-09-11 19:51:59 +03:00
Alan Orth 18d4245fc0
roles/common: fix tarsnap signing of apt repo 2023-09-11 19:37:49 +03:00
Alan Orth 1bddf3cccd
Pipfile.lock: run pipenv update 2023-09-11 18:52:25 +03:00
Alan Orth 20dbe61fe1
roles/mariadb: use MariaDB 10.11
The server has already been updated from 10.6 to 10.11.

See: https://mariadb.com/kb/en/upgrading-from-mariadb-10-6-to-mariadb-10-11/
2023-09-10 22:53:10 +03:00
Alan Orth 899e87321b
host_vars/web22: WordPress 6.3.1 2023-09-10 22:44:23 +03:00
Alan Orth 06416a3b64
roles: run ansible-lint --write 2023-08-23 22:22:51 +03:00
Alan Orth 7a9a24ef5d
roles/common: rework fail2ban again
Actually, we do want to run fail2ban on all hosts because the sshd
monitoring via systemd is nice. At the very least it reduces spam
from failed logins in our systemd journal.
2023-08-23 22:15:24 +03:00
Alan Orth 067adcd9f5
roles/common: rework fail2ban tasks
We can only run fail2ban when we have logs to monitor. When a host
is running Caddy we don't have logs, so fail2ban doesn't have any-
thing to monitor out of the box. For now I will restrict the task
to hosts running nginx.
2023-08-23 21:59:28 +03:00
Alan Orth 84d210cfab
roles/common: re-format handlers
Use the newer Ansible format.
2023-08-23 21:35:28 +03:00
Alan Orth 17736a4f14
roles/common: run ansible-lint --write 2023-08-23 21:33:22 +03:00
Alan Orth b9e91c4a3d
roles/common: minor updates to tarsnap task
Use modern Ansible task format
2023-08-23 21:20:22 +03:00
Alan Orth 51c95e5d4c
roles/common: update tarsnap task
Update tarsnap task to use apt signed-by for package signing keys
instead of adding keys directly to apt-key.
2023-08-23 21:18:27 +03:00
Alan Orth 8dbec29d2a
roles/nginx: prepare letsencrypt task for Debian 12 2023-08-23 21:01:12 +03:00
Alan Orth d3bf3dab04
roles/php-fpm: add support for PHP 8.2
This is used in Debian 12.
2023-08-23 20:56:35 +03:00
Alan Orth 8f50b7756b
host_vars/web22: WordPress 6.3 2023-08-22 21:33:49 +03:00
Alan Orth e86ccc9979
roles/nginx: minor rework of apt key stuff 2023-08-22 21:33:19 +03:00
Alan Orth cea8529f49
Pipfile.lock: run pipenv update 2023-08-22 21:02:17 +03:00
Alan Orth d77718edae
host_vars: add fail2ban_ignoreip 2023-08-14 16:37:07 +02:00
Alan Orth 14d57fc477
roles/nginx: reformat main tasks 2023-08-10 22:44:47 +02:00
Alan Orth 5c39f1abd8
roles/common: minor changes to Debian sshd_config files 2023-08-10 22:10:04 +02:00
Alan Orth 6794eb0432
roles/common: default to disabling SSH passwords 2023-08-10 22:09:03 +02:00
Alan Orth 11614e3725
host_vars: replace nomad02 with nomad03
The former is Ubuntu 20.04, the latter is Debian 12. Running Drone
CI.
2023-08-10 08:37:09 +02:00
Alan Orth b106f9d9e5
roles/common: ignore apt sources.list on Scaleway
While testing Debian 12 on Scaleway I noticed their apt sources.list
is in some weird format I've never seen before, so let's skip it on
those hosts.
2023-08-10 08:08:42 +02:00
Alan Orth 3c8250e6ac
Pipfile.lock: run pipenv update 2023-08-09 22:07:54 +02:00
Alan Orth d280859b0d
roles/common: minor updates to Debian 11 sshd_config 2023-08-09 21:55:04 +02:00
Alan Orth bca1629d2f
Minor comment updates for Debian 12 2023-08-09 21:51:53 +02:00
Alan Orth 4fa82faf18
roles/common: adjust sshd_config for Debian 12
Adjust sshd_config based on ssh-audit profile for OpenSSH 9.2.
2023-08-09 21:27:19 +02:00
Alan Orth b8f0b4b1fb
roles/common: add vanilla sshd_config for Debian 12 2023-08-09 21:16:50 +02:00
Alan Orth 68e5d05bbb
host_vars/web22: WordPress 6.2.2 2023-07-27 18:48:37 +03:00
Alan Orth 446d402778
roles: minor fix to Debian version comparisons 2023-07-27 18:48:07 +03:00
Alan Orth 67379fc2e4
host_vars/web22: WordPress 6.2 2023-05-04 07:10:40 +03:00
Alan Orth 73546967b6
Pipfile.lock: run pipenv update 2023-05-04 06:58:25 +03:00
Alan Orth 16b661efe1
Pipfile.lock: run pipenv update 2023-04-14 10:09:29 -07:00
Alan Orth fdb9a75489
roles/common: update tarsnap GPG key 2023-04-14 10:09:11 -07:00
Alan Orth 232d7a0348
host_vars/web22: WordPress 6.1.1 2022-11-24 18:31:48 +03:00
Alan Orth 6e4bb5bc34
host_vars/web21: use caddy 2022-11-13 18:58:57 +03:00
Alan Orth c840ffe018
roles/caddy: improve vhost template
Support domain aliases that redirect to the main domain and allow
sites to say they are static sites where they only need a document
root.
2022-11-13 18:54:03 +03:00
Alan Orth 45c9d7ea0a
Pipfile.lock: run pipenv update 2022-11-13 16:50:07 +03:00
Alan Orth a62bc446e8
host_vars/web22: WordPress 6.1 2022-11-06 23:00:41 +03:00
Alan Orth 62a6a491db
host_vars/web23: use caddy 2022-11-02 22:30:32 +03:00
Alan Orth 4867d6da6a
Add basic caddy role 2022-11-02 22:29:30 +03:00
Alan Orth d9f7c7a93b
group_vars/web: set default webserver to nginx
While I'm still getting experience with caddy and adapting it to my
workloads.
2022-11-02 22:12:36 +03:00
Alan Orth bc8c030700
roles/common: update Tarsnap GPG key 2022-11-02 22:11:37 +03:00
Alan Orth f7598d8f1c
Pipfile.lock: run pipenv update 2022-11-02 20:50:59 +03:00
Alan Orth c353e84a84
site.yml: use fully-qualified modules 2022-10-25 21:08:27 +03:00
Alan Orth 99ca23f258
Pipfile.lock: run pipenv update 2022-10-17 19:56:30 +03:00
Alan Orth b663d27fd8
roles/common: rework firewall_Debian.yml playbook
Use newer Ansible task format, move from apt to package module, and
do package installs in one transaction using a list instead of a
loop.
2022-09-12 17:25:40 +03:00
Alan Orth 67c99dacf6
roles/common: rework firewall_Ubuntu.yml playbook
Use newer Ansible task format, move from apt to package module, and
do package installs in one transaction using a list instead of a loop.
2022-09-12 17:18:33 +03:00
Alan Orth 4abf2b10e4
ansible.cfg: smart fact gathering 2022-09-12 17:18:19 +03:00
Alan Orth f5199264f9
ansible.cfg: disable SSH host key checking 2022-09-12 17:14:39 +03:00
Alan Orth b259f09cbd
roles/common: add SSH public key from other machine 2022-09-12 17:06:31 +03:00
Alan Orth f4b32e516b
roles/mariadb: use newer Ansible task syntax 2022-09-12 10:16:42 +03:00
Alan Orth fcb12ecee0
roles/mariadb: remove sources.list template 2022-09-12 10:13:27 +03:00
Alan Orth 5bc03ceacc
roles/mariadb: install packages in single transaction
Using a list we can install these in a single apt transaction. Also
use the newer task format.
2022-09-12 10:12:07 +03:00
Alan Orth c317429f6d
roles/mariadb: rework package signing key and repo 2022-09-12 10:09:41 +03:00
Alan Orth b512a7f765
roles/common: create /etc/apt/keyrings
According the the Debian docs for third-party repositories we must
create this manually on distros before Debian 12 and Ubuntu 22.04.
This is due to changes in apt-secure and the deprecation of apt-key.

See: https://wiki.debian.org/DebianRepository/UseThirdParty
2022-09-12 10:05:12 +03:00
Alan Orth e3a87d4f79
roles/mariadb: MariaDB 10.6
See: https://mariadb.com/kb/en/mariadb-1069-release-notes/
See: https://mariadb.com/kb/en/upgrading-from-mariadb-105-to-mariadb-106/
2022-09-12 09:25:46 +03:00
Alan Orth dec2d50fbc
host_vars/web22: WordPress 6.0.2 2022-09-12 09:00:05 +03:00
Alan Orth 34be0013b7
Remove Debian 10 support 2022-09-11 09:21:08 +03:00
Alan Orth 399585f4e7
roles: don't compare literal true and false
I changed these yesterday when editing the truthy values, but acco-
rding to ansible-link we can just rely on them being true or false
without comparing.
2022-09-11 08:41:25 +03:00
Alan Orth 0240897b1b
Remove Ubuntu 18.04 support 2022-09-10 23:30:04 +03:00
Alan Orth 1da0da53ec
roles: use longer format for when conditionals
When the condition is an AND we can use this more succinct format.
2022-09-10 23:12:49 +03:00
Alan Orth 677cc9f160
roles/php-fpm: fix truthy-ness in when 2022-09-10 23:12:26 +03:00
Alan Orth ffe7a872dd
roles: strict truthy values
According to Ansible we can use yes, true, True, "or any quoted st-
ring" for a boolean true, but ansible-lint wants us to use either
true or false.

See: https://chronicler.tech/red-hat-ansible-yes-no-and/
2022-09-10 22:33:19 +03:00
Alan Orth 95d0005978
Add ansible-lint 2022-09-10 18:36:53 +03:00
Alan Orth 498766fdc4
Pipfile.lock: run pipenv update 2022-09-10 18:36:07 +03:00
Alan Orth fc0fcc5742 roles/common: fix unnamed blocks 2022-09-10 18:35:27 +03:00
Alan Orth 587bd6dcdd roles: use fully qualified module names 2022-09-10 18:35:27 +03:00
Alan Orth 92a4c72809
Pipfile.lock: run pipenv update 2022-08-16 21:24:34 -07:00
Alan Orth a2d61abba2
roles/mariadb: update mirror
I started getting 'does not have a Release file' for the old repo-
sitory. Not sure why.
2022-08-14 22:09:47 -07:00
Alan Orth d2a5a28809
Pipfile.lock: run pipenv update 2022-08-01 15:20:56 +03:00
Alan Orth 84c0589aee
host_vars/web22: WordPress 5.9.2 2022-03-31 22:35:15 +03:00
Alan Orth 2961578a54
roles/common: Update list of abusive IP addresses
This comes from the AbuseIPDB with a confidence level of 95%. I use
the following command to download and sort the IPs:

  $ curl -G https://api.abuseipdb.com/api/v2/blacklist -d \
    confidenceMinimum=95 -H "Key: $ABUSEIPDB_API_KEY" \
    -H "Accept: text/plain" | sort | sed -e '/:/w /tmp/ipv6.txt' \
    -e '/:/d' > /tmp/ipv4.txt

I manually add the XML formatting to each file and run them through
tidy:

  $ tidy -xml -utf8 -m -iq -w 0 roles/common/files/abusers-ipv4.xml
  $ tidy -xml -utf8 -m -iq -w 0 roles/common/files/abusers-ipv6.xml

Then I formatted the nftables files manually. Meh...
2022-02-28 18:51:35 +03:00
Alan Orth 4d74f76b3c
Pipfile.lock: run pipenv update 2022-02-04 21:47:53 +03:00
Alan Orth 9e737466c5
roles/common: Update list of abusive IP addresses
This comes from the AbuseIPDB with a confidence level of 95%. I use
the following command to download and sort the IPs:

  $ curl -G https://api.abuseipdb.com/api/v2/blacklist -d \
    confidenceMinimum=95 -H "Key: $ABUSEIPDB_API_KEY" \
    -H "Accept: text/plain" | sort | sed -e '/:/w /tmp/ipv6.txt' \
    -e '/:/d' > /tmp/ipv4.txt

I manually add the XML formatting to each file and run them through
tidy:

  $ tidy -xml -utf8 -m -iq -w 0 roles/common/files/abusers-ipv4.xml
  $ tidy -xml -utf8 -m -iq -w 0 roles/common/files/abusers-ipv6.xml

Then I formatted the nftables files manually. Meh...
2022-02-04 21:47:37 +03:00
Alan Orth 0ffb1b1a36
roles/common: use pyinotify backend for nginx fail2ban jail
This seems to be automatically selected, but on some other servers
I notice it is not. I will set it here explicitly so fail2ban does
not fall back to the inefficient "polling" or incorrect "systemd"
backends.
2022-01-04 15:10:02 +02:00
Alan Orth 68f0b85eb3
Pipfile.lock: run pipenv update 2021-12-22 11:49:24 +02:00
Alan Orth ebbde530d2
roles/common: Update list of abusive IP addresses
This comes from the AbuseIPDB with a confidence level of 95%. I use
the following command to download and sort the IPs:

  $ curl -G https://api.abuseipdb.com/api/v2/blacklist -d \
    confidenceMinimum=95 -H "Key: $ABUSEIPDB_API_KEY" \
    -H "Accept: text/plain" | sort | sed -e '/:/w /tmp/ipv6.txt' \
    -e '/:/d' > /tmp/ipv4.txt

I manually add the XML formatting to each file and run them through
tidy:

  $ tidy -xml -utf8 -m -iq -w 0 roles/common/files/abusers-ipv4.xml
  $ tidy -xml -utf8 -m -iq -w 0 roles/common/files/abusers-ipv6.xml

Then I created the nftables files manually. Meh...
2021-12-22 11:40:27 +02:00
Alan Orth ab47df6031
Use Python 3.10 with pipenv 2021-12-13 08:38:08 +02:00
Alan Orth de75b2ffb6
host_vars/web22: WordPress 5.8.2 2021-11-30 19:48:18 +02:00
Alan Orth e10d83dadd
Pipfile.lock: run pipenv update 2021-11-30 19:34:46 +02:00
Alan Orth f070fd9a64
roles/common: Update list of abusive IP addresses
This comes from the AbuseIPDB with a confidence level of 95%. I use
the following command to download and sort the IPs:

  $ curl -G https://api.abuseipdb.com/api/v2/blacklist -d \
    confidenceMinimum=95 -H "Key: $ABUSEIPDB_API_KEY" \
    -H "Accept: text/plain" | sort | sed -e '/:/w /tmp/ipv6.txt' \
    -e '/:/d' > /tmp/ipv4.txt

I manually add the XML formatting to each file and run them through
tidy:

  $ tidy -xml -utf8 -m -iq -w 0 roles/common/files/abusers-ipv4.xml
  $ tidy -xml -utf8 -m -iq -w 0 roles/common/files/abusers-ipv6.xml
2021-11-07 10:12:43 +02:00
Alan Orth 6e1527b1a8
Pipfile.lock: run pipenv update 2021-11-07 10:11:46 +02:00
Alan Orth ebd8b0632b
roles/common: Disable unsafe Diffie-Hellman SSH moduli
The WeakDH team showed (in 2015) that Diffie-Hellman key exchange
with prime number groups of 1024 bits or less were weaker than we
previously thought, and well within the reach of nation states. They
recommended (in 2015) using 2048-bit or higher prime groups.

The SSH audit project recommends that we should use 3072-bit now.

See: https://weakdh.org/
See: https://github.com/jtesta/ssh-audit/
2021-10-10 16:57:05 +03:00
Alan Orth df26b6c17e
roles/common: notify fail2ban after updating firewall
We should always restart fail2ban after updating the firewall. Also
note that the order of execution of handlers depends on how they are
defined in the handler config, not on the order they are listed in
the task's notify statement.

See: https://docs.ansible.com/ansible/latest/user_guide/playbooks_handlers.html
2021-09-28 10:45:51 +03:00
Alan Orth d92151b8a6
roles/common: Update list of abusive IP addresses
This comes from the AbuseIPDB with a confidence level of 95%. I use
the following command to download and sort the IPs:

  $ curl -G https://api.abuseipdb.com/api/v2/blacklist -d \
    confidenceMinimum=95 -H "Key: $ABUSEIPDB_API_KEY" \
    -H "Accept: text/plain" | sort | sed -e '/:/w /tmp/ipv6.txt' \
    -e '/:/d' > /tmp/ipv4.txt

I manually add the XML formatting to each file and run them through
tidy:

  $ tidy -xml -utf8 -m -iq -w 0 roles/common/files/abusers-ipv4.xml
  $ tidy -xml -utf8 -m -iq -w 0 roles/common/files/abusers-ipv6.xml

Note: there were no IPv6 addresses in the top 10,000 this time so I
used a dummy address for the nftables set so the syntax was valid.
2021-09-28 10:28:02 +03:00
Alan Orth b13ead0657
roles/common: use a range for mosh ports in nftables
This is better than a loop in Jinja (though that is useful!).
2021-09-28 07:34:25 +03:00
Alan Orth 89ced6f952
Pipfile.lock: run pipenv update 2021-09-27 17:28:41 +03:00
Alan Orth ae5ba0607a
Remove host_vars/nomad01
Replaced by web23.
2021-09-27 14:17:48 +03:00
Alan Orth 89fd642b78
roles/nginx: minor rework of acme.sh tasks
After the inital acme.sh script is downloaded and bootstrapped we
can remove it. If a host already has been bootstrapped then there
is no need to download it and do it over again.
2021-09-27 13:40:17 +03:00
Alan Orth 65e6dd34cd
roles/common: Add missing section to Debian 11 sshd_config
We need to be able to configure the list of SSH users.
2021-09-27 12:59:27 +03:00
Alan Orth 0421807e4d
Add web23
Will replace nomad01
2021-09-27 12:22:45 +03:00
Alan Orth d5eed5055e
roles/nginx: Add support for gitea
gitea hosts are basically webservers, but we need to proxy pass. I
am setting up gitea itself manually for now.
2021-09-27 12:15:47 +03:00
Alan Orth f8752bb3e7
roles/nginx: add todo about document roots
We assume it's always /var/www/$domain_name but it can be overriden
in the host_vars...
2021-09-27 12:05:53 +03:00
Alan Orth 170e591701
roles/common: Install rsync and lsof 2021-09-27 11:36:40 +03:00
Alan Orth 8d6c3c57c3
roles/nginx: install acme.sh after downloading
This is basically just bootstrapping it. I used to do this by hand
before requesting the certs.
2021-09-27 11:28:02 +03:00
Alan Orth 79b29f0c51
roles/nginx: generate snakeoil cert manually
The ssl-cert does this, but it includes the hostname of the server
as the subject name in the cert, which is a huge leak of privacy.
2021-09-27 10:48:24 +03:00
Alan Orth a4acc85704
roles/common: Remove iptables on newer Debian 2021-09-27 10:35:38 +03:00
Alan Orth f7b9aa67f5
roles/common: Fix comment about Debian 10 firewall 2021-09-27 10:31:31 +03:00
Alan Orth 0a39c4f0ef
README.md: Update debian/ubuntu note 2021-09-27 10:13:47 +03:00
Alan Orth 85323d789c
Remove host_vars/web19
Replaced by web22.
2021-09-13 11:49:32 +03:00
Alan Orth 341a1bf11e
roles/php-fpm: Install php7.4-xml
The RSS feeds in the WordPress admin dashboard need this.
2021-09-13 10:19:33 +03:00
Alan Orth 6ee389eda5
roles/php-fpm: Use concrete dependencies
The php-gd, php-mysql, etc packages are meta packages that just end
up installing the concrete ones for our specific version.
2021-09-13 10:18:40 +03:00
Alan Orth 83fea62b0f
host_vars/web22: WordPress 5.8.1 2021-09-13 07:37:40 +03:00
Alan Orth 0d1a5fbb25
Add host_vars/web22
Will replace web19 soon.
2021-09-12 21:59:38 +03:00
Alan Orth 4d8444abf2
host_vars/web21: Fix path to cert 2021-09-12 20:39:45 +03:00
Alan Orth e8486f6c9e
host_vars/nomad02: Update Drone to version 2 2021-09-10 21:49:00 +03:00
Alan Orth 20cd6f213c
roles/common: cache_valid_time explicitly sets update_cache
See: https://docs.ansible.com/ansible/latest/collections/ansible/builtin/apt_module.html
2021-09-08 21:59:51 +03:00
Alan Orth eb80e797c6
Add host_vars/web21
Replaces web20.
2021-09-08 21:57:04 +03:00
Alan Orth 736bb8eb38
Remove host_vars/web20
Will be replaced by web21.
2021-09-08 21:56:43 +03:00
Alan Orth 34a30c4d13
roles/common: Don't update apt cache when removing packages 2021-09-08 17:05:48 +03:00
Alan Orth c03e75d736
roles/common: explicitly install systemd-timesyncd
It is a standalone package on (at least) Ubuntu 20.04 and Debian 11
and some cloud images do not have it installed by default (for exa-
mple Scaleway).
2021-09-08 17:04:46 +03:00
Alan Orth d08f10f9c8
roles/common: Fix comment in ntp playbook 2021-09-08 17:04:20 +03:00
Alan Orth 8467dc1300
roles/mariadb: Change socket location
Instead of using /var/run, just use /run directly. This is the real
path and it's the default anyways.
2021-09-08 15:50:48 +03:00
Alan Orth 635bb5234d
roles/common: fix logic for copying AbuseIPDB.com nft sets
We have to force these because they are not updated on the host like
the other lists (API limit of five requests per day!). We update the
list periodically here in git.
2021-09-08 09:58:13 +03:00
Alan Orth 37901da5b5
roles/common: update AbuseIPDB lists for nftables 2021-09-08 09:57:58 +03:00
Alan Orth e36ae3b11e
roles/common: Update list of abusive IP addresses
This comes from the AbuseIPDB with a confidence level of 95%. I use
the following command to download and sort the IPs:

  $ curl -G https://api.abuseipdb.com/api/v2/blacklist -d \
    confidenceMinimum=95 -H "Key: $ABUSEIPDB_API_KEY" \
    -H "Accept: text/plain" | sort | sed -e '/:/w /tmp/ipv6.txt' \
    -e '/:/d' > /tmp/ipv4.txt

I manually add the XML formatting to each file and run them through
tidy:

  $ tidy -xml -utf8 -m -iq -w 0 roles/common/files/abusers-ipv4.xml
  $ tidy -xml -utf8 -m -iq -w 0 roles/common/files/abusers-ipv6.xml
2021-09-08 09:35:36 +03:00
Alan Orth 81c1231a28
roles/php-fpm: Fix logic
First, we cannot do a global check for has_wordpress or needs_php,
as those are defined per nginx vhost. Second, I realized that this
was only working in the past because vhosts that had WordPress or
needed PHP were listed first in the nginx_vhosts dict.

This changes the logic to first check if any vhosts have WordPress
or need PHP, then sets a fact that we can use to decide whether to
run php-fpm tasks or not.
2021-09-08 09:32:06 +03:00
Alan Orth bb6f058025
roles/php-fpm: whitespace 2021-09-07 20:12:31 +03:00
Alan Orth 547395b26e
roles/nginx: Use php7.4-fpm socket on Debian 11 as well 2021-09-07 17:51:54 +03:00
Alan Orth 15208241d3
roles/common: Add git-lfs to base packages 2021-09-07 17:51:33 +03:00
Alan Orth 0fd05d496e
roles/nginx: Set mode of downloaded acme.sh 2021-09-07 17:10:35 +03:00
Alan Orth 023a0d48ba
roles/nginx: Remove old comment 2021-09-07 17:07:53 +03:00
Alan Orth c687b7a91a
roles/nginx: Run Let's Encrypt on Debian 11 too 2021-09-07 17:07:33 +03:00
Alan Orth bd4ae36bb6
roles/mariadb: use socket for all operations
Otherwise Ansible will try to connect with host 'localhost', which
we do not use (and we have disabled name resolution anyways).
2021-09-07 16:48:15 +03:00
Alan Orth b60637c7d9
roles/mariadb: Update comments for Ansible module 2021-09-07 16:47:47 +03:00
Alan Orth 479127a5e4
roles/common: Fix nftables handler in Debian firewall
We used to use reload, but now the idempotent thing to do is to use
restart instead of reload.
2021-09-07 15:43:33 +03:00
Alan Orth d261f81642
roles/php-fpm: Use Ubuntu 20.04 configs on Debian 11
They both use PHP 7.4.
2021-09-06 21:19:57 +03:00
Alan Orth 6bc044d454
host_vars: remove mosh rules
They are in roles/common now.
2021-09-05 16:33:45 +03:00
Alan Orth 9e07e27fbe
host_vars/web19: remove extra mosh rules
These are now in the common role for all hosts.
2021-09-05 16:24:28 +03:00
Alan Orth 575a9fdfe6
roles/common: Add mosh ports to common
These have been in each hosts's "extra" rules lists forever and I
use them on every single host so they might as well be in the base
rules.
2021-09-05 16:23:42 +03:00
Alan Orth 35fa3b0d72
roles/common: Fix typo in handlers 2021-09-05 16:19:31 +03:00
Alan Orth ba5760bf8c
host_vars/web19: WordPress 5.8 2021-09-05 15:55:58 +03:00
Alan Orth 5e918da88e
Pipfile.lock: run pipenv update 2021-09-05 15:38:51 +03:00
Alan Orth f7e87ea7be
roles/common: Fix fail2ban ignoreip
According to jail.conf we actually need to separate multiple values
with spaces instead of commas. On some versions of fail2ban this is
a fatal error:

> CRITICAL Unhandled exception in Fail2Ban:
> Traceback (most recent call last):
>   File "/usr/lib/python3/dist-packages/fail2ban/server/jailthread.py", line 66, in run_with_except_hook
>     run(*args, **kwargs)
>   File "/usr/lib/python3/dist-packages/fail2ban/server/filtersystemd.py", line 246, in run
>     *self.formatJournalEntry(logentry))
>   File "/usr/lib/python3/dist-packages/fail2ban/server/filter.py", line 432, in processLineAndAdd
>     if self.inIgnoreIPList(ip, log_ignore=True):
>   File "/usr/lib/python3/dist-packages/fail2ban/server/filter.py", line 371, in inIgnoreIPList
>     "(?<=b)1+", bin(DNSUtils.addr2bin(s[1]))).group())
>   File "/usr/lib/python3/dist-packages/fail2ban/server/filter.py", line 928, in addr2bin
>     return struct.unpack("!L", socket.inet_aton(ipstring))[0]
> OSError: illegal IP address string passed to inet_aton

This affects (at least) fail2ban 0.9.3 on Ubuntu 16.04, but I never
noticed.
2021-08-12 15:24:50 +03:00
Alan Orth 7b233eb31d
Pipfile.lock: Run pipenv update
Ansible 4.3.0
2021-08-01 16:14:42 +03:00
Alan Orth b5ea575d8d
roles/common: Always restart nftables service
The "reload" capability only exists on Ubuntu, and it is exactly
the same as the "restart" functionality.
2021-08-01 14:23:00 +03:00
Alan Orth 98cc3a8c2e
Add nginx filter for fail2ban
Some hosts can use fail2ban's nginx-botsearch filter to ban anyone
making requests to non-existent files like wp-login.php. There is
no reason to request such files naively and anyone found doing so
can be banned immediately.

In theory I should report them to AbuseIPDB.com, but that will take
a little more wiring up.
2021-08-01 09:56:43 +03:00
Alan Orth a67d901641
roles/common: Use AbuseIPDB.com list in nftables
For now I am still manually updating this, as we can only hit their
API five times per day, so it is not possible to have each host get
the list themselves every day with our one API key.
2021-07-31 21:46:50 +03:00
Alan Orth 7ae100faeb
roles/common: Add comments to nftables.conf 2021-07-30 09:37:30 +03:00
Alan Orth debcb21161
roles/common: Install curl for Abuse.ch update scripts 2021-07-29 10:24:32 +03:00
Alan Orth 8dd7663b3c
roles/common: Use Abuse.ch's SSL Blacklist in nftables
This adds Abuse.sh's list of IPs using blacklisted SSL certificates
to nftables. These IPs are high confidence indicators of compromise
and we should not route them. The list is updated daily by a systemd
timer.

See: https://sslbl.abuse.ch/blacklist/
2021-07-29 10:16:00 +03:00
Alan Orth cba2a7a996
roles/common: Fix nftables in Debian firewall
The previous commit meant to move the service start, not the config
copying task.
2021-07-29 10:10:04 +03:00
Alan Orth 197bdf7666
roles/common: Start nftables service later
We should only try to start the nftables service after we finish
copying all the config files just in case there is some unclean
state in one of them. On a first run this shouldn't matter, but
after nftables and some abuse list update scripts have run this
can happen (mostly in testing!).
2021-07-29 10:05:15 +03:00
Alan Orth 46fc2ce3d4
roles/common: Move cleanup to a one-off play
We only need to run this once on existing hosts that are using the
old firewalld/ipsets setup before applying the new nftables config.
2021-07-29 10:00:30 +03:00
Alan Orth b4d50166f4
roles/common: Fix loop in firewall cleanup 2021-07-28 23:46:53 +03:00
Alan Orth c336b217c5
Remove extra TCP ports from firewall rules
Now all web hosts get TCP 80 and 443 open automatically.
2021-07-28 14:49:50 +03:00
Alan Orth af6c3dd12a
roles/common: Update cache in firewall playbook
cron-apt updates the system against the security-only databases at
night so many packages are "missing" unless you run apt update. We
need to update the cache on all apt tasks actually because I might
be running them by their tag and they currently only get updated at
the beginning of the playbook.
2021-07-28 14:46:58 +03:00
Alan Orth b66c724109
roles/common: Use nftables on Ubuntu 20.04 as well
This mostly copies the Debian 11 nftables setup and includes a play
to clean up the old firewalld settings, timers, etc.
2021-07-28 14:18:41 +03:00
Alan Orth 8bc2b6f493
roles/common: Retab nftables.conf.j2 2021-07-27 22:03:23 +03:00
Alan Orth a74d6dfc08
roles/common: Don't overwrite spamhaus nft sets
The ones in this repo are only placeholders that get updated by the
update-spamhaus-nftables service, so we shouldn't overwrite them if
they exist.
2021-07-27 22:01:57 +03:00
Alan Orth d3922e7878
roles/common: Port configurable firewall logic to nftables
This opens TCP port 22 on all hosts, TCP ports 80 and 443 on hosts
in the web group, and allows configuration of "extra" rules in the
host or group vars.
2021-07-27 21:22:32 +03:00
Alan Orth 14814aa5d9
roles/common: Wire up fail2ban
The nftables support works easily and creates the table, chains, and
sets on demand.
2021-07-26 22:07:31 +03:00
Alan Orth 3b053167b1
roles/common: Fix sources.list for Debian 11 Bullseye
Seems the path to the security updates repo changed.
2021-07-26 21:12:05 +03:00
Alan Orth 9bba0d96bb
roles/common: Add initial support for nftables on Debian 11
I will try using nftables directly instead of via firewalld as of
Debian 11 as it is the replacement for the iptables/ipset stack in
recent years and is easier to work with.

This also includes a systemd service, timer, and script to update
the spamhaus DROP lists as nftables sets.

Still need to add fail2ban support.
2021-07-26 13:09:41 +03:00
Alan Orth 38c333045b
roles/common: bring Ubuntu firewall changes to Debian 11
Note that there is currently an issue loading the spamhaus rules on
Debian 11 when using ipsets with firewalld and the nftables backend.
The bug is apparently caused by overlapping CIDR segments, and the
solution appears to be that we need to manually aggregate them with
a tool like aggregate6 (Python).

See: https://bugzilla.redhat.com/show_bug.cgi?id=1836571
See: https://wiki.fysik.dtu.dk/it/Linux_firewall_configuration#using-ipsets-in-firewalld-on-rhel-centos-8
See: https://github.com/job/aggregate6
2021-07-24 23:09:33 +03:00
Alan Orth d4ede33099
roles/common: Don't configure apt sources on ARM
I was using this on Ubuntu, but might as well bring it here too so
that I can run Debian on Scaleway's ARM instances, for example.
2021-07-24 22:32:20 +03:00
Alan Orth 0bad75788d
roles/common: Add encryption settings to Debian 11 sshd_config
Mostly based on the ssh-audit policy for OpenSSH 8.4, but with any
algorithms using less than 256 bits removed. NSA's Suite B removed
these long ago, and the new CNSA suite only uses 256 and up.

See: https://github.com/jtesta/ssh-audit/blob/master/src/ssh_audit/policy.py
See: https://en.wikipedia.org/wiki/Commercial_National_Security_Algorithm_Suite
2021-07-24 22:28:59 +03:00
Alan Orth 892033b880
roles/common: port common settings to Debian 11 sshd_config
Still need to add the encryption settings.
2021-07-22 14:16:20 +03:00
Alan Orth 7c6ab2a652 roles/common: Add sshd_config from Debian 11 RC2 2021-07-22 14:15:00 +03:00
Alan Orth 1c95c1faa8
roles/common: Update KexAlgorithms in Ubuntu 20.04 sshd_config
Recommended by ssh-audit. Note that curve25519-sha256 is the new name
for the previously private implementation in libssh.
2021-07-22 12:57:31 +03:00
Alan Orth 9ea14de6f5
roles/common: Remove Encrypt-and-MAC modes from Ubuntu 20.04 sshd_config
Recommended by ssh-audit, but also generally the concensus for a few
years that Encrypt-and-MAC is hard to get right. OpenSSH has several
Encrypt-then-MAC schemes available so we can use those.

See: https://www.daemonology.net/blog/2009-06-24-encrypt-then-mac.html
2021-07-22 12:48:12 +03:00
Alan Orth 9b7a31ebf9
roles/common: Remove 00-persistent-journal.conf
This was to enable the persistent systemd journal, but it is no lo-
nger needed as of Ubuntu 18.04 and Debian 11. I had removed the ta-
asks long ago, but forgot to remove this file.
2021-07-21 10:02:33 +03:00
Alan Orth d7c34a30a3
roles/common: Add Spamhaus DROP lists to firewalld ipsets
This configures the recommended DROP, EDROP, and DROPv6 lists from
Spamhaus as ipsets in firewalld. First we copy an empty placeholder
ipset to seed firewalld, then we use a shell script to download the
real lists and activate them. The same shell script is run daily as
a service (update-spamhaus-lists.service) by a systemd timer.

I am strictly avoiding any direct ipset commands here because I want
to make sure that this works on older hosts where ipsets is used as
well as newer hosts that have moved to nftables such as Ubuntu 20.04.
So far I have tested this on Ubuntu 16.04, 18.04, and 20.04, but ev-
entually I need to abstract the tasks and run them on CentOS 7+ as
well.

See: https://www.spamhaus.org/drop/
2021-07-21 09:34:51 +03:00
Alan Orth ee5f4cdf74
host_vars: don't hard code python path
We now use auto mode in ansible.cfg, so we don't need to hard code
this in every single host's vars file.

See: https://docs.ansible.com/ansible/latest/reference_appendices/interpreter_discovery.html
2021-07-07 12:23:05 +03:00
Alan Orth b014c09a2c
ansible.cfg: Use auto discovery of Python interpreter
Uses a built-in table of OSes and Python versions to decide which
Python interpreter to use. This is better than hard coding python3
in every single host's host_vars.

See: https://docs.ansible.com/ansible/latest/reference_appendices/interpreter_discovery.html
2021-07-07 12:22:00 +03:00
Alan Orth 531ff99af0
roles/common: Update list of abusive IP addresses
This comes from the AbuseIPDB with a confidence level of 95%. I use
the following command to download and sort the IPs:

  $ curl -G https://api.abuseipdb.com/api/v2/blacklist -d \
    confidenceMinimum=95 -H "Key: $ABUSEIPDB_API_KEY" \
    -H "Accept: text/plain" | sort | sed -e '/:/w /tmp/ipv6.txt' \
    -e '/:/d' > /tmp/ipv4.txt

I manually add the XML formatting to each file and run them through
tidy:

  $ tidy -xml -utf8 -m -iq -w 0 roles/common/files/abusers-ipv4.xml
  $ tidy -xml -utf8 -m -iq -w 0 roles/common/files/abusers-ipv6.xml
2021-07-04 11:15:32 +03:00
Alan Orth 82d3a7ff2a
roles/nginx: Add convenience tags to fact task 2021-07-01 18:17:14 +03:00
Alan Orth 6c3cf40a16
roles/nginx: Use snakeoil cert from ssl-cert
Instead of manually creating our own self-signed certificate we can
use the one created automatically by the ssl-cert package on Debian.
This is only used by the dummy default HTTPS vhost.
2021-07-01 18:11:34 +03:00
Alan Orth 681be5eb19
Pipfile.lock: run pipenv update
Ansible 4.2.0 and Ansible Core 2.11.2
2021-07-01 18:11:11 +03:00
Alan Orth 4fae56a386
host_vars/web19: WordPress 5.7.2 2021-06-13 16:14:22 +03:00
Alan Orth 1d5db7bdbe
Pipfile.lock: run pipenv update 2021-06-13 16:14:05 +03:00
Alan Orth 32da3a3341
Pipfile.lock: Re-create pipenv environment for Ansible 4.0.0
Seems we need to manually uninstall and re-install.
2021-05-20 10:21:01 +03:00
Alan Orth 31a3f5832a
roles/common: Update list of abusive IP addresses
This comes from the AbuseIPDB with a confidence level of 95%. I use
the following command to download and sort the IPs:

  $ curl -G https://api.abuseipdb.com/api/v2/blacklist -d \
    confidenceMinimum=95 -H "Key: $ABUSEIPDB_API_KEY" \
    -H "Accept: text/plain" | sort | sed -e '/:/w /tmp/ipv6.txt' \
    -e '/:/d' > /tmp/ipv4.txt

I manually add the XML formatting to each file and run them through
tidy:

  $ tidy -xml -utf8 -m -iq -w 0 roles/common/files/abusers-ipv4.xml
  $ tidy -xml -utf8 -m -iq -w 0 roles/common/files/abusers-ipv6.xml
2021-05-20 10:20:47 +03:00
Alan Orth 3e7130b519
Pipfile.lock: run pipenv update 2021-05-14 13:56:56 +03:00
Alan Orth bd0b6a16de
roles/nginx/defaults/main.yml: Update version comment
Stable is now 1.20.0
2021-05-10 16:00:44 +03:00
Alan Orth 7145298f90
Pipfile.lock: Run pipenv update 2021-05-10 15:59:34 +03:00
Alan Orth 1bfd2bc441
Pipfile.lock: Run pipenv update
Ansible 3.3.0
2021-04-28 12:49:23 +03:00
Alan Orth 884b3b8425
host_vars/web19: remove dead host 2021-04-24 20:17:17 +03:00
Alan Orth e06a0c4093
host_vars/web19: WordPress 5.7.1 2021-04-16 19:51:55 +03:00
Alan Orth 7ba5afcec4
roles/nginx: Opt out of Google FLoC
Google's new Federated Learning of Cohorts (FLoC) will read user's
browser history and assign them to cohorts to track them unless we
set this header.
2021-04-16 12:41:09 +03:00
Alan Orth d3978e5b07
Pipfile.lock: run pipenv update 2021-04-13 14:28:34 +03:00
Alan Orth 4150dac57b
roles/common: Update list of abusive IP addresses
This comes from the AbuseIPDB with a confidence level of 95%. I use
the following command to download and sort the IPs:

  $ curl -G https://api.abuseipdb.com/api/v2/blacklist -d \
    confidenceMinimum=95 -H "Key: $ABUSEIPDB_API_KEY" \
    -H "Accept: text/plain" | sort | sed -e '/:/w /tmp/ipv6.txt' \
    -e '/:/d' > /tmp/ipv4.txt

I manually add the XML formatting to each file and run them through
tidy:

  $ tidy -xml -utf8 -m -iq -w 0 roles/common/files/abusers-ipv4.xml
  $ tidy -xml -utf8 -m -iq -w 0 roles/common/files/abusers-ipv6.xml
2021-04-13 12:11:11 +03:00
Alan Orth 58bc9d191f
roles/common: Update list of abusive IP addresses
This comes from the AbuseIPDB with a confidence level of 95%. I use
the following command to download and sort the IPs:

  $ curl -G https://api.abuseipdb.com/api/v2/blacklist -d \
    confidenceMinimum=95 -H "Key: $ABUSEIPDB_API_KEY" \
    -H "Accept: text/plain" | sort | sed -e '/:/w /tmp/ipv6.txt' \
    -e '/:/d' > /tmp/ipv4.txt

I manually add the XML formatting to each file and run them through
tidy:

  $ tidy -xml -utf8 -m -iq -w 0 roles/common/files/abusers-ipv4.xml
  $ tidy -xml -utf8 -m -iq -w 0 roles/common/files/abusers-ipv6.xml
2021-03-24 10:02:43 +02:00
Alan Orth 96cefc7f74
roles/nginx: Parameterize HSTS header
This parameterizes the HTTP Strict Transport Security header so we
can use it consistently across all templates. Also, it updates the
max-age to be ~1 year in seconds, which is recommended by Google.

See: https://hstspreload.org/
2021-03-23 15:36:28 +02:00
Alan Orth f85eb2841a
roles/nginx: Add webroot to systemd renewal service 2021-03-20 00:18:17 +02:00
Alan Orth 5d506ebc65
README.md: Update copyright year 2021-03-20 00:16:16 +02:00
Alan Orth af49f27551
roles/nginx: Update comment in defaults 2021-03-19 23:50:39 +02:00
Alan Orth f341d2e5eb
roles/nginx: Remove nginx pre/post hooks
We are now using the well-known webroot.
2021-03-19 23:46:22 +02:00
Alan Orth ceba0ea417
roles/nginx: Use consistent task style 2021-03-19 23:45:41 +02:00
Alan Orth a34cb1e666
roles/nginx: Switch to acme.sh for Let's Encrypt
The certbot-auto client that I've been using for a long time is now
only supported if you install it using snap. I don't use snap on my
systems so I decided to switch to the acme.sh client, which is imp-
lemented in POSIX shell with no dependencies. One bonus of this is
that I can start using ECC certificates.

This also configures the .well-known directory so we can use webroot
when installing and renewing certificates. I have yet to understand
how the renewal works with regards to webroot, though. I may have to
update the systemd timers to point to /var/lib/letsencrypt/.well-known.
2021-03-19 23:39:30 +02:00
Alan Orth 65fc52c5e5
roles/nginx: Use variable for nginx_ssl_dhparam
I went years without realizing that I was hard coding the file dest
in this particular task.
2021-03-19 18:13:55 +02:00
Alan Orth 7f13c8c675
host_vars/web19: WordPress 3.7 2021-03-19 13:27:34 +02:00
Alan Orth 9c36cfb8e5
Pipfile.lock: Run pipenv update 2021-03-19 13:18:19 +02:00
Alan Orth 7f72a9eda4
roles/nginx: Use RFC 7919 4096-bit dhparams
Recommended by internet.nl, which made me aware of RFC 7919.

See: https://tools.ietf.org/html/rfc7919#page-14
2021-03-19 13:13:56 +02:00
Alan Orth 6e96d48ea6
Pipfile.lock: Run pipenv update
Ansible 3.0.0
2021-03-01 15:27:58 +02:00
Alan Orth db412066b3
roles/mariadb: Only create users on 127.0.0.1 and ::1
A few months ago I disabled hostname lookups so only IP addresses
work now anyways.
2021-02-13 13:11:28 +02:00
Alan Orth 63a836e2a7
roles/common: Update Tarsnap GPG key
Apparently this changed since I last ran the tarsnap task.
2021-02-13 12:57:17 +02:00
100 changed files with 13197 additions and 13995 deletions

View File

@ -7,6 +7,7 @@ verify_ssl = true
[packages]
ansible = "*"
ansible-lint = "*"
[requires]
python_version = "3.9"
python_version = "3.11"

737
Pipfile.lock generated
View File

@ -1,11 +1,11 @@
{
"_meta": {
"hash": {
"sha256": "65b615b857250757470e21fc3a4b1cdfe75b4b012c0d1d633a5ebf1988d9cb91"
"sha256": "51db83e5e0106df431f03c2f87ecaccd2b1d4374dad0b714277db02d51c3da9c"
},
"pipfile-spec": 6,
"requires": {
"python_version": "3.9"
"python_version": "3.11"
},
"sources": [
{
@ -18,204 +18,619 @@
"default": {
"ansible": {
"hashes": [
"sha256:ae97002e4fb1ed3de947428ff43906c76c66751fe104721cf6b25fa115dbbe8d"
"sha256:471993dd239611b4b6134e46911612f85639035f10d82b6c888528b5ffb3b16a",
"sha256:7f4ea0e4d065538879b3e11e81e85eed4d802d1940f6564ad950e9d11a31b03c"
],
"index": "pypi",
"version": "==2.10.6"
"markers": "python_version >= '3.10'",
"version": "==9.3.0"
},
"ansible-base": {
"ansible-compat": {
"hashes": [
"sha256:33ae323923b841f3d822f355380ce7c92610440362efeed67b4b39db41e555af"
"sha256:74a91807808a39af48ab6595811b9340d1458db26b138362f48bf39292190705",
"sha256:b3e9f9d7c3a1ce6222de444e9dc6fece7eba70ac64f2a0befdc4e2d542018b4a"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
"version": "==2.10.5"
"markers": "python_version >= '3.9'",
"version": "==4.1.11"
},
"ansible-core": {
"hashes": [
"sha256:2cd208b0915948c88bffad331e5d07097b6edca1872cb53375e51b6719e6a060",
"sha256:c55d9a5f55651eb6c7f004ca9a9ed854d8cc310e6b438d96cea051cf3d2b2710"
],
"markers": "python_version >= '3.10'",
"version": "==2.16.4"
},
"ansible-lint": {
"hashes": [
"sha256:c3619deaadf852c353decff7242589bd1339e29271552e4e37bfa8f67db4c56b",
"sha256:d9e11aa06429610f0b461ec5eb9adf7317d4b2abb78475a9a1ec7e8f8e2c1316"
],
"index": "pypi",
"markers": "python_version >= '3.10'",
"version": "==24.2.1"
},
"attrs": {
"hashes": [
"sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30",
"sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1"
],
"markers": "python_version >= '3.7'",
"version": "==23.2.0"
},
"black": {
"hashes": [
"sha256:2818cf72dfd5d289e48f37ccfa08b460bf469e67fb7c4abb07edc2e9f16fb63f",
"sha256:41622020d7120e01d377f74249e677039d20e6344ff5851de8a10f11f513bf93",
"sha256:4acf672def7eb1725f41f38bf6bf425c8237248bb0804faa3965c036f7672d11",
"sha256:4be5bb28e090456adfc1255e03967fb67ca846a03be7aadf6249096100ee32d0",
"sha256:4f1373a7808a8f135b774039f61d59e4be7eb56b2513d3d2f02a8b9365b8a8a9",
"sha256:56f52cfbd3dabe2798d76dbdd299faa046a901041faf2cf33288bc4e6dae57b5",
"sha256:65b76c275e4c1c5ce6e9870911384bff5ca31ab63d19c76811cb1fb162678213",
"sha256:65c02e4ea2ae09d16314d30912a58ada9a5c4fdfedf9512d23326128ac08ac3d",
"sha256:6905238a754ceb7788a73f02b45637d820b2f5478b20fec82ea865e4f5d4d9f7",
"sha256:79dcf34b33e38ed1b17434693763301d7ccbd1c5860674a8f871bd15139e7837",
"sha256:7bb041dca0d784697af4646d3b62ba4a6b028276ae878e53f6b4f74ddd6db99f",
"sha256:7d5e026f8da0322b5662fa7a8e752b3fa2dac1c1cbc213c3d7ff9bdd0ab12395",
"sha256:9f50ea1132e2189d8dff0115ab75b65590a3e97de1e143795adb4ce317934995",
"sha256:a0c9c4a0771afc6919578cec71ce82a3e31e054904e7197deacbc9382671c41f",
"sha256:aadf7a02d947936ee418777e0247ea114f78aff0d0959461057cae8a04f20597",
"sha256:b5991d523eee14756f3c8d5df5231550ae8993e2286b8014e2fdea7156ed0959",
"sha256:bf21b7b230718a5f08bd32d5e4f1db7fc8788345c8aea1d155fc17852b3410f5",
"sha256:c45f8dff244b3c431b36e3224b6be4a127c6aca780853574c00faf99258041eb",
"sha256:c7ed6668cbbfcd231fa0dc1b137d3e40c04c7f786e626b405c62bcd5db5857e4",
"sha256:d7de8d330763c66663661a1ffd432274a2f92f07feeddd89ffd085b5744f85e7",
"sha256:e19cb1c6365fd6dc38a6eae2dcb691d7d83935c10215aef8e6c38edee3f77abd",
"sha256:e2af80566f43c85f5797365077fb64a393861a3730bd110971ab7a0c94e873e7"
],
"markers": "python_version >= '3.8'",
"version": "==24.3.0"
},
"bracex": {
"hashes": [
"sha256:a27eaf1df42cf561fed58b7a8f3fdf129d1ea16a81e1fadd1d17989bc6384beb",
"sha256:efdc71eff95eaff5e0f8cfebe7d01adf2c8637c8c92edaf63ef348c241a82418"
],
"markers": "python_version >= '3.8'",
"version": "==2.4"
},
"cffi": {
"hashes": [
"sha256:00a1ba5e2e95684448de9b89888ccd02c98d512064b4cb987d48f4b40aa0421e",
"sha256:00e28066507bfc3fe865a31f325c8391a1ac2916219340f87dfad602c3e48e5d",
"sha256:045d792900a75e8b1e1b0ab6787dd733a8190ffcf80e8c8ceb2fb10a29ff238a",
"sha256:0638c3ae1a0edfb77c6765d487fee624d2b1ee1bdfeffc1f0b58c64d149e7eec",
"sha256:105abaf8a6075dc96c1fe5ae7aae073f4696f2905fde6aeada4c9d2926752362",
"sha256:155136b51fd733fa94e1c2ea5211dcd4c8879869008fc811648f16541bf99668",
"sha256:1a465cbe98a7fd391d47dce4b8f7e5b921e6cd805ef421d04f5f66ba8f06086c",
"sha256:1d2c4994f515e5b485fd6d3a73d05526aa0fcf248eb135996b088d25dfa1865b",
"sha256:2c24d61263f511551f740d1a065eb0212db1dbbbbd241db758f5244281590c06",
"sha256:51a8b381b16ddd370178a65360ebe15fbc1c71cf6f584613a7ea08bfad946698",
"sha256:594234691ac0e9b770aee9fcdb8fa02c22e43e5c619456efd0d6c2bf276f3eb2",
"sha256:5cf4be6c304ad0b6602f5c4e90e2f59b47653ac1ed9c662ed379fe48a8f26b0c",
"sha256:64081b3f8f6f3c3de6191ec89d7dc6c86a8a43911f7ecb422c60e90c70be41c7",
"sha256:6bc25fc545a6b3d57b5f8618e59fc13d3a3a68431e8ca5fd4c13241cd70d0009",
"sha256:798caa2a2384b1cbe8a2a139d80734c9db54f9cc155c99d7cc92441a23871c03",
"sha256:7c6b1dece89874d9541fc974917b631406233ea0440d0bdfbb8e03bf39a49b3b",
"sha256:7ef7d4ced6b325e92eb4d3502946c78c5367bc416398d387b39591532536734e",
"sha256:840793c68105fe031f34d6a086eaea153a0cd5c491cde82a74b420edd0a2b909",
"sha256:8d6603078baf4e11edc4168a514c5ce5b3ba6e3e9c374298cb88437957960a53",
"sha256:9cc46bc107224ff5b6d04369e7c595acb700c3613ad7bcf2e2012f62ece80c35",
"sha256:9f7a31251289b2ab6d4012f6e83e58bc3b96bd151f5b5262467f4bb6b34a7c26",
"sha256:9ffb888f19d54a4d4dfd4b3f29bc2c16aa4972f1c2ab9c4ab09b8ab8685b9c2b",
"sha256:a5ed8c05548b54b998b9498753fb9cadbfd92ee88e884641377d8a8b291bcc01",
"sha256:a7711edca4dcef1a75257b50a2fbfe92a65187c47dab5a0f1b9b332c5919a3fb",
"sha256:af5c59122a011049aad5dd87424b8e65a80e4a6477419c0c1015f73fb5ea0293",
"sha256:b18e0a9ef57d2b41f5c68beefa32317d286c3d6ac0484efd10d6e07491bb95dd",
"sha256:b4e248d1087abf9f4c10f3c398896c87ce82a9856494a7155823eb45a892395d",
"sha256:ba4e9e0ae13fc41c6b23299545e5ef73055213e466bd107953e4a013a5ddd7e3",
"sha256:c6332685306b6417a91b1ff9fae889b3ba65c2292d64bd9245c093b1b284809d",
"sha256:d5ff0621c88ce83a28a10d2ce719b2ee85635e85c515f12bac99a95306da4b2e",
"sha256:d9efd8b7a3ef378dd61a1e77367f1924375befc2eba06168b6ebfa903a5e59ca",
"sha256:df5169c4396adc04f9b0a05f13c074df878b6052430e03f50e68adf3a57aa28d",
"sha256:ebb253464a5d0482b191274f1c8bf00e33f7e0b9c66405fbffc61ed2c839c775",
"sha256:ec80dc47f54e6e9a78181ce05feb71a0353854cc26999db963695f950b5fb375",
"sha256:f032b34669220030f905152045dfa27741ce1a6db3324a5bc0b96b6c7420c87b",
"sha256:f60567825f791c6f8a592f3c6e3bd93dd2934e3f9dac189308426bd76b00ef3b",
"sha256:f803eaa94c2fcda012c047e62bc7a51b0bdabda1cad7a92a522694ea2d76e49f"
"sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc",
"sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a",
"sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417",
"sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab",
"sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520",
"sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36",
"sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743",
"sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8",
"sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed",
"sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684",
"sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56",
"sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324",
"sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d",
"sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235",
"sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e",
"sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088",
"sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000",
"sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7",
"sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e",
"sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673",
"sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c",
"sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe",
"sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2",
"sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098",
"sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8",
"sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a",
"sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0",
"sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b",
"sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896",
"sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e",
"sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9",
"sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2",
"sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b",
"sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6",
"sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404",
"sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f",
"sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0",
"sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4",
"sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc",
"sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936",
"sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba",
"sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872",
"sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb",
"sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614",
"sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1",
"sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d",
"sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969",
"sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b",
"sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4",
"sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627",
"sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956",
"sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357"
],
"version": "==1.14.4"
"markers": "platform_python_implementation != 'PyPy'",
"version": "==1.16.0"
},
"click": {
"hashes": [
"sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28",
"sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"
],
"markers": "python_version >= '3.7'",
"version": "==8.1.7"
},
"cryptography": {
"hashes": [
"sha256:0003a52a123602e1acee177dc90dd201f9bb1e73f24a070db7d36c588e8f5c7d",
"sha256:0e85aaae861d0485eb5a79d33226dd6248d2a9f133b81532c8f5aae37de10ff7",
"sha256:594a1db4511bc4d960571536abe21b4e5c3003e8750ab8365fafce71c5d86901",
"sha256:69e836c9e5ff4373ce6d3ab311c1a2eed274793083858d3cd4c7d12ce20d5f9c",
"sha256:788a3c9942df5e4371c199d10383f44a105d67d401fb4304178020142f020244",
"sha256:7e177e4bea2de937a584b13645cab32f25e3d96fc0bc4a4cf99c27dc77682be6",
"sha256:83d9d2dfec70364a74f4e7c70ad04d3ca2e6a08b703606993407bf46b97868c5",
"sha256:84ef7a0c10c24a7773163f917f1cb6b4444597efd505a8aed0a22e8c4780f27e",
"sha256:9e21301f7a1e7c03dbea73e8602905a4ebba641547a462b26dd03451e5769e7c",
"sha256:9f6b0492d111b43de5f70052e24c1f0951cb9e6022188ebcb1cc3a3d301469b0",
"sha256:a69bd3c68b98298f490e84519b954335154917eaab52cf582fa2c5c7efc6e812",
"sha256:b4890d5fb9b7a23e3bf8abf5a8a7da8e228f1e97dc96b30b95685df840b6914a",
"sha256:c366df0401d1ec4e548bebe8f91d55ebcc0ec3137900d214dd7aac8427ef3030",
"sha256:dc42f645f8f3a489c3dd416730a514e7a91a59510ddaadc09d04224c098d3302"
"sha256:0270572b8bd2c833c3981724b8ee9747b3ec96f699a9665470018594301439ee",
"sha256:111a0d8553afcf8eb02a4fea6ca4f59d48ddb34497aa8706a6cf536f1a5ec576",
"sha256:16a48c23a62a2f4a285699dba2e4ff2d1cff3115b9df052cdd976a18856d8e3d",
"sha256:1b95b98b0d2af784078fa69f637135e3c317091b615cd0905f8b8a087e86fa30",
"sha256:1f71c10d1e88467126f0efd484bd44bca5e14c664ec2ede64c32f20875c0d413",
"sha256:2424ff4c4ac7f6b8177b53c17ed5d8fa74ae5955656867f5a8affaca36a27abb",
"sha256:2bce03af1ce5a5567ab89bd90d11e7bbdff56b8af3acbbec1faded8f44cb06da",
"sha256:329906dcc7b20ff3cad13c069a78124ed8247adcac44b10bea1130e36caae0b4",
"sha256:37dd623507659e08be98eec89323469e8c7b4c1407c85112634ae3dbdb926fdd",
"sha256:3eaafe47ec0d0ffcc9349e1708be2aaea4c6dd4978d76bf6eb0cb2c13636c6fc",
"sha256:5e6275c09d2badf57aea3afa80d975444f4be8d3bc58f7f80d2a484c6f9485c8",
"sha256:6fe07eec95dfd477eb9530aef5bead34fec819b3aaf6c5bd6d20565da607bfe1",
"sha256:7367d7b2eca6513681127ebad53b2582911d1736dc2ffc19f2c3ae49997496bc",
"sha256:7cde5f38e614f55e28d831754e8a3bacf9ace5d1566235e39d91b35502d6936e",
"sha256:9481ffe3cf013b71b2428b905c4f7a9a4f76ec03065b05ff499bb5682a8d9ad8",
"sha256:98d8dc6d012b82287f2c3d26ce1d2dd130ec200c8679b6213b3c73c08b2b7940",
"sha256:a011a644f6d7d03736214d38832e030d8268bcff4a41f728e6030325fea3e400",
"sha256:a2913c5375154b6ef2e91c10b5720ea6e21007412f6437504ffea2109b5a33d7",
"sha256:a30596bae9403a342c978fb47d9b0ee277699fa53bbafad14706af51fe543d16",
"sha256:b03c2ae5d2f0fc05f9a2c0c997e1bc18c8229f392234e8a0194f202169ccd278",
"sha256:b6cd2203306b63e41acdf39aa93b86fb566049aeb6dc489b70e34bcd07adca74",
"sha256:b7ffe927ee6531c78f81aa17e684e2ff617daeba7f189f911065b2ea2d526dec",
"sha256:b8cac287fafc4ad485b8a9b67d0ee80c66bf3574f655d3b97ef2e1082360faf1",
"sha256:ba334e6e4b1d92442b75ddacc615c5476d4ad55cc29b15d590cc6b86efa487e2",
"sha256:ba3e4a42397c25b7ff88cdec6e2a16c2be18720f317506ee25210f6d31925f9c",
"sha256:c41fb5e6a5fe9ebcd58ca3abfeb51dffb5d83d6775405305bfa8715b76521922",
"sha256:cd2030f6650c089aeb304cf093f3244d34745ce0cfcc39f20c6fbfe030102e2a",
"sha256:cd65d75953847815962c84a4654a84850b2bb4aed3f26fadcc1c13892e1e29f6",
"sha256:e4985a790f921508f36f81831817cbc03b102d643b5fcb81cd33df3fa291a1a1",
"sha256:e807b3188f9eb0eaa7bbb579b462c5ace579f1cedb28107ce8b48a9f7ad3679e",
"sha256:f12764b8fffc7a123f641d7d049d382b73f96a34117e0b637b80643169cec8ac",
"sha256:f8837fe1d6ac4a8052a9a8ddab256bc006242696f03368a4009be7ee3075cdb7"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'",
"version": "==3.3.1"
"markers": "python_version >= '3.7'",
"version": "==42.0.5"
},
"filelock": {
"hashes": [
"sha256:521f5f56c50f8426f5e03ad3b281b490a87ef15bc6c526f168290f0c7148d44e",
"sha256:57dbda9b35157b05fb3e58ee91448612eb674172fab98ee235ccb0b5bee19a1c"
],
"markers": "python_version >= '3.8'",
"version": "==3.13.1"
},
"jinja2": {
"hashes": [
"sha256:03e47ad063331dd6a3f04a43eddca8a966a26ba0c5b7207a9a9e4e08f1b29419",
"sha256:a6d58433de0ae800347cab1fa3043cebbabe8baa9d29e668f1c768cb87a333c6"
"sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa",
"sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
"version": "==2.11.3"
"markers": "python_version >= '3.7'",
"version": "==3.1.3"
},
"jsonschema": {
"hashes": [
"sha256:7996507afae316306f9e2290407761157c6f78002dcf7419acb99822143d1c6f",
"sha256:85727c00279f5fa6bedbe6238d2aa6403bedd8b4864ab11207d07df3cc1b2ee5"
],
"markers": "python_version >= '3.8'",
"version": "==4.21.1"
},
"jsonschema-specifications": {
"hashes": [
"sha256:48a76787b3e70f5ed53f1160d2b81f586e4ca6d1548c5de7085d1682674764cc",
"sha256:87e4fdf3a94858b8a2ba2778d9ba57d8a9cafca7c7489c46ba0d30a8bc6a9c3c"
],
"markers": "python_version >= '3.8'",
"version": "==2023.12.1"
},
"markdown-it-py": {
"hashes": [
"sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1",
"sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"
],
"markers": "python_version >= '3.8'",
"version": "==3.0.0"
},
"markupsafe": {
"hashes": [
"sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473",
"sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161",
"sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235",
"sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5",
"sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42",
"sha256:195d7d2c4fbb0ee8139a6cf67194f3973a6b3042d742ebe0a9ed36d8b6f0c07f",
"sha256:22c178a091fc6630d0d045bdb5992d2dfe14e3259760e713c490da5323866c39",
"sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff",
"sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b",
"sha256:2beec1e0de6924ea551859edb9e7679da6e4870d32cb766240ce17e0a0ba2014",
"sha256:3b8a6499709d29c2e2399569d96719a1b21dcd94410a586a18526b143ec8470f",
"sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1",
"sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e",
"sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183",
"sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66",
"sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b",
"sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1",
"sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15",
"sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1",
"sha256:6f1e273a344928347c1290119b493a1f0303c52f5a5eae5f16d74f48c15d4a85",
"sha256:6fffc775d90dcc9aed1b89219549b329a9250d918fd0b8fa8d93d154918422e1",
"sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e",
"sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b",
"sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905",
"sha256:7fed13866cf14bba33e7176717346713881f56d9d2bcebab207f7a036f41b850",
"sha256:84dee80c15f1b560d55bcfe6d47b27d070b4681c699c572af2e3c7cc90a3b8e0",
"sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735",
"sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d",
"sha256:98bae9582248d6cf62321dcb52aaf5d9adf0bad3b40582925ef7c7f0ed85fceb",
"sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e",
"sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d",
"sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c",
"sha256:a6a744282b7718a2a62d2ed9d993cad6f5f585605ad352c11de459f4108df0a1",
"sha256:acf08ac40292838b3cbbb06cfe9b2cb9ec78fce8baca31ddb87aaac2e2dc3bc2",
"sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21",
"sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2",
"sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5",
"sha256:b1dba4527182c95a0db8b6060cc98ac49b9e2f5e64320e2b56e47cb2831978c7",
"sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b",
"sha256:b7d644ddb4dbd407d31ffb699f1d140bc35478da613b441c582aeb7c43838dd8",
"sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6",
"sha256:bf5aa3cbcfdf57fa2ee9cd1822c862ef23037f5c832ad09cfea57fa846dec193",
"sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f",
"sha256:caabedc8323f1e93231b52fc32bdcde6db817623d33e100708d9a68e1f53b26b",
"sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f",
"sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2",
"sha256:d53bc011414228441014aa71dbec320c66468c1030aae3a6e29778a3382d96e5",
"sha256:d73a845f227b0bfe8a7455ee623525ee656a9e2e749e4742706d80a6065d5e2c",
"sha256:d9be0ba6c527163cbed5e0857c451fcd092ce83947944d6c14bc95441203f032",
"sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7",
"sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be",
"sha256:feb7b34d6325451ef96bc0e36e1a6c0c1c64bc1fbec4b854f4529e51887b1621"
"sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf",
"sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff",
"sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f",
"sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3",
"sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532",
"sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f",
"sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617",
"sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df",
"sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4",
"sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906",
"sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f",
"sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4",
"sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8",
"sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371",
"sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2",
"sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465",
"sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52",
"sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6",
"sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169",
"sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad",
"sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2",
"sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0",
"sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029",
"sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f",
"sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a",
"sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced",
"sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5",
"sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c",
"sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf",
"sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9",
"sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb",
"sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad",
"sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3",
"sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1",
"sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46",
"sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc",
"sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a",
"sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee",
"sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900",
"sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5",
"sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea",
"sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f",
"sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5",
"sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e",
"sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a",
"sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f",
"sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50",
"sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a",
"sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b",
"sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4",
"sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff",
"sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2",
"sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46",
"sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b",
"sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf",
"sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5",
"sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5",
"sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab",
"sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd",
"sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==1.1.1"
"markers": "python_version >= '3.7'",
"version": "==2.1.5"
},
"mdurl": {
"hashes": [
"sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8",
"sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"
],
"markers": "python_version >= '3.7'",
"version": "==0.1.2"
},
"mypy-extensions": {
"hashes": [
"sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d",
"sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"
],
"markers": "python_version >= '3.5'",
"version": "==1.0.0"
},
"packaging": {
"hashes": [
"sha256:5b327ac1320dc863dca72f4514ecc086f31186744b84a230374cc1fd776feae5",
"sha256:67714da7f7bc052e064859c05c595155bd1ee9f69f76557e21f051443c20947a"
"sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5",
"sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==20.9"
"markers": "python_version >= '3.7'",
"version": "==24.0"
},
"pathspec": {
"hashes": [
"sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08",
"sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"
],
"markers": "python_version >= '3.8'",
"version": "==0.12.1"
},
"platformdirs": {
"hashes": [
"sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068",
"sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768"
],
"markers": "python_version >= '3.8'",
"version": "==4.2.0"
},
"pycparser": {
"hashes": [
"sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0",
"sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705"
"sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9",
"sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==2.20"
"version": "==2.21"
},
"pyparsing": {
"pygments": {
"hashes": [
"sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1",
"sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"
"sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c",
"sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367"
],
"markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==2.4.7"
"markers": "python_version >= '3.7'",
"version": "==2.17.2"
},
"pyyaml": {
"hashes": [
"sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf",
"sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696",
"sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393",
"sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77",
"sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922",
"sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5",
"sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8",
"sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10",
"sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc",
"sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018",
"sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e",
"sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253",
"sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183",
"sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb",
"sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185",
"sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db",
"sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46",
"sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b",
"sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63",
"sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df",
"sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc"
"sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5",
"sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc",
"sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df",
"sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741",
"sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206",
"sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27",
"sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595",
"sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62",
"sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98",
"sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696",
"sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290",
"sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9",
"sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d",
"sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6",
"sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867",
"sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47",
"sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486",
"sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6",
"sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3",
"sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007",
"sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938",
"sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0",
"sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c",
"sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735",
"sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d",
"sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28",
"sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4",
"sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba",
"sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8",
"sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef",
"sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5",
"sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd",
"sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3",
"sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0",
"sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515",
"sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c",
"sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c",
"sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924",
"sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34",
"sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43",
"sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859",
"sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673",
"sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54",
"sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a",
"sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b",
"sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab",
"sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa",
"sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c",
"sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585",
"sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d",
"sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'",
"version": "==5.4.1"
"markers": "python_version >= '3.6'",
"version": "==6.0.1"
},
"six": {
"referencing": {
"hashes": [
"sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259",
"sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"
"sha256:5773bd84ef41799a5a8ca72dc34590c041eb01bf9aa02632b4a973fb0181a844",
"sha256:d53ae300ceddd3169f1ffa9caf2cb7b769e92657e4fafb23d34b93679116dfd4"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==1.15.0"
"markers": "python_version >= '3.8'",
"version": "==0.34.0"
},
"resolvelib": {
"hashes": [
"sha256:04ce76cbd63fded2078ce224785da6ecd42b9564b1390793f64ddecbe997b309",
"sha256:d2da45d1a8dfee81bdd591647783e340ef3bcb104b54c383f70d422ef5cc7dbf"
],
"version": "==1.0.1"
},
"rich": {
"hashes": [
"sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222",
"sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432"
],
"markers": "python_full_version >= '3.7.0'",
"version": "==13.7.1"
},
"rpds-py": {
"hashes": [
"sha256:01e36a39af54a30f28b73096dd39b6802eddd04c90dbe161c1b8dbe22353189f",
"sha256:044a3e61a7c2dafacae99d1e722cc2d4c05280790ec5a05031b3876809d89a5c",
"sha256:08231ac30a842bd04daabc4d71fddd7e6d26189406d5a69535638e4dcb88fe76",
"sha256:08f9ad53c3f31dfb4baa00da22f1e862900f45908383c062c27628754af2e88e",
"sha256:0ab39c1ba9023914297dd88ec3b3b3c3f33671baeb6acf82ad7ce883f6e8e157",
"sha256:0af039631b6de0397ab2ba16eaf2872e9f8fca391b44d3d8cac317860a700a3f",
"sha256:0b8612cd233543a3781bc659c731b9d607de65890085098986dfd573fc2befe5",
"sha256:11a8c85ef4a07a7638180bf04fe189d12757c696eb41f310d2426895356dcf05",
"sha256:1374f4129f9bcca53a1bba0bb86bf78325a0374577cf7e9e4cd046b1e6f20e24",
"sha256:1d4acf42190d449d5e89654d5c1ed3a4f17925eec71f05e2a41414689cda02d1",
"sha256:1d9a5be316c15ffb2b3c405c4ff14448c36b4435be062a7f578ccd8b01f0c4d8",
"sha256:1df3659d26f539ac74fb3b0c481cdf9d725386e3552c6fa2974f4d33d78e544b",
"sha256:22806714311a69fd0af9b35b7be97c18a0fc2826e6827dbb3a8c94eac6cf7eeb",
"sha256:2644e47de560eb7bd55c20fc59f6daa04682655c58d08185a9b95c1970fa1e07",
"sha256:2e6d75ab12b0bbab7215e5d40f1e5b738aa539598db27ef83b2ec46747df90e1",
"sha256:30f43887bbae0d49113cbaab729a112251a940e9b274536613097ab8b4899cf6",
"sha256:34b18ba135c687f4dac449aa5157d36e2cbb7c03cbea4ddbd88604e076aa836e",
"sha256:36b3ee798c58ace201289024b52788161e1ea133e4ac93fba7d49da5fec0ef9e",
"sha256:39514da80f971362f9267c600b6d459bfbbc549cffc2cef8e47474fddc9b45b1",
"sha256:39f5441553f1c2aed4de4377178ad8ff8f9d733723d6c66d983d75341de265ab",
"sha256:3a96e0c6a41dcdba3a0a581bbf6c44bb863f27c541547fb4b9711fd8cf0ffad4",
"sha256:3f26b5bd1079acdb0c7a5645e350fe54d16b17bfc5e71f371c449383d3342e17",
"sha256:41ef53e7c58aa4ef281da975f62c258950f54b76ec8e45941e93a3d1d8580594",
"sha256:42821446ee7a76f5d9f71f9e33a4fb2ffd724bb3e7f93386150b61a43115788d",
"sha256:43fbac5f22e25bee1d482c97474f930a353542855f05c1161fd804c9dc74a09d",
"sha256:4457a94da0d5c53dc4b3e4de1158bdab077db23c53232f37a3cb7afdb053a4e3",
"sha256:465a3eb5659338cf2a9243e50ad9b2296fa15061736d6e26240e713522b6235c",
"sha256:482103aed1dfe2f3b71a58eff35ba105289b8d862551ea576bd15479aba01f66",
"sha256:4832d7d380477521a8c1644bbab6588dfedea5e30a7d967b5fb75977c45fd77f",
"sha256:4901165d170a5fde6f589acb90a6b33629ad1ec976d4529e769c6f3d885e3e80",
"sha256:5307def11a35f5ae4581a0b658b0af8178c65c530e94893345bebf41cc139d33",
"sha256:5417558f6887e9b6b65b4527232553c139b57ec42c64570569b155262ac0754f",
"sha256:56a737287efecafc16f6d067c2ea0117abadcd078d58721f967952db329a3e5c",
"sha256:586f8204935b9ec884500498ccc91aa869fc652c40c093bd9e1471fbcc25c022",
"sha256:5b4e7d8d6c9b2e8ee2d55c90b59c707ca59bc30058269b3db7b1f8df5763557e",
"sha256:5ddcba87675b6d509139d1b521e0c8250e967e63b5909a7e8f8944d0f90ff36f",
"sha256:618a3d6cae6ef8ec88bb76dd80b83cfe415ad4f1d942ca2a903bf6b6ff97a2da",
"sha256:635dc434ff724b178cb192c70016cc0ad25a275228f749ee0daf0eddbc8183b1",
"sha256:661d25cbffaf8cc42e971dd570d87cb29a665f49f4abe1f9e76be9a5182c4688",
"sha256:66e6a3af5a75363d2c9a48b07cb27c4ea542938b1a2e93b15a503cdfa8490795",
"sha256:67071a6171e92b6da534b8ae326505f7c18022c6f19072a81dcf40db2638767c",
"sha256:685537e07897f173abcf67258bee3c05c374fa6fff89d4c7e42fb391b0605e98",
"sha256:69e64831e22a6b377772e7fb337533c365085b31619005802a79242fee620bc1",
"sha256:6b0817e34942b2ca527b0e9298373e7cc75f429e8da2055607f4931fded23e20",
"sha256:6c81e5f372cd0dc5dc4809553d34f832f60a46034a5f187756d9b90586c2c307",
"sha256:6d7faa6f14017c0b1e69f5e2c357b998731ea75a442ab3841c0dbbbfe902d2c4",
"sha256:6ef0befbb5d79cf32d0266f5cff01545602344eda89480e1dd88aca964260b18",
"sha256:6ef687afab047554a2d366e112dd187b62d261d49eb79b77e386f94644363294",
"sha256:7223a2a5fe0d217e60a60cdae28d6949140dde9c3bcc714063c5b463065e3d66",
"sha256:77f195baa60a54ef9d2de16fbbfd3ff8b04edc0c0140a761b56c267ac11aa467",
"sha256:793968759cd0d96cac1e367afd70c235867831983f876a53389ad869b043c948",
"sha256:7bd339195d84439cbe5771546fe8a4e8a7a045417d8f9de9a368c434e42a721e",
"sha256:7cd863afe7336c62ec78d7d1349a2f34c007a3cc6c2369d667c65aeec412a5b1",
"sha256:7f2facbd386dd60cbbf1a794181e6aa0bd429bd78bfdf775436020172e2a23f0",
"sha256:84ffab12db93b5f6bad84c712c92060a2d321b35c3c9960b43d08d0f639d60d7",
"sha256:8c8370641f1a7f0e0669ddccca22f1da893cef7628396431eb445d46d893e5cd",
"sha256:8db715ebe3bb7d86d77ac1826f7d67ec11a70dbd2376b7cc214199360517b641",
"sha256:8e8916ae4c720529e18afa0b879473049e95949bf97042e938530e072fde061d",
"sha256:8f03bccbd8586e9dd37219bce4d4e0d3ab492e6b3b533e973fa08a112cb2ffc9",
"sha256:8f2fc11e8fe034ee3c34d316d0ad8808f45bc3b9ce5857ff29d513f3ff2923a1",
"sha256:923d39efa3cfb7279a0327e337a7958bff00cc447fd07a25cddb0a1cc9a6d2da",
"sha256:93df1de2f7f7239dc9cc5a4a12408ee1598725036bd2dedadc14d94525192fc3",
"sha256:998e33ad22dc7ec7e030b3df701c43630b5bc0d8fbc2267653577e3fec279afa",
"sha256:99f70b740dc04d09e6b2699b675874367885217a2e9f782bdf5395632ac663b7",
"sha256:9a00312dea9310d4cb7dbd7787e722d2e86a95c2db92fbd7d0155f97127bcb40",
"sha256:9d54553c1136b50fd12cc17e5b11ad07374c316df307e4cfd6441bea5fb68496",
"sha256:9dbbeb27f4e70bfd9eec1be5477517365afe05a9b2c441a0b21929ee61048124",
"sha256:a1ce3ba137ed54f83e56fb983a5859a27d43a40188ba798993812fed73c70836",
"sha256:a34d557a42aa28bd5c48a023c570219ba2593bcbbb8dc1b98d8cf5d529ab1434",
"sha256:a5f446dd5055667aabaee78487f2b5ab72e244f9bc0b2ffebfeec79051679984",
"sha256:ad36cfb355e24f1bd37cac88c112cd7730873f20fb0bdaf8ba59eedf8216079f",
"sha256:aec493917dd45e3c69d00a8874e7cbed844efd935595ef78a0f25f14312e33c6",
"sha256:b316144e85316da2723f9d8dc75bada12fa58489a527091fa1d5a612643d1a0e",
"sha256:b34ae4636dfc4e76a438ab826a0d1eed2589ca7d9a1b2d5bb546978ac6485461",
"sha256:b34b7aa8b261c1dbf7720b5d6f01f38243e9b9daf7e6b8bc1fd4657000062f2c",
"sha256:bc362ee4e314870a70f4ae88772d72d877246537d9f8cb8f7eacf10884862432",
"sha256:bed88b9a458e354014d662d47e7a5baafd7ff81c780fd91584a10d6ec842cb73",
"sha256:c0013fe6b46aa496a6749c77e00a3eb07952832ad6166bd481c74bda0dcb6d58",
"sha256:c0b5dcf9193625afd8ecc92312d6ed78781c46ecbf39af9ad4681fc9f464af88",
"sha256:c4325ff0442a12113a6379af66978c3fe562f846763287ef66bdc1d57925d337",
"sha256:c463ed05f9dfb9baebef68048aed8dcdc94411e4bf3d33a39ba97e271624f8f7",
"sha256:c8362467a0fdeccd47935f22c256bec5e6abe543bf0d66e3d3d57a8fb5731863",
"sha256:cd5bf1af8efe569654bbef5a3e0a56eca45f87cfcffab31dd8dde70da5982475",
"sha256:cf1ea2e34868f6fbf070e1af291c8180480310173de0b0c43fc38a02929fc0e3",
"sha256:d62dec4976954a23d7f91f2f4530852b0c7608116c257833922a896101336c51",
"sha256:d68c93e381010662ab873fea609bf6c0f428b6d0bb00f2c6939782e0818d37bf",
"sha256:d7c36232a90d4755b720fbd76739d8891732b18cf240a9c645d75f00639a9024",
"sha256:dd18772815d5f008fa03d2b9a681ae38d5ae9f0e599f7dda233c439fcaa00d40",
"sha256:ddc2f4dfd396c7bfa18e6ce371cba60e4cf9d2e5cdb71376aa2da264605b60b9",
"sha256:e003b002ec72c8d5a3e3da2989c7d6065b47d9eaa70cd8808b5384fbb970f4ec",
"sha256:e32a92116d4f2a80b629778280103d2a510a5b3f6314ceccd6e38006b5e92dcb",
"sha256:e4461d0f003a0aa9be2bdd1b798a041f177189c1a0f7619fe8c95ad08d9a45d7",
"sha256:e541ec6f2ec456934fd279a3120f856cd0aedd209fc3852eca563f81738f6861",
"sha256:e546e768d08ad55b20b11dbb78a745151acbd938f8f00d0cfbabe8b0199b9880",
"sha256:ea7d4a99f3b38c37eac212dbd6ec42b7a5ec51e2c74b5d3223e43c811609e65f",
"sha256:ed4eb745efbff0a8e9587d22a84be94a5eb7d2d99c02dacf7bd0911713ed14dd",
"sha256:f8a2f084546cc59ea99fda8e070be2fd140c3092dc11524a71aa8f0f3d5a55ca",
"sha256:fcb25daa9219b4cf3a0ab24b0eb9a5cc8949ed4dc72acb8fa16b7e1681aa3c58",
"sha256:fdea4952db2793c4ad0bdccd27c1d8fdd1423a92f04598bc39425bcc2b8ee46e"
],
"markers": "python_version >= '3.8'",
"version": "==0.18.0"
},
"ruamel.yaml": {
"hashes": [
"sha256:57b53ba33def16c4f3d807c0ccbc00f8a6081827e81ba2491691b76882d0c636",
"sha256:8b27e6a217e786c6fbe5634d8f3f11bc63e0f80f6a5890f28863d9c45aac311b"
],
"markers": "python_version >= '3.7'",
"version": "==0.18.6"
},
"ruamel.yaml.clib": {
"hashes": [
"sha256:024cfe1fc7c7f4e1aff4a81e718109e13409767e4f871443cbff3dba3578203d",
"sha256:03d1162b6d1df1caa3a4bd27aa51ce17c9afc2046c31b0ad60a0a96ec22f8001",
"sha256:07238db9cbdf8fc1e9de2489a4f68474e70dffcb32232db7c08fa61ca0c7c462",
"sha256:09b055c05697b38ecacb7ac50bdab2240bfca1a0c4872b0fd309bb07dc9aa3a9",
"sha256:1707814f0d9791df063f8c19bb51b0d1278b8e9a2353abbb676c2f685dee6afe",
"sha256:1758ce7d8e1a29d23de54a16ae867abd370f01b5a69e1a3ba75223eaa3ca1a1b",
"sha256:184565012b60405d93838167f425713180b949e9d8dd0bbc7b49f074407c5a8b",
"sha256:1b617618914cb00bf5c34d4357c37aa15183fa229b24767259657746c9077615",
"sha256:1dc67314e7e1086c9fdf2680b7b6c2be1c0d8e3a8279f2e993ca2a7545fecf62",
"sha256:25ac8c08322002b06fa1d49d1646181f0b2c72f5cbc15a85e80b4c30a544bb15",
"sha256:25c515e350e5b739842fc3228d662413ef28f295791af5e5110b543cf0b57d9b",
"sha256:305889baa4043a09e5b76f8e2a51d4ffba44259f6b4c72dec8ca56207d9c6fe1",
"sha256:3213ece08ea033eb159ac52ae052a4899b56ecc124bb80020d9bbceeb50258e9",
"sha256:3f215c5daf6a9d7bbed4a0a4f760f3113b10e82ff4c5c44bec20a68c8014f675",
"sha256:46d378daaac94f454b3a0e3d8d78cafd78a026b1d71443f4966c696b48a6d899",
"sha256:4ecbf9c3e19f9562c7fdd462e8d18dd902a47ca046a2e64dba80699f0b6c09b7",
"sha256:53a300ed9cea38cf5a2a9b069058137c2ca1ce658a874b79baceb8f892f915a7",
"sha256:56f4252222c067b4ce51ae12cbac231bce32aee1d33fbfc9d17e5b8d6966c312",
"sha256:5c365d91c88390c8d0a8545df0b5857172824b1c604e867161e6b3d59a827eaa",
"sha256:700e4ebb569e59e16a976857c8798aee258dceac7c7d6b50cab63e080058df91",
"sha256:75e1ed13e1f9de23c5607fe6bd1aeaae21e523b32d83bb33918245361e9cc51b",
"sha256:77159f5d5b5c14f7c34073862a6b7d34944075d9f93e681638f6d753606c6ce6",
"sha256:7f67a1ee819dc4562d444bbafb135832b0b909f81cc90f7aa00260968c9ca1b3",
"sha256:840f0c7f194986a63d2c2465ca63af8ccbbc90ab1c6001b1978f05119b5e7334",
"sha256:84b554931e932c46f94ab306913ad7e11bba988104c5cff26d90d03f68258cd5",
"sha256:87ea5ff66d8064301a154b3933ae406b0863402a799b16e4a1d24d9fbbcbe0d3",
"sha256:955eae71ac26c1ab35924203fda6220f84dce57d6d7884f189743e2abe3a9fbe",
"sha256:a1a45e0bb052edf6a1d3a93baef85319733a888363938e1fc9924cb00c8df24c",
"sha256:a5aa27bad2bb83670b71683aae140a1f52b0857a2deff56ad3f6c13a017a26ed",
"sha256:a6a9ffd280b71ad062eae53ac1659ad86a17f59a0fdc7699fd9be40525153337",
"sha256:a75879bacf2c987c003368cf14bed0ffe99e8e85acfa6c0bfffc21a090f16880",
"sha256:aa2267c6a303eb483de8d02db2871afb5c5fc15618d894300b88958f729ad74f",
"sha256:aab7fd643f71d7946f2ee58cc88c9b7bfc97debd71dcc93e03e2d174628e7e2d",
"sha256:b16420e621d26fdfa949a8b4b47ade8810c56002f5389970db4ddda51dbff248",
"sha256:b42169467c42b692c19cf539c38d4602069d8c1505e97b86387fcf7afb766e1d",
"sha256:bba64af9fa9cebe325a62fa398760f5c7206b215201b0ec825005f1b18b9bccf",
"sha256:beb2e0404003de9a4cab9753a8805a8fe9320ee6673136ed7f04255fe60bb512",
"sha256:bef08cd86169d9eafb3ccb0a39edb11d8e25f3dae2b28f5c52fd997521133069",
"sha256:c2a72e9109ea74e511e29032f3b670835f8a59bbdc9ce692c5b4ed91ccf1eedb",
"sha256:c58ecd827313af6864893e7af0a3bb85fd529f862b6adbefe14643947cfe2942",
"sha256:c69212f63169ec1cfc9bb44723bf2917cbbd8f6191a00ef3410f5a7fe300722d",
"sha256:cabddb8d8ead485e255fe80429f833172b4cadf99274db39abc080e068cbcc31",
"sha256:d176b57452ab5b7028ac47e7b3cf644bcfdc8cacfecf7e71759f7f51a59e5c92",
"sha256:da09ad1c359a728e112d60116f626cc9f29730ff3e0e7db72b9a2dbc2e4beed5",
"sha256:e2b4c44b60eadec492926a7270abb100ef9f72798e18743939bdbf037aab8c28",
"sha256:e79e5db08739731b0ce4850bed599235d601701d5694c36570a99a0c5ca41a9d",
"sha256:ebc06178e8821efc9692ea7544aa5644217358490145629914d8020042c24aa1",
"sha256:edaef1c1200c4b4cb914583150dcaa3bc30e592e907c01117c08b13a07255ec2",
"sha256:f481f16baec5290e45aebdc2a5168ebc6d35189ae6fea7a58787613a25f6e875",
"sha256:fff3573c2db359f091e1589c3d7c5fc2f86f5bdb6f24252c2d8e539d4e45f412"
],
"markers": "platform_python_implementation == 'CPython' and python_version < '3.13'",
"version": "==0.2.8"
},
"subprocess-tee": {
"hashes": [
"sha256:b3c124993f8b88d1eb1c2fde0bc2069787eac720ba88771cba17e8c93324825d",
"sha256:eca56973a1c1237093c2055b2731bcaab784683b83f22c76f26e4c5763402e28"
],
"markers": "python_version >= '3.8'",
"version": "==0.4.1"
},
"wcmatch": {
"hashes": [
"sha256:24c19cedc92bc9c9e27f39db4e1824d72f95bd2cea32b254a47a45b1a1b227ed",
"sha256:c0088c7f6426cf6bf27e530e2b7b734031905f7e490475fd83c7c5008ab581b3"
],
"markers": "python_version >= '3.8'",
"version": "==8.5.1"
},
"yamllint": {
"hashes": [
"sha256:2e16e504bb129ff515b37823b472750b36b6de07963bd74b307341ef5ad8bdc3",
"sha256:7a003809f88324fd2c877734f2d575ee7881dd9043360657cc8049c809eba6cd"
],
"markers": "python_version >= '3.8'",
"version": "==1.35.1"
}
},
"develop": {}

View File

@ -4,7 +4,7 @@ Ansible playbook for base and initial configuration of the web server hosting my
## Assumptions
Before you can run this, a few things are assumed:
- You have a clean, minimal Ubuntu 18.04, Debian 10, or Ubuntu 20.04 host up and running
- You have a clean, minimal Ubuntu 20.04 or Debian 11/12 host up and running
- Python 3 is installed on the remote server (requirement of Ansible)
- You have a user account with password-less SSH access to the machine
- You have sudo privileges on the remote host
@ -25,7 +25,7 @@ Once you've satisfied the the above assumptions, you can execute:
- Switch from `cron-apt` to [`unattended-upgrades`](https://wiki.debian.org/UnattendedUpgrades)
## License
Copyright (C) 20142020 Alan Orth
Copyright (C) 20142021 Alan Orth
The contents of this repository are free software: you can redistribute
it and/or modify it under the terms of the GNU General Public License

View File

@ -2,9 +2,16 @@
retry_files_enabled=False
force_handlers=True
inventory=hosts
gathering = smart
# instead of using --ask-vault-pass
ask_vault_pass=True
remote_user = provisioning
interpreter_python=auto
# Don't warn on unknown SSH host keys because it's super annoying for new hosts
# or if you get a new laptop and run Ansible there!
#
# See: https://docs.ansible.com/ansible/latest/user_guide/connection_details.html#managing-host-key-checking
host_key_checking = False
ansible_managed = This file is managed by Ansible.%n
template: {file}

11
group_vars/web Normal file
View File

@ -0,0 +1,11 @@
---
# file: group_vars/web
# run nginx by default
webserver: nginx
# all hosts run fail2ban with the sshd filter, but some can use other filters
extra_fail2ban_filters:
- nginx
# vim: set ts=2 sw=2:

View File

@ -1,87 +0,0 @@
$ANSIBLE_VAULT;1.1;AES256
37356463383831623061363666396235346361663734326234323239633332383431656534636337
3238613566336363636235393535373330363562333135630a626531343430396666323139633833
37656533353537393335393966323637326335666134613633643330313334383237383736623637
6533343338396536640a376466633436643162393533646464343930346665616165613835373630
66353037653339633038353033316463393234313630646138636633643066653636343739383730
65343161306339343931323737336531646131363034343163366137616231363638313330343365
31663932343436313364326331373733373830646637313733323335306161626135616438656363
32623333646637633636316139613234613232393462306364633966666639623231643735663266
35396266313936326532383139346361626532323263633662373139363638303961616638636535
65343862623865386436643930353834323566356164386432373434336536363262356638313333
64626633353565303538353634626438363131633164636263643938386538323932346337343730
31336266343532306531626234323962353930343333656436356436343666336335633233386462
34623332393734633761303762306336656232326533313131316331326639376338393437363834
32663766633037316266373064376638643237343434356166613862383963633231353531646432
36393438653234326330316438333862396163383231623034383963336435393533393263653739
38373764373034313231373536653233666230333437626431383161346636376434383135393434
30353361343136663135356536316630643163613930306363343830323932393635343936396535
38366638353737336637356237646332353438303632396238356364343464323064373031656331
31346134323965646336666336303835326463656339356131613633336539613234653332353539
35613362653335663863626532363433663634393036373462663833636333646661643865353533
39376535313635373434633466643135323762613539366135376536653761303134303964343534
65333934396638373239646339343732623139303037336133363533653330383261383437393061
37336334363237333437633664313637366566396232336337303235366337616530333261356662
39666531653762326364353534623431333530653935316161383535663762636136316239336233
35373962623934633663656337306439616431316165666563336532373135323566386431303733
36313264323066653164346338653433393337623666646162383666303930613939396662373965
38653863623935336632666366373764383136376163663137313234663761343066336235626232
35303532376537643663653431323830623364623362346437396664386363396632646364666130
62663265363334383663626661363632646432393463373564396633393235353434636437623261
30323866636332356136396662363930613961613961343963313733343033616539316131323262
65666665663731636633623464353430623135373430313065626438396363366335363466316132
64353730383761386563353133396262366265343637643931643565386461303138613565303239
37646339316366316431663237653230346464643433376639356462643133643234386131613965
66333831663832326131343134633231636633373735333634663861393531633738366136356130
38653534666662303539353534636537343665366231346565376437313037646162663365666630
33366631653530326234326333623333346535343362666263376561333334633533356264393637
64633864616430653663366133343962376233656562643335633336326335626664653861323334
65653864323062616234343636633435396332636635653266353032623637356133383538383034
36383936666238333366386637313434656332626266346439346566666537623039323936303936
62353130663632636636623466326663623639313433353766346230383138323461643962666562
65646234346631613139393265666663663537323236383832373532393662643566636164653364
39636133613937393433636231626238386463376434666166643662313661663635356436636165
38333830313638643863373162636530346433613366613437643932383035643464363732663633
38633065366638656635356462393935383665386532633936366437333233316563366231393935
32393736343365383164346634326336373436386630386630616436373139646531353038333562
39646132643332373563613664303931633735656135376561646166343934396130343834653461
62343662386239313731336538393430316263333966306530616161633763306331633834323633
35633237333136366439376666636461356131663830323832646462653035643561396337633362
64323532663637323966663262353266316361353931333738323762656532343165626266653035
36353462306361383233303464353766323466393862313037386139326231656230343630616139
34626533323065646636643736323535356461623063663262656562333466666634376239356633
38373362363030346434316261643236363337663237323032623339393936303130393662666434
33386134386633623930376334333466666137356432636131373562306533333836353332316136
63653533336232336632353465373263363037313933663131633763343366663034353364373661
63333166306332663837313334623231653561363964306337353564326266353366343538366433
63383335336566366564333735383337353765613035383135616135653662346133333338303730
36303334623335613836333938646366376634353664633731666235346638346662656634393631
35396262323939393562306530323763353939363264666331373266363937653063366138636364
36623835383961336331303439613731633734343135323938306263363637616235336461333732
65303636623766313038356266363666316665343832623662643263623233356232333062333933
65373763376430366565363161333330376138313130363534623364653434616438363732643333
61336631653762613231373236613164623566663730396163383136366430353439346637623965
39356138633037313165333034633234353666646132656532386332393962626239383633383833
64396430343535346438623233326632663839336233316336383261346330353739633331396362
65643161396430646436376636613061656566623038633665623938656232633665633365613837
36386633313032306238373063346662333539313931366232323931613165343639666437386630
63343766633336346632393231303566323562373236656135366135376262613163646235646635
31356264393231353335363331663666623832643638653064366438373063623462333631663631
32356664663332356538636462383364633036303733393161366565393361363530626431623532
34303538653032313138373339663833613637356364376561316535643238356633356130376665
37643231333037626164663634383666323333316235353832333335393262366235613461623166
30343933643637656262613337313962666432656632323631353066353838373864383734646361
35393966646331633466316636326162343831393639383034396133383537313138646339646163
37363736613135326634363031626132326664343732646161623362373036323337623063653064
37373839396261653764626338393438643634666463336263346566653366336536376464643934
31366261353734383064346433363730623762636463613432373338356337656665376338353965
34353866343734633661633466313132663463323962653431316536643565666364386438336236
35376163313462383130366337653239623866663837666238346262636238623932333435623634
65333132373436353533333834653131656638336362623535613366346266653863326431666137
32613563316138333837333131663637346634663962616230623534383239616132623130646137
62613863626632323838343736633765393666336664313563316535346130333462353063656166
62376237663566396665366238323937343434363964653133393163343932353761353038373234
33303462613837653730646462643765396631656536353335353532663033663433613032623833
36656534646163353266316531343137626131316536396338666262336136653734613838333133
62663937346566626131323033313432333562633337326634623866656363393165363235386265
6332653639336330336135333865633662363738613565303766

View File

@ -1,127 +0,0 @@
$ANSIBLE_VAULT;1.1;AES256
35356461313263333464373365643730653766393437316133336138313761343130646131363861
3834623038366139376261326439633334393565346666650a323963393665366134386535316530
61316264343737383331663361353838656333623335393635393762303533313036373161393462
6664616164633039360a613766323932323266613166646635376333626333356364316233633931
37646436383339343938356164646262363032663063393038616535346139633435623265343762
33663036393761643861386538336665366537626464373931386535666237636439383133393636
31383938376331313531366237336463323563323134313037393435333239613663663234376239
62346163663061316666636138353962383336623133333030396534323033626632343561386466
30356266313566316565626562376364643238386561323165633730383262343638326337636264
35636264386262363264633833653265393962373435653639363733636562343238363931663031
63666135613437366166643130623034616636616632633838653464666130383365326434666234
32643164353766323131343137373438613663646635326338303934613065653466613036323961
38353034636434663061353138393130316432366539643937623935643834633964653630326564
31636563336138623433366536663632313863313435333531353865623066656631343032383937
65313535303563653762646261396366333737306331643037366433323030303265613638616164
36336338333837393235326539303964323261393039393533643538623634613432643532333863
66376166336662306564323433356330336662333433633061313266323638396165656665663965
38376465383662626633396366326466333436333338373361363039306539396337333061643264
37356562623130373765366331643332376337353065366561656261353131666533636466386432
31643438633464356464333065316139626166326164616666363666393562356239343637333030
39366231316462663265346464613333306336316163643131303235616432613565613733333466
33343036326435643736336465303861643739663536343965346433363231323065643733336634
63646133633037613964393935373161666161383862616333376638616336616537616363643661
36326665316332303537663935633431626533323838393638653661343665306332396130393866
66303231666533393132396538393963626132643366373539656437386663653261323465613366
39633964366362353866326562313834313266656265363161316261386638623737393034663665
66303966623830366431316432323863386332383362396534396166343238616534346335323761
31366164623465643331323330323736336337653230623362626230623365636364633261653765
38613566626537386134373133376139623062383736356634393739353665326164343131323833
31313038363663316636356431613032636131303964373564633462303735323364636131373033
30623336306663346639326638303930383466323938356163633964623565313261363139303238
31326666363164376261393062616339643039316163346362633865356433346636323664656262
65323565346137333338363864346437373261383936626531316330316539653339303464623462
32616635373631323465646632323732323432316332353033656339366639663732313939303733
37306130656662383237613361326161313039326561396538396333373362633365353130343963
35613833616635353266636265313766323635303764346236306664346432366632376132333034
65303235366137356634666138343232366533613966363030376537386162396638656637663932
66663939393737313634383430323339663634333533653265656163326637636635386163313333
38666236626131333139633834373534316638303364666135396361616130303061313431643936
64666134623666363937356334356134306463386466613365363136663136393833616430623836
65373663363664333766373136336636393663376535623532626632396665366436623661636665
62333961383034353664323333353766343939666636616539653236646634313333373639643765
32353161633665306463386633616131333130303139306134646134663865306463353838323565
39313538393034323065333031386634396261336131333763393466633335666238373663623564
38316633663536383730376532633830623939633662346636356632653031633335313732666663
33613133653666313564626261353730373637396137323964363866653964373838613130643337
32376165356236663332366566626639313038363138343061306438313435613862626564613830
61306262613262366539663338643962313066613665353063306537643561666462333763623866
30643230313334646535336662616137326437323438336361376562663361376230316362323235
65363630666464323638323761343033313763633866623361376636653631396263626239613764
64656163343435643838353033316364306134663833616231343831613338653330643466643630
62323039396231366136353432373732613465336163326132353731313765356163323866633736
35326665613165373339353165613036646665313065343432663563306664323163306535613338
31663138333639666133323139326339313733663334336637373866636661636538666630346233
31393364313433626565616661313265336165613534666232333835383963646433316632303533
62626134623830363533393833633439313034633965346163393932636464326664653335643833
35386332663736343766656232313031306534653434363164623530613232306531336561373534
37333763626135373538313561303737623035653832333533663534313035313530373037616634
30613937626664373333643735633164663930316235336663376132353338356333623431343535
37623138363937646665626535303463643330333233363136313134383939343535646539346363
61633966396234393961663735646634373266373264626635306162386632376262646336316266
36363166393332626533613736353038656266323263333036303964656662663436616532396665
64366638386164313466313630663138333066653061666362336661336539653339616234646538
30316334346162363065313438663865346434313564363863613532313637313430653439333962
34643039383030623564666230623264303338343564643961653531366463623166333661653630
38613062626464663963626233663837653533626532653239343065383036663162646261386535
36356231383263396365653639613664346361643666336463623136616330336161373336643535
36613530396266633861643530633732333436373966613437343736653537333531663466383438
64323064356262646133363463316639353630653766663731653030616461393139396265343033
31336662366465633264643065386432376435346236323565326562663161396435373762613839
36316365633937636330643837646335613262363734396261313633373731363466356632636532
37653036336665393733343832363739323739383730306635306666333566366663396230623433
64663338626239313265623838383933653539666666383633623939343461393036303230663562
35363232636635613739356536386439326537363965626261363962383231386532623565343662
61633931613131303836356366653030656333623235663266636535666632353666386666386630
36303134613262663335623330356639383432353133333137363665633565363037333136653933
64396230613837396435333835343265633638346232303738663764663032343061346539393135
63303064366130333030663739326331633762386332333162393631346234306363313737663261
31303437376339353634393438316139663862333530653339393030633932343765326435303530
30326566336361646563313433663063396338663661353832666561393437306131336465343332
63316533623362613062626337306530633833323132616662613366653566396136643936653435
33323938333666333439653037383335353763386132643362643361386232383964366237326538
32343061643462343265383234366465366232666434623634383132303138643333343663613039
65663339663030326364663561383833333432633437313232356265396532303735316234353565
39313532306437333238373064643238666632383166313832326662663762316165323936623239
62366239393530366666343866376566623863373333666266316334346138396566613263333539
38373438653663353537323961373434363735303838306262323330616538636333306366373663
62666462336331623761363036353331356632643664373665656332663530613931376666353261
64346531363265316439393633346334383439623338653334343739353464316436626635653139
39633232626463303463646162633131626538353232646663356335363663613234376338623539
30303765636635633331326337373334626664343063623130393438633863306531653631323763
63323661356362346536646430623864306135663766313833366165653066343439663064336331
33353135383830373831623463646461616665326139623565666464363961306461343361343665
30633331666533383161623130613963376266613533366334393262313730313630323836623162
33613637363431306632366230336537373732613337613830666635353632383834383465303261
39633334616561386163353661306564333632653731363434666562353561363462376563626563
63353666653637336666376138333966643237633434396561386164623435333836653238383261
30643331373138313062616532366265313831613938373865336435383564636266663462636461
63663230626532613130623566376437356337653564303033393737663735316130633234643163
30373264363331366435383837303762363531333335613738613463336139643333626239346232
31393631663861623330353536313731353332313135363436643161353435653865313666373639
37313734306461633338363033623535653066633135666463303261383366333266613830623138
37303963666139306632666537633137326434366231333435323335623130356332313165353733
37656238613138396635303765376666303631633034306133393639363662313066653062373638
63313961343932393964643538663863313664616164363264663438393639306161373539653265
34346535373939316563353437663066656439353161623337343935396463363231636262656565
61653766616238393030333837616631373736323837363136623337623539336661633533653663
37376530303630313861376261323231303464653666323237373466353037313230333861373366
61323964636235373030343462326166323533343266353236653138326639363664633066346239
66636439373262646536333134306363313531333437316536656337633764356339633933336131
64366565323438343864666462356232616263623530613631303265313861383135333562343263
39633938313435313266386538346132336638303938373964616535313035653063636435643538
31636134393930363635613733343538326637366661623833396531623832616238323637633866
35666266656465323830356432653839633763643430363431326632393664656464363238363364
64356132326561376330316434393765663661356466346463366538323439393531343632316134
65313436623664613230616562323138343831623033643338363839343837303334346361356433
63356163626432343733336531366333636466613863613438373662643266636134633934326432
31386634363161653965303230306336373434613232613237343836353061613533616237666462
35393935383431323764646465636563363633336463353064346631363531383061333135386161
64363366303262336464646232316231613332333732373932643562626534666634316565343164
39336436366163326137396236393034363162366634616233376465303063663330386137343733
65393231343634316365326663666532646162623633373530393563313861653638353932396137
38666161336432303666316263396538663665353334376637343762613262303062313932363831
65346637366163333233633562393535306263666330666636613363383939393035643132326162
35656130366237363136643938633931363731623662343536623136313436616265333138646239
3765356139356136346264386137316437303865646335643530

88
host_vars/nomad03 Normal file
View File

@ -0,0 +1,88 @@
$ANSIBLE_VAULT;1.1;AES256
30626135313830363339656165316536336564353362383439346465373932326136363337343762
3566343231306635313739303335616162396232303139620a323764663132323135663063393334
62656434643333663062356266626235363439393231333734343432333363643934393636373935
6332353333303231370a373839636135363730636539326335343533316633623366663230353262
37396264313763366438663139376638613337336634393665663032623035646631653564353966
30353165333638363864656531396165363430653438376465656233306639353336353237343532
62363330333662316630656662633333626462363062366637386163336230386634353933316238
36373365323735373435616262613933333964323033633233333766396362616534316166386432
31333831353130616166633735366131653137363361313333363763623364303435346338643838
63323831616135643830653839323663386239343430356437346665343937306666333836363163
37386663616136653861663530383865343930306263663366633438363332336561326330353235
64613332643962323930323436393934636263396239366364306136303437323739343237656263
33613964363139363862396235636435626432326432663166633765613635666165363165663539
62366232316632356233326564633737643466343535656564653833623766373637313833373331
38356336396461666535386363633437376232396330623162333936366434376361326261343336
35396237346663646334306663306633383061353333643639613335643661633835313732353963
64623234373033656366613566363639663762646663396462323361363463373961383530653962
61613962316336653266383638393630323338383161303565333862633932646463313134613232
31326262336561383066633430383833353835373363623163303830663837313265663662313862
39353062333234663631653565613135396337626664626264366534633566386236393562303861
66316335343638356261396339353932633331356363343231363862333066366438323764633331
39316236343262666337303839356138666338306130323462646633373464646163613734366132
37623739333435396266316131383238323365646632636339353631376166613532386133393165
64633933393062623230346430653961646366316662356336646162313466393964323332616431
34336562343337636138616431313736613539373137303666666435373238346233383438383963
39346138393635626263376137643436393736636435393234646439353932386136653034393961
65336230356336386539386334653236303964623632323738383333623361643235656530363731
39306538353533663538366362613739386463336632653665636533616462363530636466626165
32623762616266623231393938663931306231626139663736613862363234643861366563633532
31393934333433316138323131373836306135333061363231363461643933303836633231343266
37323732383036326664376438343261333733636532303664613965353561376337633564373062
64316133333263393138333261323062626363343765393161363935386232353862353762626334
31346661303239383832343637376663316537353938346534306134626534363438386162653133
66616237663864633837356132663139633734303532653637366138386534653462323163313836
34633337643661656465653839316362633236633833646632393930656136313730646566316537
39653935633636363635386435373062333031356363633661366530616537356533323133366339
34336139323138336532313833633364363566613833636339396462326530313961613133613761
63356231313363303862663032373663626262646565353933663963363633363663373238656632
31393264333732366565376164623766663162386365356233383132303835643932386436333631
65663334336434663562326238326338376662303339616233616464313139363864623463613761
36326235396433633435366263393964383936616433653861326431343133346435663832363437
33333232636536363863373037616436313335393639393966653062303330366463323861376661
39383665316665303363636331373461623339323031393333323465313733336236303037313132
37613163373432316132306235343061393530366237626134323431323836316261326237323965
33643662663361356164653430323566666230656561633434333538303365663334373537306164
65633264323836656537623766316533386564663765376661663537303835393438623430343263
64353031633436343938383263313439383033326532313466653766616164653463333434353664
30653034353632373561346565616631656235323637333562613538663538363936663464383064
31336365613037626331363731376663653537613639313839303934633462666430306635613434
65333736653430363936663566666535346231383563366630653535313038383964326630616264
63616563356361313439303833646438386163313865356634636536336661626664316163333739
63303465643861656362386530353363383836396534373461663630636461633336333862353830
38666536353663386466313066376562383366643062343965386132666435376433626165353735
61666432613133646130373839336261333565303532643164306264633736346637373835393266
33306133346531333835303238393361663463346162636161646565313266616133623735653838
62396531313634343936363861373031383830636538376334316161326364303930383435653936
36653233343935646337376232396638343033613130663563326135633231636362373162623565
39323762623966393332376235643666383461356263346332663939616235346564636233333463
35356161616536613939313436616233386563343764643335653961643366656632646338313536
35323732333539326239386436306230646230663336623566633763383534626162386463613961
62353737363435653866383633343830356536633462373636323734656231636466336235306162
62666133656166633838363262613930396236393862306438316135643131393737363531373631
31626635613233313063326463663738393632373135373632323731396332323138633962356364
39396565393038623532313230383539656564383134363161393663373539393837313335303636
38626138613932643265643231366364373964623436663566623838643939323331646661653435
37373765393736303861346164373938393532636637353737326539333435666562643664363365
65646662626630663238336264663665663762666439626336376434386436653965363832346339
30396630343430323762666232366336376563616430643136336630373864623132386465393761
66396439346563393539616335383562633237353962383033356230323339353336343964366134
38623661326336376561633937613565386164656462313863336339643733663834373732643266
61666438666635656236376239393433306239613936613731636235353638396432326438396432
63333237333633333761666630663339613232313136316232346234363562333937363463333137
39653336343732303536616662643961623932643330653936343337316135366535363964616439
37376433326332386339363961656537326632333830346435353234333661636434343730356139
37346131303930306364623334313335323563333631653539383637376433623439386564633035
38346436376661333233663334623762646633346530643466336664386134353662363430316438
63393333333034623537303030353136633035353865383366613961373766646463366131623564
34646630666233333834383761363566373935333037633666336261313566613762616531653739
34643162323438646165643433333438656664383232376233306233623539366233633337663565
35323636633533343064376434666435666564666134343839653630326236343262633431326133
36663432396666306631613162643065313135373332303863326234356537366436333938303637
36636334396231316564643733646662376138313637643232373836373632643362383363363530
32363736646162303532356132373337616162636464643164323432623338363463663736373433
34343136646339376132383434623261356163393032306134633665323130623766333738656639
64306632346162396533316431343339366664333335643464386266376464393039633439653837
36303363326239316663346434613336636239653331626661393962356166383339333234376135
653361363631363366323165353538313438

View File

@ -1,111 +0,0 @@
$ANSIBLE_VAULT;1.1;AES256
66313066303030333063353236313063303262626561316535646263633936336534356437353265
3432356362393665303438333166643066666164363861610a643434356531666366393936353233
37353036656435616361613164323038663364666464373964653337396465373061666533373938
6536323936393135370a666134613830306533623365363933376631313534326265666634366235
36623637383636396437333735336238343434353733303764326237303033303562353237353165
31653866633363623764353533356262643239613531643039393335313731383038343638663830
36356139336363343437666230656366636132613531613339353962373435643563313734646135
61613330323938363063313430343738306536636233353963636665393132643162303562666531
61343365326634303730656133633632353936386431303631363731313730666132656334353731
33616537313230666462653165643535386134663166346262363535383365616431613838383863
65326163303966373938653033613238326634393166643630316230613065353437306237313933
65366131396266393236373162343866383565633030356465613461353131643562343630336566
30633534636634616666616462383136373830623137396366626639373230373834316563343464
38303333366166323238346237646165383633383264333431663530326462323432366332333630
62633132666439313034616465663861323064646564303963633565353734353665313138373636
34653639353333373737613238626535356333633833363737646330643163326131386364646365
64356435636635663737376239313236356361363061313731626230366336326535663866373231
37623262613135636538343934336262633662383266653238613965356639626339303437306633
38373837653737313465376231363637353561303937336138343465376638326163643065336462
61633236373737363633646135396565303835643336393763393933613964663435306336346636
38316231383363616533616437366362376664393135623765646330323161366134323263376466
31386332333565643764343863353039313466643962373736643533666562353766383862326134
31633366636365313231366337313334333130373833656135396262373136393135353039623739
63626463636237633963323739303961663632376330336236663134666461383965303861333835
38663337393930383834653936636365663966333033346562356331306430306338333761353762
38363733356262363161353135633836336363376232326261623264623338663230663838386330
35353762393839646338366365313763346339666433306532353530353261363838356639623436
62306437616630663039653862393466353933333763386163373035373335343834663439633039
34613463303436366631396462363866656533343063356265333539353038326637613063326164
62663833363165643436343538666565386561383335393964313839626237623031343564656632
35613534636437306463373466653431336562303132313462326233663561343837323331353035
33303336356237306464363564666136633230396635623066376564373737353335356432343231
66633735316466633039663338316566343739373664316335366462356237366139363731643366
33353039373665333232383235303932623435366638313465396333316565646134343463336330
65306334623631386364353364313638643930306265343363666366663164643435333834376439
64396434366362343733323366343232653930646565313762376436663965626562636238623066
63303236326362323966666630343136336563343564393833636465333832396666396638653661
61323561393563326437386462656266303830353730313839613136656331323938616631386235
30633730303838313038313263363363633136623861326662623366613461343133356261633030
34333732343037396131343764366535343639326333353036353038656533333339306363653435
39656166393265356338656631353065653630303237663761386332323530663966343864663438
65356365386131333236396234623537323062363539383061323832363563326435306465663234
66316638376436613265353662646264666138666165343763393330613765346163356138616633
66373338393163333435666236386239663735653135386532633135646539316665313036323763
38666464363432656534313263306266323066646133353765386463343264633131633936373036
31326138633131393962633861333036373537366163613562383033336333616130636435326331
66653766653065306164613335623933616135393335383438356337633239363131303237653566
62636263383236656136376237646363363234363232643636623333396531363461303538373662
36313537393238626337613964623731666261316366346666323261386661643035353164613637
32303061336363306335306431613263646266303038323739636662326465303961616339333461
65626263366333333562386461636231636438623966626136663932303035343531363234356663
37313661353764343764396666633666613238323638646233353138383638353938303933396431
65366564353533363039383838313562663561633434393833636365303561333534393930653630
63663464613334623864313663383630353166363862373132343532393135313666626464376436
34616566663764363566663530646638363338653538353661393835383035346236646233363564
34656165303737326261353032363435333731363031343366353863313138653865346535636564
31393134336534616161303132353764343833636465356661376638633163643739383830616534
65386262663734356134303039623265303935363764623537326565633030613465666435636232
61623334393734616262613232306339396639643636373762653738333463616361653430656438
63316265303634323033303330353232636136333863366261656532383065313334386335666636
34303564636333356364663565333932343064333266383638663365366636643866353132373966
66336563346233656531643735663062393630616537656264323136353266623161353261333239
33636563376566333331366336353338343730383962653138636535623039643461303763333961
63373264333037653563643937373664373665343136396635316634613632653232353033666266
31333064623765326536386630353435333438326232633565663531303730636530386564366633
63326335333639376266396562343838636430643664303737373565363635643037616231393665
36636337633564373561343266666632656235646662633965663733383731633832373334646335
34396163636635633637393834396566663062633135383330396564656536333330623737636332
36646362623131366166626639386238616566323135323334636638393934663336663532306336
38396634393433623963316261303061616634333566306239366666373238376466633166623464
33313538663838373465626638316432613135386262376233633362616463623363646433353666
32633838303837656335333336353564343461373236353736623032663139333338646463323533
65326131616433666563343163663462393235366135633661366564623662303932626164366632
38306430356238633162656337303536663065653639353562343965663366373861646162653562
62306236326163393336643232663336656637623539353835613536653164393038623966316433
32623462343037616465623736306530633736623061343430356638633530313331306363323837
63396263393136363137643632623938316363386238346237333862303735363065386633366263
31313834646239323631393335633534383930373630663538653864383930666465653731616263
35333830633430343436646266663231303466343138643338343634346133613666613734313037
34383931643631633539346262653631336565623366343564303332333831346436373162356362
66383864313732303962653662333036373239343335623765616536306465623030393138663838
30313861636631393462653836626164373034666533323338383262393132396436666639363262
39356132343939366534666665393231346566663432653236376333323363643166393431316161
33343666316138353333346263346266343731613065356631336231373266343338393939663038
35343235393563623434313266306163323266346662623063353631663433646436613130636663
38356335616438633638383236333131663163613436303934386335363432323063303234383331
34636432653262643438653931313233626462623034346137303738643932353334373531303439
30366233373535343431373365393566383538363763313036623262343066346236303061326631
64376463336538363132656464666365343861393330313637356237666361343666633436346534
33636332386336646333616330613738343264626438613135313962336534373130316330366233
30316333636564326165663565666361643430656366393939616538323530383632636661326331
35366663646533313034333764626237623637363164356163636432653765656439326438383134
62623638633934336334393636333336633164343066336161333138653637333435306230653865
35363032393633623331363933373463623032333361616365373037666333643634343963663835
34363033363731346663643363383965336536353332646262326136353965353137383737336165
33613733656463376333376264633935373239363337323538356636636439393564373332323031
31623733663530326632373235313830396133373430613061613438653336653462316336623438
30343032346133363830656231663966653734326635333831626639393666303033653437326238
65333566643066393331323466366662383135383734313537663664376161323265613436653535
63643832616663303632623433636161333339376635333635626137326662396562633830343337
65376165376564396433343736313134656332383533356138383039386266636238613936653962
32373337346335383136303838343034376432363436356465613836366230313463303239373531
65383334646431346565656638353537333765623430333133663663326134646566306137643663
65643338386439666636376461356466396261326165333030623633613364343631343830653939
64323266626131666332666433386434313936306361633164373532626231366234623735333932
62306362346164336433336139313561366162303666353635653634396139313734626463663735
38306466626237626634666138363665326636316563356431333432313534363638613833613539
38306237353764376462323238663034646662393433623830616361623735343162666465626230
30633731323939633265323338373537383261333235303262633336636433316339383433653861
3861653261646632636364623830626561393864666135346634

View File

@ -1,49 +0,0 @@
$ANSIBLE_VAULT;1.1;AES256
30313139316131383630353236343338323465653163323838616464396137656365393639613766
3733323562386139353933626339663039653437363037350a356263643762313634613736356363
30383534346664353030346233653163616330376562346164613731346566393330623165306234
3833306632616536650a386239363931326463663665346363313462646464646632643961343631
63393164366163353461633038653833623963363233396464663839653330386231303461636564
39613265343765323636373736646462333665303333373737633632346465343439386335623334
35333933363966623730643632313361356661303562393535646230626639363335623861323033
32356664663539343262336535623233326234356463373031356361633536366430346338393831
34666232373761643430356662653431646661646165663134633135663933616262393763356133
61323063383036313166643866303136656164386239326437303238623338306433633762303630
39396438396639666433376533333765313431383862383031333031616334656136643262636438
65626565333939616631336237633063396430376434626437313666646165333239376463383837
64656635343661353735666666306134653530303033326662613230663061613034383461326534
65306131326634643732326530336136623731663336656138383635383730653633373737386335
31316136643634613536366439393565633964643735333336613865366138396539663534646435
61626530353836366337643062366532323538326161633137353336626537633739393464646632
32343730356362393336313535303034363531373961616265623934393161306261663562653464
63336164366531636130343939353235343261316534613665316363346266396332633763346536
65633038366530356138373661306234316161343762343638366639653132333438613766343939
61316232386465643236326430396130333831666363313032623537383032646663396239663338
38313939306465353033663066633435626635353138336330336333616231363634653665386532
65326463663933343966356437353433313565316139366365323934643131346636323737626437
36343435643231366663323134656561666133303030383734316237386532396662366461646365
38303434363763363866383761386535383262323432333730323236353439653163613966333032
39306533333132373736313834326464643134393432303537643835336438393461663233333239
32333365663337653436303662393263366161326465663036373934373764363438656436666232
32326134393161656133613266633966396663353631616537363361396537623164373964636666
61613731306333303336316337343635316134363431646433333932633336363065393637343030
39366537656430663932616335323661316533643763643161613463646363656232346333303331
38363234333261653135316266313736366439343138666165366533353035613731633466396363
31663166336431653461663463383333623664356365396230353130386138363261356331663965
66636338336466366132633437396535643736333733633430373964343533366338666532346263
38353233303437663339616532636662373761393461666439663133373633653139613531393738
32383937373833323938356333343963306534633734393162363965356163643862643037636231
65366461663161353939633866323162613761663836626232346236343263386364303233313161
32313265366562313731656630393166336662616661313964666661616439343265383566383332
33386266366534383934363839636636316532613133636664323136373130363534333531613663
35333964626634643135663639373339626335643366333766386631363439393435626439636166
37616339313336656634393538323935383964343437646433636636383061366437386330643334
34383237353036396563643730373663383165623633326336313031326435623538376130393130
64636538663963303938623866626431313238646465633437333863363865666435636564323764
39303638663830656162393836366262663161633763656630663434386435643462353661353035
63336461333464363838313765653037393964633536636435666162346461633561386364333966
32623761373435366665363239626632646364323934383163346637356562653332373536343462
31323036356132373930656364393061306130353632623661663032343230633635336664376134
38363239396139333230346138386337313364353934396362373233376266383537346431653234
34323835306165613739383336303964656565373636343639303831386466623031396665343234
33373164663339653839

27
host_vars/web21 Normal file
View File

@ -0,0 +1,27 @@
$ANSIBLE_VAULT;1.1;AES256
38663333313561616264323430323162323837623430363739623561633331656664613936666665
6364373033623163393239663035306337383066343438310a383666313434323036643037363065
30396333626130303633663930663965666662646233393439376661346265616565616236623366
3930373433646231610a336233663132306263656465633034333030316362643939316465666534
38353961393038613961353732613434663565633466303265383231343336386330333464376363
33616330643364376332623634363766656366666239633964316439376463313063333162343963
61356634393438313063666434626338616264613639656462626639616263366531663135393466
66346635616439306364356133303664376134626636616131373138656562363363306633333164
62623135343633393834393165383231316562643062343165663235313930663039623135373263
61343336643235303962333938613230356465346436376334373438386461366231383737643137
36343832353730366131653430633465383163396336353065306638373166386438356264616139
65346635663338366463343932336231386235393836616238373864626235623935663661396663
31633565356465333737303339333435383162316530396563333335613062623138333232336162
62376363666431363931663231643561616562383230643737393261623934363633313231333137
39383238656237343661626662366465356463396336386261326334613436396364633062646532
61313136366636363861316166396134316562666435653437326331363563653035343138636163
66336139636533656334643966383962383734623565323435333665666164353732663736326364
35616264383237316330386539363065376334643432393636643464646238633034333166663665
33313166393738626133636136346637646437306335326263393634363133663736666338313838
64623139613037653461643563666539613237323934376534376461313833336338623032616661
64643062663633366436383232366137373936383430306332616634636331326361383931363961
62313236313563326438303935373837666434313435653236643135303739373763656562393537
31653265653739346433663937343439656231663963333633373066356231623762313438393763
36306336656566633034373834316363333233326130626639313130643935333437653934313636
32383034346234333561333466653561323834346166633831303566376266373933356536383031
6236303934323963336662386666653138313165366133303434

138
host_vars/web22 Normal file
View File

@ -0,0 +1,138 @@
$ANSIBLE_VAULT;1.1;AES256
65343136316335383839326463313466616564633339336561333461363664643437353934333766
6434613431626537643266623333633633393031353333340a316664323433653235343433366631
38356463643933623637656165316333663432306336353332353539396565336537343961383563
3730393237376165390a323537303738383863393061626633623165653335333164613364343462
30316530353036633531663961623463626464316131623437333134666561373065633034333736
37653735343131613735353136383232616539663831633739326631633538393834303664396564
34343739333166333731326434366131383337313035646363613035633038393963313732636432
31363032623533323338353436383039663430343836373633626334376363616130353737323761
64323739613036303834303236646238633335396534623761336661663936643166356665663634
61323235373262653163663832626133306263653530366463636563386263333665646264646161
32383766393632633061626233333464353132366132303232613465666633313064363361636131
62353462343231373366643765326364313834343966363837393130616138613538326635396562
32663335633935643633366437333235353531623135393331336237356536396630353438303030
39663762366463316131313162313264316134616634303963303163656562303235356131373365
62393435303731666263333161646437383131633663386564653732353166373562396466633766
62323731623637326230306534336465396165643564343064303565343030666238643036646339
65383830613761623935356438643032333565393665653262333931316139356535323033633465
62353063326630363666323832383865653761343732313361353935376236366632383934366336
37666461623166306230373735353233386432626632363037643166363465303938343037666266
62373831636338386139643231333639623561653664646438396439353139396435303334376538
36393833306138363765656431313161393762646665656632633065393131396631613464626334
30373266326264366335353838356530626532646532303263366139393566343866653166313832
64323331376565326263313464356265323561373562666666653465353139303063383736613662
32343963663161356265303132343534323333633639303461336331343536333430303738383661
65313832343062373931373765323338313239653861346263343866396563616463383461306262
32323862363064633166343531616135323839333637376638366162653133626266326231383064
36633963623136646136376663643138613432643039653637633535373763666235323732326539
65616265653931323330623764316466343332333666373363633634386135613764346531653661
38376637663734343863366339313431633134303432323336613263316335616364376566353631
62383437353939663834306265636565326233353262343532633363383336663531646239646139
63653632316365666662653561626135646464316263316134643530393233646636383066326533
64656337343231616537333533373962383466643761643337646565616462326235353236323162
63376631386261343066623330626532303461663934613361643437383937623038356432666131
36643262396433623633303961393239613839306465656335643831613963326262636561656330
37653836383737373738373639653235613230376464323062313336383764633438646238393430
32303131376363353333313262323338653461623835376562393736333263656536373435613132
32656139363431386163346262636562333037346632656436313464356431623562373139643531
62366466323332633530353333616630343734306263613231303538633061383739663761363230
37353565633963373235373366363535646661396331333638333533636537336666656465373864
37313935346561633030383737353062316337623233636130376333653364386632313738346637
39656234376535373361333866313163333166363632633138363337383163356263343063666534
66626661636330653233376239303334346563346433393135316231616130343232376430346162
32303031626666323930333366306531343161323437626361323632643439353935646336346132
63356264363566303262653565653837363035663564303135653966333466386262306437646638
30306537346564306633653735303835313434396439353730313030363431353733366337336533
65373030613565343265663566363066643135353961393638646539326635663763626332373534
66653230316332663165613937316531643065383730313739313730653931613930376263363539
38356330303333323438396561396530363537323865366238353964303331653330626539613933
32316661323039666661323963383738356435396135363032616536356532353630656536613161
61353737323135353062653365366330386532656363643533316163616437336131376365633633
66656137333463373330646334623531356361373335316538656239366239333165316637643439
62373562303839383036646661656635646139643962303237313330356165353936623834646230
34343265356464356330663038343033356138366134616331643031666633356432633337653930
36663733643064376232633265326137643965366438343336383735313638393338656139393033
31343835663837376430666638323165353763316564396630666336666163313533666431626566
61636165333831393962663731346665353736303630613932333165366563303933326633306236
37643166353065633530326238643236313631333630613663393062623537306235373332373230
64363266613366613932363836633530386630643564646365613465613863356132383639383930
38376538623665653437323539353562613163333234383331366236626339656463646162326434
30616236383237616139313064363664313561323166613334386339346538356165653231373065
63613435333734666335396337653437643034353266623635356261326135336130383633383033
66623735623162326365626130376564326365646636666464373737636664336136363162396636
33373366636132346336643065383431666263356265336532393335666365653864636165656334
63336437613733396430386337656433643038666662386166666437326537353739613735386261
30393362363461353132386630376463316665383138363939613634373637346136396234396461
64663064656565313730646666353132663965363731666537616266383934653165636436363062
64386638623936303061356335333266366335653235313166633063306636343531313038616335
62626363643537643030643761306230383034666232373538633065613136613932633064656535
33653466613565376137613732393361336232353435633634366235343138383038303462623532
62336439303561393030366135343164363165323436383262333935383035316534653439663437
63343166326364613835333239316139653836666634383535616433363539323464363732663039
62396532393863633739663061613762313865323465363562326231393638313235376161363131
64636266616462633334316236393262373461643266633131383831306539633735383839643665
63343738343535303365656630623066393365656362306363373730303839383034323166616662
36663438636665663235333364373538343763323335353530636635373935333535383663613966
62626361383536306464626134313432623038356336343538393439323231643266626263343761
62363665386139326634343264663737353063306234666437323139386563313839376364343637
62653765356132343430623464333161316436306238303134346638663763323932306663326433
62326336626366633565373732303032663138626430346239633834393761346232356134356534
31323261336266373533623538383234333235656133666232323862383031346266366438393065
61366238653737636135303134396132373565633561643137613737353234393739333762626564
62386535626331303562623535643461646434396335383436353939666135343933323266363938
39326432333839393934653936303964316261326132323030663235363430303735633965626562
65633266353338303030363862376261323232366262656165373161303734663335386639363865
64363238623964376439383032393831396130643263626131383162386565643263623439326431
66376561666134653738636538653462373537353863336265353733356461623261343766636338
33646666373337666463626333343963643865613566396235373935346436353034616237666331
36643936633732373631303235316230633334656530363761643862343466613636666462393939
39633961346537613634623061353437363464626237643730303334616464633535346632343463
36613164366533346465653435613165613436656661613537613430353730336265393330316432
65356232356538383933356536383563363732616465356532386336616633646363643165623234
33663137623433363463333435373435613337306561393536623965626662646463616664646464
35343363336365393937303265386464623562366232353434613632613934313133376466626639
33386634346466353238313936353534356534316436326664616536316164323563613961643061
33343162643037316438666161306664316635666335333036333861323134343638333465626335
34333262303161643534666261363032643065393832343864656237663439623230633766353633
36353862663239656333383561633830343932343361613365343461653735346164343434646137
37343638316464333932626463633433323261636436666134633365383962366138306563636461
37363339646665393534383735383338376661343264303036306230333030626133383231633332
30346133393863613133353165346439623534626361643534396339303865336239383834373432
39626463396632346164363734386337316164333338623832616538353631396535653961626665
64333134363539646266343134366432306166643561396436316364333939373431383662656237
34663665616266626261616163363831383534323161353361363634373764616233323364396638
38653335386466643233663133633339323965343661633033636165363936376631333537613035
64653533353533323865643066646263376539623463636664383866303733306462383265666534
65633665383664306432346264666532306138326630376436396434643033643336653562346330
39636138643733343262653761333430623333643664663763313734396634366462303763616139
35656237306637346133303839313137663137353236373465343539363664383861663831656137
63633635643038663464333863643731333263326137623662366362323934323366616166313739
37373461306636663761313235316436653862373238313630396635316261326665366631346566
38303738616236303639333833373762366138653836306461633738663234623361656233653630
62663939626332646163333261323032373134363631383162653863316330396339343534353766
62326334346565343034313766386338633831343739613931366433613239646239313533666163
61393366386434353734316334623635613466653736633932383634313233346438313565383738
35643461316536363534326338396131333734383561313036366131663932623066366365343864
36316265633432633361326635663262643962346433633537383761623663373435303362623464
30396461666535363339666536306566366661656135633137643161663539373365326463343535
63373764383966653735663530376230346437613230656232666165343734376563616434613563
61356334386238383861643363376638626366336134373838376633323639306537343037376630
61333635343132646664366235376332613365613238303531353964316438396564383262303564
39626365623464363432333364373635313064623334333839336533306131656166333464343131
37663335633139656330616662636439313361306232326634366436323436363936663566636662
38666363623738313462313566643864613435393530643731653638613566666531373337656134
66636530393433613061303366353564376533623334386463343332323232663462383036636361
39613231306333646662303236323963663363643262636432393932396564353361616237636261
36366264626632396133356530616633326435626436353839616134323037636534633464313536
62653564306163366430373066653030363938626139353633623162356666326531666333373936
65316338343535373835333334386630326463323739366533623830376661666335663434626535
35656132633164636435356335366663646239656461633138656166366630653364616235663336
32386533306561343161623739346563376633343734643161626237666337623462633165633733
34346533653938653234613433333536343465653339633263326363386137373931306132636265
31363036633664313131343939383434343763653664623466386465353666313464323036383937
63323333663063303332323134386338666461656165623464303034306666396239353637366665
39636366356465666135336437303161333261666638346130343235396534313163333564306263
33656336656664636533346434653433633436386566653163366236653539623634663165316131
30366161316639343230633966666137356266383935306435373332376638386532343130633762
3034

67
host_vars/web23 Normal file
View File

@ -0,0 +1,67 @@
$ANSIBLE_VAULT;1.1;AES256
64326662336532386161646564656439396461666266656463393335663130323930326139386562
3639653630336132663666646161363938386334323064320a663564613066313533353433333434
30346561616465646163646534356339666639333862623637613435376361323032636439633930
3731313063363337380a373961353530383764623830363935626231333734303364313565626633
37343037633862633632613165323136373662396438613663636433346566653064653632313338
36396333393334336434326630646164333531306432386133353664336535343363343939393464
34626335626436353239366138323863656336636536383733363931633933636331643263653566
30613931616462373336393337363430353962613665353936383533326364353365623333316664
62383439396131303831326562323264336638623461643361663763356236373464346464316237
65393232343733643338653734326562626166366562303037613862396564636662363066356664
32656363616637303039373732396533643432343961666365313963383131643464333765643737
32386165666131626365313938633530346361383734323334613464353862393931323836626563
62656531346532646530306463653364326362613162323536643836643839663933343132613435
63303234646335306632316166626266313635303566396363333464363631353834373761353837
65643461623135363139646564336430353461336433633765303138313730613630346465326666
61393133636262653836333664623333656164663361353130623863653863323131326136373238
33376333316433653337373834666136363130373261333330643439313734343036636364306532
63343662383539633235356162656366323965383331343139616361653466633865626337326562
63643761613536613334333065643533323066393764633931633066353064393966646161376361
37623939386636346161346164303832303534323038626335336665653634386132343031303861
61323765306366333936303765636436633465356539316631343562363535663932333666363035
30386233623265636464393662386464333430396337626230306438396563303437363938303061
32653939383136376365343934613339383563303935623664633639326137353437363261393637
66613331643530623862636665396536613730306537373666623135663837393466343261646461
62376162613861643633656334303132353034333834626664666237393534386439313638393933
35643663613432323432646466386434363335353234643264643463613334356462313766643030
30336364396235663230356235303264323339643761333036333537633862343862386130626533
36626536396663393031303533313238616133323239356634303830353439363133353839663266
36306539636563633734623162356230383232306138393831393336626336383966643335376564
36303730313936633361643736613736303163363536313038316432323039643362636538333037
65613663333032623035656665393565366363396134363832363163656532363537373435623233
36373961333237373264326634353363356537356538343663613034396132396366626330303365
62353461616434343938386237373365633861333733613631633234623034366364363761613636
34393532316466323264363363653335366639613731326131393335313039646538626665356333
62663435633539643237326631636563363833633130363535653336333538366137306235663730
36633934636536633865376262356239303966646638626638386536366662386432343466366161
36646436636538643366623864326630396565373462393132343834626638313437316137353564
34646138616438323065336266366434316135613938643131353034646230396632386433366365
38616436346232363563336439613939313464323861616530633962316634363462373530613665
63653636646565303664326631363535373037663734663965346430363831613431613365393832
62373030336262643430313635626261613232656236333130396537633238623265363932333966
34326135363762396564613064323135313663613565646461376162306532643433333336666532
65383661303137613335653336663666653463623565386137326662653839633536326135633764
33623437333931393737363061356235336232376437643131373531356566323336306138353561
66333863313461613930383231663162616261616639323238646439656166666261626533636161
38333362393033316266633364313739366262636530363937386137616234326638303137613433
65313962653566333364383732386165396136303666383439303064326463346563663434646364
62396130646632653039383661613638303162363538376236666338623865366639663138363636
36373766386234383465316635323931356233366262386135363238366538623135623361386436
64653533646233653463656334633566373433303365353965663732636566663332343337626337
34623861373562386264346430333133343631653631376366373735626664363965666561306262
35666235653235346233636361383566616533646662333662323139313865383264633734643263
63656431393834633935613430643839613433326431666665323136376562333737383862313261
65656431336439303563373833343965323965346439636131633366633431393032613963666539
38326539343132326334316233323362633835356265333031663066643535363639623031336362
64346230383638363763323462386261666266623134393139303264343234623132323437396630
66363738376133393731616535653230303262313937373333353932303038626166346366303163
66613831353731373165636532363165356561383137626437333563616561386666623234313438
37333435306530323235393164383138346131653235633536383636316161316238313064636261
33353963333430383236303038333939316637326130396430623964633338353863613534653663
30333839393230626261663966616230303330636335323565663938343562666663303536636332
34336665323764663163653161373166313631393534326532613538313637313136356336313433
34353036653738343433613763383137336562373332333062326134626638633938336364376131
61303435333163663636653135363162303663663266393438656430306532343438386436343735
31343231653263373532386263653263386435363633396638396164323539306233303562303862
3339306136613431636138333266633739323666633431363039

View File

@ -13,13 +13,13 @@
- hosts: all
user: provisioning
become: yes
become: true
vars_files:
- "../vars/{{ ansible_distribution }}.yml"
tasks:
- name: Set password, shell, homedir for provisioning user
when: provisioning_user is defined
user: name={{ provisioning_user.name }} password={{ provisioning_user.password }} shell={{ provisioning_user.shell }} state={{ provisioning_user.state }} createhome=no
user: name={{ provisioning_user.name }} password={{ provisioning_user.password }} shell={{ provisioning_user.shell }} state={{ provisioning_user.state }} createhome=false
# vim: set sw=2 ts=2:

View File

@ -2,7 +2,7 @@
# file: nomads.yml
- hosts: nomads
become: yes
become: true
roles:
- common
- munin

View File

@ -0,0 +1,11 @@
---
# file: roles/caddy/defaults/main.yml
# parent directory of vhost document roots
caddy_root_prefix: /var/www
# Email address to use for the ACME account managing the site's certificates.
# Not sure what Caddy does if this doesn't exist.
caddy_email: foo@example.com
# vim: set ts=2 sw=2:

View File

@ -0,0 +1,10 @@
---
# file: roles/caddy/handlers/main.yml
# I'm currently not sure when we need to restart versus reload
- name: reload caddy
ansible.builtin.systemd:
name: caddy
state: reloaded
# vim: set sw=2 ts=2:

View File

@ -0,0 +1,81 @@
---
# file: roles/caddy/tasks/main.yml
#
# Configure Caddy.
- name: Check Caddy package signing key
ansible.builtin.stat:
path: /etc/apt/keyrings/caddy-stable-archive-keyring.key
register: caddy_signing_key_stat
tags:
- packages
- caddy
# See: https://caddyserver.com/docs/install#debian-ubuntu-raspbian
- name: Download Caddy package signing key
ansible.builtin.get_url:
url: https://dl.cloudsmith.io/public/caddy/stable/gpg.key
dest: /etc/apt/keyrings/caddy-stable-archive-keyring.key
owner: root
group: root
mode: "0644"
register: download_caddy_signing_key
when: not caddy_signing_key_stat.stat.exists
tags:
- packages
- caddy
- name: Add Caddy stable repo
ansible.builtin.apt_repository:
repo: deb [signed-by=/etc/apt/keyrings/caddy-stable-archive-keyring.key] https://dl.cloudsmith.io/public/caddy/stable/deb/debian any-version main
filename: caddy-stable
state: present
register: add_caddy_apt_repository
tags:
- packages
- caddy
- name: Update apt cache
ansible.builtin.apt: # noqa no-handler
update_cache: true
when: (download_caddy_signing_key.status_code is defined and download_caddy_signing_key.status_code == 200) or add_caddy_apt_repository is changed
tags:
- packages
- caddy
- name: Install Caddy
ansible.builtin.apt:
name: caddy
state: present
install_recommends: false
cache_valid_time: 3600
tags:
- caddy
- packages
- name: Create Caddyfile
ansible.builtin.template:
src: etc/caddy/Caddyfile.j2
dest: /etc/caddy/Caddyfile
mode: "0755"
owner: root
group: root
notify:
- reload caddy
tags: caddy
- name: Create Caddy conf.d directory
ansible.builtin.file:
path: /etc/caddy/conf.d
state: directory
mode: "0755"
owner: root
group: root
# TODO: the variable is still named nginx_vhosts
- name: Configure Caddy virtual hosts
ansible.builtin.include_tasks: vhosts.yml
when: nginx_vhosts is defined
tags: caddy
# vim: set sw=2 ts=2:

View File

@ -0,0 +1,14 @@
---
- name: Configure vhosts
ansible.builtin.template:
src: etc/caddy/conf.d/vhost.j2
dest: /etc/caddy/conf.d/{{ item.domain_name }}
mode: "0644"
owner: root
group: root
loop: "{{ nginx_vhosts }}"
notify:
- reload caddy
tags: caddy
# vim: set ts=2 sw=2:

View File

@ -0,0 +1,29 @@
# Global options
{
email {{ caddy_email }}
}
# Common security response headers
(security-headers) {
header {
# disable Google FLoC tracking
Permissions-Policy interest-cohort=()
# enable HSTS
Strict-Transport-Security max-age=31536000
# disable clients from sniffing the media type
X-Content-Type-Options nosniff
# clickjacking protection: refuse to allow rendering this page
# in a frame, iframe, etc.
X-Frame-Options DENY
# keep referrer data off of HTTP connections
Referrer-Policy no-referrer-when-downgrade
}
}
# Import additional caddy config files in /etc/caddy/conf.d/
# Note: these are imported in lexical sort order!
import /etc/caddy/conf.d/*

View File

@ -0,0 +1,35 @@
{{ ansible_managed | comment }}
{# helper variables and per-site defaults that we can't set in role defaults #}
{% set domain_name = item.domain_name %}
{% set domain_aliases = item.domain_aliases | default("") %}
{# assume optional features are off unless a vhost explicitly sets them #}
{% set has_wordpress = item.has_wordpress | default(false) %}
{% set needs_php = item.needs_php | default(false) %}
{% set has_gitea = item.has_gitea | default(false) %}
{% set static_site = item.static_site | default(false) %}
{% if domain_aliases %}
{# domain_aliases is a string, so we split on space #}
{% for domain in domain_aliases | split (' ') %}
{{ domain }} {
redir https://{{domain_name}}{uri}
}
{% endfor %}
{% endif %}
{{ domain_name }} {
{% if has_gitea %}
reverse_proxy :3000
{% endif %}
{% if static_site -%}
root * {{ item.document_root }}
encode zstd gzip
file_server
{% endif %}
import security-headers
}

View File

@ -1,11 +1,17 @@
---
#file - roles/common/defaults/main.yml
# add a dummy API key for AbuseIPDB.com (override with real one in host_vars)
abuseipdb_api_key: dummy
fail2ban_maxretry: 6
# 1 hour in seconds
fail2ban_findtime: 3600
# 2 weeks in seconds
fail2ban_bantime: 1209600
fail2ban_ignoreip: 127.0.0.1/8,172.26.0.0/16,192.168.5.0/24
fail2ban_ignoreip: 127.0.0.1/8 172.26.0.0/16 192.168.5.0/24
# Disable SSH passwords. Must use SSH keys. This is OK because we add the keys
# before re-configuring the SSH daemon to disable passwords.
ssh_password_authentication: disabled
# vim: set ts=2 sw=2:

View File

@ -1,2 +0,0 @@
[Journal]
Storage=persistent

View File

@ -0,0 +1,5 @@
#!/usr/sbin/nft -f
define ABUSECH_IPV4 = {
192.168.254.254
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,5 @@
#!/usr/sbin/nft -f
define ABUSEIPDB_IPV6 = {
fd21:3523:74e0:7301::
}

File diff suppressed because it is too large Load Diff

View File

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<ipset type="hash:ip">
<option name="family" value="inet6" />
<short>abusers-ipv6</short>
<description>A list of abusive IPv6 addresses.</description>
<entry>2001:41d0:1:f934::1</entry>
<entry>2001:41d0:602:238d::</entry>
<entry>2001:41d0:a:2a31::</entry>
<entry>2400:6180:0:d1::476:7001</entry>
<entry>2402:1f00:8001:8bd::</entry>
<entry>2604:a880:800:10::5bf:2001</entry>
<entry>2a00:d680:20:50::bcb2</entry>
<entry>2a02:2168:a01:33ee::1</entry>
</ipset>

View File

@ -0,0 +1,89 @@
#!/usr/bin/perl
#
# aggregate-cidr-addresses - combine a list of CIDR address blocks
# Copyright (C) 2001,2007 Mark Suter <suter@zwitterion.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see L<http://www.gnu.org/licenses/>.
#
# [MJS 22 Oct 2001] Aggregate CIDR addresses
# [MJS 9 Oct 2007] Overlap idea from Anthony Ledesma at theplanet dot com.
# [MJS 16 Feb 2012] Prompted to clarify license by Alexander Talos-Zens - at at univie dot ac dot at
# [MJS 21 Feb 2012] IPv6 fixes by Alexander Talos-Zens
# [MJS 21 Feb 2012] Split ranges into prefixes (fixes a 10+ year old bug)
use strict;
use warnings;
use English qw( -no_match_vars );
use Net::IP;
## Read in all the IP addresses
my @addrs = map { Net::IP->new($_) or die "$PROGRAM_NAME: Not an IP: \"$_\"."; }
map { / \A \s* (.+?) \s* \Z /msix and $1; } <>;
## Split any ranges into prefixes
@addrs = map {
defined $_->prefixlen ? $_ : map { Net::IP->new($_) }
$_->find_prefixes
} @addrs;
## Sort the IP addresses
@addrs = sort { $a->version <=> $b->version or $a->bincomp( 'lt', $b ) ? -1 : $a->bincomp( 'gt', $b ) ? 1 : 0 } @addrs;
## Handle overlaps
my $count = 0;
my $current = $addrs[0];
foreach my $next ( @addrs[ 1 .. $#addrs ] ) {
my $r = $current->overlaps($next);
if ( $current->version != $next->version or $r == $IP_NO_OVERLAP ) {
$current = $next;
$count++;
}
elsif ( $r == $IP_A_IN_B_OVERLAP ) {
$current = $next;
splice @addrs, $count, 1;
}
elsif ( $r == $IP_B_IN_A_OVERLAP or $r == $IP_IDENTICAL ) {
splice @addrs, $count + 1, 1;
}
else {
die "$PROGRAM_NAME: internal error - overlaps() returned an unexpected value!\n";
}
}
## Keep aggregating until we don't change anything
my $change = 1;
while ($change) {
$change = 0;
my @new_addrs = ();
$current = $addrs[0];
foreach my $next ( @addrs[ 1 .. $#addrs ] ) {
if ( my $total = $current->aggregate($next) ) {
$current = $total;
$change = 1;
}
else {
push @new_addrs, $current;
$current = $next;
}
}
push @new_addrs, $current;
@addrs = @new_addrs;
}
## Print out the IP addresses
foreach (@addrs) {
print $_->prefix(), "\n";
}
# $Id: aggregate-cidr-addresses,v 1.9 2012/02/21 10:14:22 suter Exp suter $

View File

@ -0,0 +1,5 @@
#!/usr/sbin/nft -f
define SPAMHAUS_IPV4 = {
192.168.254.254/32
}

View File

@ -0,0 +1,5 @@
#!/usr/sbin/nft -f
define SPAMHAUS_IPV6 = {
fd21:3523:74e0:7301::/64
}

View File

@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHmRO6E0G4Ls3TifVfJ+mQjlfWiBZNJfsSXGhwQ/HA1M aorth@balozi

View File

@ -0,0 +1,27 @@
[Unit]
Description=Update Abuse.ch SSL Blacklist IPs
# This service will fail if nftables is not running so we use Requires to make
# sure that nftables is started.
Requires=nftables.service
# Make sure the network is up and nftables is started
After=network-online.target nftables.service
Wants=network-online.target update-abusech-nftables.timer
[Service]
# https://www.ctrl.blog/entry/systemd-service-hardening.html
# Doesn't need access to /home or /root
ProtectHome=true
# Possibly only works on Ubuntu 18.04+
ProtectKernelTunables=true
ProtectSystem=full
# Newer systemd can use ReadWritePaths to list files, but this works everywhere
ReadWriteDirectories=/etc/nftables
PrivateTmp=true
WorkingDirectory=/var/tmp
SyslogIdentifier=update-abusech-nftables
ExecStart=/usr/bin/flock -x update-abusech-nftables.lck \
/usr/local/bin/update-abusech-nftables.sh
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,63 @@
#!/usr/bin/env bash
#
# update-abuseipdb-nftables.sh v0.0.1
#
# Download IP addresses seen using a blacklisted SSL certificate and load them
# into nftables sets. As of 2021-07-28 these appear to only be IPv4.
#
# See: https://sslbl.abuse.ch/blacklist
#
# Copyright (C) 2021 Alan Orth
#
# SPDX-License-Identifier: GPL-3.0-only
# Exit on first error
set -o errexit
abusech_ipv4_set_path=/etc/nftables/abusech-ipv4.nft
abusech_list_temp=$(mktemp)
echo "Downloading Abuse.sh SSL Blacklist IPs"
abusech_response=$(curl -s -G -w "%{http_code}\n" https://sslbl.abuse.ch/blacklist/sslipblacklist.txt --output "$abusech_list_temp")
if [[ $abusech_response -ne 200 ]]; then
echo "Abuse.ch responded: HTTP $abusech_response"
exit 1
fi
if [[ -f "$abusech_list_temp" ]]; then
echo "Processing IPv4 list"
abusech_ipv4_list_temp=$(mktemp)
abusech_ipv4_set_temp=$(mktemp)
# Remove comments, DOS carriage returns, and IPv6 addresses (even though
# Abuse.ch seems to only have IPv4 addresses, let's not break our shit on
# that assumption some time down the line).
sed -e '/#/d' -e 's/ //' -e '/:/d' "$abusech_list_temp" > "$abusech_ipv4_list_temp"
echo "Building abusech-ipv4 set"
cat << NFT_HEAD > "$abusech_ipv4_set_temp"
#!/usr/sbin/nft -f
define ABUSECH_IPV4 = {
NFT_HEAD
while read -r network; do
# nftables doesn't mind if the last element in the set has a trailing
# comma so we don't need to do anything special here.
echo "$network," >> "$abusech_ipv4_set_temp"
done < $abusech_ipv4_list_temp
echo "}" >> "$abusech_ipv4_set_temp"
install -m 0600 "$abusech_ipv4_set_temp" "$abusech_ipv4_set_path"
rm -f "$abusech_list_temp" "$abusech_ipv4_list_temp" "$abusech_ipv4_set_temp"
fi
echo "Reloading nftables"
# The abusech nftables sets are included by nftables.conf
/usr/sbin/nft -f /etc/nftables.conf

View File

@ -0,0 +1,12 @@
[Unit]
Description=Update Abuse.ch SSL Blacklist IPs
[Timer]
# Once a day at midnight
OnCalendar=*-*-* 00:00:00
# Add a random delay of 03600 seconds
RandomizedDelaySec=3600
Persistent=true
[Install]
WantedBy=timers.target

View File

@ -0,0 +1,27 @@
[Unit]
Description=Update Spamhaus lists
# This service will fail if nftables is not running so we use Requires to make
# sure that nftables is started.
Requires=nftables.service
# Make sure the network is up and nftables is started
After=network-online.target nftables.service
Wants=network-online.target update-spamhaus-nftables.timer
[Service]
# https://www.ctrl.blog/entry/systemd-service-hardening.html
# Doesn't need access to /home or /root
ProtectHome=true
# Possibly only works on Ubuntu 18.04+
ProtectKernelTunables=true
ProtectSystem=full
# Newer systemd can use ReadWritePaths to list files, but this works everywhere
ReadWriteDirectories=/etc/nftables
PrivateTmp=true
WorkingDirectory=/var/tmp
SyslogIdentifier=update-spamhaus-nftables
ExecStart=/usr/bin/flock -x update-spamhaus-nftables.lck \
/usr/local/bin/update-spamhaus-nftables.sh
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,91 @@
#!/usr/bin/env bash
#
# update-spamhaus-nftables.sh v0.0.1
#
# Download Spamhaus DROP lists and load them into nftables sets.
#
# See: https://www.spamhaus.org/drop/
#
# Copyright (C) 2021 Alan Orth
#
# SPDX-License-Identifier: GPL-3.0-only
# Exit on first error
set -o errexit
spamhaus_ipv4_set_path=/etc/nftables/spamhaus-ipv4.nft
spamhaus_ipv6_set_path=/etc/nftables/spamhaus-ipv6.nft
function download() {
echo "Downloading $1"
wget -q -O - "https://www.spamhaus.org/drop/$1" > "$1"
}
download drop.txt
download edrop.txt
download dropv6.txt
if [[ -f "drop.txt" && -f "edrop.txt" ]]; then
echo "Processing IPv4 DROP lists"
spamhaus_ipv4_list_temp=$(mktemp)
spamhaus_ipv4_set_temp=$(mktemp)
# Extract all networks from drop.txt and edrop.txt, skipping blank lines and
# comments. Use aggregate-cidr-addresses.pl to merge overlapping IPv4 CIDR
# ranges to work around a firewalld bug.
#
# See: https://bugzilla.redhat.com/show_bug.cgi?id=1836571
cat drop.txt edrop.txt | sed -e '/^$/d' -e '/^;.*/d' -e 's/[[:space:]];[[:space:]].*//' | aggregate-cidr-addresses.pl > "$spamhaus_ipv4_list_temp"
echo "Building spamhaus-ipv4 set"
cat << NFT_HEAD > "$spamhaus_ipv4_set_temp"
#!/usr/sbin/nft -f
define SPAMHAUS_IPV4 = {
NFT_HEAD
while read -r network; do
# nftables doesn't mind if the last element in the set has a trailing
# comma so we don't need to do anything special here.
echo "$network," >> "$spamhaus_ipv4_set_temp"
done < $spamhaus_ipv4_list_temp
echo "}" >> "$spamhaus_ipv4_set_temp"
install -m 0600 "$spamhaus_ipv4_set_temp" "$spamhaus_ipv4_set_path"
rm -f "$spamhaus_ipv4_list_temp" "$spamhaus_ipv4_set_temp"
fi
if [[ -f "dropv6.txt" ]]; then
echo "Processing IPv6 DROP lists"
spamhaus_ipv6_list_temp=$(mktemp)
spamhaus_ipv6_set_temp=$(mktemp)
sed -e '/^$/d' -e '/^;.*/d' -e 's/[[:space:]];[[:space:]].*//' dropv6.txt > "$spamhaus_ipv6_list_temp"
echo "Building spamhaus-ipv6 set"
cat << NFT_HEAD > "$spamhaus_ipv6_set_temp"
#!/usr/sbin/nft -f
define SPAMHAUS_IPV6 = {
NFT_HEAD
while read -r network; do
echo "$network," >> "$spamhaus_ipv6_set_temp"
done < $spamhaus_ipv6_list_temp
echo "}" >> "$spamhaus_ipv6_set_temp"
install -m 0600 "$spamhaus_ipv6_set_temp" "$spamhaus_ipv6_set_path"
rm -f "$spamhaus_ipv6_list_temp" "$spamhaus_ipv6_set_temp"
fi
echo "Reloading nftables"
# The spamhaus nftables sets are included by nftables.conf
/usr/sbin/nft -f /etc/nftables.conf
rm -v drop.txt edrop.txt dropv6.txt

View File

@ -0,0 +1,12 @@
[Unit]
Description=Update Spamhaus lists
[Timer]
# Once a day at midnight
OnCalendar=*-*-* 00:00:00
# Add a random delay of 03600 seconds
RandomizedDelaySec=3600
Persistent=true
[Install]
WantedBy=timers.target

View File

@ -1,17 +1,27 @@
---
# file: roles/common/handlers/main.yml
# ansible.builtin.file: roles/common/handlers/main.yml
- name: reload sshd
systemd: name={{ sshd_service_name }} state=reloaded
ansible.builtin.systemd:
name: "{{ sshd_service_name }}"
state: reloaded
- name: reload sysctl
command: sysctl -p /etc/sysctl.conf
- name: restart firewalld
systemd: name=firewalld state=restarted
- name: restart fail2ban
systemd: name=fail2ban state=restarted
- name: reload systemd
systemd: daemon_reload=yes
ansible.builtin.systemd:
daemon_reload: true
- name: restart nftables
ansible.builtin.systemd:
name: nftables
state: restarted
# 2021-09-28: note to self to keep fail2ban at the end, as handlers are executed
# in the order they are defined, not in the order they are listed in the task's
# notify statement and we must restart fail2ban after updating the firewall.
- name: restart fail2ban
ansible.builtin.systemd:
name: fail2ban
state: restarted

View File

@ -1,12 +1,11 @@
---
- name: Configure cron-apt (config)
copy: src={{ item.src }} dest={{ item.dest }} mode={{ item.mode }} owner={{ item.owner }} group={{ item.group }}
ansible.builtin.copy: src={{ item.src }} dest={{ item.dest }} mode={{ item.mode }} owner={{ item.owner }} group={{ item.group }}
loop:
- { src: 'etc/cron-apt/config', dest: '/etc/cron-apt/config', mode: '0644', owner: 'root', group: 'root' }
- { src: 'etc/cron-apt/3-download', dest: '/etc/cron-apt/action.d/3-download', mode: '0644', owner: 'root', group: 'root' }
- { src: etc/cron-apt/config, dest: /etc/cron-apt/config, mode: "0644", owner: root, group: root }
- { src: etc/cron-apt/3-download, dest: /etc/cron-apt/action.d/3-download, mode: "0644", owner: root, group: root }
- name: Configure cron-apt (security)
template: src=security.sources.list.j2 dest=/etc/apt/security.sources.list mode=0644 owner=root group=root
ansible.builtin.template: src=security.sources.list.j2 dest=/etc/apt/security.sources.list mode=0644 owner=root group=root
# vim: set ts=2 sw=2:

View File

@ -1,20 +1,56 @@
---
- name: Install fail2ban
when:
- ansible_distribution_major_version is version('11', '>=')
ansible.builtin.package:
name:
- fail2ban
- python3-systemd
state: present
cache_valid_time: 3600
- name: Configure fail2ban sshd filter
template: src=etc/fail2ban/jail.d/sshd.local.j2 dest=/etc/fail2ban/jail.d/sshd.local owner=root mode=0644
ansible.builtin.template:
src: etc/fail2ban/jail.d/sshd.local.j2
dest: /etc/fail2ban/jail.d/sshd.local
owner: root
mode: "0644"
notify: restart fail2ban
- name: Configure fail2ban nginx filter
when:
- webserver is defined and webserver == 'nginx'
- extra_fail2ban_filters is defined
- "'nginx' in extra_fail2ban_filters"
ansible.builtin.template:
src: etc/fail2ban/jail.d/nginx.local.j2
dest: /etc/fail2ban/jail.d/nginx.local
owner: root
mode: "0644"
notify: restart fail2ban
- name: Create fail2ban service override directory
file: path=/etc/systemd/system/fail2ban.service.d state=directory owner=root mode=0755
ansible.builtin.file:
path: /etc/systemd/system/fail2ban.service.d
state: directory
owner: root
mode: "0755"
# See Arch Linux's example: https://wiki.archlinux.org/index.php/Fail2ban
- name: Configure fail2ban service override
template: src=etc/systemd/system/fail2ban.service.d/override.conf.j2 dest=/etc/systemd/system/fail2ban.service.d/override.conf owner=root mode=0644
ansible.builtin.template:
src: etc/systemd/system/fail2ban.service.d/override.conf.j2
dest: /etc/systemd/system/fail2ban.service.d/override.conf
owner: root
mode: "0644"
notify:
- reload systemd
- restart fail2ban
- name: Start and enable fail2ban service
systemd: name=fail2ban state=started enabled=yes
ansible.builtin.systemd:
name: fail2ban
state: started
enabled: true
# vim: set sw=2 ts=2:

View File

@ -1,60 +1,115 @@
---
# Debian 11+ will use nftables directly, with no firewalld.
- block:
- name: Set Debian firewall packages
set_fact:
debian_firewall_packages:
- firewalld
- tidy
- fail2ban
- python3-systemd # for fail2ban systemd backend
- name: Install Debian firewall packages
when: ansible_distribution_major_version is version('11', '>=')
ansible.builtin.package:
name:
- libnet-ip-perl # for aggregate-cidr-addresses.pl
- nftables
- curl # for nftables update scripts
state: present
cache_valid_time: 3600
- name: Install firewalld and deps
when: ansible_distribution_major_version is version('9', '>=')
apt: pkg={{ debian_firewall_packages }} state=present
- name: Remove iptables on newer Debian
when: ansible_distribution_major_version is version('11', '>=')
ansible.builtin.apt:
pkg: iptables
state: absent
- name: Use iptables backend in firewalld
when: ansible_distribution_major_version is version('10', '>=')
lineinfile:
dest: /etc/firewalld/firewalld.conf
regexp: '^FirewallBackend=nftables$'
line: 'FirewallBackend=iptables'
notify:
- restart firewalld
- name: Copy nftables.conf
when: ansible_distribution_major_version is version('11', '>=')
ansible.builtin.template:
src: nftables.conf.j2
dest: /etc/nftables.conf
owner: root
mode: "0644"
notify:
- restart nftables
- restart fail2ban
# firewalld seems to have an issue with iptables 1.8.2 when using the nftables
# backend. Using individual calls seems to work around it.
# See: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=931722
- name: Use individual iptables calls
when: ansible_distribution_major_version is version('10', '>=')
lineinfile:
dest: /etc/firewalld/firewalld.conf
regexp: '^IndividualCalls=no$'
line: 'IndividualCalls=yes'
notify:
- restart firewalld
- name: Create /etc/nftables extra config directory
when: ansible_distribution_major_version is version('11', '>=')
ansible.builtin.file:
path: /etc/nftables
state: directory
owner: root
mode: "0755"
- name: Copy firewalld public zone file
when: ansible_distribution_major_version is version('9', '>=')
template: src=public.xml.j2 dest=/etc/firewalld/zones/public.xml owner=root mode=0600
- name: Copy extra nftables configuration files
when: ansible_distribution_major_version is version('11', '>=')
ansible.builtin.copy:
src: "{{ item.src }}"
dest: /etc/nftables/{{ item.src }}
owner: root
group: root
mode: "0644"
force: "{{ item.force }}"
loop:
- { src: spamhaus-ipv4.nft, force: "no" }
- { src: spamhaus-ipv6.nft, force: "no" }
- { src: abusech-ipv4.nft, force: "no" }
- { src: abuseipdb-ipv4.nft, force: "yes" }
- { src: abuseipdb-ipv6.nft, force: "yes" }
notify:
- restart nftables
- restart fail2ban
- name: Format public.xml firewalld zone file
when: ansible_distribution_major_version is version('9', '>=')
command: tidy -xml -iq -m -w 0 /etc/firewalld/zones/public.xml
notify:
- restart firewalld
- name: Copy nftables update scripts
when: ansible_distribution_version is version('11', '>=')
ansible.builtin.copy:
src: "{{ item }}"
dest: /usr/local/bin/{{ item }}
mode: "0755"
owner: root
group: root
loop:
- update-spamhaus-nftables.sh
- aggregate-cidr-addresses.pl
- update-abusech-nftables.sh
- name: Copy ipsets of abusive IPs
when: ansible_distribution_major_version is version('9', '>=')
copy: src={{ item }} dest=/etc/firewalld/ipsets/{{ item }} owner=root group=root mode=0600
loop:
- abusers-ipv4.xml
- abusers-ipv6.xml
notify:
- restart firewalld
- name: Copy nftables systemd units
when: ansible_distribution_version is version('11', '>=')
ansible.builtin.copy:
src: "{{ item }}"
dest: /etc/systemd/system/{{ item }}
mode: "0644"
owner: root
group: root
loop:
- update-spamhaus-nftables.service
- update-spamhaus-nftables.timer
- update-abusech-nftables.service
- update-abusech-nftables.timer
register: nftables_systemd_units
- include_tasks: fail2ban.yml
when: ansible_distribution_major_version is version('9', '>=')
# need to reload to pick up service/timer/environment changes
- name: Reload systemd daemon
ansible.builtin.systemd:
daemon_reload: true
when: nftables_systemd_units is changed
- name: Start and enable nftables update timers
when: ansible_distribution_version is version('11', '>=')
ansible.builtin.systemd:
name: "{{ item }}"
state: started
enabled: true
loop:
- update-spamhaus-nftables.timer
- update-abusech-nftables.timer
- name: Start and enable nftables
when: ansible_distribution_major_version is version('11', '>=')
ansible.builtin.systemd:
name: nftables
state: started
enabled: true
- ansible.builtin.include_tasks: fail2ban.yml
when:
- ansible_distribution_major_version is version('9', '>=')
tags: firewall
# vim: set sw=2 ts=2:

View File

@ -1,64 +1,114 @@
---
# Ubuntu 20.04 will use nftables directly, with no firewalld.
- block:
- name: Set Ubuntu firewall packages
set_fact:
ubuntu_firewall_packages:
- firewalld
- tidy
- fail2ban
- python3-systemd # for fail2ban systemd backend
- name: Install Ubuntu firewall packages
when: ansible_distribution_version is version('20.04', '>=')
ansible.builtin.package:
name:
- libnet-ip-perl # for aggregate-cidr-addresses.pl
- nftables
- curl # for nftables update scripts
state: present
cache_valid_time: 3600
- name: Install firewalld and deps
when: ansible_distribution_version is version('16.04', '>=')
apt: pkg={{ ubuntu_firewall_packages }} state=present
- name: Remove ufw
ansible.builtin.package:
name: ufw
state: absent
- name: Remove ufw
when: ansible_distribution_version is version('16.04', '>=')
apt: pkg=ufw state=absent
- name: Copy nftables.conf
when: ansible_distribution_version is version('20.04', '>=')
ansible.builtin.template:
src: nftables.conf.j2
dest: /etc/nftables.conf
owner: root
mode: "0644"
notify:
- restart nftables
- restart fail2ban
# I'm not sure why, but you can use firewalld with the nftables backend even
# if nftables itself is not installed. In that case the only way to see the
# currently active rules is with firewall-cmd. I prefer installing nftables
# so that we can have somewhat of a parallel with iptables:
#
# nft list ruleset
#
# See: https://firewalld.org/2018/07/nftables-backend
- name: Install nftables
when: ansible_distribution_version is version('20.04', '==')
apt: pkg=nftables state=present
- name: Create /etc/nftables extra config directory
when: ansible_distribution_version is version('20.04', '>=')
ansible.builtin.file:
path: /etc/nftables
state: directory
owner: root
mode: "0755"
- name: Use nftables backend in firewalld
when: ansible_distribution_version is version('20.04', '==')
lineinfile:
dest: /etc/firewalld/firewalld.conf
regexp: '^FirewallBackend=iptables$'
line: 'FirewallBackend=nftables'
notify:
- restart firewalld
- name: Copy extra nftables configuration files
when: ansible_distribution_version is version('20.04', '>=')
ansible.builtin.copy:
src: "{{ item.src }}"
dest: /etc/nftables/{{ item.src }}
owner: root
group: root
mode: "0644"
force: "{{ item.force }}"
loop:
- { src: spamhaus-ipv4.nft, force: "no" }
- { src: spamhaus-ipv6.nft, force: "no" }
- { src: abusech-ipv4.nft, force: "no" }
- { src: abuseipdb-ipv4.nft, force: "yes" }
- { src: abuseipdb-ipv6.nft, force: "yes" }
notify:
- restart nftables
- restart fail2ban
- name: Copy firewalld public zone file
when: ansible_distribution_version is version('16.04', '>=')
template: src=public.xml.j2 dest=/etc/firewalld/zones/public.xml owner=root mode=0600
- name: Copy nftables update scripts
when: ansible_distribution_version is version('20.04', '>=')
ansible.builtin.copy:
src: "{{ item }}"
dest: /usr/local/bin/{{ item }}
mode: "0755"
owner: root
group: root
loop:
- update-spamhaus-nftables.sh
- aggregate-cidr-addresses.pl
- update-abusech-nftables.sh
- name: Format public.xml firewalld zone file
when: ansible_distribution_version is version('16.04', '>=')
command: tidy -xml -iq -m -w 0 /etc/firewalld/zones/public.xml
notify:
- restart firewalld
- name: Copy nftables systemd units
when: ansible_distribution_version is version('20.04', '>=')
ansible.builtin.copy:
src: "{{ item }}"
dest: /etc/systemd/system/{{ item }}
mode: "0644"
owner: root
group: root
loop:
- update-spamhaus-nftables.service
- update-spamhaus-nftables.timer
- update-abusech-nftables.service
- update-abusech-nftables.timer
register: nftables_systemd_units
- name: Copy ipsets of abusive IPs
when: ansible_distribution_version is version('16.04', '>=')
copy: src={{ item }} dest=/etc/firewalld/ipsets/{{ item }} owner=root group=root mode=0600
loop:
- abusers-ipv4.xml
- abusers-ipv6.xml
notify:
- restart firewalld
# need to reload to pick up service/timer/environment changes
- name: Reload systemd daemon
ansible.builtin.systemd:
daemon_reload: true
when: nftables_systemd_units is changed
- include_tasks: fail2ban.yml
when: ansible_distribution_version is version('16.04', '>=')
- name: Start and enable nftables update timers
when: ansible_distribution_version is version('20.04', '>=')
ansible.builtin.systemd:
name: "{{ item }}"
state: started
enabled: true
loop:
- update-spamhaus-nftables.timer
- update-abusech-nftables.timer
- name: Start and enable nftables
when: ansible_distribution_version is version('20.04', '>=')
ansible.builtin.systemd:
name: nftables
state: started
enabled: true
- ansible.builtin.include_tasks: fail2ban.yml
when:
- ansible_distribution_version is version('16.04', '>=')
tags: firewall
# vim: set sw=2 ts=2:

View File

@ -1,54 +1,50 @@
---
- name: Import OS-specific variables
include_vars: "vars/{{ ansible_distribution }}.yml"
ansible.builtin.include_vars: vars/{{ ansible_distribution }}.yml
tags: always
- name: Configure network time
import_tasks: ntp.yml
ansible.builtin.import_tasks: ntp.yml
tags: ntp
- name: Install common packages
include_tasks: packages_Debian.yml
ansible.builtin.include_tasks: packages_Debian.yml
when: ansible_distribution == 'Debian'
tags: packages
- name: Install common packages
include_tasks: packages_Ubuntu.yml
ansible.builtin.include_tasks: packages_Ubuntu.yml
when: ansible_distribution == 'Ubuntu'
tags: packages
- name: Configure firewall
include_tasks: firewall_Debian.yml
ansible.builtin.include_tasks: firewall_Debian.yml
when: ansible_distribution == 'Debian'
tags: firewall
- name: Configure firewall
include_tasks: firewall_Ubuntu.yml
ansible.builtin.include_tasks: firewall_Ubuntu.yml
when: ansible_distribution == 'Ubuntu'
tags: firewall
- name: Configure secure shell daemon
import_tasks: sshd.yml
ansible.builtin.import_tasks: sshd.yml
tags: sshd
# containers identify as virtualization hosts, which makes this tricky, because we have actual Debian VM hosts!
- name: Reconfigure /etc/sysctl.conf
when: ansible_virtualization_role != 'host'
template: src=sysctl_{{ ansible_distribution }}.j2 dest=/etc/sysctl.conf owner=root group=root mode=0644
ansible.builtin.template: src=sysctl_{{ ansible_distribution }}.j2 dest=/etc/sysctl.conf owner=root group=root mode=0644
notify:
- reload sysctl
tags: sysctl
- name: Reconfigure /etc/rc.local
when: ansible_distribution == 'Ubuntu' and ansible_distribution_version is version('19.04', '<=')
template: src=rc.local_Ubuntu.j2 dest=/etc/rc.local owner=root group=root mode=0755
- name: Set I/O scheduler
template: src=etc/udev/rules.d/60-scheduler.rules.j2 dest=/etc/udev/rules.d/60-scheduler.rules owner=root group=root mode=0644
ansible.builtin.template: src=etc/udev/rules.d/60-scheduler.rules.j2 dest=/etc/udev/rules.d/60-scheduler.rules owner=root group=root mode=0644
tags: udev
- name: Copy admin SSH keys
import_tasks: ssh-keys.yml
ansible.builtin.import_tasks: ssh-keys.yml
tags: ssh-keys
# vim: set sw=2 ts=2:

View File

@ -1,18 +1,27 @@
---
# Hosts running Ubuntu 16.04+ and Debian 9+ use systemd init system and should
# use timedatectl as a network time client instead of the standalone ntp client.
# use systemd-timesyncd as a network time client instead of the standalone ntp
# client.
- name: Set timezone
when: timezone is defined and ansible_service_mgr == 'systemd'
command: /usr/bin/timedatectl set-timezone {{ timezone }}
tags: timezone
# Apparently some cloud images don't have this installed by default. From what
# I can see on existing servers, systemd-timesyncd is a standalone package on
# Ubuntu 20.04 and Debian 11.
- name: Install systemd-timesyncd
when: (ansible_distribution == 'Ubuntu' and ansible_distribution_version is version('20.04', '==')) or (ansible_distribution == 'Debian' and ansible_distribution_version
is version('11', '>='))
ansible.builtin.apt: name=systemd-timesyncd state=present cache_valid_time=3600
- name: Start and enable systemd's NTP client
when: ansible_service_mgr == 'systemd'
systemd: name=systemd-timesyncd state=started enabled=yes
ansible.builtin.systemd: name=systemd-timesyncd state=started enabled=true
- name: Uninstall ntp on modern Ubuntu/Debian
apt: name=ntp state=absent update_cache=yes
ansible.builtin.apt: name=ntp state=absent
when: ansible_service_mgr == 'systemd'
# vim: set ts=2 sw=2:

View File

@ -1,37 +1,62 @@
---
- name: Configure Debian packages
block:
# Create directory for third-party package signing keys. Required on distros
# older than Debian 12 / Ubuntu 22.04.
#
# See: https://wiki.debian.org/DebianRepository/UseThirdParty
- name: Create /etc/apt/keyrings
file:
path: /etc/apt/keyrings
mode: "0755"
owner: root
group: root
state: directory
when: ansible_distribution_major_version is version('12', '<')
- block:
- name: Configure apt mirror
template: src=sources.list.j2 dest=/etc/apt/sources.list owner=root group=root mode=0644
# Scaleway seems to use a weird sources.list format as of Debian 12?
- name: Check for weird Debian sources
ansible.builtin.stat:
path: /etc/apt/sources.list.d/debian.sources
register: weird_debian_sources_stat
- name: Set fact for base packages
set_fact:
base_packages:
- git
- tmux
- iotop
- htop
- strace
- cron-apt
- safe-rm
- debian-goodies
- mosh
- python3-pycurl # for ansible's apt_repository
- vim
- unzip
- apt-transport-https # for https support in apt
- gnupg2
- zstd
- name: Configure apt mirror
ansible.builtin.template: src=sources.list.j2 dest=/etc/apt/sources.list owner=root group=root mode=0644
when:
- ansible_architecture != 'armv7l'
- not weird_debian_sources_stat
- name: Install base packages
apt: name={{ base_packages }} state=present update_cache=yes cache_valid_time=3600
- name: Set fact for base packages
ansible.builtin.set_fact:
base_packages:
- git
- git-lfs
- tmux
- iotop
- htop
- strace
- cron-apt
- safe-rm
- debian-goodies
- mosh
- python3-pycurl # for ansible's apt_repository
- vim
- unzip
- apt-transport-https # for https support in apt
- gnupg2
- zstd
- rsync
- lsof
- name: Configure cron-apt
import_tasks: cron-apt.yml
tags: cron-apt
- name: Install base packages
ansible.builtin.apt: name={{ base_packages }} state=present cache_valid_time=3600
- name: Install tarsnap
import_tasks: tarsnap.yml
- name: Configure cron-apt
ansible.builtin.import_tasks: cron-apt.yml
tags: cron-apt
- name: Install tarsnap
ansible.builtin.import_tasks: tarsnap.yml
tags: packages
# vim: set sw=2 ts=2:

View File

@ -1,105 +1,105 @@
---
- name: Configure Ubuntu packages
block:
# Create directory for third-party package signing keys. Required on distros
# older than Debian 12 / Ubuntu 22.04.
#
# See: https://wiki.debian.org/DebianRepository/UseThirdParty
- name: Create /etc/apt/keyrings
file:
path: /etc/apt/keyrings
mode: "0755"
owner: root
group: root
state: directory
when: ansible_distribution_major_version is version('22.04', '<')
- block:
- name: Configure apt mirror
template: src=sources.list.j2 dest=/etc/apt/sources.list owner=root group=root mode=0644
when: ansible_architecture != 'armv7l'
- name: Configure apt mirror
ansible.builtin.template: src=sources.list.j2 dest=/etc/apt/sources.list owner=root group=root mode=0644
when: ansible_architecture != 'armv7l'
- name: Upgrade base OS
apt: upgrade=dist update_cache=yes cache_valid_time=3600
- name: Upgrade base OS
ansible.builtin.apt: upgrade=dist cache_valid_time=3600
- name: Set Ubuntu base packages
set_fact:
ubuntu_base_packages:
- git
- tmux
- iotop
- htop
- strace
- cron-apt
- safe-rm
- debian-goodies
- mosh
- python-pycurl # for ansible's apt_repository
- vim
- unzip
- apt-transport-https # for https support in apt
- zstd
- name: Set Ubuntu base packages
ansible.builtin.set_fact:
ubuntu_base_packages:
- git
- git-lfs
- tmux
- iotop
- htop
- strace
- cron-apt
- safe-rm
- debian-goodies
- mosh
- python-pycurl # for ansible's apt_repository
- vim
- unzip
- apt-transport-https # for https support in apt
- zstd
- rsync
- lsof
- name: Install base packages
apt: pkg={{ ubuntu_base_packages }} state=present update_cache=yes cache_valid_time=3600
- name: Install base packages
ansible.builtin.apt: pkg={{ ubuntu_base_packages }} state=present cache_valid_time=3600
# We have to remove snaps one by one in a specific order because some depend
# on others. Only after that can we remove the corresponding system packages.
- name: Remove lxd snap
snap: name=lxd state=absent
when: ansible_distribution_version is version('20.04', '==')
ignore_errors: yes
# We have to remove snaps one by one in a specific order because some depend
# on others. Only after that can we remove the corresponding system packages.
- name: Remove lxd snap
community.general.snap: name=lxd state=absent
when: ansible_distribution_version is version('20.04', '==')
ignore_errors: true
- name: Remove core18 snap
snap: name=core18 state=absent
when: ansible_distribution_version is version('20.04', '==')
ignore_errors: yes
- name: Remove core18 snap
community.general.snap: name=core18 state=absent
when: ansible_distribution_version is version('20.04', '==')
ignore_errors: true
- name: Remove snapd snap
snap: name=snapd state=absent
when: ansible_distribution_version is version('20.04', '==')
ignore_errors: yes
- name: Remove snapd snap
community.general.snap: name=snapd state=absent
when: ansible_distribution_version is version('20.04', '==')
ignore_errors: true
- name: Set fact for packages to remove (Ubuntu <= 18.04)
set_fact:
ubuntu_annoying_packages:
- whoopsie # security (CIS 4.1)
- apport # security (CIS 4.1)
- command-not-found # annoying
- command-not-found-data # annoying
- python3-commandnotfound # annoying
- snapd # annoying (Ubuntu >= 16.04)
- lxd # annoying (Ubuntu >= 16.04)
- lxd-client # annoying (Ubuntu >= 16.04)
- liblxc1 # annoying (Ubuntu >= 16.04)
- lxc-common # annoying (Ubuntu >= 16.04)
- lxcfs #annoying (Ubuntu >= 16.04)
when: ansible_distribution_version is version('18.04', '<=')
- name: Set fact for packages to remove (Ubuntu 20.04)
ansible.builtin.set_fact:
ubuntu_annoying_packages:
- whoopsie # security (CIS 4.1)
- apport # security (CIS 4.1)
- command-not-found # annoying
- command-not-found-data # annoying
- python3-commandnotfound # annoying
- snapd # annoying (Ubuntu >= 16.04)
- lxd-agent-loader # annoying (Ubuntu 20.04)
when: ansible_distribution_version is version('20.04', '==')
- name: Set fact for packages to remove (Ubuntu 20.04)
set_fact:
ubuntu_annoying_packages:
- whoopsie # security (CIS 4.1)
- apport # security (CIS 4.1)
- command-not-found # annoying
- command-not-found-data # annoying
- python3-commandnotfound # annoying
- snapd # annoying (Ubuntu >= 16.04)
- lxd-agent-loader # annoying (Ubuntu 20.04)
when: ansible_distribution_version is version('20.04', '==')
- name: Remove packages
ansible.builtin.apt: name={{ ubuntu_annoying_packages }} state=absent purge=true
- name: Remove packages
apt: name={{ ubuntu_annoying_packages }} state=absent purge=yes
- name: Disable annoying Canonical spam in MOTD
ansible.builtin.file: path={{ item }} mode=0644 state=absent
loop:
- /etc/update-motd.d/99-esm # Ubuntu 14.04
- /etc/update-motd.d/10-help-text # Ubuntu 14.04+
- /etc/update-motd.d/50-motd-news # Ubuntu 18.04+
- /etc/update-motd.d/80-esm # Ubuntu 18.04+
- /etc/update-motd.d/80-livepatch # Ubuntu 18.04+
ignore_errors: true
- name: Disable annoying Canonical spam in MOTD
file: path={{ item }} mode=0644 state=absent
loop:
- /etc/update-motd.d/99-esm # Ubuntu 14.04
- /etc/update-motd.d/10-help-text # Ubuntu 14.04+
- /etc/update-motd.d/50-motd-news # Ubuntu 18.04+
- /etc/update-motd.d/80-esm # Ubuntu 18.04+
- /etc/update-motd.d/80-livepatch # Ubuntu 18.04+
ignore_errors: yes
- name: Disable annoying Canonical spam in MOTD
ansible.builtin.systemd: name={{ item }} state=stopped enabled=no
when: ansible_service_mgr == 'systemd'
loop:
- motd-news.service
- motd-news.timer
- name: Disable annoying Canonical spam in MOTD
systemd: name={{ item }} state=stopped enabled=no
when: ansible_service_mgr == 'systemd'
loop:
- motd-news.service
- motd-news.timer
- name: Configure cron-apt
ansible.builtin.import_tasks: cron-apt.yml
tags: cron-apt
- name: Configure cron-apt
import_tasks: cron-apt.yml
tags: cron-apt
- name: Install tarsnap
import_tasks: tarsnap.yml
- name: Install tarsnap
ansible.builtin.import_tasks: tarsnap.yml
tags: packages
# vim: set sw=2 ts=2:

View File

@ -1,9 +1,9 @@
---
- name: Zero .ssh/authorized_keys for provisioning user
file: dest={{ provisioning_user.home }}/.ssh/authorized_keys state=absent
ansible.builtin.file: dest={{ provisioning_user.home }}/.ssh/authorized_keys state=absent
- name: Add public keys to authorized_keys
authorized_key: { user: '{{ provisioning_user.name }}', key: "{{ lookup('file',item) }}" }
ansible.posix.authorized_key: { user: "{{ provisioning_user.name }}", key: "{{ lookup('file',item) }}" }
with_fileglob:
# use descriptive names for keys, like: aorth-mzito-rsa.pub
- ssh-pub-keys/*.pub

View File

@ -1,20 +1,46 @@
---
# SSH configs don't change in Debian minor versions
- name: Reconfigure /etc/ssh/sshd_config
template: src=sshd_config_{{ ansible_distribution }}-{{ ansible_distribution_major_version }}.j2 dest=/etc/ssh/sshd_config owner=root group=root mode=0600
ansible.builtin.template: src=sshd_config_{{ ansible_distribution }}-{{ ansible_distribution_major_version }}.j2 dest=/etc/ssh/sshd_config owner=root group=root
mode=0600
when: ansible_distribution == 'Debian'
notify: reload sshd
# Ubuntu is the only distro we have where SSH version is very different from 14.04 -> 14.10,
# ie with new ciphers supported etc.
- name: Reconfigure /etc/ssh/sshd_config
template: src=sshd_config_{{ ansible_distribution }}-{{ ansible_distribution_version }}.j2 dest=/etc/ssh/sshd_config owner=root group=root mode=0600
ansible.builtin.template: src=sshd_config_{{ ansible_distribution }}-{{ ansible_distribution_version }}.j2 dest=/etc/ssh/sshd_config owner=root group=root mode=0600
when: ansible_distribution == 'Ubuntu'
notify: reload sshd
# See: WeakDH (2015): https://weakdh.org/sysadmin.html
- name: Remove small Diffie-Hellman SSH moduli
block:
- name: Check unsafe Diffie-Hellman SSH moduli
ansible.builtin.shell:
cmd: awk '$5 < 3071' moduli
chdir: /etc/ssh
creates: moduli.safe
register: check_unsafe_moduli
- name: Extract safe Diffie-Hellman SSH moduli
ansible.builtin.shell:
cmd: awk '$5 >= 3071' moduli > moduli.safe
chdir: /etc/ssh
creates: moduli.safe
when: check_unsafe_moduli.stdout | length > 0
register: extract_safe_moduli
- name: Replace unsafe Diffie-Hellman SSH moduli
ansible.builtin.command:
cmd: mv moduli.safe moduli
chdir: /etc/ssh
register: replace_small_moduli
when: extract_safe_moduli is changed
notify: reload sshd
- name: Remove DSA and ECDSA host keys
file: name=/etc/ssh/{{ item }} state=absent
ansible.builtin.file: name=/etc/ssh/{{ item }} state=absent
loop:
- ssh_host_dsa_key
- ssh_host_dsa_key.pub

View File

@ -1,24 +1,45 @@
---
- name: Add Tarsnap apt mirror
template: src=tarsnap_sources.list.j2 dest=/etc/apt/sources.list.d/tarsnap.list owner=root group=root mode=0644
- name: Check tarsnap apt signing key
ansible.builtin.stat:
path: /etc/apt/keyrings/tarsnap-deb-packaging-key.asc
register: tarsnap_signing_key_stat
- name: Download tarsnap apt signing key
ansible.builtin.get_url:
url: https://pkg.tarsnap.com/tarsnap-deb-packaging-key.asc
dest: /etc/apt/keyrings/tarsnap-deb-packaging-key.asc
owner: root
group: root
mode: "0644"
register: download_tarsnap_signing_key
when: not tarsnap_signing_key_stat.stat.exists
- name: Add tarsnap.org repo
ansible.builtin.template:
src: tarsnap_sources.list.j2
dest: /etc/apt/sources.list.d/tarsnap.list
owner: root
group: root
mode: "0644"
register: add_tarsnap_apt_repository
when: ansible_architecture != 'armv7l'
- name: Add GPG key for Tarsnap
apt_key: id=0xFC72A10BF6B692AA url=https://pkg.tarsnap.com/tarsnap-deb-packaging-key.asc state=present
register: add_tarsnap_apt_key
- name: Update apt cache
apt:
update_cache: yes
when:
add_tarsnap_apt_key is changed or
add_tarsnap_apt_repository is changed
ansible.builtin.apt: # noqa no-handler
update_cache: true
when: (download_tarsnap_signing_key.status_code is defined and download_tarsnap_signing_key.status_code == 200) or add_tarsnap_apt_repository is changed
- name: Install tarsnap
apt: pkg=tarsnap cache_valid_time=3600
ansible.builtin.apt:
pkg: tarsnap
cache_valid_time: 3600
- name: Copy tarsnaprc
copy: src=tarsnaprc dest=/root/.tarsnaprc owner=root group=root mode=0600
ansible.builtin.copy:
src: tarsnaprc
dest: /root/.tarsnaprc
owner: root
group: root
mode: "0600"
# vim: set sw=2 ts=2:

View File

@ -0,0 +1,13 @@
[nginx]
enabled = true
# See: /etc/fail2ban/filter.d/nginx-botsearch.conf
filter = nginx-botsearch
# Integrate with nftables
banaction=nftables[type=allports]
backend = pyinotify
logpath = /var/log/nginx/*-access.log
# Try to find a non-existent wp-login.php once and get banned. Tough luck.
maxretry = 1
findtime = {{ fail2ban_findtime }}
bantime = {{ fail2ban_bantime }}
ignoreip = {{ fail2ban_ignoreip }}

View File

@ -2,8 +2,8 @@
enabled = true
# See: /etc/fail2ban/filter.d/sshd.conf
filter = sshd
# Integrate with firewalld and ipsets
banaction = firewallcmd-ipset
# Integrate with nftables
banaction=nftables[type=allports]
backend = systemd
maxretry = {{ fail2ban_maxretry }}
findtime = {{ fail2ban_findtime }}

View File

@ -2,14 +2,14 @@
PrivateDevices=yes
PrivateTmp=yes
ProtectHome=read-only
{% if ansible_distribution == 'Ubuntu' and ansible_distribution_major_version is version('18','>=') %}
{% if (ansible_distribution == 'Ubuntu' and ansible_distribution_major_version is version('18','>=')) or (ansible_distribution == 'Debian' and ansible_distribution_major_version is version('11','>=')) %}
ProtectSystem=strict
{% else %}
{# Older systemd versions don't have ProtectSystem=strict #}
ProtectSystem=full
{% endif %}
NoNewPrivileges=yes
{% if ansible_distribution == 'Ubuntu' and ansible_distribution_major_version is version('18','>=') %}
{% if (ansible_distribution == 'Ubuntu' and ansible_distribution_major_version is version('18','>=')) or (ansible_distribution == 'Debian' and ansible_distribution_major_version is version('11','>=')) %}
ReadWritePaths=-/var/run/fail2ban
ReadWritePaths=-/var/lib/fail2ban
ReadWritePaths=-/var/log/fail2ban.log

View File

@ -0,0 +1,116 @@
#!/usr/sbin/nft -f
#
# Initially based on: https://wiki.nftables.org/wiki-nftables/index.php/Simple_ruleset_for_a_server
#
flush ruleset
# Lists updated daily by update-spamhaus-nftables.sh
include "/etc/nftables/spamhaus-ipv4.nft"
include "/etc/nftables/spamhaus-ipv6.nft"
# Lists updated monthly (manually)
include "/etc/nftables/abuseipdb-ipv4.nft"
include "/etc/nftables/abuseipdb-ipv6.nft"
# Lists updated daily by update-abusech-nftables.sh
include "/etc/nftables/abusech-ipv4.nft"
# Notes:
# - tables hold chains, chains hold rules
# - inet is for both ipv4 and ipv6
table inet filter {
set spamhaus-ipv4 {
type ipv4_addr
# if the set contains prefixes we need to use the interval flag
flags interval
elements = $SPAMHAUS_IPV4
}
set spamhaus-ipv6 {
type ipv6_addr
flags interval
elements = $SPAMHAUS_IPV6
}
set abusech-ipv4 {
type ipv4_addr
elements = $ABUSECH_IPV4
}
set abuseipdb-ipv4 {
type ipv4_addr
elements = $ABUSEIPDB_IPV4
}
set abuseipdb-ipv6 {
type ipv6_addr
elements = $ABUSEIPDB_IPV6
}
chain input {
type filter hook input priority 0;
ct state {established, related} accept comment "Allow traffic from established and related packets"
ct state invalid counter drop comment "Early drop of invalid connections"
ip saddr @spamhaus-ipv4 counter drop comment "Early drop of incoming packets matching spamhaus-ipv4 list"
ip6 saddr @spamhaus-ipv6 counter drop comment "Early drop of incoming packets matching spamhaus-ipv6 list"
ip saddr @abusech-ipv4 counter drop comment "Early drop of packets matching abusech-ipv4 list"
ip saddr @abuseipdb-ipv4 counter drop comment "Early drop of incoming packets matching abuseipdb-ipv4 list"
ip6 saddr @abuseipdb-ipv6 counter drop comment "Early drop of incoming packets matching abuseipdb-ipv6 list"
iifname lo accept comment "Allow from loopback"
ip protocol icmp limit rate 4/second accept comment "Allow ICMP"
ip6 nexthdr ipv6-icmp limit rate 4/second accept comment "Allow IPv6 ICMP"
ip protocol igmp limit rate 4/second accept comment "Allow IGMP"
{# SSH rules #}
ip saddr 0.0.0.0/0 ct state new tcp dport 22 counter accept comment "Allow SSH"
ip6 saddr ::/0 ct state new tcp dport 22 counter accept comment "Allow SSH"
{# Web rules #}
{% if 'web' in group_names %}
ip saddr 0.0.0.0/0 ct state new tcp dport 80 counter accept comment "Allow HTTP"
ip saddr 0.0.0.0/0 ct state new tcp dport 443 counter accept comment "Allow HTTPS"
ip6 saddr ::/0 ct state new tcp dport 80 counter accept comment "Allow HTTP"
ip6 saddr ::/0 ct state new tcp dport 443 counter accept comment "Allow HTTPS"
{% endif %}
ip saddr 0.0.0.0/0 ct state new udp dport 60001-60003 counter accept comment "Allow mosh"
ip6 saddr ::/0 ct state new udp dport 60001-60003 counter accept comment "Allow mosh"
{# Extra rules #}
{% if extra_iptables_rules is defined %}
{% for rule in extra_iptables_rules %}
ip saddr {{ ghetto_ipsets[rule.acl].src }} ct state new {{ rule.protocol }} dport {{ rule.port }} counter accept
{% if ghetto_ipsets[rule.acl].ipv6src is defined %}
ip6 saddr {{ ghetto_ipsets[rule.acl].ipv6src }} ct state new {{ rule.protocol }} dport {{ rule.port }} counter accept
{% endif %}
{% endfor %}
{% endif %}
# everything else
reject with icmpx type port-unreachable
}
chain forward {
type filter hook forward priority 0;
}
chain output {
type filter hook output priority 0;
ip daddr @spamhaus-ipv4 counter drop comment "Drop outgoing packets matching spamhaus-ipv4 list"
ip6 daddr @spamhaus-ipv6 counter drop comment "Drop outgoing packets matching spamhaus-ipv6 list"
ip daddr @abusech-ipv4 counter drop comment "Drop outgoing packets matching abusech-ipv4 list"
ip daddr @abuseipdb-ipv4 counter drop comment "Drop outgoing packets matching abuseipdb-ipv4 list"
ip6 daddr @abuseipdb-ipv6 counter drop comment "Drop outgoing packets matching abuseipdb-ipv6 list"
}
}

View File

@ -1,72 +0,0 @@
<zone>
<short>Public</short>
<description>For use in public areas. You do not trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.</description>
<interface name="{{ ansible_default_ipv4.interface }}"/>
{# ssh rules #}
<rule family="ipv4">
<source address="0.0.0.0/0"/>
<port protocol="tcp" port="22"/>
<accept/>
</rule>
{# ipv6 ssh rules #}
<rule family="ipv6">
<source address="::/0"/>
<port protocol="tcp" port="22"/>
<accept/>
</rule>
{# web rules #}
<rule family="ipv4">
<source address="0.0.0.0/0"/>
<port protocol="tcp" port="80"/>
<accept/>
</rule>
{# ipv6 web rules #}
<rule family="ipv6">
<source address="::/0"/>
<port protocol="tcp" port="80"/>
<accept/>
</rule>
{# munin rules #}
{% if munin_master_host is defined %}
<rule family="ipv4">
<source address="{{ ghetto_ipsets[munin_master_host].src }}"/>
<port protocol="tcp" port="{{ munin_node_port }}"/>
<accept/>
</rule>
{% endif %}
{# extra rules #}
{% if extra_iptables_rules is defined %}
{% for rule in extra_iptables_rules %}
<rule family="ipv4">
<source address="{{ ghetto_ipsets[rule.acl].src }}"/>
<port protocol="{{ rule.protocol }}" port="{{ rule.port }}"/>
<accept/>
</rule>
{# ipv6 extra rules #}
{% if ghetto_ipsets[rule.acl].ipv6src is defined %}
<rule family="ipv6">
<source address="{{ ghetto_ipsets[rule.acl].ipv6src }}"/>
<port protocol="{{ rule.protocol }}" port="{{ rule.port }}"/>
<accept/>
</rule>
{% endif %}
{% endfor %}
{% endif %}
<rule>
<source ipset="abusers-ipv4"/>
<drop/>
</rule>
<rule>
<source ipset="abusers-ipv6"/>
<drop/>
</rule>
</zone>

View File

@ -1,14 +0,0 @@
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
exit 0

View File

@ -9,7 +9,7 @@ deb http://security.ubuntu.com/ubuntu/ {{ ansible_distribution_release }}-securi
{% set apt_mirror = apt_mirror | default('deb.debian.org') %}
deb http://{{ apt_mirror }}/debian/ {{ ansible_distribution_release }} main contrib non-free
deb http://security.debian.org/debian-security {{ ansible_distribution_release }}/updates main contrib non-free
deb http://security.debian.org/debian-security {{ ansible_distribution_release }}-security main contrib non-free
deb http://{{ apt_mirror }}/debian/ {{ ansible_distribution_release }}-updates main contrib non-free

View File

@ -1,4 +1,4 @@
# $OpenBSD: sshd_config,v 1.101 2017/03/14 07:19:07 djm Exp $
# $OpenBSD: sshd_config,v 1.103 2018/04/09 20:41:22 tj Exp $
# This is the sshd server system-wide configuration file. See
# sshd_config(5) for more information.
@ -10,6 +10,8 @@
# possible, but leave them commented. Uncommented options override the
# default value.
Include /etc/ssh/sshd_config.d/*.conf
#Port 22
#AddressFamily any
#ListenAddress 0.0.0.0
@ -54,7 +56,11 @@ AuthorizedKeysFile .ssh/authorized_keys
#IgnoreRhosts yes
# To disable tunneled clear text passwords, change to no here!
#PasswordAuthentication yes
{% if ssh_password_authentication == 'disabled' %}
PasswordAuthentication no
{% else %}
PasswordAuthentication yes
{% endif %}
#PermitEmptyPasswords no
# Change to yes to enable challenge-response passwords (beware issues with
@ -94,7 +100,6 @@ X11Forwarding no
PrintMotd no
#PrintLastLog yes
#TCPKeepAlive yes
#UseLogin no
#PermitUserEnvironment no
#Compression delayed
#ClientAliveInterval 0
@ -122,12 +127,20 @@ Subsystem sftp /usr/lib/openssh/sftp-server
# PermitTTY no
# ForceCommand cvs server
# Originally from: https://stribika.github.io/2015/01/04/secure-secure-shell.html
# ... but with ciphers and MACs with < 256 bits removed, as NSA's Suite B now
# does away with these! See: https://www.nsa.gov/ia/programs/suiteb_cryptography/index.shtml
# Based on the ssh-audit profile for OpenSSH 8.4, but with but with all algos
# with less than 256 bits removed, as NSA's Suite B removed them years ago and
# the new (2018) CNSA suite is 256 bits and up.
#
# See: https://github.com/jtesta/ssh-audit/blob/master/src/ssh_audit/policy.py
# See: https://en.wikipedia.org/wiki/Commercial_National_Security_Algorithm_Suite
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes256-ctr
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512,hmac-sha2-256
KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com
KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha256
# only allow shell access by provisioning user
AllowUsers {{ provisioning_user.name }}
{% if ssh_allowed_users is defined and ssh_allowed_users %}
# Is there a list of allowed users?
# Is it populated? (An empty list is 'None', which evaluates as False in Python)
# merge the items of a list into one string using a space as a separator
# http://jinja.pocoo.org/docs/dev/templates/#join
AllowUsers {{ ssh_allowed_users|join(" ") }} {{ provisioning_user.name }}
{% endif %}

View File

@ -0,0 +1,146 @@
# This is the sshd server system-wide configuration file. See
# sshd_config(5) for more information.
# This sshd was compiled with PATH=/usr/local/bin:/usr/bin:/bin:/usr/games
# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented. Uncommented options override the
# default value.
Include /etc/ssh/sshd_config.d/*.conf
#Port 22
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::
#HostKey /etc/ssh/ssh_host_rsa_key
#HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
# Ciphers and keying
#RekeyLimit default none
# Logging
#SyslogFacility AUTH
# LogLevel VERBOSE logs user's key fingerprint on login. Needed to have a clear audit track of which key was using to log in.
LogLevel VERBOSE
# Authentication:
#LoginGraceTime 2m
PermitRootLogin prohibit-password
#StrictModes yes
MaxAuthTries 4
#MaxSessions 10
#PubkeyAuthentication yes
# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2
# but this is overridden so installations will only check .ssh/authorized_keys
AuthorizedKeysFile .ssh/authorized_keys
#AuthorizedPrincipalsFile none
#AuthorizedKeysCommand none
#AuthorizedKeysCommandUser nobody
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
#HostbasedAuthentication no
# Change to yes if you don't trust ~/.ssh/known_hosts for
# HostbasedAuthentication
#IgnoreUserKnownHosts no
# Don't read the user's ~/.rhosts and ~/.shosts files
#IgnoreRhosts yes
# To disable tunneled clear text passwords, change to no here!
{% if ssh_password_authentication == 'disabled' %}
PasswordAuthentication no
{% else %}
PasswordAuthentication yes
{% endif %}
#PermitEmptyPasswords no
# Change to yes to enable challenge-response passwords (beware issues with
# some PAM modules and threads)
KbdInteractiveAuthentication no
# Kerberos options
#KerberosAuthentication no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
#KerberosGetAFSToken no
# GSSAPI options
#GSSAPIAuthentication no
#GSSAPICleanupCredentials yes
#GSSAPIStrictAcceptorCheck yes
#GSSAPIKeyExchange no
# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the KbdInteractiveAuthentication and
# PasswordAuthentication. Depending on your PAM configuration,
# PAM authentication via KbdInteractiveAuthentication may bypass
# the setting of "PermitRootLogin prohibit-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and KbdInteractiveAuthentication to 'no'.
UsePAM yes
#AllowAgentForwarding yes
#AllowTcpForwarding yes
#GatewayPorts no
X11Forwarding no
#X11DisplayOffset 10
#X11UseLocalhost yes
#PermitTTY yes
PrintMotd no
#PrintLastLog yes
#TCPKeepAlive yes
#PermitUserEnvironment no
#Compression delayed
#ClientAliveInterval 0
#ClientAliveCountMax 3
#UseDNS no
#PidFile /run/sshd.pid
#MaxStartups 10:30:100
#PermitTunnel no
#ChrootDirectory none
#VersionAddendum none
# no default banner path
#Banner none
# Allow client to pass locale environment variables
AcceptEnv LANG LC_*
# override default of no subsystems
Subsystem sftp /usr/lib/openssh/sftp-server
# Example of overriding settings on a per-user basis
#Match User anoncvs
# X11Forwarding no
# AllowTcpForwarding no
# PermitTTY no
# ForceCommand cvs server
# Based on the ssh-audit profile for OpenSSH 9.2, but with but with all algos
# with less than 256 bits removed, as NSA's Suite B removed them years ago and
# the new (2018) CNSA suite is 256 bits and up.
#
# See: https://github.com/jtesta/ssh-audit/blob/master/src/ssh_audit/policy.py
# See: https://en.wikipedia.org/wiki/Commercial_National_Security_Algorithm_Suite
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes256-ctr
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com
KexAlgorithms sntrup761x25519-sha512@openssh.com,curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha256
{% if ssh_allowed_users is defined and ssh_allowed_users %}
# Is there a list of allowed users?
# Is it populated? (An empty list is 'None', which evaluates as False in Python)
# merge the items of a list into one string using a space as a separator
# http://jinja.pocoo.org/docs/dev/templates/#join
AllowUsers {{ ssh_allowed_users|join(" ") }} {{ provisioning_user.name }}
{% endif %}

View File

@ -56,7 +56,11 @@ AuthorizedKeysFile .ssh/authorized_keys
#IgnoreRhosts yes
# To disable tunneled clear text passwords, change to no here!
#PasswordAuthentication yes
{% if ssh_password_authentication == 'disabled' %}
PasswordAuthentication no
{% else %}
PasswordAuthentication yes
{% endif %}
#PermitEmptyPasswords no
# Change to yes to enable challenge-response passwords (beware issues with
@ -122,14 +126,13 @@ Subsystem sftp /usr/lib/openssh/sftp-server
# AllowTcpForwarding no
# PermitTTY no
# ForceCommand cvs server
PasswordAuthentication yes
# Originally from: https://stribika.github.io/2015/01/04/secure-secure-shell.html
# ... but with ciphers and MACs with < 256 bits removed, as NSA's Suite B now
# does away with these! See: https://www.nsa.gov/ia/programs/suiteb_cryptography/index.shtml
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes256-ctr
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512,hmac-sha2-256
KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com
KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256
{% if ssh_allowed_users is defined and ssh_allowed_users %}
# Is there a list of allowed users?

View File

@ -1 +1 @@
deb [arch=amd64] https://pkg.tarsnap.com/deb/{{ ansible_distribution_release }} ./
deb [arch=amd64 signed-by=/etc/apt/keyrings/tarsnap-deb-packaging-key.asc] https://pkg.tarsnap.com/deb/{{ ansible_distribution_release }} ./

View File

@ -1,5 +1,5 @@
---
# file: roles/mariadb/defaults/main.yml
# ansible.builtin.file: roles/mariadb/defaults/main.yml
#
# Based on my running of mysqltuner.pl on a host with three WordPress databases
#
@ -17,7 +17,7 @@ innodb_buffer_pool_size: 256M
# Ansible 2.7.x with PyMySQL seems to default to TCP connection so we should
# force it to use a Unix socket.
# See: https://github.com/ansible/ansible/issues/47736
mariadb_login_unix_socket: /var/run/mysqld/mysqld.sock
mariadb_login_unix_socket: /run/mysqld/mysqld.sock
# default is 100 but the max I've seen used is 5, so let's reduce it
max_connections: 33

View File

@ -1,5 +1,5 @@
---
- name: restart mariadb
systemd: name=mariadb state=restarted
ansible.builtin.systemd: name=mariadb state=restarted
# vim: set ts=2 sw=2:

View File

@ -1,57 +1,109 @@
---
- name: Add GPG key for MariaDB repo
apt_key: id=0x177F4010FE56CA3336300305F1656F24C74CD1D8 url=https://mariadb.org/mariadb_release_signing_key.asc
register: add_mariadb_apt_key
tags: mariadb, packages
- name: Remove MariaDB key from apt-key
ansible.builtin.apt_key:
id: "013577200103762554506315430003013705453362230723150730"
state: absent
tags:
- packages
- mariadb
- name: Add MariaDB 10.5 repo
template: src=mariadb.list.j2 dest=/etc/apt/sources.list.d/mariadb.list owner=root group=root mode=0644
- name: Check MariaDB package signing key
ansible.builtin.stat:
path: /etc/apt/keyrings/mariadb_release_signing_key.asc
register: mariadb_signing_key_stat
tags:
- packages
- mariadb
- name: Download MariaDB package signing key
ansible.builtin.get_url:
url: https://mariadb.org/mariadb_release_signing_key.asc
dest: /etc/apt/keyrings/mariadb_release_signing_key.asc
owner: root
group: root
mode: "0644"
register: download_mariadb_signing_key
when: not mariadb_signing_key_stat.stat.exists
tags:
- packages
- mariadb
- name: Add MariaDB 10.11 repo
ansible.builtin.apt_repository:
repo: deb [arch=amd64 signed-by=/etc/apt/keyrings/mariadb_release_signing_key.asc] https://dlm.mariadb.com/repo/mariadb-server/10.11/repo/debian {{ ansible_distribution_release
}} main
filename: mariadb
state: present
register: add_mariadb_apt_repository
tags: mariadb, packages
tags:
- packages
- mariadb
- name: Update apt cache
apt:
update_cache: yes
when:
add_mariadb_apt_key is changed or
add_mariadb_apt_repository is changed
ansible.builtin.apt: # noqa no-handler
update_cache: true
when: (download_mariadb_signing_key.status_code is defined and download_mariadb_signing_key.status_code == 200) or add_mariadb_apt_repository is changed
tags:
- packages
- mariadb
- name: Install mariadb-server
apt: name={{ item }} state=present cache_valid_time=3600
loop:
- mariadb-server
- python3-pymysql # for ansible
ansible.builtin.apt:
name: [mariadb-server, python3-pymysql]
state: present
cache_valid_time: 3600
tags: mariadb, packages
- name: Create system my.cnf
template: src=my.cnf.j2 dest=/etc/mysql/my.cnf owner=root group=root mode=0644
ansible.builtin.template:
src: my.cnf.j2
dest: /etc/mysql/my.cnf
owner: root
group: root
mode: "0644"
notify:
- restart mariadb
tags: mariadb
# 'localhost' needs to be the last item for idempotency, see
# https://docs.ansible.com/ansible/latest/mysql_user_module.html
# See: https://docs.ansible.com/ansible/latest/collections/community/mysql/mysql_user_module.html
- name: Update MariaDB root password for all root accounts
mysql_user: name=root host={{ item }} password={{ mariadb_root_password }} login_unix_socket={{ mariadb_login_unix_socket }}
community.mysql.mysql_user:
name: root
host: "{{ item }}"
password: "{{ mariadb_root_password }}"
login_unix_socket: "{{ mariadb_login_unix_socket }}"
loop:
- "{{ inventory_hostname }}"
- 127.0.0.1
- ::1
- localhost
tags: mariadb
- name: Create .my.conf file with root credentials
template: src=.my.cnf.j2 dest=/root/.my.cnf owner=root mode=0600
ansible.builtin.template:
src: .my.cnf.j2
dest: /root/.my.cnf
owner: root
mode: "0600"
tags: mariadb
# See: https://docs.ansible.com/ansible/latest/collections/community/mysql/mysql_db_module.html
- name: Create MariaDB database(s)
mysql_db: db={{ item.name }} state=present encoding=utf8mb4
community.mysql.mysql_db:
db: "{{ item.name }}"
state: present
encoding: utf8mb4
login_unix_socket: "{{ mariadb_login_unix_socket }}"
loop: "{{ mariadb_databases }}"
when: mariadb_databases is defined
tags: mariadb
- name: Create MariaDB user(s)
mysql_user: name={{ item.user }} password={{ item.pass }} priv={{ item.name }}.*:ALL host=127.0.0.1 state=present
community.mysql.mysql_user:
name: "{{ item.user }}"
password: "{{ item.pass }}"
priv: "{{ item.name }}.*:ALL"
host: 127.0.0.1
state: present
login_unix_socket: "{{ mariadb_login_unix_socket }}"
loop: "{{ mariadb_databases }}"
when: mariadb_databases is defined
tags: mariadb

View File

@ -1,3 +0,0 @@
{{ ansible_managed | comment }}
deb [arch=amd64] http://mirror.23media.de/mariadb/repo/10.5/{{ ansible_distribution | lower }} {{ ansible_distribution_release }} main

View File

@ -19,14 +19,14 @@
# Remember to edit /etc/mysql/debian.cnf when changing the socket location.
[client]
port = 3306
socket = /var/run/mysqld/mysqld.sock
socket = /run/mysqld/mysqld.sock
# Here is entries for some specific programs
# The following values assume you have at least 32M ram
# This was formally known as [safe_mysqld]. Both versions are currently parsed.
[mysqld_safe]
socket = /var/run/mysqld/mysqld.sock
socket = /run/mysqld/mysqld.sock
nice = 0
[mysqld]
@ -34,8 +34,8 @@ nice = 0
# * Basic Settings
#
user = mysql
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
pid-file = /run/mysqld/mysqld.pid
socket = /run/mysqld/mysqld.sock
port = 3306
basedir = /usr
datadir = /var/lib/mysql

View File

@ -1,4 +1,4 @@
---
# file: roles/munin/handlers/main.yml
# ansible.builtin.file: roles/munin/handlers/main.yml
- name: restart munin-node
systemd: name=munin-node state=restarted
ansible.builtin.systemd: name=munin-node state=restarted

View File

@ -1,8 +1,8 @@
---
- name: Configure munin scraper
import_tasks: munin.yml
ansible.builtin.import_tasks: munin.yml
tags: munin
- name: Configure munin listener
import_tasks: munin-node.yml
ansible.builtin.import_tasks: munin-node.yml
tags: munin-node

View File

@ -1,25 +1,25 @@
---
- name: Install munin-node
apt: name=munin-node state=present
ansible.builtin.apt: name=munin-node state=present
tags: packages
# some nice things to have for munin-node on Ubuntu
# libwww-perl: for munin's nginx_status check
- name: Install munin-node deps
apt: name=libwww-perl state=present
ansible.builtin.apt: name=libwww-perl state=present
tags: packages
- name: Create munin-node.conf
template: src=munin-node.conf.j2 dest=/etc/munin/munin-node.conf
ansible.builtin.template: src=munin-node.conf.j2 dest=/etc/munin/munin-node.conf
notify:
- restart munin-node
- name: Configure munin-node
shell: munin-node-configure --shell --families=contrib,auto | sh -x
ansible.builtin.shell: munin-node-configure --shell --families=contrib,auto | sh -x
notify:
- restart munin-node
- name: Start munin-node
systemd: name=munin-node state=started enabled=true
ansible.builtin.systemd: name=munin-node state=started enabled=true
# vim: set ts=2 sw=2:

View File

@ -1,9 +1,9 @@
---
- name: Install munin package
apt: name=munin state=present
ansible.builtin.apt: name=munin state=present
tags: packages
- name: Create munin configuration file
template: src=munin.conf.j2 dest=/etc/munin/munin.conf owner=root group=root mode=0644
ansible.builtin.template: src=munin.conf.j2 dest=/etc/munin/munin.conf owner=root group=root mode=0644
# vim: set ts=2 sw=2:

View File

@ -1,5 +1,5 @@
---
# file: roles/nginx/defaults/main.yml
# ansible.builtin.file: roles/nginx/defaults/main.yml
# path config
nginx_confd_path: /etc/nginx/conf.d
@ -14,24 +14,31 @@ nginx_ssl_session_cache: shared:SSL:10m
# 1400 bytes to fit in one MTU (default is 16k!)
nginx_ssl_buffer_size: 1400
nginx_ssl_dhparam: /etc/ssl/certs/dhparam.pem
nginx_ssl_protocols: 'TLSv1.2 TLSv1.3'
nginx_ssl_protocols: TLSv1.2 TLSv1.3
# DNS resolvers for OCSP stapling (default to Cloudflare public DNS)
# See: https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_stapling
nginx_ssl_stapling_resolver: '1.1.1.1 1.0.0.1 [2606:4700:4700::1111] [2606:4700:4700::1001]'
nginx_ssl_stapling_resolver: 1.1.1.1 1.0.0.1 [2606:4700:4700::1111] [2606:4700:4700::1001]
# install certbot + dependencies?
# True unless you're in development and using "localhost" + snakeoil certs
use_letsencrypt: True
# HTTP Strict-Transport-Security header, recommended by Google to be ~1 year
# in seconds, see: https://hstspreload.org/
nginx_hsts_max_age: 31536000
# install acme.sh?
# true unless you're in development and using "localhost" + snakeoil certs
use_letsencrypt: true
# Directory root for Let's Encrypt certs
letsencrypt_root: /etc/letsencrypt/live
letsencrypt_root: /etc/ssl
# Location of Let's Encrypt's certbot script
letsencrypt_certbot_dest: /opt/certbot-auto
# Location where to save initial acme.sh script. After installation the script
# will automatically create its home in the /root/.acme.sh directory (including
# a copy of the script itself). The initial script is not needed after.
letsencrypt_acme_script_temp: /root/acme.sh
letsencrypt_acme_home: /root/.acme.sh
# stable is 1.18.x
# mainline is 1.19.x
# stable is 1.20.x
# mainline is 1.21.x
nginx_version: mainline
# vim: set ts=2 sw=2:

View File

@ -15,3 +15,6 @@ add_header X-XSS-Protection "1; mode=block" always;
# CSP can be quite difficult to configure, and cause real issues if you get it wrong
# There is website that helps you generate a policy here http://cspisawesome.com/
# add_header Content-Security-Policy "default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' https://www.google-analytics.com;" always;
# Opt this site out of Google Chrome's Federated Learning of Cohorts (FLoC)
add_header Permissions-Policy interest-cohort=() always;

View File

@ -1,3 +0,0 @@
#!/usr/bin/env bash
/bin/systemctl start nginx

View File

@ -1,3 +0,0 @@
#!/usr/bin/env bash
/bin/systemctl stop nginx

View File

@ -1,5 +1,5 @@
---
- name: reload nginx
systemd: name=nginx state=reloaded
ansible.builtin.systemd: name=nginx state=reloaded
# vim: set ts=2 sw=2:

View File

@ -1,137 +1,90 @@
---
# Use acme.sh instead of certbot because they only support installation via
# snap now.
- block:
- name: Copy systemd service to renew Let's Encrypt certs
template: src=renew-letsencrypt.service.j2 dest=/etc/systemd/system/renew-letsencrypt.service mode=0644 owner=root group=root
- name: Remove certbot
ansible.builtin.apt:
name: certbot
state: absent
- name: Copy systemd timer to renew Let's Encrypt certs
copy: src=renew-letsencrypt.timer dest=/etc/systemd/system/renew-letsencrypt.timer mode=0644 owner=root group=root
- name: Remove old certbot post and pre hooks for nginx
ansible.builtin.file:
dest: "{{ item }}"
state: absent
with_items:
- /etc/letsencrypt/renewal-hooks/pre/stop-nginx.sh
- /etc/letsencrypt/renewal-hooks/post/start-nginx.sh
# always issues daemon-reload just in case the server/timer changed
- name: Start and enable systemd timer to renew Let's Encrypt certs
systemd: name=renew-letsencrypt.timer state=started enabled=yes daemon_reload=yes
- name: Check if acme.sh is installed
ansible.builtin.stat:
path: "{{ letsencrypt_acme_home }}"
register: acme_home
- name: Download certbot
get_url: dest={{ letsencrypt_certbot_dest }} url=https://dl.eff.org/certbot-auto mode=700
- name: Download acme.sh
ansible.builtin.get_url:
url: https://raw.githubusercontent.com/acmesh-official/acme.sh/master/acme.sh
dest: "{{ letsencrypt_acme_script_temp }}"
mode: "0700"
register: acme_download
when: not acme_home.stat.exists
# Dependencies certbot checks for on its first run. I set them in a fact so that
# I can pass the list directly to the apt module to install in one transaction.
- name: Set certbot dependencies (Debian 10)
when: ansible_distribution == 'Debian' and ansible_distribution_major_version is version('10', '==')
set_fact:
certbot_dependencies:
- augeas-lenses
- binutils
- binutils-common
- binutils-x86-64-linux-gnu
- cpp
- cpp-8
- gcc
- gcc-8
- libasan5
- libatomic1
- libaugeas0
- libbinutils
- libc-dev-bin
- libc6-dev
- libcc1-0
- libexpat1-dev
- libffi-dev
- libgcc-8-dev
- libgomp1
- libisl19
- libitm1
- liblsan0
- libmpc3
- libmpfr6
- libmpx2
- libpython-dev
- libpython2-dev
- libpython2.7
- libpython2.7-dev
- libquadmath0
- libssl-dev
- libtsan0
- libubsan1
- linux-libc-dev
- python-dev
- python-pip-whl
- python-pkg-resources
- python-virtualenv
- python2-dev
- python2.7-dev
- python3-distutils
- python3-lib2to3
- python3-virtualenv
- virtualenv
# Run the "install" for acme.sh so it creates the .acme.sh dir (currently I
# have to chdir to the /root directory where the script exists or else it
# fails. Ansible runs it, but the script can't find itself...).
- name: Install acme.sh
ansible.builtin.command:
cmd: "{{ letsencrypt_acme_script_temp }} --install --no-profile --no-cron"
creates: "{{ letsencrypt_acme_home }}/acme.sh"
chdir: /root
register: acme_install
when: acme_download is changed
# Dependencies certbot checks for on its first run. I set them in a fact so that
# I can pass the list directly to the apt module to install in one transaction.
- name: Set certbot dependencies (Ubuntu 18.04)
when: ansible_distribution == 'Ubuntu' and ansible_distribution_version is version('18.04', '==')
set_fact:
certbot_dependencies:
- augeas-lenses
- binutils
- binutils-common
- binutils-x86-64-linux-gnu
- cpp
- cpp-7
- gcc
- gcc-7
- gcc-7-base
- libasan4
- libatomic1
- libaugeas0
- libbinutils
- libc-dev-bin
- libc6-dev
- libcc1-0
- libcilkrts5
- libexpat1-dev
- libffi-dev
- libgcc-7-dev
- libgomp1
- libisl19
- libitm1
- liblsan0
- libmpc3
- libmpx2
- libpython-dev
- libpython2.7
- libpython2.7-dev
- libquadmath0
- libssl-dev
- libtsan0
- libubsan0
- linux-libc-dev
- python-dev
- python-pip-whl
- python-pkg-resources
- python-virtualenv
- python2.7-dev
- python3-virtualenv
- virtualenv
- name: Remove temporary acme.sh script
ansible.builtin.file:
dest: "{{ letsencrypt_acme_script_temp }}"
state: absent
when:
- acme_install.rc is defined
- acme_install.rc == 0
- name: Install certbot dependencies
apt: name={{ certbot_dependencies }} state=present update_cache=yes
- name: Set default certificate authority for acme.sh
ansible.builtin.command:
cmd: "{{ letsencrypt_acme_home }}/acme.sh --set-default-ca --server letsencrypt"
when: ansible_distribution != 'Ubuntu' and ansible_distribution_major_version is version('20.04', '!=')
tags: letsencrypt
- name: Prepare Let's Encrypt well-known directory
ansible.builtin.file:
state: directory
path: /var/lib/letsencrypt/.well-known
owner: root
group: nginx
mode: g+s
# On Ubuntu 20.04 it is no longer recommended/supported to use the standalone
# certbot-auto so I guess we need to use the one from the repositories.
- block:
- name: Install certbot (Ubuntu 20.04)
apt: name=certbot state=present update_cache=yes
- name: Copy systemd service to renew Let's Encrypt certs
ansible.builtin.template:
src: renew-letsencrypt.service.j2
dest: /etc/systemd/system/renew-letsencrypt.service
mode: "0644"
owner: root
group: root
- name: Copy certbot post and pre hooks for nginx
copy: src={{ item.src }} dest={{ item.dest }} owner=root group=root mode=0755
with_items:
- { src: 'stop-nginx.sh', dest: '/etc/letsencrypt/renewal-hooks/pre/stop-nginx.sh' }
- { src: 'start-nginx.sh', dest: '/etc/letsencrypt/renewal-hooks/post/start-nginx.sh' }
- name: Copy systemd timer to renew Let's Encrypt certs
ansible.builtin.copy:
src: renew-letsencrypt.timer
dest: /etc/systemd/system/renew-letsencrypt.timer
mode: "0644"
owner: root
group: root
when: ansible_distribution == 'Ubuntu' and ansible_distribution_version is version('20.04', '==')
# always issues daemon-reload just in case the service/timer changed
- name: Start and enable systemd timer to renew Let's Encrypt certs
ansible.builtin.systemd:
name: renew-letsencrypt.timer
state: started
enabled: true
daemon_reload: true
when: (ansible_distribution == 'Ubuntu' and ansible_distribution_version is version('20.04', '==')) or (ansible_distribution == 'Debian' and ansible_distribution_version
is version('11', '>='))
tags: letsencrypt
# vim: set ts=2 sw=2:

View File

@ -1,33 +1,77 @@
---
- name: Add nginx.org apt signing key
apt_key: id=0x573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62 url=https://nginx.org/keys/nginx_signing.key state=present
register: add_nginx_apt_key
tags: nginx, packages
- name: Remove nginx apt signing key from apt-key
ansible.builtin.apt_key:
id: "053473772654754373614404074646527257655730117366337542"
state: absent
tags:
- packages
- nginx
- name: Check nginx apt signing key
ansible.builtin.stat:
path: /usr/share/keyrings/nginx_signing.key
register: nginx_signing_key_stat
tags:
- packages
- nginx
- name: Download nginx apt signing key
ansible.builtin.get_url:
url: https://nginx.org/keys/nginx_signing.key
dest: /usr/share/keyrings/nginx_signing.key
owner: root
group: root
mode: "0644"
register: download_nginx_signing_key
when: not nginx_signing_key_stat.stat.exists
tags:
- packages
- nginx
- name: Add nginx.org repo
template: src=nginx_org_sources.list.j2 dest=/etc/apt/sources.list.d/nginx_org_sources.list owner=root group=root mode=0644
ansible.builtin.template:
src: nginx_org_sources.list.j2
dest: /etc/apt/sources.list.d/nginx_org_sources.list
owner: root
group: root
mode: "0644"
register: add_nginx_apt_repository
tags: nginx, packages
tags:
- nginx
- packages
- name: Update apt cache
apt:
update_cache: yes
when:
add_nginx_apt_key is changed or
add_nginx_apt_repository is changed
ansible.builtin.apt: # noqa no-handler
update_cache: true
when: (download_nginx_signing_key.status_code is defined and download_nginx_signing_key.status_code == 200) or add_nginx_apt_repository is changed
- name: Install nginx
apt: pkg=nginx cache_valid_time=3600 state=present
tags: nginx, packages
ansible.builtin.apt:
pkg: nginx
cache_valid_time: 3600
state: present
tags:
- nginx
- packages
- name: Copy nginx.conf
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf mode=0644 owner=root group=root
ansible.builtin.template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
mode: "0644"
owner: root
group: root
notify:
- reload nginx
tags: nginx
- name: Copy extra nginx configs
copy: src={{ item }} dest=/etc/nginx/{{ item }} mode=0644 owner=root group=root
ansible.builtin.copy:
src: "{{ item }}"
dest: /etc/nginx/{{ item }}
mode: "0644"
owner: root
group: root
loop:
- extra-security.conf
- fastcgi_cache
@ -36,42 +80,61 @@
tags: nginx
- name: Remove default nginx vhost
file: path=/etc/nginx/conf.d/default.conf state=absent
ansible.builtin.file:
path: /etc/nginx/conf.d/default.conf
state: absent
tags: nginx
- name: Create fastcgi cache dir
file: path=/var/cache/nginx/cached/fastcgi state=directory owner=nginx group=nginx mode=0755
ansible.builtin.file:
path: /var/cache/nginx/cached/fastcgi
state: directory
owner: nginx
group: nginx
mode: "0755"
tags: nginx
- name: Configure nginx virtual hosts
include_tasks: vhosts.yml
ansible.builtin.include_tasks: vhosts.yml
when: nginx_vhosts is defined
tags: nginx
- name: Configure WordPress
include_tasks: wordpress.yml
ansible.builtin.include_tasks: wordpress.yml
when: nginx_vhosts is defined
tags: wordpress
- name: Configure blank nginx vhost
template: src=blank-vhost.conf.j2 dest={{ nginx_confd_path }}/blank-vhost.conf mode=0644 owner=root group=root
ansible.builtin.template:
src: blank-vhost.conf.j2
dest: "{{ nginx_confd_path }}/blank-vhost.conf"
mode: "0644"
owner: root
group: root
notify:
- reload nginx
tags: nginx
- name: Configure munin vhost
copy: src=munin.conf dest=/etc/nginx/conf.d/munin.conf mode=0644 owner=root group=root
ansible.builtin.copy:
src: munin.conf
dest: /etc/nginx/conf.d/munin.conf
mode: "0644"
owner: root
group: root
notify:
- reload nginx
tags: nginx
- name: Start and enable nginx service
systemd: name=nginx state=started enabled=yes
ansible.builtin.systemd:
name: nginx
state: started
enabled: true
tags: nginx
- name: Configure Let's Encrypt
include_tasks: letsencrypt.yml
when: use_letsencrypt is defined and use_letsencrypt
ansible.builtin.include_tasks: letsencrypt.yml
tags: letsencrypt
# vim: set ts=2 sw=2:

View File

@ -1,25 +1,29 @@
---
- block:
- name: Configure https vhosts
template: src=vhost.conf.j2 dest={{ nginx_confd_path }}/{{ item.domain_name }}.conf mode=0644 owner=root group=root
loop: "{{ nginx_vhosts }}"
notify:
- reload nginx
- name: Configure https vhosts
ansible.builtin.template: src=vhost.conf.j2 dest={{ nginx_confd_path }}/{{ item.domain_name }}.conf mode=0644 owner=root group=root
loop: "{{ nginx_vhosts }}"
notify:
- reload nginx
- name: Generate self-signed TLS cert
command: openssl req -x509 -nodes -sha256 -days 365 -subj "/C=SO/ST=SO/L=snakeoil/O=snakeoil/CN=snakeoil" -newkey rsa:2048 -keyout /etc/ssl/private/nginx-snakeoil.key -out /etc/ssl/certs/nginx-snakeoil.crt -extensions v3_ca creates=/etc/ssl/certs/nginx-snakeoil.crt
notify:
- reload nginx
- name: Generate self-signed TLS cert
ansible.builtin.command: openssl req -x509 -nodes -sha256 -days 365 -subj "/C=SO/ST=SO/L=snakeoil/O=snakeoil/CN=snakeoil" -newkey rsa:2048 -keyout /etc/ssl/private/nginx-snakeoil.key
-out /etc/ssl/certs/nginx-snakeoil.crt -extensions v3_ca creates=/etc/ssl/certs/nginx-snakeoil.crt
notify:
- reload nginx
- name: Generate 2048-bit dhparam
command: openssl dhparam -out dhparam.pem 2048 chdir=/etc/ssl/certs creates=dhparam.pem
notify:
- reload nginx
- name: Download 4096-bit RFC 7919 dhparams
ansible.builtin.get_url:
url: https://raw.githubusercontent.com/internetstandards/dhe_groups/master/ffdhe4096.pem
checksum: sha256:64852d6890ff9e62eecd1ee89c72af9af244dfef5b853bcedea3dfd7aade22b3
dest: "{{ nginx_ssl_dhparam }}"
notify:
- reload nginx
- name: Create vhost document roots
file: path={{ nginx_root_prefix }}/{{ item.domain_name }} state=directory mode=0755 owner=nginx group=nginx
loop: "{{ nginx_vhosts }}"
# TODO: this could break because we can override the document root in host vars
- name: Create vhost document roots
ansible.builtin.file: path={{ nginx_root_prefix }}/{{ item.domain_name }} state=directory mode=0755 owner=nginx group=nginx
loop: "{{ nginx_vhosts }}"
tags: nginx
# vim: set ts=2 sw=2:

View File

@ -1,15 +1,19 @@
---
- block:
- name: Install WordPress
git: repo=https://github.com/WordPress/WordPress.git dest={{ nginx_root_prefix }}/{{ item.domain_name }}/wordpress version={{ item.wordpress_version }} depth=1 force=yes
when: item.has_wordpress is defined and item.has_wordpress
loop: "{{ nginx_vhosts }}"
- name: Install WordPress
ansible.builtin.git: repo=https://github.com/WordPress/WordPress.git dest={{ nginx_root_prefix }}/{{ item.domain_name }}/wordpress version={{ item.wordpress_version
}} depth=1 force=true
when:
- item.has_wordpress is defined
- item.has_wordpress
loop: "{{ nginx_vhosts }}"
- name: Fix WordPress directory permissions
file: path={{ nginx_root_prefix }}/{{ item.domain_name }} state=directory owner=nginx group=nginx recurse=yes
when: item.has_wordpress is defined and item.has_wordpress
loop: "{{ nginx_vhosts }}"
- name: Fix WordPress directory permissions
ansible.builtin.file: path={{ nginx_root_prefix }}/{{ item.domain_name }} state=directory owner=nginx group=nginx recurse=true
when:
- item.has_wordpress is defined
- item.has_wordpress
loop: "{{ nginx_vhosts }}"
tags: wordpress
# vim: set ts=2 sw=2:

View File

@ -16,7 +16,7 @@ server {
listen [::]:443 ssl http2 default_server;
server_name _;
# "snakeoil" certificate (self signed!)
# self-signed "snakeoil" certificate
ssl_certificate /etc/ssl/certs/nginx-snakeoil.crt;
ssl_certificate_key /etc/ssl/private/nginx-snakeoil.key;

View File

@ -0,0 +1,5 @@
location / {
proxy_pass http://localhost:3000;
}

View File

@ -1,7 +1,7 @@
{# helper variables and per-site defaults that we can't set in role defaults #}
{% set domain_name = item.domain_name %}
{# assume HSTS is off unless a vhost explicitly sets it to True #}
{% set enable_hsts = item.enable_hsts | default(False) %}
{# assume HSTS is off unless a vhost explicitly sets it to true #}
{% set enable_hsts = item.enable_hsts | default(false) %}
{# first, check if the current vhost has a custom cert (perhaps self-signed) #}
{% if item.tls_certificate_path is defined and item.tls_key_path is defined %}
@ -16,8 +16,8 @@
# concatenated key + cert
# See: http://nginx.org/en/docs/http/configuring_https_servers.html
ssl_certificate {{ letsencrypt_root }}/{{ domain_name }}/fullchain.pem;
ssl_certificate_key {{ letsencrypt_root }}/{{ domain_name }}/privkey.pem;
ssl_certificate {{ letsencrypt_root }}/certs/{{ domain_name }}.fullchain.pem;
ssl_certificate_key {{ letsencrypt_root }}/private/{{ domain_name }}.key.pem;
{% endif %}
@ -31,7 +31,7 @@
ssl_prefer_server_ciphers on;
{# OSCP stapling only works with real certs #}
{% if use_letsencrypt == True or item.tls_certificate_path %}
{% if use_letsencrypt == true or item.tls_certificate_path %}
# OCSP stapling...
ssl_stapling on;
ssl_stapling_verify on;
@ -47,9 +47,9 @@
# of such infrastructure, consider turning off session tickets:
ssl_session_tickets off;
{% if enable_hsts == True %}
{% if enable_hsts == true %}
# Enable this if you want HSTS (recommended, but be careful)
# Include all subdomains and indicate to Google that we want this pre-loaded in Chrome's HSTS store
# See: https://hstspreload.appspot.com/
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload" always;
add_header Strict-Transport-Security "max-age={{ nginx_hsts_max_age }}; includeSubDomains; preload" always;
{% endif %}

View File

@ -3,17 +3,17 @@
{% if ansible_distribution == 'Ubuntu' %}
{% if nginx_version == "stable" %}
deb [arch=amd64] https://nginx.org/packages/ubuntu/ {{ ansible_distribution_release }} nginx
deb [arch=amd64 signed-by=/usr/share/keyrings/nginx_signing.key] https://nginx.org/packages/ubuntu/ {{ ansible_distribution_release }} nginx
{% elif nginx_version == "mainline" %}
deb [arch=amd64] https://nginx.org/packages/mainline/ubuntu/ {{ ansible_distribution_release }} nginx
deb [arch=amd64 signed-by=/usr/share/keyrings/nginx_signing.key] https://nginx.org/packages/mainline/ubuntu/ {{ ansible_distribution_release }} nginx
{% endif %}
{% elif ansible_distribution == 'Debian' %}
{% if nginx_version == "stable" %}
deb [arch=amd64] https://nginx.org/packages/debian/ {{ ansible_distribution_release }} nginx
deb [arch=amd64 signed-by=/usr/share/keyrings/nginx_signing.key] https://nginx.org/packages/debian/ {{ ansible_distribution_release }} nginx
{% elif nginx_version == "mainline" %}
deb [arch=amd64] https://nginx.org/packages/mainline/debian/ {{ ansible_distribution_release }} nginx
deb [arch=amd64 signed-by=/usr/share/keyrings/nginx_signing.key] https://nginx.org/packages/mainline/debian/ {{ ansible_distribution_release }} nginx
{% endif %}
{% endif %}

View File

@ -1,7 +1,9 @@
[Unit]
Description=Renew Let's Encrypt certificates
ConditionFileIsExecutable={{ letsencrypt_certbot_dest }}
ConditionFileIsExecutable={{ letsencrypt_acme_home }}/acme.sh
[Service]
Type=oneshot
ExecStart={{ letsencrypt_certbot_dest }} renew --standalone --pre-hook "/bin/systemctl stop nginx" --post-hook "/bin/systemctl start nginx"
ExecStart={{ letsencrypt_acme_home }}/acme.sh --cron --home {{ letsencrypt_acme_home }} --reloadcmd "/bin/systemctl reload nginx" -w /var/lib/letsencrypt
SuccessExitStatus=0 2

View File

@ -4,9 +4,10 @@
{% set domain_name = item.domain_name %}
{% set domain_aliases = item.domain_aliases | default("") %}
{# assume optional features are off unless a vhost explicitly sets them #}
{% set enable_hsts = item.enable_hsts | default(False) %}
{% set has_wordpress = item.has_wordpress | default(False) %}
{% set needs_php = item.needs_php | default(False) %}
{% set enable_hsts = item.enable_hsts | default(false) %}
{% set has_wordpress = item.has_wordpress | default(false) %}
{% set needs_php = item.needs_php | default(false) %}
{% set has_gitea = item.has_gitea | default(false) %}
# http -> https vhost
server {
@ -14,6 +15,8 @@ server {
listen [::]:80;
server_name {{ domain_name }} {{ domain_aliases }};
{% include 'well-known.j2' %}
# redirect http -> https
location / {
# ? in rewrite makes sure nginx doesn't append query string again
@ -36,23 +39,27 @@ server {
{# will only work if the TLS cert covers the domain + aliases, like example.com and www.example.com #}
server_name {{ domain_name }} {{ domain_aliases }};
index {% if has_wordpress == True or needs_php == True %}index.php{% else %}index.html{% endif %};
index {% if has_wordpress == true or needs_php == true %}index.php{% else %}index.html{% endif %};
access_log /var/log/nginx/{{ domain_name }}-access.log;
error_log /var/log/nginx/{{ domain_name }}-error.log;
{% include 'https.j2' %}
{% if has_wordpress == True %}
{% if has_wordpress == true %}
{% include 'wordpress.j2' %}
{% endif %}
{% if has_gitea == true %}
{% include 'gitea.j2' %}
{% endif %}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
{% if has_wordpress == True or needs_php == True %}
{% if has_wordpress == true or needs_php == true %}
location ~ [^/]\.php(/|$) {
# Zero-day exploit defense.
# http://forum.nginx.org/read.php?2,88845,page=3
@ -68,14 +75,9 @@ server {
# See: https://httpoxy.org/
fastcgi_param HTTP_PROXY "";
{# As of Ubuntu 16.04 and Debian 9, the PHP-FPM configs are the same #}
{% if (ansible_distribution == 'Ubuntu' and ansible_distribution_version is version('16.04', '==')) or (ansible_distribution == 'Debian' and ansible_distribution_major_version is version('9', '==')) %}
fastcgi_pass unix:/run/php/php7.0-fpm-{{ domain_name }}.sock;
{% elif ansible_distribution == 'Ubuntu' and ansible_distribution_version is version('18.04', '==') %}
fastcgi_pass unix:/run/php/php7.2-fpm-{{ domain_name }}.sock;
{% elif ansible_distribution == 'Debian' and ansible_distribution_version is version('10', '==') %}
fastcgi_pass unix:/run/php/php7.3-fpm-{{ domain_name }}.sock;
{% elif ansible_distribution == 'Ubuntu' and ansible_distribution_version is version('20.04', '==') %}
{% if ansible_distribution == 'Debian' and ansible_distribution_major_version is version('12', '==') %}
fastcgi_pass unix:/run/php/php8.2-fpm-{{ domain_name }}.sock;
{% elif (ansible_distribution == 'Ubuntu' and ansible_distribution_version is version('20.04', '==')) or (ansible_distribution == 'Debian' and ansible_distribution_major_version is version('11', '==')) %}
fastcgi_pass unix:/run/php/php7.4-fpm-{{ domain_name }}.sock;
{% else %}
fastcgi_pass unix:/var/run/php5-fpm-{{ domain_name }}.sock;
@ -92,11 +94,11 @@ server {
fastcgi_cache_bypass $http_pragma $wordpress_logged_in;
fastcgi_no_cache $http_pragma $wordpress_logged_in;
{% if enable_hsts == True %}
{% if enable_hsts == true %}
# Enable this if you want HSTS (recommended, but be careful)
# Include all subdomains and indicate to Google that we want this pre-loaded in Chrome's HSTS store
# See: https://hstspreload.appspot.com/
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload" always;
add_header Strict-Transport-Security "max-age={{ nginx_hsts_max_age }}; includeSubDomains; preload" always;
{% endif %}
include extra-security.conf;
@ -106,7 +108,7 @@ server {
include extra-security.conf;
}
{% if has_wordpress == True %}
{% if has_wordpress == true %}
# Check if a user is logged in
# if so, set $wordpress_logged_in = 1
# otherwise, set $wordpress_logged_in = 0

View File

@ -0,0 +1,6 @@
location ^~ /.well-known/acme-challenge/ {
allow all;
root /var/lib/letsencrypt/;
default_type "text/plain";
try_files $uri =404;
}

View File

@ -5,22 +5,22 @@
location / {
try_files $uri $uri/ /index.php?$args;
{% if enable_hsts == True %}
{% if enable_hsts == true %}
# Enable this if you want HSTS (recommended, but be careful)
# Include all subdomains and indicate to Google that we want this pre-loaded in Chrome's HSTS store
# See: https://hstspreload.appspot.com/
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload" always;
add_header Strict-Transport-Security "max-age={{ nginx_hsts_max_age }}; includeSubDomains; preload" always;
{% endif %}
}
location ~* \.(?:ico|css|js|gif|jpe?g|png|svg)$ {
add_header Cache-Control "max-age=604800";
{% if enable_hsts == True %}
{% if enable_hsts == true %}
# Enable this if you want HSTS (recommended, but be careful)
# Include all subdomains and indicate to Google that we want this pre-loaded in Chrome's HSTS store
# See: https://hstspreload.appspot.com/
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload" always;
add_header Strict-Transport-Security "max-age={{ nginx_hsts_max_age }}; includeSubDomains; preload" always;
{% endif %}
}

View File

@ -1,5 +1,5 @@
---
# file: roles/php-fpm/defaults/main.yml
# ansible.builtin.file: roles/php-fpm/defaults/main.yml
# default is on, but turn it off because of protection in nginx vhosts
cgi_fix_pathinfo: 0

View File

@ -1,14 +1,12 @@
---
# For Ubuntu 18.04
- name: reload php7.2-fpm
systemd: name=php7.2-fpm state=reloaded
# For Debian 10
- name: reload php7.3-fpm
systemd: name=php7.3-fpm state=reloaded
# For Ubuntu 20.04
# For Ubuntu 20.04 and Debian 11
- name: reload php7.4-fpm
systemd: name=php7.4-fpm state=reloaded
ansible.builtin.systemd: name=php7.4-fpm state=reloaded
# For Debian 12
- name: reload php8.2-fpm
ansible.builtin.systemd:
name: php8.2-fpm
state: reloaded
# vim: set ts=2 sw=2:

View File

@ -1,34 +0,0 @@
---
- block:
- name: Set php-fpm packages
set_fact:
php_fpm_packages:
- php-fpm
# for WordPress
- php-mysql
- php-gd
- php-curl
- name: Install php-fpm and deps
apt: name={{ php_fpm_packages }} state=present update_cache=yes
# only copy php-fpm config for vhosts that need WordPress or PHP
- name: Copy php-fpm pool config
template: src=php7.3-pool.conf.j2 dest=/etc/php/7.3/fpm/pool.d/{{ item.domain_name }}.conf owner=root group=root mode=0644
loop: "{{ nginx_vhosts }}"
when: (item.has_wordpress is defined and item.has_wordpress) or (item.needs_php is defined and item.needs_php)
notify: reload php7.3-fpm
- name: Remove default www pool
file: path=/etc/php/7.3/fpm/pool.d/www.conf state=absent
notify: reload php7.3-fpm
# re-configure php.ini
- name: Update php.ini
template: src=php7.3-php.ini.j2 dest=/etc/php/7.3/fpm/php.ini owner=root group=root mode=0644
notify: reload php7.3-fpm
tags: php-fpm
when: (item.has_wordpress is defined and item.has_wordpress) or (item.needs_php is defined and item.needs_php)
# vim: set ts=2 sw=2:

View File

@ -0,0 +1,50 @@
---
- block:
- name: Set php-fpm packages
ansible.builtin.set_fact:
php_fpm_packages:
- php8.2-fpm
# for WordPress
- php8.2-mysql
- php8.2-gd
- php8.2-curl
- php8.2-xml
- name: Install php-fpm and deps
ansible.builtin.apt:
name: "{{ php_fpm_packages }}"
state: present
update_cache: true
# only copy php-fpm config for vhosts that need WordPress or PHP
- name: Copy php-fpm pool config
ansible.builtin.template:
src: php8.2-pool.conf.j2
dest: /etc/php/8.2/fpm/pool.d/{{ item.domain_name }}.conf
owner: root
group: root
mode: "0644"
loop: "{{ nginx_vhosts }}"
when: (item.has_wordpress is defined and item.has_wordpress) or (item.needs_php is defined and item.needs_php)
notify: reload php8.2-fpm
- name: Remove default www pool
ansible.builtin.file:
path: /etc/php/8.2/fpm/pool.d/www.conf
state: absent
notify: reload php8.2-fpm
# re-configure php.ini
- name: Update php.ini
ansible.builtin.template:
src: php8.2-php.ini.j2
dest: /etc/php/8.2/fpm/php.ini
owner: root
group: root
mode: "0644"
notify: reload php8.2-fpm
tags: php-fpm
when: install_php
# vim: set ts=2 sw=2:

View File

@ -1,34 +0,0 @@
---
- block:
- name: Set php-fpm packages
set_fact:
php_fpm_packages:
- php-fpm
# for WordPress
- php-mysql
- php-gd
- php-curl
- name: Install php-fpm and deps
apt: name={{ php_fpm_packages }} state=present update_cache=yes
# only copy php-fpm config for vhosts that need WordPress or PHP
- name: Copy php-fpm pool config
template: src=php7.2-pool.conf.j2 dest=/etc/php/7.2/fpm/pool.d/{{ item.domain_name }}.conf owner=root group=root mode=0644
loop: "{{ nginx_vhosts }}"
when: (item.has_wordpress is defined and item.has_wordpress) or (item.needs_php is defined and item.needs_php)
notify: reload php7.2-fpm
- name: Remove default www pool
file: path=/etc/php/7.2/fpm/pool.d/www.conf state=absent
notify: reload php7.2-fpm
# re-configure php.ini
- name: Update php.ini
template: src=php7.2-php.ini.j2 dest=/etc/php/7.2/fpm/php.ini owner=root group=root mode=0644
notify: reload php7.2-fpm
tags: php-fpm
when: (item.has_wordpress is defined and item.has_wordpress) or (item.needs_php is defined and item.needs_php)
# vim: set ts=2 sw=2:

View File

@ -1,34 +1,35 @@
---
- block:
- name: Set php-fpm packages
set_fact:
php_fpm_packages:
- php-fpm
# for WordPress
- php-mysql
- php-gd
- php-curl
- name: Set php-fpm packages
ansible.builtin.set_fact:
php_fpm_packages:
- php7.4-fpm
# for WordPress
- php7.4-mysql
- php7.4-gd
- php7.4-curl
- php7.4-xml
- name: Install php-fpm and deps
apt: name={{ php_fpm_packages }} state=present update_cache=yes
- name: Install php-fpm and deps
ansible.builtin.apt: name={{ php_fpm_packages }} state=present update_cache=true
# only copy php-fpm config for vhosts that need WordPress or PHP
- name: Copy php-fpm pool config
template: src=php7.4-pool.conf.j2 dest=/etc/php/7.4/fpm/pool.d/{{ item.domain_name }}.conf owner=root group=root mode=0644
loop: "{{ nginx_vhosts }}"
when: (item.has_wordpress is defined and item.has_wordpress) or (item.needs_php is defined and item.needs_php)
notify: reload php7.4-fpm
# only copy php-fpm config for vhosts that need WordPress or PHP
- name: Copy php-fpm pool config
ansible.builtin.template: src=php7.4-pool.conf.j2 dest=/etc/php/7.4/fpm/pool.d/{{ item.domain_name }}.conf owner=root group=root mode=0644
loop: "{{ nginx_vhosts }}"
when: (item.has_wordpress is defined and item.has_wordpress) or (item.needs_php is defined and item.needs_php)
notify: reload php7.4-fpm
- name: Remove default www pool
file: path=/etc/php/7.4/fpm/pool.d/www.conf state=absent
notify: reload php7.4-fpm
- name: Remove default www pool
ansible.builtin.file: path=/etc/php/7.4/fpm/pool.d/www.conf state=absent
notify: reload php7.4-fpm
# re-configure php.ini
- name: Update php.ini
ansible.builtin.template: src=php7.4-php.ini.j2 dest=/etc/php/7.4/fpm/php.ini owner=root group=root mode=0644
notify: reload php7.4-fpm
# re-configure php.ini
- name: Update php.ini
template: src=php7.4-php.ini.j2 dest=/etc/php/7.4/fpm/php.ini owner=root group=root mode=0644
notify: reload php7.4-fpm
tags: php-fpm
when: (item.has_wordpress is defined and item.has_wordpress) or (item.needs_php is defined and item.needs_php)
when: install_php
# vim: set ts=2 sw=2:

View File

@ -1,21 +1,53 @@
---
# Ubuntu 18.04 uses php-fpm 7.2
# Debian 10 uses php-fpm 7.3
# Ubuntu 20.04 uses PHP 7.4
# Debian 11 uses PHP 7.4
# Debian 12 uses PHP 8.2
- name: Configure php-fpm on Ubuntu 18.04
include_tasks: Ubuntu_18.04.yml
when: ansible_distribution == 'Ubuntu' and ansible_distribution_version is version('18.04', '==')
tags: php-fpm
# If any of the vhosts on this host need WordPress then we need to install PHP.
# This uses selectattr to filter the list of dicts in nginx_vhosts, selecting
# any that have has_wordpress defined, and has_wordpress set to true.
#
# See: https://stackoverflow.com/a/31896249
- name: Check if any vhost needs WordPress
ansible.builtin.set_fact:
install_php: true
when: nginx_vhosts | selectattr('has_wordpress', 'defined') | selectattr('has_wordpress', 'equalto', true) | list | length > 0
- name: Configure php-fpm on Debian 10
include_tasks: Debian_10.yml
when: ansible_distribution == 'Debian' and ansible_distribution_version is version('10', '==')
tags: php-fpm
# Legacy, was only for Piwik, but leaving for now.
- name: Check if any vhost needs PHP
ansible.builtin.set_fact:
install_php: true
when: nginx_vhosts | selectattr('needs_php', 'defined') | selectattr('needs_php', 'equalto', true) | list | length > 0
# If install_php has not been set, then we assume no vhosts need PHP. This is
# a bit hacky, but it's the closest we come to an if/then/else.
- name: Set install_php to false
ansible.builtin.set_fact:
install_php: false
when: install_php is not defined
- name: Configure php-fpm on Ubuntu 20.04
include_tasks: Ubuntu_20.04.yml
when: ansible_distribution == 'Ubuntu' and ansible_distribution_version is version('20.04', '==')
ansible.builtin.include_tasks: Ubuntu_20.04.yml
when:
- ansible_distribution == 'Ubuntu'
- ansible_distribution_version is version('20.04', '==')
- install_php
tags: php-fpm
- name: Configure php-fpm on Debian 11
ansible.builtin.include_tasks: Ubuntu_20.04.yml
when:
- ansible_distribution == 'Debian'
- ansible_distribution_major_version is version('11', '==')
- install_php
tags: php-fpm
- name: Configure php-fpm on Debian 12
ansible.builtin.include_tasks: Debian_12.yml
when:
- ansible_distribution == 'Debian'
- ansible_distribution_major_version is version('12', '==')
- install_php
tags: php-fpm
# vim: set ts=2 sw=2:

File diff suppressed because it is too large Load Diff

View File

@ -1,415 +0,0 @@
{% set domain_name = item.domain_name %}
; Start a new pool named '{{ domain_name }}'.
; the variable $pool can we used in any directive and will be replaced by the
; pool name ('{{ domain_name }}' here)
[{{ domain_name }}]
; Per pool prefix
; It only applies on the following directives:
; - 'access.log'
; - 'slowlog'
; - 'listen' (unixsocket)
; - 'chroot'
; - 'chdir'
; - 'php_values'
; - 'php_admin_values'
; When not set, the global prefix (or /usr) applies instead.
; Note: This directive can also be relative to the global prefix.
; Default Value: none
;prefix = /path/to/pools/$pool
; Unix user/group of processes
; Note: The user is mandatory. If the group is not set, the default user's group
; will be used.
user = nginx
group = nginx
; The address on which to accept FastCGI requests.
; Valid syntaxes are:
; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific IPv4 address on
; a specific port;
; '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on
; a specific port;
; 'port' - to listen on a TCP socket to all addresses
; (IPv6 and IPv4-mapped) on a specific port;
; '/path/to/unix/socket' - to listen on a unix socket.
; Note: This value is mandatory.
listen = /run/php/php7.2-fpm-{{ domain_name }}.sock
; Set listen(2) backlog.
; Default Value: 511 (-1 on FreeBSD and OpenBSD)
;listen.backlog = 511
; Set permissions for unix socket, if one is used. In Linux, read/write
; permissions must be set in order to allow connections from a web server. Many
; BSD-derived systems allow connections regardless of permissions.
; Default Values: user and group are set as the running user
; mode is set to 0660
listen.owner = nginx
listen.group = nginx
;listen.mode = 0660
; When POSIX Access Control Lists are supported you can set them using
; these options, value is a comma separated list of user/group names.
; When set, listen.owner and listen.group are ignored
;listen.acl_users =
;listen.acl_groups =
; List of addresses (IPv4/IPv6) of FastCGI clients which are allowed to connect.
; Equivalent to the FCGI_WEB_SERVER_ADDRS environment variable in the original
; PHP FCGI (5.2.2+). Makes sense only with a tcp listening socket. Each address
; must be separated by a comma. If this value is left blank, connections will be
; accepted from any ip address.
; Default Value: any
;listen.allowed_clients = 127.0.0.1
; Specify the nice(2) priority to apply to the pool processes (only if set)
; The value can vary from -19 (highest priority) to 20 (lower priority)
; Note: - It will only work if the FPM master process is launched as root
; - The pool processes will inherit the master process priority
; unless it specified otherwise
; Default Value: no set
; process.priority = -19
; Choose how the process manager will control the number of child processes.
; Possible Values:
; static - a fixed number (pm.max_children) of child processes;
; dynamic - the number of child processes are set dynamically based on the
; following directives. With this process management, there will be
; always at least 1 children.
; pm.max_children - the maximum number of children that can
; be alive at the same time.
; pm.start_servers - the number of children created on startup.
; pm.min_spare_servers - the minimum number of children in 'idle'
; state (waiting to process). If the number
; of 'idle' processes is less than this
; number then some children will be created.
; pm.max_spare_servers - the maximum number of children in 'idle'
; state (waiting to process). If the number
; of 'idle' processes is greater than this
; number then some children will be killed.
; ondemand - no children are created at startup. Children will be forked when
; new requests will connect. The following parameter are used:
; pm.max_children - the maximum number of children that
; can be alive at the same time.
; pm.process_idle_timeout - The number of seconds after which
; an idle process will be killed.
; Note: This value is mandatory.
pm = dynamic
; The number of child processes to be created when pm is set to 'static' and the
; maximum number of child processes when pm is set to 'dynamic' or 'ondemand'.
; This value sets the limit on the number of simultaneous requests that will be
; served. Equivalent to the ApacheMaxClients directive with mpm_prefork.
; Equivalent to the PHP_FCGI_CHILDREN environment variable in the original PHP
; CGI. The below defaults are based on a server without much resources. Don't
; forget to tweak pm.* to fit your needs.
; Note: Used when pm is set to 'static', 'dynamic' or 'ondemand'
; Note: This value is mandatory.
pm.max_children = 5
; The number of child processes created on startup.
; Note: Used only when pm is set to 'dynamic'
; Default Value: min_spare_servers + (max_spare_servers - min_spare_servers) / 2
pm.start_servers = 2
; The desired minimum number of idle server processes.
; Note: Used only when pm is set to 'dynamic'
; Note: Mandatory when pm is set to 'dynamic'
pm.min_spare_servers = 1
; The desired maximum number of idle server processes.
; Note: Used only when pm is set to 'dynamic'
; Note: Mandatory when pm is set to 'dynamic'
pm.max_spare_servers = 3
; The number of seconds after which an idle process will be killed.
; Note: Used only when pm is set to 'ondemand'
; Default Value: 10s
;pm.process_idle_timeout = 10s;
; The number of requests each child process should execute before respawning.
; This can be useful to work around memory leaks in 3rd party libraries. For
; endless request processing specify '0'. Equivalent to PHP_FCGI_MAX_REQUESTS.
; Default Value: 0
;pm.max_requests = 500
; The URI to view the FPM status page. If this value is not set, no URI will be
; recognized as a status page. It shows the following informations:
; pool - the name of the pool;
; process manager - static, dynamic or ondemand;
; start time - the date and time FPM has started;
; start since - number of seconds since FPM has started;
; accepted conn - the number of request accepted by the pool;
; listen queue - the number of request in the queue of pending
; connections (see backlog in listen(2));
; max listen queue - the maximum number of requests in the queue
; of pending connections since FPM has started;
; listen queue len - the size of the socket queue of pending connections;
; idle processes - the number of idle processes;
; active processes - the number of active processes;
; total processes - the number of idle + active processes;
; max active processes - the maximum number of active processes since FPM
; has started;
; max children reached - number of times, the process limit has been reached,
; when pm tries to start more children (works only for
; pm 'dynamic' and 'ondemand');
; Value are updated in real time.
; Example output:
; pool: www
; process manager: static
; start time: 01/Jul/2011:17:53:49 +0200
; start since: 62636
; accepted conn: 190460
; listen queue: 0
; max listen queue: 1
; listen queue len: 42
; idle processes: 4
; active processes: 11
; total processes: 15
; max active processes: 12
; max children reached: 0
;
; By default the status page output is formatted as text/plain. Passing either
; 'html', 'xml' or 'json' in the query string will return the corresponding
; output syntax. Example:
; http://www.foo.bar/status
; http://www.foo.bar/status?json
; http://www.foo.bar/status?html
; http://www.foo.bar/status?xml
;
; By default the status page only outputs short status. Passing 'full' in the
; query string will also return status for each pool process.
; Example:
; http://www.foo.bar/status?full
; http://www.foo.bar/status?json&full
; http://www.foo.bar/status?html&full
; http://www.foo.bar/status?xml&full
; The Full status returns for each process:
; pid - the PID of the process;
; state - the state of the process (Idle, Running, ...);
; start time - the date and time the process has started;
; start since - the number of seconds since the process has started;
; requests - the number of requests the process has served;
; request duration - the duration in µs of the requests;
; request method - the request method (GET, POST, ...);
; request URI - the request URI with the query string;
; content length - the content length of the request (only with POST);
; user - the user (PHP_AUTH_USER) (or '-' if not set);
; script - the main script called (or '-' if not set);
; last request cpu - the %cpu the last request consumed
; it's always 0 if the process is not in Idle state
; because CPU calculation is done when the request
; processing has terminated;
; last request memory - the max amount of memory the last request consumed
; it's always 0 if the process is not in Idle state
; because memory calculation is done when the request
; processing has terminated;
; If the process is in Idle state, then informations are related to the
; last request the process has served. Otherwise informations are related to
; the current request being served.
; Example output:
; ************************
; pid: 31330
; state: Running
; start time: 01/Jul/2011:17:53:49 +0200
; start since: 63087
; requests: 12808
; request duration: 1250261
; request method: GET
; request URI: /test_mem.php?N=10000
; content length: 0
; user: -
; script: /home/fat/web/docs/php/test_mem.php
; last request cpu: 0.00
; last request memory: 0
;
; Note: There is a real-time FPM status monitoring sample web page available
; It's available in: /usr/share/php/7.2/fpm/status.html
;
; Note: The value must start with a leading slash (/). The value can be
; anything, but it may not be a good idea to use the .php extension or it
; may conflict with a real PHP file.
; Default Value: not set
;pm.status_path = /status
; The ping URI to call the monitoring page of FPM. If this value is not set, no
; URI will be recognized as a ping page. This could be used to test from outside
; that FPM is alive and responding, or to
; - create a graph of FPM availability (rrd or such);
; - remove a server from a group if it is not responding (load balancing);
; - trigger alerts for the operating team (24/7).
; Note: The value must start with a leading slash (/). The value can be
; anything, but it may not be a good idea to use the .php extension or it
; may conflict with a real PHP file.
; Default Value: not set
;ping.path = /ping
; This directive may be used to customize the response of a ping request. The
; response is formatted as text/plain with a 200 response code.
; Default Value: pong
;ping.response = pong
; The access log file
; Default: not set
;access.log = log/$pool.access.log
; The access log format.
; The following syntax is allowed
; %%: the '%' character
; %C: %CPU used by the request
; it can accept the following format:
; - %{user}C for user CPU only
; - %{system}C for system CPU only
; - %{total}C for user + system CPU (default)
; %d: time taken to serve the request
; it can accept the following format:
; - %{seconds}d (default)
; - %{miliseconds}d
; - %{mili}d
; - %{microseconds}d
; - %{micro}d
; %e: an environment variable (same as $_ENV or $_SERVER)
; it must be associated with embraces to specify the name of the env
; variable. Some exemples:
; - server specifics like: %{REQUEST_METHOD}e or %{SERVER_PROTOCOL}e
; - HTTP headers like: %{HTTP_HOST}e or %{HTTP_USER_AGENT}e
; %f: script filename
; %l: content-length of the request (for POST request only)
; %m: request method
; %M: peak of memory allocated by PHP
; it can accept the following format:
; - %{bytes}M (default)
; - %{kilobytes}M
; - %{kilo}M
; - %{megabytes}M
; - %{mega}M
; %n: pool name
; %o: output header
; it must be associated with embraces to specify the name of the header:
; - %{Content-Type}o
; - %{X-Powered-By}o
; - %{Transfert-Encoding}o
; - ....
; %p: PID of the child that serviced the request
; %P: PID of the parent of the child that serviced the request
; %q: the query string
; %Q: the '?' character if query string exists
; %r: the request URI (without the query string, see %q and %Q)
; %R: remote IP address
; %s: status (response code)
; %t: server time the request was received
; it can accept a strftime(3) format:
; %d/%b/%Y:%H:%M:%S %z (default)
; %T: time the log has been written (the request has finished)
; it can accept a strftime(3) format:
; %d/%b/%Y:%H:%M:%S %z (default)
; %u: remote user
;
; Default: "%R - %u %t \"%m %r\" %s"
;access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%"
; The log file for slow requests
; Default Value: not set
; Note: slowlog is mandatory if request_slowlog_timeout is set
;slowlog = log/$pool.log.slow
; The timeout for serving a single request after which a PHP backtrace will be
; dumped to the 'slowlog' file. A value of '0s' means 'off'.
; Available units: s(econds)(default), m(inutes), h(ours), or d(ays)
; Default Value: 0
;request_slowlog_timeout = 0
; Depth of slow log stack trace.
; Default Value: 20
;request_slowlog_trace_depth = 20
; The timeout for serving a single request after which the worker process will
; be killed. This option should be used when the 'max_execution_time' ini option
; does not stop script execution for some reason. A value of '0' means 'off'.
; Available units: s(econds)(default), m(inutes), h(ours), or d(ays)
; Default Value: 0
;request_terminate_timeout = 0
; Set open file descriptor rlimit.
; Default Value: system defined value
;rlimit_files = 1024
; Set max core size rlimit.
; Possible Values: 'unlimited' or an integer greater or equal to 0
; Default Value: system defined value
;rlimit_core = 0
; Chroot to this directory at the start. This value must be defined as an
; absolute path. When this value is not set, chroot is not used.
; Note: you can prefix with '$prefix' to chroot to the pool prefix or one
; of its subdirectories. If the pool prefix is not set, the global prefix
; will be used instead.
; Note: chrooting is a great security feature and should be used whenever
; possible. However, all PHP paths will be relative to the chroot
; (error_log, sessions.save_path, ...).
; Default Value: not set
;chroot =
; Chdir to this directory at the start.
; Note: relative path can be used.
; Default Value: current directory or / when chroot
;chdir = /var/www
; Redirect worker stdout and stderr into main error log. If not set, stdout and
; stderr will be redirected to /dev/null according to FastCGI specs.
; Note: on highloaded environement, this can cause some delay in the page
; process time (several ms).
; Default Value: no
catch_workers_output = yes
; Clear environment in FPM workers
; Prevents arbitrary environment variables from reaching FPM worker processes
; by clearing the environment in workers before env vars specified in this
; pool configuration are added.
; Setting to "no" will make all environment variables available to PHP code
; via getenv(), $_ENV and $_SERVER.
; Default Value: yes
;clear_env = no
; Limits the extensions of the main script FPM will allow to parse. This can
; prevent configuration mistakes on the web server side. You should only limit
; FPM to .php extensions to prevent malicious users to use other extensions to
; execute php code.
; Note: set an empty value to allow all extensions.
; Default Value: .php
;security.limit_extensions = .php .php3 .php4 .php5 .php7
; Pass environment variables like LD_LIBRARY_PATH. All $VARIABLEs are taken from
; the current environment.
; Default Value: clean env
;env[HOSTNAME] = $HOSTNAME
;env[PATH] = /usr/local/bin:/usr/bin:/bin
;env[TMP] = /tmp
;env[TMPDIR] = /tmp
;env[TEMP] = /tmp
; Additional php.ini defines, specific to this pool of workers. These settings
; overwrite the values previously defined in the php.ini. The directives are the
; same as the PHP SAPI:
; php_value/php_flag - you can set classic ini defines which can
; be overwritten from PHP call 'ini_set'.
; php_admin_value/php_admin_flag - these directives won't be overwritten by
; PHP call 'ini_set'
; For php_*flag, valid values are on, off, 1, 0, true, false, yes or no.
; Defining 'extension' will load the corresponding shared extension from
; extension_dir. Defining 'disable_functions' or 'disable_classes' will not
; overwrite previously defined php.ini values, but will append the new value
; instead.
; Note: path INI options can be relative and will be expanded with the prefix
; (pool, global or /usr)
; Default Value: nothing is defined by default except the values in php.ini and
; specified at startup with the -d argument
;php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f www@my.domain.com
;php_flag[display_errors] = off
;php_admin_value[error_log] = /var/log/fpm-php.www.log
;php_admin_flag[log_errors] = on
;php_admin_value[memory_limit] = 32M

View File

@ -19,9 +19,14 @@
; Default Value: none
;prefix = /path/to/pools/$pool
; Unix user/group of processes
; Note: The user is mandatory. If the group is not set, the default user's group
; will be used.
; Unix user/group of the child processes. This can be used only if the master
; process running user is root. It is set after the child process is created.
; The user and group can be specified either by their name or by their numeric
; IDs.
; Note: If the user is root, the executable needs to be started with
; --allow-to-run-as-root option to work.
; Default Values: The user is set to master process running user by default.
; If the group is not set, the user's group is used.
user = nginx
group = nginx
@ -35,20 +40,22 @@ group = nginx
; (IPv6 and IPv4-mapped) on a specific port;
; '/path/to/unix/socket' - to listen on a unix socket.
; Note: This value is mandatory.
listen = /run/php/php7.3-fpm-{{ domain_name }}.sock
listen = /run/php/php8.2-fpm-{{ domain_name }}.sock
; Set listen(2) backlog.
; Default Value: 511 (-1 on FreeBSD and OpenBSD)
; Default Value: 511 (-1 on Linux, FreeBSD and OpenBSD)
;listen.backlog = 511
; Set permissions for unix socket, if one is used. In Linux, read/write
; permissions must be set in order to allow connections from a web server. Many
; BSD-derived systems allow connections regardless of permissions.
; Default Values: user and group are set as the running user
; mode is set to 0660
; BSD-derived systems allow connections regardless of permissions. The owner
; and group can be specified either by name or by their numeric IDs.
; Default Values: Owner is set to the master process running user. If the group
; is not set, the owner's group is used. Mode is set to 0660.
listen.owner = nginx
listen.group = nginx
;listen.mode = 0660
; When POSIX Access Control Lists are supported you can set them using
; these options, value is a comma separated list of user/group names.
; When set, listen.owner and listen.group are ignored
@ -63,6 +70,10 @@ listen.group = nginx
; Default Value: any
;listen.allowed_clients = 127.0.0.1
; Set the associated the route table (FIB). FreeBSD only
; Default Value: -1
;listen.setfib = 1
; Specify the nice(2) priority to apply to the pool processes (only if set)
; The value can vary from -19 (highest priority) to 20 (lower priority)
; Note: - It will only work if the FPM master process is launched as root
@ -71,8 +82,9 @@ listen.group = nginx
; Default Value: no set
; process.priority = -19
; Set the process dumpable flag (PR_SET_DUMPABLE prctl) even if the process user
; or group is differrent than the master process user. It allows to create process
; Set the process dumpable flag (PR_SET_DUMPABLE prctl for Linux or
; PROC_TRACE_CTL procctl for FreeBSD) even if the process user
; or group is different than the master process user. It allows to create process
; core dump and ptrace the process for the pool user.
; Default Value: no
; process.dumpable = yes
@ -94,6 +106,8 @@ listen.group = nginx
; state (waiting to process). If the number
; of 'idle' processes is greater than this
; number then some children will be killed.
; pm.max_spawn_rate - the maximum number of rate to spawn child
; processes at once.
; ondemand - no children are created at startup. Children will be forked when
; new requests will connect. The following parameter are used:
; pm.max_children - the maximum number of children that
@ -116,7 +130,7 @@ pm.max_children = 5
; The number of child processes created on startup.
; Note: Used only when pm is set to 'dynamic'
; Default Value: min_spare_servers + (max_spare_servers - min_spare_servers) / 2
; Default Value: (min_spare_servers + max_spare_servers) / 2
pm.start_servers = 2
; The desired minimum number of idle server processes.
@ -129,6 +143,12 @@ pm.min_spare_servers = 1
; Note: Mandatory when pm is set to 'dynamic'
pm.max_spare_servers = 3
; The number of rate to spawn child processes at once.
; Note: Used only when pm is set to 'dynamic'
; Note: Mandatory when pm is set to 'dynamic'
; Default Value: 32
;pm.max_spawn_rate = 32
; The number of seconds after which an idle process will be killed.
; Note: Used only when pm is set to 'ondemand'
; Default Value: 10s
@ -141,7 +161,7 @@ pm.max_spare_servers = 3
;pm.max_requests = 500
; The URI to view the FPM status page. If this value is not set, no URI will be
; recognized as a status page. It shows the following informations:
; recognized as a status page. It shows the following information:
; pool - the name of the pool;
; process manager - static, dynamic or ondemand;
; start time - the date and time FPM has started;
@ -231,7 +251,7 @@ pm.max_spare_servers = 3
; last request memory: 0
;
; Note: There is a real-time FPM status monitoring sample web page available
; It's available in: /usr/share/php/7.3/fpm/status.html
; It's available in: /usr/share/php/8.2/fpm/status.html
;
; Note: The value must start with a leading slash (/). The value can be
; anything, but it may not be a good idea to use the .php extension or it
@ -239,6 +259,22 @@ pm.max_spare_servers = 3
; Default Value: not set
;pm.status_path = /status
; The address on which to accept FastCGI status request. This creates a new
; invisible pool that can handle requests independently. This is useful
; if the main pool is busy with long running requests because it is still possible
; to get the status before finishing the long running requests.
;
; Valid syntaxes are:
; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific IPv4 address on
; a specific port;
; '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on
; a specific port;
; 'port' - to listen on a TCP socket to all addresses
; (IPv6 and IPv4-mapped) on a specific port;
; '/path/to/unix/socket' - to listen on a unix socket.
; Default Value: value of the listen option
;pm.status_listen = 127.0.0.1:9001
; The ping URI to call the monitoring page of FPM. If this value is not set, no
; URI will be recognized as a ping page. This could be used to test from outside
; that FPM is alive and responding, or to
@ -271,13 +307,13 @@ pm.max_spare_servers = 3
; %d: time taken to serve the request
; it can accept the following format:
; - %{seconds}d (default)
; - %{miliseconds}d
; - %{mili}d
; - %{milliseconds}d
; - %{milli}d
; - %{microseconds}d
; - %{micro}d
; %e: an environment variable (same as $_ENV or $_SERVER)
; it must be associated with embraces to specify the name of the env
; variable. Some exemples:
; variable. Some examples:
; - server specifics like: %{REQUEST_METHOD}e or %{SERVER_PROTOCOL}e
; - HTTP headers like: %{HTTP_HOST}e or %{HTTP_USER_AGENT}e
; %f: script filename
@ -306,14 +342,30 @@ pm.max_spare_servers = 3
; %s: status (response code)
; %t: server time the request was received
; it can accept a strftime(3) format:
; The strftime(3) format must be encapsuled in a %{<strftime_format>}t tag
; The strftime(3) format must be encapsulated in a %{<strftime_format>}t tag
; %T: time the log has been written (the request has finished)
; it can accept a strftime(3) format:
; The strftime(3) format must be encapsuled in a %{<strftime_format>}t tag
; The strftime(3) format must be encapsulated in a %{<strftime_format>}t tag
; %u: remote user
;
; Default: "%R - %u %t \"%m %r\" %s"
;access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%"
;access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{milli}d %{kilo}M %C%%"
; A list of request_uri values which should be filtered from the access log.
;
; As a security precuation, this setting will be ignored if:
; - the request method is not GET or HEAD; or
; - there is a request body; or
; - there are query parameters; or
; - the response code is outwith the successful range of 200 to 299
;
; Note: The paths are matched against the output of the access.format tag "%r".
; On common configurations, this may look more like SCRIPT_NAME than the
; expected pre-rewrite URI.
;
; Default Value: not set
;access.suppress_path[] = /ping
;access.suppress_path[] = /health_check.php
; The log file for slow requests
; Default Value: not set
@ -337,6 +389,14 @@ pm.max_spare_servers = 3
; Default Value: 0
;request_terminate_timeout = 0
; The timeout set by 'request_terminate_timeout' ini option is not engaged after
; application calls 'fastcgi_finish_request' or when application has finished and
; shutdown functions are being called (registered via register_shutdown_function).
; This option will enable timeout limit to be applied unconditionally
; even in such cases.
; Default Value: no
;request_terminate_timeout_track_finished = no
; Set open file descriptor rlimit.
; Default Value: system defined value
;rlimit_files = 1024
@ -364,7 +424,7 @@ pm.max_spare_servers = 3
; Redirect worker stdout and stderr into main error log. If not set, stdout and
; stderr will be redirected to /dev/null according to FastCGI specs.
; Note: on highloaded environement, this can cause some delay in the page
; Note: on highloaded environment, this can cause some delay in the page
; process time (several ms).
; Default Value: no
;catch_workers_output = yes

View File

@ -1,7 +1,10 @@
---
# file: site.yml
- import_playbook: nomads.yml
- import_playbook: web.yml
- name: Import nomads playbook
ansible.builtin.import_playbook: nomads.yml
- name: Import web playbook
ansible.builtin.import_playbook: web.yml
# vim: set sw=2 ts=2:

View File

@ -3,11 +3,12 @@
- name: Configure web servers
hosts: web
become: yes
become: true
roles:
- common
- { role: mariadb, when: mariadb_databases is defined}
- nginx
- { role: nginx, when: webserver is defined and webserver == 'nginx' }
- { role: caddy, when: webserver is defined and webserver == 'caddy' }
- php-fpm
- munin
vars_files: