Compare commits

...

150 Commits

Author SHA1 Message Date
73fd06fe3a roles/common: remove cron-apt
Use unattended-upgrades instead. It has sane defaults on Debian at
least (I haven't checked Ubuntu).
2025-04-07 09:51:09 +03:00
88cb3a370e Remove logic for Ubuntu 20.04 and Debian 11 2025-03-29 23:09:44 +03:00
027a43ddbe roles/caddy: use default for encode 2025-03-29 22:49:30 +03:00
bb30c3be20 host_vars/web22: update vhosts 2025-03-29 22:48:19 +03:00
d8d9790d21 roles/nginx: enable nginx ssl_session_tickets
This has apparently been supported since nginx 1.23.2 and is safe
to use the default (on) now.

See: https://github.com/mozilla/server-side-tls/issues/284
2025-03-29 22:35:56 +03:00
9a500ebc0d roles/nginx: disable nginx ssl_prefer_server_ciphers
This is apparently the default and recommended by Mozilla's server-
side SSL configurator also recommends. This lets the client choose
the ciphers best for them (and the ciphers in TLS 1.2 and 1.3 are
not currently known to be dangerous).
2025-03-29 22:34:41 +03:00
4bae942585 roles/nginx: add nginx ssl_ecdh_curve
This seems to be new since I last looked at the Mozilla server-side
SSL configurator.
2025-03-29 22:34:37 +03:00
99866c0c90 roles/nginx: use one day for nginx ssl_session_timeout
This is a new default since I last looked at the Mozilla server-side
SSL configurator.
2025-03-29 22:34:32 +03:00
0afb8a4493 roles/nginx: update nginx ssl_buffer_size
The old default has not been changed in eight years and I see that
there have been some discussions over the years about this. I will
change this from the slightly extreme 1400 bytes to 4k (nginx def-
ault is still 16k so this is more "optimal" for HTML/CSS content).

See: https://github.com/igrigorik/istlsfastyet.com/issues/63
2025-03-29 22:34:27 +03:00
506695da31 roles/nginx/defaults: update version comments 2025-03-29 22:24:49 +03:00
f67ed7762c roles/nginx: fix http2 syntax 2025-03-29 22:20:49 +03:00
014f4d9502 roles/nginx: add newline 2025-03-29 22:19:41 +03:00
22c16e1ed3 roles/caddy/templates: closer to supporting WordPress
I still wouldn't want to deploy WordPress on Caddy until it's more
obvious and standard to block paths that shouldn't be accessible.
It seems that this is still left as an exercise to the site admin.

This discussion has some tips, but it is four years old and hasn't
changed since I last looked.

See: https://caddy.community/t/using-caddy-to-harden-wordpress/13575
2025-03-29 22:09:37 +03:00
5aa6a33e51 roles/php-fpm: set user and group based on webserver
We use either caddy or nginx, which are conveniently named the same
as the Unix user and group.
2025-03-29 21:01:56 +03:00
7f9b06af9c roles/nginx: smarter setting of document root 2025-03-29 19:34:53 +03:00
84db337fea roles/caddy: smarter setting of document root 2025-03-29 19:33:02 +03:00
7b23f5f94f roles/caddy: add missing tag 2025-03-29 19:16:03 +03:00
9830338be3 Use one default root prefix for nginx and caddy 2025-03-29 19:15:56 +03:00
e3eed26765 roles/caddy: update vhost template 2025-03-29 18:37:28 +03:00
8b31c7e148 host_vars/web22: WordPress 6.7.2 2025-03-29 16:10:23 +03:00
3ff8043aaf Pipfile.lock: run pipenv update 2025-03-29 15:30:08 +03:00
cb79f7ef70 roles/common: minor change to firehol update script
They include bogons like 127.0.0.1 that should not be routed on the
public Internet, but this blocks local applications we proxy to.
2025-01-28 09:14:48 +03:00
bb14f05d2a roles/common: use Ansible timezone module
No need to use a command for that. The module does it better because
it doesn't register a change unless the timezone changes.
2025-01-27 23:11:56 +03:00
5b1530fa91 roles/common: rework firewall
Use firehol instead of all the others. AbuseIPDB.com can't be upd-
ated automatically, Abuse.ch is no longer maintained, and Spamhaus
is already in firehol.
2025-01-27 23:05:45 +03:00
5312dc6bd5 roles/common: use common nftables task
Use a common nftables task on Debian and Ubuntu.
2025-01-27 23:05:38 +03:00
d6e060d3af roles/common: simplify firewall tasks
Apply firewall tag to included tasks, then we don't need to use a
block.
2025-01-27 22:30:50 +03:00
b873af004a roles/common: single firewall task include
Use one include from the main tasks file.
2025-01-27 22:28:27 +03:00
7ea3ab46f8 host_vars/web22: WordPress 6.7.1 2025-01-27 21:48:16 +03:00
0561bd5b52 Pipfile.lock: run pipenv update 2025-01-27 21:36:13 +03:00
d62572f02c Pipfile: python 3.13 2025-01-27 21:35:58 +03:00
2ffe5e87d9 host_vars/web22: WordPress 6.6.2 2024-12-30 11:03:47 +03:00
38d4f1a303 Pipfile.lock: run pipenv update 2024-12-30 11:03:35 +03:00
ed8cb88038 host_vars/web22: WordPress 6.5.5 2024-06-25 08:18:22 +03:00
c31e447861 roles/nginx: update signing key 2024-06-25 08:11:59 +03:00
545684467c host_vars/nomad03: remove 2024-06-05 20:35:29 +03:00
24ae5eaab1 host_vars/web22: WordPress 6.5.3 2024-05-13 14:51:45 +03:00
dac23f1427 Pipfile: use Python 3.12 2024-05-13 14:51:34 +03:00
41fbc73dd1 host_vars/web22: WordPress 6.4.3 2024-03-20 20:28:13 +03:00
fee794bcf0 Update Pipfile 2024-03-20 20:28:00 +03:00
8bce1d8b1b host_vars/web22: WordPress 6.4.1 2023-12-02 22:40:06 +03:00
6dc2ea36b6 roles/nginx: fix path to php 8.2 socket 2023-09-11 19:55:24 +03:00
af71a9b5f8 roles/php-fpm: remove fmt strings
Ansible confuses them for jinja2 tokens.
2023-09-11 19:52:18 +03:00
4dd57803e2 roles/php-fpm: fix user/group for php 8.2 configs 2023-09-11 19:51:59 +03:00
18d4245fc0 roles/common: fix tarsnap signing of apt repo 2023-09-11 19:37:49 +03:00
1bddf3cccd Pipfile.lock: run pipenv update 2023-09-11 18:52:25 +03:00
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
899e87321b host_vars/web22: WordPress 6.3.1 2023-09-10 22:44:23 +03:00
06416a3b64 roles: run ansible-lint --write 2023-08-23 22:22:51 +03:00
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
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
84d210cfab roles/common: re-format handlers
Use the newer Ansible format.
2023-08-23 21:35:28 +03:00
17736a4f14 roles/common: run ansible-lint --write 2023-08-23 21:33:22 +03:00
b9e91c4a3d roles/common: minor updates to tarsnap task
Use modern Ansible task format
2023-08-23 21:20:22 +03:00
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
8dbec29d2a roles/nginx: prepare letsencrypt task for Debian 12 2023-08-23 21:01:12 +03:00
d3bf3dab04 roles/php-fpm: add support for PHP 8.2
This is used in Debian 12.
2023-08-23 20:56:35 +03:00
8f50b7756b host_vars/web22: WordPress 6.3 2023-08-22 21:33:49 +03:00
e86ccc9979 roles/nginx: minor rework of apt key stuff 2023-08-22 21:33:19 +03:00
cea8529f49 Pipfile.lock: run pipenv update 2023-08-22 21:02:17 +03:00
d77718edae host_vars: add fail2ban_ignoreip 2023-08-14 16:37:07 +02:00
14d57fc477 roles/nginx: reformat main tasks 2023-08-10 22:44:47 +02:00
5c39f1abd8 roles/common: minor changes to Debian sshd_config files 2023-08-10 22:10:04 +02:00
6794eb0432 roles/common: default to disabling SSH passwords 2023-08-10 22:09:03 +02:00
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
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
3c8250e6ac Pipfile.lock: run pipenv update 2023-08-09 22:07:54 +02:00
d280859b0d roles/common: minor updates to Debian 11 sshd_config 2023-08-09 21:55:04 +02:00
bca1629d2f Minor comment updates for Debian 12 2023-08-09 21:51:53 +02:00
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
b8f0b4b1fb roles/common: add vanilla sshd_config for Debian 12 2023-08-09 21:16:50 +02:00
68e5d05bbb host_vars/web22: WordPress 6.2.2 2023-07-27 18:48:37 +03:00
446d402778 roles: minor fix to Debian version comparisons 2023-07-27 18:48:07 +03:00
67379fc2e4 host_vars/web22: WordPress 6.2 2023-05-04 07:10:40 +03:00
73546967b6 Pipfile.lock: run pipenv update 2023-05-04 06:58:25 +03:00
16b661efe1 Pipfile.lock: run pipenv update 2023-04-14 10:09:29 -07:00
fdb9a75489 roles/common: update tarsnap GPG key 2023-04-14 10:09:11 -07:00
232d7a0348 host_vars/web22: WordPress 6.1.1 2022-11-24 18:31:48 +03:00
6e4bb5bc34 host_vars/web21: use caddy 2022-11-13 18:58:57 +03:00
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
45c9d7ea0a Pipfile.lock: run pipenv update 2022-11-13 16:50:07 +03:00
a62bc446e8 host_vars/web22: WordPress 6.1 2022-11-06 23:00:41 +03:00
62a6a491db host_vars/web23: use caddy 2022-11-02 22:30:32 +03:00
4867d6da6a Add basic caddy role 2022-11-02 22:29:30 +03:00
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
bc8c030700 roles/common: update Tarsnap GPG key 2022-11-02 22:11:37 +03:00
f7598d8f1c Pipfile.lock: run pipenv update 2022-11-02 20:50:59 +03:00
c353e84a84 site.yml: use fully-qualified modules 2022-10-25 21:08:27 +03:00
99ca23f258 Pipfile.lock: run pipenv update 2022-10-17 19:56:30 +03:00
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
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
4abf2b10e4 ansible.cfg: smart fact gathering 2022-09-12 17:18:19 +03:00
f5199264f9 ansible.cfg: disable SSH host key checking 2022-09-12 17:14:39 +03:00
b259f09cbd roles/common: add SSH public key from other machine 2022-09-12 17:06:31 +03:00
f4b32e516b roles/mariadb: use newer Ansible task syntax 2022-09-12 10:16:42 +03:00
fcb12ecee0 roles/mariadb: remove sources.list template 2022-09-12 10:13:27 +03:00
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
c317429f6d roles/mariadb: rework package signing key and repo 2022-09-12 10:09:41 +03:00
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
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
dec2d50fbc host_vars/web22: WordPress 6.0.2 2022-09-12 09:00:05 +03:00
34be0013b7 Remove Debian 10 support 2022-09-11 09:21:08 +03:00
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
0240897b1b Remove Ubuntu 18.04 support 2022-09-10 23:30:04 +03:00
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
677cc9f160 roles/php-fpm: fix truthy-ness in when 2022-09-10 23:12:26 +03:00
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
95d0005978 Add ansible-lint 2022-09-10 18:36:53 +03:00
498766fdc4 Pipfile.lock: run pipenv update 2022-09-10 18:36:07 +03:00
fc0fcc5742 roles/common: fix unnamed blocks 2022-09-10 18:35:27 +03:00
587bd6dcdd roles: use fully qualified module names 2022-09-10 18:35:27 +03:00
92a4c72809 Pipfile.lock: run pipenv update 2022-08-16 21:24:34 -07:00
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
d2a5a28809 Pipfile.lock: run pipenv update 2022-08-01 15:20:56 +03:00
84c0589aee host_vars/web22: WordPress 5.9.2 2022-03-31 22:35:15 +03:00
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
4d74f76b3c Pipfile.lock: run pipenv update 2022-02-04 21:47:53 +03:00
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
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
68f0b85eb3 Pipfile.lock: run pipenv update 2021-12-22 11:49:24 +02:00
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
ab47df6031 Use Python 3.10 with pipenv 2021-12-13 08:38:08 +02:00
de75b2ffb6 host_vars/web22: WordPress 5.8.2 2021-11-30 19:48:18 +02:00
e10d83dadd Pipfile.lock: run pipenv update 2021-11-30 19:34:46 +02:00
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
6e1527b1a8 Pipfile.lock: run pipenv update 2021-11-07 10:11:46 +02:00
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
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
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
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
89ced6f952 Pipfile.lock: run pipenv update 2021-09-27 17:28:41 +03:00
ae5ba0607a Remove host_vars/nomad01
Replaced by web23.
2021-09-27 14:17:48 +03:00
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
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
0421807e4d Add web23
Will replace nomad01
2021-09-27 12:22:45 +03:00
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
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
170e591701 roles/common: Install rsync and lsof 2021-09-27 11:36:40 +03:00
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
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
a4acc85704 roles/common: Remove iptables on newer Debian 2021-09-27 10:35:38 +03:00
f7b9aa67f5 roles/common: Fix comment about Debian 10 firewall 2021-09-27 10:31:31 +03:00
0a39c4f0ef README.md: Update debian/ubuntu note 2021-09-27 10:13:47 +03:00
85323d789c Remove host_vars/web19
Replaced by web22.
2021-09-13 11:49:32 +03:00
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
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
83fea62b0f host_vars/web22: WordPress 5.8.1 2021-09-13 07:37:40 +03:00
0d1a5fbb25 Add host_vars/web22
Will replace web19 soon.
2021-09-12 21:59:38 +03:00
4d8444abf2 host_vars/web21: Fix path to cert 2021-09-12 20:39:45 +03:00
e8486f6c9e host_vars/nomad02: Update Drone to version 2 2021-09-10 21:49:00 +03:00
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
101 changed files with 2399 additions and 26973 deletions

View File

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

806
Pipfile.lock generated
View File

@ -1,11 +1,11 @@
{ {
"_meta": { "_meta": {
"hash": { "hash": {
"sha256": "65b615b857250757470e21fc3a4b1cdfe75b4b012c0d1d633a5ebf1988d9cb91" "sha256": "47970866f4ffc7775e3a95dd04ee8b75f9784c457baadd8a31fe1783584fa73f"
}, },
"pipfile-spec": 6, "pipfile-spec": 6,
"requires": { "requires": {
"python_version": "3.9" "python_version": "3.13"
}, },
"sources": [ "sources": [
{ {
@ -18,224 +18,672 @@
"default": { "default": {
"ansible": { "ansible": {
"hashes": [ "hashes": [
"sha256:cc5352b2351a381015ece79eab783a1b0668f97b377810fed3c746e2f1d50db1" "sha256:d25a7f26bf5821f8043bc806019822fd2810bd65e6b6bafb698bbeedadba72bf",
"sha256:fb56f6e5d5b08f69499a76f0972ac0b88ddc488ada1f386129ba40cb0b5c6ec7"
], ],
"index": "pypi", "index": "pypi",
"version": "==4.5.0" "markers": "python_version >= '3.11'",
"version": "==11.4.0"
},
"ansible-compat": {
"hashes": [
"sha256:25acf1bb49d8072e2737fc109fa9aa981ca9fed17b075af3c812635dad48ba2a",
"sha256:ebf8620021dd25c2d7c3e8e9382efbe7328db58ea396cbbe688ebef80dc8f8ae"
],
"markers": "python_version >= '3.10'",
"version": "==25.1.4"
}, },
"ansible-core": { "ansible-core": {
"hashes": [ "hashes": [
"sha256:22eaa7c2dfe6c875e9ae380323f1cba6259c6050a5e4c8819f85f92b3683ea49" "sha256:c642d484c1d3486a923b152150034eddd5cdf4bea58039c928183900fb35d8ba",
"sha256:e1f8f5c33546362b0ee933e0969a3ba364b486515a6fa1bc25ebb5d95f8ec5f4"
], ],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "markers": "python_version >= '3.11'",
"version": "==2.11.4" "version": "==2.18.4"
},
"ansible-lint": {
"hashes": [
"sha256:b68b2149423246ec6369be86df2b79e3555b2b71507e4f7915671ec77381fa2b",
"sha256:ff92b31c83a2366381907e21c9a9d4de57f0cd7574e9943ea1b7e32b371f31a2"
],
"index": "pypi",
"markers": "python_version >= '3.10'",
"version": "==25.1.3"
},
"attrs": {
"hashes": [
"sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3",
"sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b"
],
"markers": "python_version >= '3.8'",
"version": "==25.3.0"
},
"black": {
"hashes": [
"sha256:030b9759066a4ee5e5aca28c3c77f9c64789cdd4de8ac1df642c40b708be6171",
"sha256:055e59b198df7ac0b7efca5ad7ff2516bca343276c466be72eb04a3bcc1f82d7",
"sha256:0e519ecf93120f34243e6b0054db49c00a35f84f195d5bce7e9f5cfc578fc2da",
"sha256:172b1dbff09f86ce6f4eb8edf9dede08b1fce58ba194c87d7a4f1a5aa2f5b3c2",
"sha256:1e2978f6df243b155ef5fa7e558a43037c3079093ed5d10fd84c43900f2d8ecc",
"sha256:33496d5cd1222ad73391352b4ae8da15253c5de89b93a80b3e2c8d9a19ec2666",
"sha256:3b48735872ec535027d979e8dcb20bf4f70b5ac75a8ea99f127c106a7d7aba9f",
"sha256:4b60580e829091e6f9238c848ea6750efed72140b91b048770b64e74fe04908b",
"sha256:759e7ec1e050a15f89b770cefbf91ebee8917aac5c20483bc2d80a6c3a04df32",
"sha256:8f0b18a02996a836cc9c9c78e5babec10930862827b1b724ddfe98ccf2f2fe4f",
"sha256:95e8176dae143ba9097f351d174fdaf0ccd29efb414b362ae3fd72bf0f710717",
"sha256:96c1c7cd856bba8e20094e36e0f948718dc688dba4a9d78c3adde52b9e6c2299",
"sha256:a1ee0a0c330f7b5130ce0caed9936a904793576ef4d2b98c40835d6a65afa6a0",
"sha256:a22f402b410566e2d1c950708c77ebf5ebd5d0d88a6a2e87c86d9fb48afa0d18",
"sha256:a39337598244de4bae26475f77dda852ea00a93bd4c728e09eacd827ec929df0",
"sha256:afebb7098bfbc70037a053b91ae8437c3857482d3a690fefc03e9ff7aa9a5fd3",
"sha256:bacabb307dca5ebaf9c118d2d2f6903da0d62c9faa82bd21a33eecc319559355",
"sha256:bce2e264d59c91e52d8000d507eb20a9aca4a778731a08cfff7e5ac4a4bb7096",
"sha256:d9e6827d563a2c820772b32ce8a42828dc6790f095f441beef18f96aa6f8294e",
"sha256:db8ea9917d6f8fc62abd90d944920d95e73c83a5ee3383493e35d271aca872e9",
"sha256:ea0213189960bda9cf99be5b8c8ce66bb054af5e9e861249cd23471bd7b0b3ba",
"sha256:f3df5f1bf91d36002b0a75389ca8663510cf0531cca8aa5c1ef695b46d98655f"
],
"markers": "python_version >= '3.9'",
"version": "==25.1.0"
},
"bracex": {
"hashes": [
"sha256:12c50952415bfa773d2d9ccb8e79651b8cdb1f31a42f6091b804f6ba2b4a66b6",
"sha256:13e5732fec27828d6af308628285ad358047cec36801598368cb28bc631dbaf6"
],
"markers": "python_version >= '3.8'",
"version": "==2.5.post1"
}, },
"cffi": { "cffi": {
"hashes": [ "hashes": [
"sha256:06c54a68935738d206570b20da5ef2b6b6d92b38ef3ec45c5422c0ebaf338d4d", "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8",
"sha256:0c0591bee64e438883b0c92a7bed78f6290d40bf02e54c5bf0978eaf36061771", "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2",
"sha256:19ca0dbdeda3b2615421d54bef8985f72af6e0c47082a8d26122adac81a95872", "sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1",
"sha256:22b9c3c320171c108e903d61a3723b51e37aaa8c81255b5e7ce102775bd01e2c", "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15",
"sha256:26bb2549b72708c833f5abe62b756176022a7b9a7f689b571e74c8478ead51dc", "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36",
"sha256:33791e8a2dc2953f28b8d8d300dde42dd929ac28f974c4b4c6272cb2955cb762", "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824",
"sha256:3c8d896becff2fa653dc4438b54a5a25a971d1f4110b32bd3068db3722c80202", "sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8",
"sha256:4373612d59c404baeb7cbd788a18b2b2a8331abcc84c3ba40051fcd18b17a4d5", "sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36",
"sha256:487d63e1454627c8e47dd230025780e91869cfba4c753a74fda196a1f6ad6548", "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17",
"sha256:48916e459c54c4a70e52745639f1db524542140433599e13911b2f329834276a", "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf",
"sha256:4922cd707b25e623b902c86188aca466d3620892db76c0bdd7b99a3d5e61d35f", "sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc",
"sha256:55af55e32ae468e9946f741a5d51f9896da6b9bf0bbdd326843fec05c730eb20", "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3",
"sha256:57e555a9feb4a8460415f1aac331a2dc833b1115284f7ded7278b54afc5bd218", "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed",
"sha256:5d4b68e216fc65e9fe4f524c177b54964af043dde734807586cf5435af84045c", "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702",
"sha256:64fda793737bc4037521d4899be780534b9aea552eb673b9833b01f945904c2e", "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1",
"sha256:6d6169cb3c6c2ad50db5b868db6491a790300ade1ed5d1da29289d73bbe40b56", "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8",
"sha256:7bcac9a2b4fdbed2c16fa5681356d7121ecabf041f18d97ed5b8e0dd38a80224", "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903",
"sha256:80b06212075346b5546b0417b9f2bf467fea3bfe7352f781ffc05a8ab24ba14a", "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6",
"sha256:818014c754cd3dba7229c0f5884396264d51ffb87ec86e927ef0be140bfdb0d2", "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d",
"sha256:8eb687582ed7cd8c4bdbff3df6c0da443eb89c3c72e6e5dcdd9c81729712791a", "sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b",
"sha256:99f27fefe34c37ba9875f224a8f36e31d744d8083e00f520f133cab79ad5e819", "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e",
"sha256:9f3e33c28cd39d1b655ed1ba7247133b6f7fc16fa16887b120c0c670e35ce346", "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be",
"sha256:a8661b2ce9694ca01c529bfa204dbb144b275a31685a075ce123f12331be790b", "sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c",
"sha256:a9da7010cec5a12193d1af9872a00888f396aba3dc79186604a09ea3ee7c029e", "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683",
"sha256:aedb15f0a5a5949ecb129a82b72b19df97bbbca024081ed2ef88bd5c0a610534", "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9",
"sha256:b315d709717a99f4b27b59b021e6207c64620790ca3e0bde636a6c7f14618abb", "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c",
"sha256:ba6f2b3f452e150945d58f4badd92310449876c4c954836cfb1803bdd7b422f0", "sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8",
"sha256:c33d18eb6e6bc36f09d793c0dc58b0211fccc6ae5149b808da4a62660678b156", "sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1",
"sha256:c9a875ce9d7fe32887784274dd533c57909b7b1dcadcc128a2ac21331a9765dd", "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4",
"sha256:c9e005e9bd57bc987764c32a1bee4364c44fdc11a3cc20a40b93b444984f2b87", "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655",
"sha256:d2ad4d668a5c0645d281dcd17aff2be3212bc109b33814bbb15c4939f44181cc", "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67",
"sha256:d950695ae4381ecd856bcaf2b1e866720e4ab9a1498cba61c602e56630ca7195", "sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595",
"sha256:e22dcb48709fc51a7b58a927391b23ab37eb3737a98ac4338e2448bef8559b33", "sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0",
"sha256:e8c6a99be100371dbb046880e7a282152aa5d6127ae01783e37662ef73850d8f", "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65",
"sha256:e9dc245e3ac69c92ee4c167fbdd7428ec1956d4e754223124991ef29eb57a09d", "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41",
"sha256:eb687a11f0a7a1839719edd80f41e459cc5366857ecbed383ff376c4e3cc6afd", "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6",
"sha256:eb9e2a346c5238a30a746893f23a9535e700f8192a68c07c0258e7ece6ff3728", "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401",
"sha256:ed38b924ce794e505647f7c331b22a693bee1538fdf46b0222c4717b42f744e7", "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6",
"sha256:f0010c6f9d1a4011e429109fda55a225921e3206e7f62a0c22a35344bfd13cca", "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3",
"sha256:f0c5d1acbfca6ebdd6b1e3eded8d261affb6ddcf2186205518f1428b8569bb99", "sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16",
"sha256:f10afb1004f102c7868ebfe91c28f4a712227fe4cb24974350ace1f90e1febbf", "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93",
"sha256:f174135f5609428cc6e1b9090f9268f5c8935fddb1b25ccb8255a2d50de6789e", "sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e",
"sha256:f3ebe6e73c319340830a9b2825d32eb6d8475c1dac020b4f0aa774ee3b898d1c", "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4",
"sha256:f627688813d0a4140153ff532537fbe4afea5a3dffce1f9deb7f91f848a832b5", "sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964",
"sha256:fd4305f86f53dfd8cd3522269ed7fc34856a8ee3709a5e28b2836b2db9d4cd69" "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c",
"sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576",
"sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0",
"sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3",
"sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662",
"sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3",
"sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff",
"sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5",
"sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd",
"sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f",
"sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5",
"sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14",
"sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d",
"sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9",
"sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7",
"sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382",
"sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a",
"sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e",
"sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a",
"sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4",
"sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99",
"sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87",
"sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b"
], ],
"version": "==1.14.6" "markers": "python_version >= '3.8'",
"version": "==1.17.1"
},
"click": {
"hashes": [
"sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2",
"sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"
],
"markers": "python_version >= '3.7'",
"version": "==8.1.8"
}, },
"cryptography": { "cryptography": {
"hashes": [ "hashes": [
"sha256:0a7dcbcd3f1913f664aca35d47c1331fce738d44ec34b7be8b9d332151b0b01e", "sha256:04abd71114848aa25edb28e225ab5f268096f44cf0127f3d36975bdf1bdf3390",
"sha256:1eb7bb0df6f6f583dd8e054689def236255161ebbcf62b226454ab9ec663746b", "sha256:0529b1d5a0105dd3731fa65680b45ce49da4d8115ea76e9da77a875396727b41",
"sha256:21ca464b3a4b8d8e86ba0ee5045e103a1fcfac3b39319727bc0fc58c09c6aff7", "sha256:1bc312dfb7a6e5d66082c87c34c8a62176e684b6fe3d90fcfe1568de675e6688",
"sha256:34dae04a0dce5730d8eb7894eab617d8a70d0c97da76b905de9efb7128ad7085", "sha256:268e4e9b177c76d569e8a145a6939eca9a5fec658c932348598818acf31ae9a5",
"sha256:3520667fda779eb788ea00080124875be18f2d8f0848ec00733c0ec3bb8219fc", "sha256:29ecec49f3ba3f3849362854b7253a9f59799e3763b0c9d0826259a88efa02f1",
"sha256:3fa3a7ccf96e826affdf1a0a9432be74dc73423125c8f96a909e3835a5ef194a", "sha256:2bf7bf75f7df9715f810d1b038870309342bff3069c5bd8c6b96128cb158668d",
"sha256:5b0fbfae7ff7febdb74b574055c7466da334a5371f253732d7e2e7525d570498", "sha256:3b721b8b4d948b218c88cb8c45a01793483821e709afe5f622861fc6182b20a7",
"sha256:8695456444f277af73a4877db9fc979849cd3ee74c198d04fc0776ebc3db52b9", "sha256:3c00b6b757b32ce0f62c574b78b939afab9eecaf597c4d624caca4f9e71e7843",
"sha256:94cc5ed4ceaefcbe5bf38c8fba6a21fc1d365bb8fb826ea1688e3370b2e24a1c", "sha256:3dc62975e31617badc19a906481deacdeb80b4bb454394b4098e3f2525a488c5",
"sha256:94fff993ee9bc1b2440d3b7243d488c6a3d9724cc2b09cdb297f6a886d040ef7", "sha256:4973da6ca3db4405c54cd0b26d328be54c7747e89e284fcff166132eb7bccc9c",
"sha256:9965c46c674ba8cc572bc09a03f4c649292ee73e1b683adb1ce81e82e9a6a0fb", "sha256:4e389622b6927d8133f314949a9812972711a111d577a5d1f4bee5e58736b80a",
"sha256:a00cf305f07b26c351d8d4e1af84ad7501eca8a342dedf24a7acb0e7b7406e14", "sha256:51e4de3af4ec3899d6d178a8c005226491c27c4ba84101bfb59c901e10ca9f79",
"sha256:a305600e7a6b7b855cd798e00278161b681ad6e9b7eca94c721d5f588ab212af", "sha256:5f6f90b72d8ccadb9c6e311c775c8305381db88374c65fa1a68250aa8a9cb3a6",
"sha256:cd65b60cfe004790c795cc35f272e41a3df4631e2fb6b35aa7ac6ef2859d554e", "sha256:6210c05941994290f3f7f175a4a57dbbb2afd9273657614c506d5976db061181",
"sha256:d2a6e5ef66503da51d2110edf6c403dc6b494cc0082f85db12f54e9c5d4c3ec5", "sha256:6f101b1f780f7fc613d040ca4bdf835c6ef3b00e9bd7125a4255ec574c7916e4",
"sha256:d9ec0e67a14f9d1d48dd87a2531009a9b251c02ea42851c060b25c782516ff06", "sha256:7bdcd82189759aba3816d1f729ce42ffded1ac304c151d0a8e89b9996ab863d5",
"sha256:f44d141b8c4ea5eb4dbc9b3ad992d45580c1d22bf5e24363f2fbf50c2d7ae8a7" "sha256:7ca25849404be2f8e4b3c59483d9d3c51298a22c1c61a0e84415104dacaf5562",
"sha256:81276f0ea79a208d961c433a947029e1a15948966658cf6710bbabb60fcc2639",
"sha256:8cadc6e3b5a1f144a039ea08a0bdb03a2a92e19c46be3285123d32029f40a922",
"sha256:8e0ddd63e6bf1161800592c71ac794d3fb8001f2caebe0966e77c5234fa9efc3",
"sha256:909c97ab43a9c0c0b0ada7a1281430e4e5ec0458e6d9244c0e821bbf152f061d",
"sha256:96e7a5e9d6e71f9f4fca8eebfd603f8e86c5225bb18eb621b2c1e50b290a9471",
"sha256:9a1e657c0f4ea2a23304ee3f964db058c9e9e635cc7019c4aa21c330755ef6fd",
"sha256:9eb9d22b0a5d8fd9925a7764a054dca914000607dff201a24c791ff5c799e1fa",
"sha256:af4ff3e388f2fa7bff9f7f2b31b87d5651c45731d3e8cfa0944be43dff5cfbdb",
"sha256:b042d2a275c8cee83a4b7ae30c45a15e6a4baa65a179a0ec2d78ebb90e4f6699",
"sha256:bc821e161ae88bfe8088d11bb39caf2916562e0a2dc7b6d56714a48b784ef0bb",
"sha256:c505d61b6176aaf982c5717ce04e87da5abc9a36a5b39ac03905c4aafe8de7aa",
"sha256:c63454aa261a0cf0c5b4718349629793e9e634993538db841165b3df74f37ec0",
"sha256:c7362add18b416b69d58c910caa217f980c5ef39b23a38a0880dfd87bdf8cd23",
"sha256:d03806036b4f89e3b13b6218fefea8d5312e450935b1a2d55f0524e2ed7c59d9",
"sha256:d1b3031093a366ac767b3feb8bcddb596671b3aaff82d4050f984da0c248b615",
"sha256:d1c3572526997b36f245a96a2b1713bf79ce99b271bbcf084beb6b9b075f29ea",
"sha256:efcfe97d1b3c79e486554efddeb8f6f53a4cdd4cf6086642784fa31fc384e1d7",
"sha256:f514ef4cd14bb6fb484b4a60203e912cfcb64f2ab139e88c2274511514bf7308"
], ],
"markers": "python_version >= '3.6'", "markers": "python_version >= '3.7' and python_full_version not in '3.9.0, 3.9.1'",
"version": "==3.4.8" "version": "==44.0.2"
},
"filelock": {
"hashes": [
"sha256:adbc88eabb99d2fec8c9c1b229b171f18afa655400173ddc653d5d01501fb9f2",
"sha256:c401f4f8377c4464e6db25fff06205fd89bdd83b65eb0488ed1b160f780e21de"
],
"markers": "python_version >= '3.9'",
"version": "==3.18.0"
},
"importlib-metadata": {
"hashes": [
"sha256:02a89390c1e15fdfdc0d7c6b25cb3e62650d0494005c97d6f148bf5b9787525e",
"sha256:310b41d755445d74569f993ccfc22838295d9fe005425094fad953d7f15c8580"
],
"markers": "python_version >= '3.9'",
"version": "==8.6.1"
}, },
"jinja2": { "jinja2": {
"hashes": [ "hashes": [
"sha256:1f06f2da51e7b56b8f238affdd6b4e2c61e39598a378cc49345bc1bd42a978a4", "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d",
"sha256:703f484b47a6af502e743c9122595cc812b0271f661722403114f71a79d0f5a4" "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67"
], ],
"markers": "python_version >= '3.6'", "markers": "python_version >= '3.7'",
"version": "==3.0.1" "version": "==3.1.6"
},
"jsonschema": {
"hashes": [
"sha256:d71497fef26351a33265337fa77ffeb82423f3ea21283cd9467bb03999266bc4",
"sha256:fbadb6f8b144a8f8cf9f0b89ba94501d143e50411a1278633f56a7acf7fd5566"
],
"markers": "python_version >= '3.8'",
"version": "==4.23.0"
},
"jsonschema-specifications": {
"hashes": [
"sha256:0f38b83639958ce1152d02a7f062902c41c8fd20d558b0c34344292d417ae272",
"sha256:a09a0680616357d9a0ecf05c12ad234479f549239d0f5b55f3deea67475da9bf"
],
"markers": "python_version >= '3.9'",
"version": "==2024.10.1"
},
"markdown-it-py": {
"hashes": [
"sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1",
"sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"
],
"markers": "python_version >= '3.8'",
"version": "==3.0.0"
}, },
"markupsafe": { "markupsafe": {
"hashes": [ "hashes": [
"sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298", "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4",
"sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64", "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30",
"sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b", "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0",
"sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567", "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9",
"sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff", "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396",
"sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724", "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13",
"sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74", "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028",
"sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646", "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca",
"sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35", "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557",
"sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6", "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832",
"sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6", "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0",
"sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad", "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b",
"sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26", "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579",
"sha256:36bc903cbb393720fad60fc28c10de6acf10dc6cc883f3e24ee4012371399a38", "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a",
"sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac", "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c",
"sha256:3c112550557578c26af18a1ccc9e090bfe03832ae994343cfdacd287db6a6ae7", "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff",
"sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6", "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c",
"sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75", "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22",
"sha256:49e3ceeabbfb9d66c3aef5af3a60cc43b85c33df25ce03d0031a608b0a8b2e3f", "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094",
"sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135", "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb",
"sha256:53edb4da6925ad13c07b6d26c2a852bd81e364f95301c66e930ab2aef5b5ddd8", "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e",
"sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a", "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5",
"sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a", "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a",
"sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9", "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d",
"sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864", "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a",
"sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914", "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b",
"sha256:6557b31b5e2c9ddf0de32a691f2312a32f77cd7681d8af66c2692efdbef84c18", "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8",
"sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8", "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225",
"sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2", "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c",
"sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d", "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144",
"sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b", "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f",
"sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b", "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87",
"sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f", "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d",
"sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb", "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93",
"sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833", "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf",
"sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28", "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158",
"sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415", "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84",
"sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902", "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb",
"sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d", "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48",
"sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9", "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171",
"sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d", "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c",
"sha256:baa1a4e8f868845af802979fcdbf0bb11f94f1cb7ced4c4b8a351bb60d108145", "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6",
"sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066", "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd",
"sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c", "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d",
"sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1", "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1",
"sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f", "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d",
"sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53", "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca",
"sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134", "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a",
"sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85", "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29",
"sha256:f5653a225f31e113b152e56f154ccbe59eeb1c7487b39b9d9f9cdb58e6c79dc5", "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe",
"sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94", "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798",
"sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509", "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c",
"sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51", "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8",
"sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872" "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f",
"sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f",
"sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a",
"sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178",
"sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0",
"sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79",
"sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430",
"sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"
], ],
"markers": "python_version >= '3.6'", "markers": "python_version >= '3.9'",
"version": "==2.0.1" "version": "==3.0.2"
},
"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": { "packaging": {
"hashes": [ "hashes": [
"sha256:7dc96269f53a4ccec5c0670940a4281106dd0bb343f47b7471f779df49c2fbe7", "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759",
"sha256:c86254f9220d55e31cc94d69bade760f0847da8000def4dfe1c6b872fd14ff14" "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"
], ],
"markers": "python_version >= '3.6'", "markers": "python_version >= '3.8'",
"version": "==21.0" "version": "==24.2"
},
"pathspec": {
"hashes": [
"sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08",
"sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"
],
"markers": "python_version >= '3.8'",
"version": "==0.12.1"
},
"platformdirs": {
"hashes": [
"sha256:a03875334331946f13c549dbd8f4bac7a13a50a895a0eb1e8c6a8ace80d40a94",
"sha256:eb437d586b6a0986388f0d6f74aa0cde27b48d0e3d66843640bfb6bdcdb6e351"
],
"markers": "python_version >= '3.9'",
"version": "==4.3.7"
}, },
"pycparser": { "pycparser": {
"hashes": [ "hashes": [
"sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0", "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6",
"sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705" "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"
], ],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "markers": "python_version >= '3.8'",
"version": "==2.20" "version": "==2.22"
}, },
"pyparsing": { "pygments": {
"hashes": [ "hashes": [
"sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1", "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199",
"sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b" "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"
], ],
"markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", "markers": "python_version >= '3.8'",
"version": "==2.4.7" "version": "==2.18.0"
}, },
"pyyaml": { "pyyaml": {
"hashes": [ "hashes": [
"sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf", "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff",
"sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696", "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48",
"sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393", "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086",
"sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77", "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e",
"sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922", "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133",
"sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5", "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5",
"sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8", "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484",
"sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10", "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee",
"sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc", "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5",
"sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018", "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68",
"sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e", "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a",
"sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253", "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf",
"sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347", "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99",
"sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183", "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8",
"sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541", "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85",
"sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb", "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19",
"sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185", "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc",
"sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc", "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a",
"sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db", "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1",
"sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa", "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317",
"sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46", "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c",
"sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122", "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631",
"sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b", "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d",
"sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63", "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652",
"sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df", "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5",
"sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc", "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e",
"sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247", "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b",
"sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6", "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8",
"sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0" "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476",
"sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706",
"sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563",
"sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237",
"sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b",
"sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083",
"sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180",
"sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425",
"sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e",
"sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f",
"sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725",
"sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183",
"sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab",
"sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774",
"sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725",
"sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e",
"sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5",
"sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d",
"sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290",
"sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44",
"sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed",
"sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4",
"sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba",
"sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12",
"sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"
], ],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", "markers": "python_version >= '3.8'",
"version": "==5.4.1" "version": "==6.0.2"
},
"referencing": {
"hashes": [
"sha256:df2e89862cd09deabbdba16944cc3f10feb6b3e6f18e902f7cc25609a34775aa",
"sha256:e8699adbbf8b5c7de96d8ffa0eb5c158b3beafce084968e2ea8bb08c6794dcd0"
],
"markers": "python_version >= '3.9'",
"version": "==0.36.2"
}, },
"resolvelib": { "resolvelib": {
"hashes": [ "hashes": [
"sha256:8113ae3ed6d33c6be0bcbf03ffeb06c0995c099b7b8aaa5ddf2e9b3b3df4e915", "sha256:04ce76cbd63fded2078ce224785da6ecd42b9564b1390793f64ddecbe997b309",
"sha256:9b9b80d5c60e4c2a8b7fbf0712c3449dc01d74e215632e5199850c9eca687628" "sha256:d2da45d1a8dfee81bdd591647783e340ef3bcb104b54c383f70d422ef5cc7dbf"
], ],
"version": "==0.5.4" "version": "==1.0.1"
},
"rich": {
"hashes": [
"sha256:2e85306a063b9492dffc86278197a60cbece75bcb766022f3436f567cae11bdc",
"sha256:a5ac1f1cd448ade0d59cc3356f7db7a7ccda2c8cbae9c7a90c28ff463d3e91f4"
],
"markers": "python_full_version >= '3.7.0'",
"version": "==13.8.0"
},
"rpds-py": {
"hashes": [
"sha256:0047638c3aa0dbcd0ab99ed1e549bbf0e142c9ecc173b6492868432d8989a046",
"sha256:006f4342fe729a368c6df36578d7a348c7c716be1da0a1a0f86e3021f8e98724",
"sha256:041f00419e1da7a03c46042453598479f45be3d787eb837af382bfc169c0db33",
"sha256:04ecf5c1ff4d589987b4d9882872f80ba13da7d42427234fce8f22efb43133bc",
"sha256:04f2b712a2206e13800a8136b07aaedc23af3facab84918e7aa89e4be0260032",
"sha256:0aeb3329c1721c43c58cae274d7d2ca85c1690d89485d9c63a006cb79a85771a",
"sha256:0e374c0ce0ca82e5b67cd61fb964077d40ec177dd2c4eda67dba130de09085c7",
"sha256:0f00c16e089282ad68a3820fd0c831c35d3194b7cdc31d6e469511d9bffc535c",
"sha256:174e46569968ddbbeb8a806d9922f17cd2b524aa753b468f35b97ff9c19cb718",
"sha256:1b221c2457d92a1fb3c97bee9095c874144d196f47c038462ae6e4a14436f7bc",
"sha256:208b3a70a98cf3710e97cabdc308a51cd4f28aa6e7bb11de3d56cd8b74bab98d",
"sha256:20f2712bd1cc26a3cc16c5a1bfee9ed1abc33d4cdf1aabd297fe0eb724df4272",
"sha256:24795c099453e3721fda5d8ddd45f5dfcc8e5a547ce7b8e9da06fecc3832e26f",
"sha256:2a0f156e9509cee987283abd2296ec816225145a13ed0391df8f71bf1d789e2d",
"sha256:2b2356688e5d958c4d5cb964af865bea84db29971d3e563fb78e46e20fe1848b",
"sha256:2c13777ecdbbba2077670285dd1fe50828c8742f6a4119dbef6f83ea13ad10fb",
"sha256:2d3ee4615df36ab8eb16c2507b11e764dcc11fd350bbf4da16d09cda11fcedef",
"sha256:2d53747da70a4e4b17f559569d5f9506420966083a31c5fbd84e764461c4444b",
"sha256:32bab0a56eac685828e00cc2f5d1200c548f8bc11f2e44abf311d6b548ce2e45",
"sha256:34d90ad8c045df9a4259c47d2e16a3f21fdb396665c94520dbfe8766e62187a4",
"sha256:369d9c6d4c714e36d4a03957b4783217a3ccd1e222cdd67d464a3a479fc17796",
"sha256:3a55fc10fdcbf1a4bd3c018eea422c52cf08700cf99c28b5cb10fe97ab77a0d3",
"sha256:3d2d8e4508e15fc05b31285c4b00ddf2e0eb94259c2dc896771966a163122a0c",
"sha256:3fab5f4a2c64a8fb64fc13b3d139848817a64d467dd6ed60dcdd6b479e7febc9",
"sha256:43dba99f00f1d37b2a0265a259592d05fcc8e7c19d140fe51c6e6f16faabeb1f",
"sha256:44d51febb7a114293ffd56c6cf4736cb31cd68c0fddd6aa303ed09ea5a48e029",
"sha256:493fe54318bed7d124ce272fc36adbf59d46729659b2c792e87c3b95649cdee9",
"sha256:4b28e5122829181de1898c2c97f81c0b3246d49f585f22743a1246420bb8d399",
"sha256:4cd031e63bc5f05bdcda120646a0d32f6d729486d0067f09d79c8db5368f4586",
"sha256:528927e63a70b4d5f3f5ccc1fa988a35456eb5d15f804d276709c33fc2f19bda",
"sha256:564c96b6076a98215af52f55efa90d8419cc2ef45d99e314fddefe816bc24f91",
"sha256:5db385bacd0c43f24be92b60c857cf760b7f10d8234f4bd4be67b5b20a7c0b6b",
"sha256:5ef877fa3bbfb40b388a5ae1cb00636a624690dcb9a29a65267054c9ea86d88a",
"sha256:5f6e3cec44ba05ee5cbdebe92d052f69b63ae792e7d05f1020ac5e964394080c",
"sha256:5fc13b44de6419d1e7a7e592a4885b323fbc2f46e1f22151e3a8ed3b8b920405",
"sha256:60748789e028d2a46fc1c70750454f83c6bdd0d05db50f5ae83e2db500b34da5",
"sha256:60d9b630c8025b9458a9d114e3af579a2c54bd32df601c4581bd054e85258143",
"sha256:619ca56a5468f933d940e1bf431c6f4e13bef8e688698b067ae68eb4f9b30e3a",
"sha256:630d3d8ea77eabd6cbcd2ea712e1c5cecb5b558d39547ac988351195db433f6c",
"sha256:63981feca3f110ed132fd217bf7768ee8ed738a55549883628ee3da75bb9cb78",
"sha256:66420986c9afff67ef0c5d1e4cdc2d0e5262f53ad11e4f90e5e22448df485bf0",
"sha256:675269d407a257b8c00a6b58205b72eec8231656506c56fd429d924ca00bb350",
"sha256:6a4a535013aeeef13c5532f802708cecae8d66c282babb5cd916379b72110cf7",
"sha256:6a727fd083009bc83eb83d6950f0c32b3c94c8b80a9b667c87f4bd1274ca30ba",
"sha256:6e1daf5bf6c2be39654beae83ee6b9a12347cb5aced9a29eecf12a2d25fff664",
"sha256:6eea559077d29486c68218178ea946263b87f1c41ae7f996b1f30a983c476a5a",
"sha256:75a810b7664c17f24bf2ffd7f92416c00ec84b49bb68e6a0d93e542406336b56",
"sha256:772cc1b2cd963e7e17e6cc55fe0371fb9c704d63e44cacec7b9b7f523b78919e",
"sha256:78884d155fd15d9f64f5d6124b486f3d3f7fd7cd71a78e9670a0f6f6ca06fb2d",
"sha256:79e8d804c2ccd618417e96720ad5cd076a86fa3f8cb310ea386a3e6229bae7d1",
"sha256:7e80d375134ddb04231a53800503752093dbb65dad8dabacce2c84cccc78e964",
"sha256:8097b3422d020ff1c44effc40ae58e67d93e60d540a65649d2cdaf9466030791",
"sha256:8205ee14463248d3349131bb8099efe15cd3ce83b8ef3ace63c7e976998e7124",
"sha256:8212ff58ac6dfde49946bea57474a386cca3f7706fc72c25b772b9ca4af6b79e",
"sha256:823e74ab6fbaa028ec89615ff6acb409e90ff45580c45920d4dfdddb069f2120",
"sha256:84e0566f15cf4d769dade9b366b7b87c959be472c92dffb70462dd0844d7cbad",
"sha256:896c41007931217a343eff197c34513c154267636c8056fb409eafd494c3dcdc",
"sha256:8aa362811ccdc1f8dadcc916c6d47e554169ab79559319ae9fae7d7752d0d60c",
"sha256:8b3b397eefecec8e8e39fa65c630ef70a24b09141a6f9fc17b3c3a50bed6b50e",
"sha256:8ebc7e65ca4b111d928b669713865f021b7773350eeac4a31d3e70144297baba",
"sha256:9168764133fd919f8dcca2ead66de0105f4ef5659cbb4fa044f7014bed9a1797",
"sha256:921ae54f9ecba3b6325df425cf72c074cd469dea843fb5743a26ca7fb2ccb149",
"sha256:92558d37d872e808944c3c96d0423b8604879a3d1c86fdad508d7ed91ea547d5",
"sha256:951cc481c0c395c4a08639a469d53b7d4afa252529a085418b82a6b43c45c240",
"sha256:998c01b8e71cf051c28f5d6f1187abbdf5cf45fc0efce5da6c06447cba997034",
"sha256:9abc80fe8c1f87218db116016de575a7998ab1629078c90840e8d11ab423ee25",
"sha256:9be4f99bee42ac107870c61dfdb294d912bf81c3c6d45538aad7aecab468b6b7",
"sha256:9c39438c55983d48f4bb3487734d040e22dad200dab22c41e331cee145e7a50d",
"sha256:9d7e8ce990ae17dda686f7e82fd41a055c668e13ddcf058e7fb5e9da20b57793",
"sha256:9ea7f4174d2e4194289cb0c4e172d83e79a6404297ff95f2875cf9ac9bced8ba",
"sha256:a18fc371e900a21d7392517c6f60fe859e802547309e94313cd8181ad9db004d",
"sha256:a36b452abbf29f68527cf52e181fced56685731c86b52e852053e38d8b60bc8d",
"sha256:a5b66d1b201cc71bc3081bc2f1fc36b0c1f268b773e03bbc39066651b9e18391",
"sha256:a824d2c7a703ba6daaca848f9c3d5cb93af0505be505de70e7e66829affd676e",
"sha256:a88c0d17d039333a41d9bf4616bd062f0bd7aa0edeb6cafe00a2fc2a804e944f",
"sha256:aa6800adc8204ce898c8a424303969b7aa6a5e4ad2789c13f8648739830323b7",
"sha256:aad911555286884be1e427ef0dc0ba3929e6821cbeca2194b13dc415a462c7fd",
"sha256:afc6e35f344490faa8276b5f2f7cbf71f88bc2cda4328e00553bd451728c571f",
"sha256:b9a4df06c35465ef4d81799999bba810c68d29972bf1c31db61bfdb81dd9d5bb",
"sha256:bb2954155bb8f63bb19d56d80e5e5320b61d71084617ed89efedb861a684baea",
"sha256:bbc4362e06f950c62cad3d4abf1191021b2ffaf0b31ac230fbf0526453eee75e",
"sha256:c0145295ca415668420ad142ee42189f78d27af806fcf1f32a18e51d47dd2052",
"sha256:c30ff468163a48535ee7e9bf21bd14c7a81147c0e58a36c1078289a8ca7af0bd",
"sha256:c347a20d79cedc0a7bd51c4d4b7dbc613ca4e65a756b5c3e57ec84bd43505b47",
"sha256:c43583ea8517ed2e780a345dd9960896afc1327e8cf3ac8239c167530397440d",
"sha256:c61a2cb0085c8783906b2f8b1f16a7e65777823c7f4d0a6aaffe26dc0d358dd9",
"sha256:c9ca89938dff18828a328af41ffdf3902405a19f4131c88e22e776a8e228c5a8",
"sha256:cc31e13ce212e14a539d430428cd365e74f8b2d534f8bc22dd4c9c55b277b875",
"sha256:cdabcd3beb2a6dca7027007473d8ef1c3b053347c76f685f5f060a00327b8b65",
"sha256:cf86f72d705fc2ef776bb7dd9e5fbba79d7e1f3e258bf9377f8204ad0fc1c51e",
"sha256:d09dc82af2d3c17e7dd17120b202a79b578d79f2b5424bda209d9966efeed114",
"sha256:d3aa13bdf38630da298f2e0d77aca967b200b8cc1473ea05248f6c5e9c9bdb44",
"sha256:d69d003296df4840bd445a5d15fa5b6ff6ac40496f956a221c4d1f6f7b4bc4d9",
"sha256:d6e109a454412ab82979c5b1b3aee0604eca4bbf9a02693bb9df027af2bfa91a",
"sha256:d8551e733626afec514b5d15befabea0dd70a343a9f23322860c4f16a9430205",
"sha256:d8754d872a5dfc3c5bf9c0e059e8107451364a30d9fd50f1f1a85c4fb9481164",
"sha256:d8f9a6e7fd5434817526815f09ea27f2746c4a51ee11bb3439065f5fc754db58",
"sha256:dbcbb6db5582ea33ce46a5d20a5793134b5365110d84df4e30b9d37c6fd40ad3",
"sha256:e0f3ef95795efcd3b2ec3fe0a5bcfb5dadf5e3996ea2117427e524d4fbf309c6",
"sha256:e13ae74a8a3a0c2f22f450f773e35f893484fcfacb00bb4344a7e0f4f48e1f97",
"sha256:e274f62cbd274359eff63e5c7e7274c913e8e09620f6a57aae66744b3df046d6",
"sha256:e838bf2bb0b91ee67bf2b889a1a841e5ecac06dd7a2b1ef4e6151e2ce155c7ae",
"sha256:e8acd55bd5b071156bae57b555f5d33697998752673b9de554dd82f5b5352727",
"sha256:e8e5ab32cf9eb3647450bc74eb201b27c185d3857276162c101c0f8c6374e098",
"sha256:ebcb786b9ff30b994d5969213a8430cbb984cdd7ea9fd6df06663194bd3c450c",
"sha256:ebea2821cdb5f9fef44933617be76185b80150632736f3d76e54829ab4a3b4d1",
"sha256:ed0ef550042a8dbcd657dfb284a8ee00f0ba269d3f2286b0493b15a5694f9fe8",
"sha256:eda5c1e2a715a4cbbca2d6d304988460942551e4e5e3b7457b50943cd741626d",
"sha256:f5c0ed12926dec1dfe7d645333ea59cf93f4d07750986a586f511c0bc61fe103",
"sha256:f6016bd950be4dcd047b7475fdf55fb1e1f59fc7403f387be0e8123e4a576d30",
"sha256:f9e0057a509e096e47c87f753136c9b10d7a91842d8042c2ee6866899a717c0d",
"sha256:fc1c892b1ec1f8cbd5da8de287577b455e388d9c328ad592eabbdcb6fc93bee5",
"sha256:fc2c1e1b00f88317d9de6b2c2b39b012ebbfe35fe5e7bef980fd2a91f6100a07",
"sha256:fd822f019ccccd75c832deb7aa040bb02d70a92eb15a2f16c7987b7ad4ee8d83"
],
"markers": "python_version >= '3.9'",
"version": "==0.24.0"
},
"ruamel.yaml": {
"hashes": [
"sha256:20c86ab29ac2153f80a428e1254a8adf686d3383df04490514ca3b79a362db58",
"sha256:30f22513ab2301b3d2b577adc121c6471f28734d3d9728581245f1e76468b4f1"
],
"markers": "python_version >= '3.7'",
"version": "==0.18.10"
},
"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": "python_version < '3.13' and platform_python_implementation == 'CPython'",
"version": "==0.2.8"
},
"subprocess-tee": {
"hashes": [
"sha256:21942e976715af4a19a526918adb03a8a27a8edab959f2d075b777e3d78f532d",
"sha256:91b2b4da3aae9a7088d84acaf2ea0abee3f4fd9c0d2eae69a9b9122a71476590"
],
"markers": "python_version >= '3.8'",
"version": "==0.4.2"
},
"wcmatch": {
"hashes": [
"sha256:0dd927072d03c0a6527a20d2e6ad5ba8d0380e60870c383bc533b71744df7b7a",
"sha256:e72f0de09bba6a04e0de70937b0cf06e55f36f37b3deb422dfaf854b867b840a"
],
"markers": "python_version >= '3.8'",
"version": "==10.0"
},
"yamllint": {
"hashes": [
"sha256:c03ab4e79ab4af964c8eb16ac9746880fc76a3bb0ffb14925b9a55220ae7dda0",
"sha256:ead81921d4d87216b2528b7a055664708f9fb8267beb0c427cb706ac6ab93580"
],
"markers": "python_version >= '3.9'",
"version": "==1.37.0"
},
"zipp": {
"hashes": [
"sha256:2c9958f6430a2040341a52eb608ed6dd93ef4392e02ffe219417c1b28b5dd1f4",
"sha256:ac1bbe05fd2991f160ebce24ffbac5f6d11d83dc90891255885223d42b3cd931"
],
"markers": "python_version >= '3.9'",
"version": "==3.21.0"
} }
}, },
"develop": {} "develop": {}

View File

@ -4,7 +4,7 @@ Ansible playbook for base and initial configuration of the web server hosting my
## Assumptions ## Assumptions
Before you can run this, a few things are assumed: 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 Debian 12 host up and running
- Python 3 is installed on the remote server (requirement of Ansible) - 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 a user account with password-less SSH access to the machine
- You have sudo privileges on the remote host - You have sudo privileges on the remote host

View File

@ -2,10 +2,16 @@
retry_files_enabled=False retry_files_enabled=False
force_handlers=True force_handlers=True
inventory=hosts inventory=hosts
gathering = smart
# instead of using --ask-vault-pass # instead of using --ask-vault-pass
ask_vault_pass=True ask_vault_pass=True
remote_user = provisioning remote_user = provisioning
interpreter_python=auto 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 ansible_managed = This file is managed by Ansible.%n
template: {file} template: {file}

View File

@ -1,8 +1,14 @@
--- ---
# file: group_vars/web # file: group_vars/web
# run nginx by default
webserver: nginx
# all hosts run fail2ban with the sshd filter, but some can use other filters # all hosts run fail2ban with the sshd filter, but some can use other filters
extra_fail2ban_filters: extra_fail2ban_filters:
- nginx - nginx
# root prefix for all web servers
web_root_prefix: /var/www
# vim: set ts=2 sw=2: # vim: set ts=2 sw=2:

View File

@ -1,71 +0,0 @@
$ANSIBLE_VAULT;1.1;AES256
39303965636262373331663530663562363864636132363362616636346166303835336463326261
6435316332636438363630386231326231666163626335350a353662623034313766383035636237
38346531313235613266646665363135393735613836393838313164356561663431333864353237
6230666363363738370a306432643732626337376638383564323032626465306263643533653561
63326261323032303466656162303132633933643232656238643936306235316436616237333963
32633363333636303564383062636463393531326565643732396539386230393434633134306433
38363130626139616631373336653530343762336165666131303464386561646434363163333034
65323837313164343238623766373431656462376262393737323166306537353365663163383032
61393662393433653937313533313537336132663432383634343163653866306232326464626131
33356630666130376565663666613032333637633061663433623363626632356531313231393136
64343463396632633061353861613438613537666466613132316265326530343733343535333836
39376632373137383636623637373639653933623639646266336331353337343166313132613131
32373632323363616333303863656537613264346439326662383265323731613263396138366161
62393838376435393036383836646433346365306239666335356265616237336138373632313139
63613236613166343332363730356262373131646462373561663964343438623863636539633030
38353430363435616139353165633330396135383939396531333436663533666564653765336330
39303832633931653461363766616562323865383832663434356534386337386262653730663838
65623234356134393963376431653965353566303261386533383736316439636536363463633339
35323939373939386436336233333664313735376439353062306562353435323031346335666334
36306537643734316131373335613234363135393866333231343533623961333562646333663332
64643036386237626138633561613966373831326331636437636564616662326563393336636138
62643034333831333765636532633235653733303838393430363830346436646632373364353832
33376635336338303230343833313936633832653235353836633932393230376435353739646563
31653765393631316135366466353162633261386132633433313866363563386563383437623538
33636134646531383130663038343939333565613736363162366132303535336663646265353138
32376536623864656531346434383537396563383130386231336431653464326461326531393861
62356361636434623133383264326433333163633964316262633138633838393234343538316465
32656534623839343132313662636464333963306138356162623462353933633436333930346430
33636235303339353236646438666233653736653566356638653538366131646432373338303535
38643630363231656334623539633235393062656165316266626538663339363538343031323835
34383865663936383161326664353464393263626262383463616336623662613233656630303037
35633461643439666233666136626462353838323162653730646632636132323632663666316166
34373237343931363331653966306535396635306364643135336234366364303062383332376532
61623337326236623861326433653739613133666538396438643937353730363062626136333034
35353733633234313965616439326666623936303464323462313037303230346164353366373661
33613231316461386636383030643862616165623565623337346264656531393232323030306464
37393065386161383532663862333263626338393832343566383065316434656564613831636535
30653330393936323733373938353763643431366134636263616535343565656164343931326464
65653464373231636337313932636238376130323566323637376634626439366635363537623234
34656466366435666162643237383163303936383061393939356438303765313566343162303038
37383531326436373336363134663838346463613462333265663363323538663437623830363831
39333934316634386562333330613831386530633365613939393638373063323830636363356432
62626562366634636266333737343238363235613366313737383335383264343435623434353838
63633964333262616439623266643938313466396339343237666239363730393935626466366434
66333739373662656237386663373465303336343432393735376463643562303431383832313934
61396134393830303234383162633533336436346334393265363766386638303831613036343163
33663638323235613465363539373965326430323035656564633830656365663537393233626365
61646162383439626638633137656639653830366162636532616634313738353166633438346433
64633037343864343939383865333737366638386331623230303830343636363938366432366265
37313963633536396433376331663132643435376164393138653738376338623239323966363430
63346464303162306332303036346362626134363666396130326163613730633966393438316333
30626365623532636436646138373434343031643131343238353661623636623138346333663866
62393937376538343135353030653838346239393633343239313137663464353165653961336237
36646332663539363438343939643335613236666630616636623837386133396262303033333435
36336566333333393137666533323439303036653362333832346537356663656635356635363761
62363638316435633563396662323131383736663939633133626131616638653665633963623439
33343038326339356634366461346132393537613232623334326561366164333862343766386137
66636437613661616261336232316436353739316463383063363663383230613934663334333538
39623037646638386263643438623137346137616664396638366436383561313933633039393936
32383432363363666466363364376631346365373239353339633532666134396138373765643031
64333061343237616135643439396266616161333537333837643530633136313932623531653163
36373165393238306264353461383765343938393635633236313565393733306536386464373639
38386131623133376230653134316536356238336162356331376465613962356231316666643661
65616138333731313961316463643137373831616266623631376266643864656164356531316238
34376264373432356162363962353338393362386434313465643533396330386666636430663530
66396665383431333534383038333163336639613435333039633136366235636638393337613232
35636336383333376138306630383230383861396164386162323264376234396130323933666437
38343036656562636130366663663565666530623765353265363833303634643862313634326461
62643864613762386366633634343964396631356462346665663131623034303133346438613433
6336623030393661663631303038366630353638613337653365

View File

@ -1,112 +0,0 @@
$ANSIBLE_VAULT;1.1;AES256
30376632333335323537323138636238323530386133633466623762316234336531396562613262
6436623766616265346136633061383834323438303661350a373331386231633036313264616262
64303263633334383736616133666330646666623936373762356131626637383939643739376563
6137333439396337330a643631353338366666363135393635356333313232633638386366653163
63643165356563383265333534303430363939643539396637303861396432633963653332653164
33346537336434666333343733623464653565386630346131306538356238306537353037363139
30383039346539356166313534666433393539633231356138303662386137626136623735303161
62633036653531303837666331636165386164613766643764653664633361353431343139653266
31393937656565303161646135376130613932376266616337633262613739333830356235633030
32326230633536353938363032373165353737643631636662663333386561393262313866346530
39376532633961376337613133636233366433623764666536616439643833316331633965616364
30336135643639313531323538663337363930373630633238356663623366666539313161323839
66656530333136663932643731663739636331633363623063646366353935666634636365653934
62643461306163626632353732356133313563326163646661343134383064353966363933643033
66346636363662656138326530366136303762326265636364323038653562366631366563613830
34316130393030643136663263643934333731626361333932363338396661346330323234363135
65663631333630303032373530363930333062643436303736303938656331373138623163396232
36643838303038363736306639353238373234643162313233356463333764393031643865323033
30353031363061643363623464376164636233623765343739613565336236626638393966396631
66396262653535663365343434316139363235633333613438316162323538663562336164656438
62653532636631653831663331353536633335376465653935313564333364363565323761636261
63653565383837623936313535313063373336663337643837363831653235303530646464633935
62663932373634356631633736656166356539346339656363613933656562323965633165613837
35396330353861316562653166363931333362333863663231386538363932383361316439313561
30313266626162633965316331633330616435376539626239356266313439653162613731323261
36343961623763376664326137303866376562346438623739393665333539366537373461393739
65336230623138336166376565643865626362323336343833653964643166613738363361353464
31333832663234613035383731666130326461393063313933343132336432653439323439373131
34376232323132623532646532306337373531316466303037326139666133613930666662373236
31303031626532333133666133306337366530353139393433643432386132393662383363376335
65623839313935613761303865313632303166343732343964393539313732333033613034306661
30333832656636316232643439633831633530373866343866306432646534336634383830353335
34303336303735386166653034346137643961363031336461653165376235323763346531353762
38346230666138336333383537353132336665376163363032613639363830353634623662303564
65373235646339386635353430623464336230313234363332656335346432313235373230643130
33623761343635303131366239363837656262366364643162393036343630336232363032623466
30663531343830613461393038353638666266623162653464643761323237616337633937353933
61643666386536306664636237346231623764326536656537613535383038613365313332623964
31306462626361653131666337653638313135663833386535366464333838333463326363306463
32396338373361303736373135326230393330376539316564626362646166343362366465623232
33623636653061653461303537613232346333396137313762663539623631636361303837336666
62636638363735653965303532393130303733316231613134313637666166323238336333333966
63353663326234663735336265643833626161623332373261376635633364613337396638666361
63653435366135666162653739303032313438343031653561313739336135333937633933383966
61336439656638616432383164376166356362333738373135386538613164373537396435323332
37626530363437323765646561366437393562653839333964396538656265326563393863653662
32646432383966363732386163376263373433633934623237636335363163386332633565636334
36396330313761663237386165333465383033376330633461643666636136656635343365316266
66643363663666343337313530663762303234643335326563656239613665373633393837643963
35356263393566363362373965393331353439633431633539336565333565326631336631323833
35656466626463663037386334343530356661663236646166353733333431656534376439646235
31653564636264666137396362643763353364393132306432336164356366616533363937393665
61353161343238316433363733636530633361316436303863666466666162363835643437653633
31376561653266373863623266393464363433303436656563376561643237396436333462333365
31656238383631643034363063633132343665663563656333613636636134383333343662313237
32643839646363343162383536343066643862666439653462376231386538356430373263393865
61663333373330316131653335643161626366333237383633363564316231633761323165313265
32666137643236333561616331373236373137663866656539663738343862666534386531336661
30643533633566326135333464316264636461376630363732336339373730663239356265663834
33643933326231373464333263336632313633303431396539346238383761346363323230623832
39623866306261373035633166656234313461306535383638386431666164313936356664616264
65343934383931303962653536643031636235626234306164386531633535633139393835636435
39616166363031396564373932376534383830313034333764333161316438396636383265643235
66373332633037376138653230333664393164613136316439393531623134383261626262383432
63313461373136616236656432343262663734663665623838383032666631636635656339353335
61636531356131393665323164643561646334363737343434613930616333383465623832306235
61396136313662663839613034633433396664336361353539633561616238623864346166356161
66373736633239353233313531633939643065303530323031623735636539633834653162633262
63633265316234653537376463636138393139643661393233303631373562393234626161343766
66363265393930353733623363653434313765323532646665626563373563616536393938623465
37326330636664386464653832306138313137616464386339366539623434333062623136353539
36643631323863393934333266376362323430356665653863316163336563323865396132323836
62346131336133643438633064326236666165386439663931636335306333396534383462356135
63306130376634386462663139323439333066383331336163623665616665316162613130376433
38333339636237326230643061386234643064656138396163396134613837666531383261333230
30643262333530396563366233323338656364666461316134363532636537303832343361313364
65626566373266643165623832626634653733383334396435616139346434393036323162373861
31356137353032613831643037613239393061306565336435313431333738623338323766303139
38333137656564386334333666636431323738623264633136663239346635386662313366336334
37643465333336383739623235373064363662373937663330623132623236313432306533373937
66623130626638333962386334633537643338376566323638373939323230643734313263386531
63623966613832626136393734326639363262386531343862353631303834643837346164646232
66623561613436326363363932373563363337343431356432633663383636356339616362366638
38363532393832643665356461393661373838613764383061643364383962663535353531346365
61366266326135663264323132353832386135383165646439633561313636373633316666353065
38396665636239653038653634653831363933633531653965636135316136393532623561373539
36333263306664633865653365363261643135633062356637343365656133656336323131313562
39316639383432326632396135313064353834656265383537313866396439663865363134363066
61646337363537323531306434646163623162333362343162316235323436386337623761666638
36376336616665336334353661333237366638343436613839613761326336363435326630633234
37303562333762393334663462633063623036343331323761393932336166363038383731363238
35363639353134383637396463633263353735386263663535336139616230303863313362616464
39303264363566346666326236643563643961333232626637356534343530356430366238336339
37626233383230636234623532643739353162303562633537303536376535646235313837376666
62376365623566666561333933346232316637326634343437363333666530326237663632356338
39376333653436366439663439343639613661396562623661376538646532316432646266663566
39306235616335313731396436363836643766333462393733363833303938346561613764343738
38356261346332666564633333363566353465316133396362313135623463376133666661363133
61626232383631353965336362623835616137323837333139653338663739346265633832396535
39373436316434633539353137636633386562323034656663303834313538333063613437393131
37616162653566346233386130363134343536363862626430313064393437363063663439383463
39613530393838323064636263633464623234323137323831383232333561663563303561363836
62383430663333613062326530346465636164393133313832626135663231353965303131323631
31363165623431373637623938353437663062623465303262316434373161326462326535616362
31613934363836613961363637303161303833646165313462323938623664326231623662616664
66613665326162373363303165613131343731323330326266336132323039306338343064663831
35303832336132633061363664633166313963336563323130663735646662636362386461623930
36356131646332336562383536626137303031323861663635393234393737353638623063363163
35643965376632383430633232343861373335373132373738383032646138303862353562333533
66306530646666363239383239616433376663303131366431666639323766616333313165313237
626437356166333063393265353264346565

View File

@ -1,82 +0,0 @@
$ANSIBLE_VAULT;1.1;AES256
32316564336430646233343166663333653363613837643863373531333737353431383233653733
6535373830313135623134666430656164386365343738650a383239383839323032383363613938
32383630373834633564336532343634336130303330323266373930623033663234306232656136
6566666131306666310a636163366161373436326461626661353130386538313361666538663531
37393336316638663065393338356535343732363765633762343536393662313539326432383337
33613438383134393535663435333364363836346266383262336439356133343464313736636134
35626530303836663834396266333461613463313634643661303430356633613137383634613038
31646632326330633430653435353431646131363466316231636333663430636531376133623935
65346466616433653463613538363630306338393632356365346330643463383835326466613930
39323766653730373763333161303564306165316336393164343235613831333762646532333139
31336561316337366537343464373735303138303763623632316235613333313230303433303337
64333065626434333831613239363831356565363231656466623830613138616438633164393337
39343634326461303839356231616336376430383639653535323538303364633761666432386230
31653037666630663434303032333163643336326563623661326536653839323263623838646366
37353566313737616337356165636234373835366236383661316331306530646165633037303866
64646639366366353534376238333435613934316666396434346336353533626131646239376634
63663064666434633265343432376337343533636566613930303930633861356234303838333138
66323063386362373930306338636463663865353339376663323936613365336533373666323465
31666634353034366236306562363361373664623634663837396162393738613536636165366332
34643935626164633436333930373535623863303331663334376434643236353462666362303963
39313139303731316264383434333863323764343737303733383535393763356130316337383564
38656434303663333534376336613036653963306363303661336464346362656563303333303566
39366163636439313030366461353064303233636364633064343664646339346365383465633038
35353234353430623830623036383466663236663964316530333964643238626562396366623763
35636439633064613931653963663331343961613764643364663336643264643535316634393834
65393932343333326166643765623266313135363362656431633933656131336163653663373335
37323531376438343561623237623433323234663531326436663162396562623963663936633837
62336139623231663339303439353362306466663834626364326466336435323764373661616437
62613664356633396264643766323535666562343336313033333632366231626666333630313261
39663365316161316261633734663063633539333535393830653034663362323764643330653539
37393832303435366639643730616239613935376233636537306232653034626532636563393336
63323633366631623738393161373037623865633039386566653239663638343864643561346534
33346238306434343639623135373861333830376561663433306139383864653333356264376631
39633437393538356565623962643465666538343031383737616532316230383466346261383762
33613535336663386434366365336330353337653365663132336130366338343433333863306135
62303738353634613462313866366231386430373566653339316333353364373761663161623736
64313262303963336364376534336462373939623033666163633337323837363138363937663665
39613263633463376362626565306564353864393965333663663334643931363862306635353061
31633063303839633030306363646161646466323734616536343965636539633630326664636139
61653832386339326132303334616136393731393263313034643037383063326566343936666562
38393363306231306436636235633533373731616137653965316133303661663163313661373466
36653864666232313064353066386133613764623562623035386263363962653432633633366230
32373033303234666264356665363031343633663236313738636238306535313536353232663037
38316237353433396166636165643261643464313762666333393265376465323630313463333465
61613735613864313662383735306638363436316162353536633836653637613439373635376566
36613162393638313363396237313466646166346139373230336533346234356665646432646562
32343863343435643462663362396564626536323665343230343632396135303930306334383534
39356166303230643465643737386634633531393238313631393664663237316236356465383532
32353263326364383465623733326532633330663738633564313264306636623137323433396264
33623164333662383335623964393330373264646265366662613236613033653035623932666264
34373639666432656464363433356466653331633238373863343064656431666561636236376332
30333930623539376636316263663663303130616537356632383036386438663630623261636239
63623238646364323431613936646337306361373539346465303635383065306664643566363137
37643163373833343162653563623432656132653462313334333439303236383563326465323038
31353936636563613865383730363462626636383430336536656436656136333764353133663936
38623330303531373461396163366237656632666538303034343961396631313966653532373465
62393562303330613164346464373764633933323539353861326239343133613236613663366265
38623138316138383832353931626530303538346433303035313266366638313437356264626661
30363631316234303634343561656431633632666139363330396465316564323864653434643730
39646531353233313639323365353736613262646164343664656162386536666361646666643238
34333462333632643236343665316534626537393362353633383539633131613233646262313961
66656131323333303939316239643739323665306433626366656538366438653934656336303130
36613430613565666437323233343132303432383533396533373439306630343430353535343333
35616361376539376661336637346562636438646534623265393635313466633937363135316238
65616265396337303431333262306330383365643035303639303538303266323932613466363336
31366565653731393661616132353235386162346338343734356633303433366666303332626662
35353261306264346534333161333165633163376534303861663863326638623761343733303433
63343365626463613965363134663137373538633533616635356561646235623365373633303064
31666562613134306632356564383166336464343833633037623663656338623637336135663562
38326538643961333363353831303266326262333730633565383666326137393430373966316161
66376230323633333562623564636264353138303039306537383930376464333233643862613038
38313231386161343438303433646566633236353232313737613563613932373035623034653066
63643330316462303832306533376330383466373566643233373334336330666362653337316137
38353930343338393162313135616165373437633737376131346662306438643537316537653330
65643731383435393530383038316431663638396538313131306661663934313535616261356532
36626435656332633861616465326231386635383838633232653432336362313164633839326339
65303834613235326436386539613537646363633733323735646630343631636235393533656266
65656639356337623464346337326232616234313664306165376437633562643861373231636131
37623735333165633762346238326430323336653962643731333166616137376562643430376531
30303164333761333161323730656430356534376166326431373137636438303636386330393435
37336533663762303230653839336534316636373238623934663934646133646135

View File

@ -1,46 +1,27 @@
$ANSIBLE_VAULT;1.1;AES256 $ANSIBLE_VAULT;1.1;AES256
38393933636634656238353339316465653462313762353035633934643835333732653032613264 38663333313561616264323430323162323837623430363739623561633331656664613936666665
3065303932666635623363323332386166313435653961360a393931333363396336623639316263 6364373033623163393239663035306337383066343438310a383666313434323036643037363065
33393961383638623831346532353139313463326562336265346665306538616262363932333532 30396333626130303633663930663965666662646233393439376661346265616565616236623366
3666323961656363350a616161376462626263353738626262326230346662383765613564643033 3930373433646231610a336233663132306263656465633034333030316362643939316465666534
37303336653431636131353230373736613436353536323863653465643139656566623539336665 38353961393038613961353732613434663565633466303265383231343336386330333464376363
65663866653764366666303433373330343965376461396433336632336637343736613332366235 33616330643364376332623634363766656366666239633964316439376463313063333162343963
32303932623532356661363634383035636138656639636133386336313631636330333466643433 61356634393438313063666434626338616264613639656462626639616263366531663135393466
34323837653365623237366433393038343035666130363962356137386161346336363866326135 66346635616439306364356133303664376134626636616131373138656562363363306633333164
62643332376438333832383036643339616362393639623636636536396266323630383938313263 62623135343633393834393165383231316562643062343165663235313930663039623135373263
64393638656232313737633863363762653661653337353538356163393434333066303037653033 61343336643235303962333938613230356465346436376334373438386461366231383737643137
32616363303364383739326235616336343665313737626339316365323332626331636661393436 36343832353730366131653430633465383163396336353065306638373166386438356264616139
65386333326237653261616231633962626663663235386636376538363066643731366237613838 65346635663338366463343932336231386235393836616238373864626235623935663661396663
30633364643565333931666462383764383033396562646433643434323035313136366131366337 31633565356465333737303339333435383162316530396563333335613062623138333232336162
35326531633038396664383662633839666436653638323861366131396232653331376239333833 62376363666431363931663231643561616562383230643737393261623934363633313231333137
63373665323537313637663237616563333139663536313536303338343231613832616263613837 39383238656237343661626662366465356463396336386261326334613436396364633062646532
34383864333133623963353761376262633862656635363738643832326237353431656139646631 61313136366636363861316166396134316562666435653437326331363563653035343138636163
33656636303338373434353338623830353534313864666134643133306637363838623530626636 66336139636533656334643966383962383734623565323435333665666164353732663736326364
63396165336561343133653265386136653636623665356436346630616531373866613264383034 35616264383237316330386539363065376334643432393636643464646238633034333166663665
33393331316232623066353639363239353333386532313438376637633834633038303333346330 33313166393738626133636136346637646437306335326263393634363133663736666338313838
66323865633032653233383632386230666236353363326430363132366262653364313638656435 64623139613037653461643563666539613237323934376534376461313833336338623032616661
37343563356466363338376239383634656230333439373830393630353232373530383735373336 64643062663633366436383232366137373936383430306332616634636331326361383931363961
35363031383734623061343935353361633365303735373765383962313339373739663131313336 62313236313563326438303935373837666434313435653236643135303739373763656562393537
37616432376232323565633561666230616533353066353439373465343366633230376536323032 31653265653739346433663937343439656231663963333633373066356231623762313438393763
35663836633634313932363865643162616135613262353834616139313534366461373734646464 36306336656566633034373834316363333233326130626639313130643935333437653934313636
36363261623837376561376365376365326338663862626437313035346431353335373734336636 32383034346234333561333466653561323834346166633831303566376266373933356536383031
61646261306231373464353866653661313937633832313665303932336564303330323736663838 6236303934323963336662386666653138313165366133303434
32333033646132626231303331373261623238653330656636646137336433373661626430343332
36643837363263373530663835623830343238616431386634303964386438663439386562346464
66323534333535383130386630313365326364626231633933316430373031363663326466363430
39326332613464343261306130623531656434366662383064393032663037666563663965626662
30643365376534343066653864363534366564653230376465366235643738346264633263366536
64653434336437373836663034646562316639646333666534663337663836663837666539333834
37663964636130316635343466323432633536363963373765333061323763333464616462366132
61643166353662306262623361363037623233356465343763323430373965376438643037346463
37656332643132613330653161396532383838306339363730373537616665313733636139633565
32376237333766663861633839363134323032383337336565396333636638383565623235373038
30396161353133393038386337326133303636653266633635373561616564303865643034613639
38323938373334366265323464636635363362373565633235383236363961343964316266323364
38343030346536353365663235346464393638666131353861646364333465663461346434323465
36643662326536386539633533303230356630633335646635613331306266656530643736656663
31396630323234356137626439393132323531613236616234383463346136646430343366313339
65623333633735383161663639653061316637623835333235323331656436313034316262313039
61366435396239376338393864613536306134376230613830653033306334623364633835386562
64343961386137666565616134373130323064313134663530666664393661356335346536356433
36316235653330396630646438323365393233653364666531663731656130326632

141
host_vars/web22 Normal file
View File

@ -0,0 +1,141 @@
$ANSIBLE_VAULT;1.1;AES256
64313136396662396631396561646634386134313337316166376264346466386533383934393130
6339663736653462613737323932396664643132383036370a343032653931343063326337626336
38383332346637633636663865333031636166643161323335363663653033646234656332333462
3833643037313134320a613332303261356363363138636138323661633233353365623665663632
30616166383161663534666337303632663532343866366261393935373935666536616530373862
66653836393966346463393061646431336666316537613364643939663938303135386463616661
31633330663364353663646338386338323039646530373165386663646235303963623837646533
30316236313736303837353536633161326564643566643533363431303130376338383034623365
34303861356264333463613739373635616363366362333738383838326162313238313966313765
35356637623833663437373765333237323961383133336161363439316632363634623734373962
32326466303536363164666532313264343661336364396562383630653865316132366538313066
65666661343632383434346639353462623735373933303263613938363635353666656139663832
66333638636136393166636332623934613938656336663431323032333339336165366664636334
65363166616462303939383838363363623530313539386635313664333136643035623262663333
35643335346639623363323535633735613965333133323639383339323166366635303536376265
35613939376135393165653466366462656162353632393139376666666334386166366162643438
31313033353661313031303961313032613539396561303734356533373234633233613465306431
31303332643931333037343164643162663738393466346639306632306534613065376138323564
31326462666336633938396230666231356439343630336132313064363636333563373637313666
32303230616235653733323032343238303230396232623364643765613764336137646630363462
64343239343530636333663764643338623630366163636232353734616333306339626136313338
35616632326436663734376263366437356236343339663430323632646136373066373961666135
38313838316266313830626234366262383037646661386537663534633263633239306461346535
32643032316266373931346232356162336437623137623365616132643731666361313637316536
39656332383466346236633461366437386538373734646337393666346562323139663734326436
65623633363266323563666437633666326363626561313133633031623632633333346332623334
31396365333336313939633161613639383963633136616562333236636666306139663430363265
63353261306332346439313534393363626638633531633532363365663265353331336231316238
37323439383930346136383036303833316565306139613235333633373832313130316534666435
30323262623037623939336265303866356532653064303436653131633162616630326362616430
33343538353139326663653735343436623834653264376264363761313835376433653531623266
34386266613733653634363135616335303138303062316664623666643263323939643939303133
32393564323833666132626664646436333733396565623164646363343065343464363465383330
33636562613734303665343366656630303732323739363339306337316266356635323262643031
63393261363764613638666231663837373263353137643265336134646364343130353237336463
62306363373339363235343034393230623035373366656531666663323936323366643938646135
62643135383734663766353230356463373337613936633037396538643365393738363234313166
62303038326236656332663939333364633132386266383665363632386235643731616631313431
37613566616463613662633734316461386261646464636539353439373431323133663435333763
63333230663431323136373564613239386531356463646366313537303861616234626561663133
32643134666337633938633530323034653131663663643732623636633834323064633832396339
35613738366666653765333434616336383635323765626561376232363062373761383665313735
30643165633930656566633339383439353931303836333537343634353434653433333933386338
64393566616166353731313261386239646531316563623363646537653964366631663266353366
65666638393337663633366132663933376135396334303461653232353765626365303464626338
30653334393439373632393662653032633264363238626431326136653561636164646237373033
32646464616137366163313634623864656666346336383037373562633333633432313439323631
34646132643834323261316166303531666238333964396165313936393937366533396436633832
34663538613139623063346666306165306530646363353732353431343831303161343535623539
38663537323132653034393335623232623530343432336531643538356430636262313132356430
33363062333931306633643733313239373934313635336465643139616266613237353166626334
35643138633561393531313835623665303531313437323664616561633764316332393435373065
38633766623633666362633336326466343938623461393736666137313965386133396433303236
34366339326637323934323236346239373565623565313433376433303061353763383732663239
65313636646539623037653761316662303565636262376262333332316136623737613338303036
37623837313636333464626664323163633136343762306462323339646535636237326138613132
33613761646237396265616135346639636566316633646165616332656333383233343836316163
36313736343263343534656533646463343933333031666433393635623461633639356430303434
34663033333933333439386532623664316364343066646232353335643536353733326165623231
66306661343939616235313238353761643034623062326632393161336462333365636536343934
63343866666237636563363561366339623161643362326632333532613562336238653562346231
33623337386233636331326232393465346362336439303336303638643430623864323434633333
63623036623764646234636433383364333763613866626230316533643535356662306136346664
36353734663866306336303439623537336266383131303365383439356462306237363030306432
38623738643434396138373837386334616435383662363032663930363038666536653334613261
36623730666333393564346539653533656434346439346632643730356665313865396463343737
31326633646661666461396365643061333361643638363835343235646231633637616464343265
36646439383737336531303236666136313063653563653433306563643362353536663863653266
38613461363432333666343264333461396461653231646133383861363763353763626334373635
35313431346465336636363531363766633234653066376366636263306238393361343936663066
61653739303230316232626335383865636235363638663463396435623737616661346666613037
32666436333937356530326566626237303065363834313837383837306432383833643632376564
39623937653631656562306565376232333463626563336630633331663764346138323466303433
38303965386635386565653035666631616239306231616530363965306134633034623936396135
32366430333763333039613734343563663065636538616139646239303533336437616162366532
38343137366563333866343537393532353835386230623536663966643730663031636639313232
33636133303432343531626539633862646466653864393737363333366238666536303663343837
39363330383432353465633132346165333564646262383736366664303239366365643533353738
65656163313966306464633237383530316338666665666236656164636433653735353739393363
30633462393933646436356365323864383239633963306366356534333036663438643438303365
37366638383066653965383764323436336230363336303233303433656563656563343630613935
64373965366662323137353631323233643463366338393639663833633635313531616539366333
30656663666561353938393761353266386533383361326439383338363762633538396638386630
31383131316137346234336462333032366337393438343237613231323164306132373136323233
38643133356166303661363761646430363734373130363334376535356565386638366630306362
63626539336134356539366166616331626361356335616665336564636638316137316230643961
65623465336232326533616538653561646263626536333738346531366661336134366362386239
39643665663566376264356332653062313536353635656231656566386333636330353765373664
34616338623161333232653832386436343361636461653338363932633337623537303261396334
30386663613335303438376234333138363432633234646133646466323930656330623161373530
36383261373139663932623933626164313765613930323035326334373231303033616665346337
32353235663465336433666539333032376365373266363436353063366139616232373037383664
31323062383063373932623030356461353039326363336165326138353335326436363165393639
33643830353734616164653833613830333066626161636130323861643866386234383136313336
37333337363462313831633437636633383137303736303264393236333633383933303939383533
38626138396537663463633961303766663636353737336365393638383832303735323266646337
62643665353431326465386162633737613935353261633963616531306233613966643862316166
38316164383433333263363630386462313639336464653061373239633235346633613237646563
62383836393063613365653635663136356538623962623961326434646635633464313932626333
36383666653264366236396638626265356338653630303930383861386534393732633437363663
38623739313131643038396335326437323231636661346164353433303235356432306532353066
63373662313366376363653039316361366266616466663663313732303962336339616235366432
32643832366231396132333236313962313932343230333832616664356333646533323732656466
34393862393434383362303531653638303366323530656661623236336630383064663135373862
61313761643038333035376535633964303564616532646139393964353165353763626235303662
65633465626365393033376437633134333532656262366462323365653466616462316664323837
64346533366238656637366665303339666433623261623635383631303862616438353166353866
66346366316562316230306233323937313364656537393063306537353237353737626164663365
38636331363138326336646434653238636463633138343134373937373835373232356363663366
37386633353439656162613736303932633333313131653364616364343761363335343430396432
39636630343066616633376237643062616666666135363232376632666132396333363334623036
63323531626632383062353162346536663233656132383734643761396264623165663738616564
61316234386135656538363861363531373232303163643364366136616130643737346438353334
63653234376562663937663135363763656236346663363738313836383466656162643131636138
63383430653030383232333830656333373765333639303265643938323833613262643863643835
66326466313730323666643939623539326639663838663737326665326164366262323731623037
33383631616530383238626431333033366134383839613761656264366331663539363131396361
64316333373134636163666634656561306130616337383030653063626161303930653730623130
33653730656332616135663631653336386166363866303932643163353963396466646662626439
39653562613461353633313533356336393334643066626137306164643530343331666430636330
63613763336663613639343036363332626232346530366633646536396338613164666163663235
37333334313436326233653866316438626366633632653336393633333931353961353132376639
66343362646630376537356638396263623262363138323630363834386162656236313365393766
39616135303337303166313663383635636165373333313463623731346561356430326164663164
30333839386564616133393630396538633032616332646639616161643739626437306532356136
34383432626136336261666166633739313663333664663035333533626334623132373037663239
38393638323833643730353432656365396161353161613733653562303731616462623436643832
35376133653665333432303132383966333362313262393931373264616664643438346566333764
34303439633538376439646435646631336361316436306330653838363665366461333366656239
33303038643139643431613764333864306134666166376164623038333330613933333766643830
30653637666533363234626465353734303538623233623532393936303566306434346537343932
39393863373635626530326139376339653764623265636530323330376633363265636439353738
32353634316162656461353666666338633233393039343935613539623766363237656161383364
61356165313637343134363932333136643464353436323333653939613666653164303363656637
32386561326461353665633339373038616464633430303763666234313032653735373832393539
33333334663336346139373064633364353530366166636465343734633465623065666563383539
30316166356239316530633239313765623438306234666235616464313765356165363435303336
39633532393965646539356439396132616637383430653762616562323065343233383034363130
32623331343035306165313637356131633963353035313838363439343133636631626532613366
33323364616262303962

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 - hosts: all
user: provisioning user: provisioning
become: yes become: true
vars_files: vars_files:
- "../vars/{{ ansible_distribution }}.yml" - "../vars/{{ ansible_distribution }}.yml"
tasks: tasks:
- name: Set password, shell, homedir for provisioning user - name: Set password, shell, homedir for provisioning user
when: provisioning_user is defined 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: # vim: set sw=2 ts=2:

View File

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

View File

@ -0,0 +1,11 @@
---
# file: roles/caddy/defaults/main.yml
# parent directory of vhost document roots
caddy_root_prefix: "{{ web_root_prefix }}"
# 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,82 @@
---
# 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
tags: caddy
# 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,46 @@
{{ 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) %}
{# Allow sites to override the document root #}
{% if item.document_root is defined %}
{% set document_root = item.document_root %}
{% else %}
{% set document_root = (caddy_root_prefix, domain_name) | ansible.builtin.path_join %}
{% endif %}
{% 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
{% elif static_site -%}
root * {{ document_root }}
encode
file_server
{% elif has_wordpress -%}
root * {{ document_root }}
encode
{% if ansible_distribution == 'Debian' and ansible_distribution_major_version is version('12', '==') -%}
php_fastcgi unix//run/php/php8.2-fpm-{{ domain_name }}.sock
{% endif -%}
file_server
{% endif -%}
import security-headers
}

View File

@ -10,4 +10,8 @@ fail2ban_findtime: 3600
fail2ban_bantime: 1209600 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: # vim: set ts=2 sw=2:

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +0,0 @@
#!/usr/sbin/nft -f
define ABUSEIPDB_IPV6 = {
2400:6180:0:d1::4ce:d001,
2607:5300:60:232d::,
2607:f298:6:a066::1bf:e80e,
}

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +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>2400:6180:0:d1::4ce:d001</entry>
<entry>2607:5300:60:232d::</entry>
<entry>2607:f298:6:a066::1bf:e80e</entry>
</ipset>

View File

@ -1,89 +0,0 @@
#!/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

@ -1,2 +0,0 @@
autoclean -y
upgrade -y -o APT::Get::Show-Upgraded=true

View File

@ -1,5 +0,0 @@
# Configuration for cron-apt. For further information about the possible
# configuration settings see the README file.
MAILON="never"
OPTIONS="-o quiet=1 -o Dir::Etc::SourceList=/etc/apt/security.sources.list -o Dir::Etc::SourceParts=\"/dev/null\""

View File

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

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<ipset type="hash:net">
<option name="family" value="inet" />
<short>spamhaus-ipv4</short>
<description>Spamhaus DROP and EDROP lists placeholder (IPv4).</description>
</ipset>

View File

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

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<ipset type="hash:net">
<option name="family" value="inet6" />
<short>spamhaus-ipv6</short>
<description>Spamhaus DROP list placeholder (IPv6).</description>
</ipset>

View File

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

View File

@ -1,27 +0,0 @@
[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

@ -1,63 +0,0 @@
#!/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

View File

@ -1,12 +0,0 @@
[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

@ -1,11 +1,11 @@
[Unit] [Unit]
Description=Update Spamhaus lists Description=Update FireHOL lists
# This service will fail if nftables is not running so we use Requires to make # This service will fail if nftables is not running so we use Requires to make
# sure that nftables is started. # sure that nftables is started.
Requires=nftables.service Requires=nftables.service
# Make sure the network is up and nftables is started # Make sure the network is up and nftables is started
After=network-online.target nftables.service After=network-online.target nftables.service
Wants=network-online.target update-spamhaus-nftables.timer Wants=network-online.target update-firehol-nftables.timer
[Service] [Service]
# https://www.ctrl.blog/entry/systemd-service-hardening.html # https://www.ctrl.blog/entry/systemd-service-hardening.html
@ -19,9 +19,9 @@ ReadWriteDirectories=/etc/nftables
PrivateTmp=true PrivateTmp=true
WorkingDirectory=/var/tmp WorkingDirectory=/var/tmp
SyslogIdentifier=update-spamhaus-nftables SyslogIdentifier=update-firehol-nftables
ExecStart=/usr/bin/flock -x update-spamhaus-nftables.lck \ ExecStart=/usr/bin/flock -x update-firehol-nftables.lck \
/usr/local/bin/update-spamhaus-nftables.sh /usr/local/bin/update-firehol-nftables.sh
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target

View File

@ -1,5 +1,5 @@
[Unit] [Unit]
Description=Update Spamhaus lists Description=Update FireHOL lists
[Timer] [Timer]
# Once a day at midnight # Once a day at midnight

View File

@ -1,27 +0,0 @@
[Unit]
Description=Update Spamhaus lists
# This service will fail if firewalld is not running so we use Requires to make
# sure that firewalld is started.
Requires=firewalld.service
# Make sure the network is up and firewalld is started
After=network-online.target firewalld.service
Wants=network-online.target update-spamhaus-lists.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/firewalld/ipsets
PrivateTmp=true
WorkingDirectory=/var/tmp
SyslogIdentifier=update-spamhaus-lists
ExecStart=/usr/bin/flock -x update-spamhaus-lists.lck \
/usr/local/bin/update-spamhaus-lists.sh
[Install]
WantedBy=multi-user.target

View File

@ -1,107 +0,0 @@
#!/usr/bin/env bash
#
# update-spamhaus-lists.sh v0.0.5
#
# Download Spamhaus DROP lists and load them into firewalld ipsets. Should work
# with both the iptables and nftables backends.
#
# 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
firewalld_ipsets=$(firewall-cmd --get-ipsets)
xml_temp=$(mktemp)
spamhaus_ipv4_ipset_path=/etc/firewalld/ipsets/spamhaus-ipv4.xml
spamhaus_ipv6_ipset_path=/etc/firewalld/ipsets/spamhaus-ipv6.xml
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"
# Extract all networks from drop.txt and edrop.txt, skipping blank lines and
# comments.
networks=$(cat drop.txt edrop.txt | sed -e '/^$/d' -e '/^;.*/d' -e 's/[[:space:]];[[:space:]].*//')
# If firewalld already has this ipset we should delete it first to emulate
# `ipset flush` (but I don't want to use that because newer hosts might be
# using nftables and firewalld will handle that for us).
if [[ "$firewalld_ipsets" =~ spamhaus-ipv4 ]]; then
echo "Deleting existing spamhaus-ipv4 ipset"
# This deletes the firewalld ipset XML file as well as the ipset itself
firewall-cmd --permanent --delete-ipset=spamhaus-ipv4
else
echo "Creating placeholder spamhaus-ipv4 ipset"
# Create a placeholder ipset so firewalld doesn't complain when we try
# to reload the ipset later after having added a new XML definition. I
# don't know why, but depending on the system state there may not be a
# ipset defined and firewalld errors on INVALID_IPSET.
firewall-cmd --permanent --new-ipset=spamhaus-ipv4 --type=hash:net --option=family=inet
fi
# I'm not proud of this, but writing the XML directly is WAY faster than
# using firewall-cmd to add each entry one by one (and we can't add from
# a file because many of our hosts are using old firewalld).
cat << XML_HEAD > "$xml_temp"
<?xml version="1.0" encoding="utf-8"?>
<ipset type="hash:net">
<option name="family" value="inet" />
<short>spamhaus-ipv4</short>
<description>Spamhaus DROP and EDROP lists (IPv4).</description>
XML_HEAD
for network in $networks; do
echo " <entry>$network</entry>" >> "$xml_temp"
done
echo "</ipset>" >> "$xml_temp"
install -m 0600 "$xml_temp" "$spamhaus_ipv4_ipset_path"
fi
if [[ -f "dropv6.txt" ]]; then
echo "Processing IPv6 DROP list"
networks=$(sed -e '/^$/d' -e '/^;.*/d' -e 's/[[:space:]];[[:space:]].*//' dropv6.txt)
if [[ "$firewalld_ipsets" =~ spamhaus-ipv6 ]]; then
echo "Deleting existing spamhaus-ipv6 ipset"
firewall-cmd --permanent --delete-ipset=spamhaus-ipv6
else
echo "Creating placeholder spamhaus-ipv6 ipset"
firewall-cmd --permanent --new-ipset=spamhaus-ipv6 --type=hash:net --option=family=inet6
fi
cat << XML_HEAD > "$xml_temp"
<?xml version="1.0" encoding="utf-8"?>
<ipset type="hash:net">
<option name="family" value="inet6" />
<short>spamhaus-ipv6</short>
<description>Spamhaus DROP lists (IPv6).</description>
XML_HEAD
for network in $networks; do
echo " <entry>$network</entry>" >> "$xml_temp"
done
echo "</ipset>" >> "$xml_temp"
install -m 0600 "$xml_temp" "$spamhaus_ipv6_ipset_path"
fi
echo "Reloading firewalld"
firewall-cmd --reload
rm -v drop.txt edrop.txt dropv6.txt "$xml_temp"

View File

@ -1,12 +0,0 @@
[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,91 +0,0 @@
#!/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

@ -1,20 +1,27 @@
--- ---
# file: roles/common/handlers/main.yml # ansible.builtin.file: roles/common/handlers/main.yml
- name: reload sshd - name: reload sshd
systemd: name={{ sshd_service_name }} state=reloaded ansible.builtin.systemd:
name: "{{ sshd_service_name }}"
state: reloaded
- name: reload sysctl - name: reload sysctl
command: sysctl -p /etc/sysctl.conf 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 - name: reload systemd
systemd: daemon_reload=yes ansible.builtin.systemd:
daemon_reload: true
- name: restart nftables - name: restart nftables
systemd: name=nftables state=restarted 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,17 @@
--- ---
- name: Remove cron-apt
ansible.builtin.apt:
name: cron-apt
state: absent
cache_valid_time: 3600
- name: Configure cron-apt (config) - name: Remove cron-apt configs
copy: src={{ item.src }} dest={{ item.dest }} mode={{ item.mode }} owner={{ item.owner }} group={{ item.group }} ansible.builtin.file:
path: "{{ item }}"
state: absent
loop: loop:
- { src: 'etc/cron-apt/config', dest: '/etc/cron-apt/config', mode: '0644', owner: 'root', group: 'root' } - /etc/cron-apt/config
- { src: 'etc/cron-apt/3-download', dest: '/etc/cron-apt/action.d/3-download', mode: '0644', owner: 'root', group: 'root' } - /etc/cron-apt/action.d/3-download
- /etc/apt/security.sources.list
- name: Configure cron-apt (security)
template: src=security.sources.list.j2 dest=/etc/apt/security.sources.list mode=0644 owner=root group=root
# vim: set ts=2 sw=2: # vim: set ts=2 sw=2:

View File

@ -1,25 +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 - 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 notify: restart fail2ban
- name: Configure fail2ban nginx filter - name: Configure fail2ban nginx filter
when: "extra_fail2ban_filters is defined and 'nginx' in extra_fail2ban_filters" when:
template: src=etc/fail2ban/jail.d/nginx.local.j2 dest=/etc/fail2ban/jail.d/nginx.local owner=root mode=0644 - 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 notify: restart fail2ban
- name: Create fail2ban service override directory - 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 # See Arch Linux's example: https://wiki.archlinux.org/index.php/Fail2ban
- name: Configure fail2ban service override - 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: notify:
- reload systemd - reload systemd
- restart fail2ban - restart fail2ban
- name: Start and enable fail2ban service - 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: # vim: set sw=2 ts=2:

View File

@ -0,0 +1,20 @@
---
- name: Configure firewall (Debian)
when: ansible_distribution == 'Debian'
ansible.builtin.include_tasks:
file: firewall_Debian.yml
apply:
tags:
- firewall
tags: firewall
- name: Configure firewall (Ubuntu)
when: ansible_distribution == 'Ubuntu'
ansible.builtin.include_tasks:
file: firewall_Ubuntu.yml
apply:
tags:
- firewall
tags: firewall

View File

@ -1,148 +1,28 @@
--- ---
# Debian 11 will use nftables directly, with no firewalld. # Debian 11+ will use nftables directly, with no firewalld.
- block: - name: Install Debian firewall packages
- name: Set Debian firewall packages when: ansible_distribution_major_version is version('11', '>=')
when: ansible_distribution_major_version is version('10', '<=') ansible.builtin.package:
set_fact: name:
debian_firewall_packages: - libnet-ip-perl # for aggregate-cidr-addresses.pl
- firewalld - nftables
- tidy - curl # for nftables update scripts
- fail2ban state: present
- python3-systemd # for fail2ban systemd backend cache_valid_time: 3600
- name: Set Debian firewall packages - name: Remove iptables on newer Debian
when: ansible_distribution_major_version is version('11', '>=') when: ansible_distribution_major_version is version('11', '>=')
set_fact: ansible.builtin.apt:
debian_firewall_packages: pkg: iptables
- fail2ban state: absent
- libnet-ip-perl # for aggregate-cidr-addresses.pl
- nftables
- python3-systemd
- curl # for nftables update scripts
- name: Install firewall packages - name: Configure nftables
apt: pkg={{ debian_firewall_packages }} state=present cache_valid_time=3600 ansible.builtin.include_tasks: nftables.yml
when: ansible_distribution_version is version('11', '>=')
- name: Copy nftables.conf - ansible.builtin.include_tasks: fail2ban.yml
when: ansible_distribution_major_version is version('11', '>=') when:
template: src=nftables.conf.j2 dest=/etc/nftables.conf owner=root mode=0644 - ansible_distribution_major_version is version('9', '>=')
notify:
- restart nftables
- name: Create /etc/nftables extra config directory
when: ansible_distribution_major_version is version('11', '>=')
file: path=/etc/nftables state=directory owner=root mode=0755
- name: Copy extra nftables configuration files
when: ansible_distribution_major_version is version('11', '>=')
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
- 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
# 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: Copy firewalld public zone file
when: ansible_distribution_major_version is version('10', '<=')
template: src=public.xml.j2 dest=/etc/firewalld/zones/public.xml owner=root mode=0600
- name: Format public.xml firewalld zone file
when: ansible_distribution_major_version is version('10', '<=')
command: tidy -xml -iq -m -w 0 /etc/firewalld/zones/public.xml
notify:
- restart firewalld
- name: Copy firewalld ipsets of abusive IPs
when: ansible_distribution_major_version is version('10', '<=')
copy: src={{ item }} dest=/etc/firewalld/ipsets/{{ item }} owner=root group=root mode=0600
loop:
- abusers-ipv4.xml
- abusers-ipv6.xml
- spamhaus-ipv4.xml
- spamhaus-ipv6.xml
notify:
- restart firewalld
- name: Copy Spamhaus firewalld update script
when: ansible_distribution_version is version('10', '<=')
copy: src=update-spamhaus-lists.sh dest=/usr/local/bin/update-spamhaus-lists.sh mode=0755 owner=root group=root
- name: Copy Spamhaus firewalld systemd units
when: ansible_distribution_version is version('10', '<=')
copy: src={{ item }} dest=/etc/systemd/system/{{ item }} mode=0644 owner=root group=root
loop:
- update-spamhaus-lists.service
- update-spamhaus-lists.timer
register: spamhaus_firewalld_systemd_units
- name: Copy Spamhaus nftables update scripts
when: ansible_distribution_version is version('11', '>=')
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 nftables systemd units
when: ansible_distribution_version is version('11', '>=')
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
# need to reload to pick up service/timer/environment changes
- name: Reload systemd daemon
systemd: daemon_reload=yes
when: spamhaus_firewalld_systemd_units is changed or
nftables_systemd_units is changed
- name: Start and enable Spamhaus firewalld update timer
when: ansible_distribution_version is version('10', '<=')
systemd: name=update-spamhaus-lists.timer state=started enabled=yes
notify:
- restart firewalld
- name: Start and enable nftables update timers
when: ansible_distribution_version is version('11', '>=')
systemd: name={{ item }} state=started enabled=yes
loop:
- update-spamhaus-nftables.timer
- update-abusech-nftables.timer
- name: Start and enable nftables
when: ansible_distribution_major_version is version('11', '>=')
systemd: name=nftables state=started enabled=yes
- include_tasks: fail2ban.yml
when: ansible_distribution_major_version is version('9', '>=')
tags: firewall
# vim: set sw=2 ts=2: # vim: set sw=2 ts=2:

View File

@ -1,133 +1,27 @@
--- ---
# Ubuntu 20.04 will use nftables directly, with no firewalld. # Ubuntu 20.04 will use nftables directly, with no firewalld.
# Ubuntu 18.04 will use firewalld with the nftables backend.
# Ubuntu 16.04 will use firewalld with the iptables backend.
- block: - name: Install Ubuntu firewall packages
- name: Set Ubuntu firewall packages when: ansible_distribution_version is version('20.04', '>=')
when: ansible_distribution_version is version('20.04', '<') ansible.builtin.package:
set_fact: name:
ubuntu_firewall_packages: - libnet-ip-perl # for aggregate-cidr-addresses.pl
- firewalld - nftables
- tidy - curl # for nftables update scripts
- fail2ban state: present
- python3-systemd # for fail2ban systemd backend cache_valid_time: 3600
- name: Set Ubuntu firewall packages - name: Remove ufw
when: ansible_distribution_version is version('20.04', '>=') ansible.builtin.package:
set_fact: name: ufw
ubuntu_firewall_packages: state: absent
- fail2ban
- libnet-ip-perl # for aggregate-cidr-addresses.pl
- nftables
- python3-systemd
- curl # for nftables update scripts
- name: Install firewall packages - name: Configure nftables
apt: pkg={{ ubuntu_firewall_packages }} state=present cache_valid_time=3600 ansible.builtin.include_tasks: nftables.yml
when: ansible_distribution_version is version('20.04', '>=')
- name: Remove ufw - ansible.builtin.include_tasks: fail2ban.yml
when: ansible_distribution_version is version('16.04', '>=') when:
apt: pkg=ufw state=absent - ansible_distribution_version is version('16.04', '>=')
- name: Copy nftables.conf
when: ansible_distribution_version is version('20.04', '>=')
template: src=nftables.conf.j2 dest=/etc/nftables.conf owner=root mode=0644
notify:
- restart nftables
- name: Create /etc/nftables extra config directory
when: ansible_distribution_version is version('20.04', '>=')
file: path=/etc/nftables state=directory owner=root mode=0755
- name: Copy extra nftables configuration files
when: ansible_distribution_version is version('20.04', '>=')
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
- name: Copy firewalld public zone file
when: ansible_distribution_version is version('18.04', '<=')
template: src=public.xml.j2 dest=/etc/firewalld/zones/public.xml owner=root mode=0600
- name: Format public.xml firewalld zone file
when: ansible_distribution_version is version('18.04', '<=')
command: tidy -xml -iq -m -w 0 /etc/firewalld/zones/public.xml
notify:
- restart firewalld
- name: Copy firewalld ipsets of abusive IPs
when: ansible_distribution_version is version('18.04', '<=')
copy: src={{ item }} dest=/etc/firewalld/ipsets/{{ item }} owner=root group=root mode=0600
loop:
- abusers-ipv4.xml
- abusers-ipv6.xml
- spamhaus-ipv4.xml
- spamhaus-ipv6.xml
notify:
- restart firewalld
- name: Copy Spamhaus firewalld update script
when: ansible_distribution_version is version('18.04', '<=')
copy: src=update-spamhaus-lists.sh dest=/usr/local/bin/update-spamhaus-lists.sh mode=0755 owner=root group=root
- name: Copy Spamhaus firewalld systemd units
when: ansible_distribution_version is version('18.04', '<=')
copy: src={{ item }} dest=/etc/systemd/system/{{ item }} mode=0644 owner=root group=root
loop:
- update-spamhaus-lists.service
- update-spamhaus-lists.timer
register: spamhaus_firewalld_systemd_units
- name: Copy nftables update scripts
when: ansible_distribution_version is version('20.04', '>=')
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 nftables systemd units
when: ansible_distribution_version is version('20.04', '>=')
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
# need to reload to pick up service/timer/environment changes
- name: Reload systemd daemon
systemd: daemon_reload=yes
when: spamhaus_firewalld_systemd_units is changed or
nftables_systemd_units is changed
- name: Start and enable Spamhaus firewalld update timer
when: ansible_distribution_version is version('18.04', '<=')
systemd: name=update-spamhaus-lists.timer state=started enabled=yes
notify:
- restart firewalld
- name: Start and enable nftables update timers
when: ansible_distribution_version is version('20.04', '>=')
systemd: name={{ item }} state=started enabled=yes
loop:
- update-spamhaus-nftables.timer
- update-abusech-nftables.timer
- name: Start and enable nftables
when: ansible_distribution_version is version('20.04', '>=')
systemd: name=nftables state=started enabled=yes
- include_tasks: fail2ban.yml
when: ansible_distribution_version is version('16.04', '>=')
tags: firewall
# vim: set sw=2 ts=2: # vim: set sw=2 ts=2:

View File

@ -1,54 +1,44 @@
--- ---
- name: Import OS-specific variables - name: Import OS-specific variables
include_vars: "vars/{{ ansible_distribution }}.yml" ansible.builtin.include_vars: vars/{{ ansible_distribution }}.yml
tags: always tags: always
- name: Configure network time - name: Configure network time
import_tasks: ntp.yml ansible.builtin.import_tasks: ntp.yml
tags: ntp tags: ntp
- name: Install common packages - name: Install common packages
include_tasks: packages_Debian.yml ansible.builtin.include_tasks: packages_Debian.yml
when: ansible_distribution == 'Debian' when: ansible_distribution == 'Debian'
tags: packages tags: packages
- name: Install common packages - name: Install common packages
include_tasks: packages_Ubuntu.yml ansible.builtin.include_tasks: packages_Ubuntu.yml
when: ansible_distribution == 'Ubuntu' when: ansible_distribution == 'Ubuntu'
tags: packages tags: packages
- name: Configure firewall - name: Configure firewall
include_tasks: firewall_Debian.yml ansible.builtin.import_tasks: firewall.yml
when: ansible_distribution == 'Debian'
tags: firewall
- name: Configure firewall
include_tasks: firewall_Ubuntu.yml
when: ansible_distribution == 'Ubuntu'
tags: firewall tags: firewall
- name: Configure secure shell daemon - name: Configure secure shell daemon
import_tasks: sshd.yml ansible.builtin.import_tasks: sshd.yml
tags: sshd tags: sshd
# containers identify as virtualization hosts, which makes this tricky, because we have actual Debian VM hosts! # containers identify as virtualization hosts, which makes this tricky, because we have actual Debian VM hosts!
- name: Reconfigure /etc/sysctl.conf - name: Reconfigure /etc/sysctl.conf
when: ansible_virtualization_role != 'host' 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: notify:
- reload sysctl - reload sysctl
tags: 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 - 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 tags: udev
- name: Copy admin SSH keys - name: Copy admin SSH keys
import_tasks: ssh-keys.yml ansible.builtin.import_tasks: ssh-keys.yml
tags: ssh-keys tags: ssh-keys
# vim: set sw=2 ts=2: # vim: set sw=2 ts=2:

View File

@ -0,0 +1,97 @@
---
# Common nftables tasks for Ubuntu 20.04, Ubuntu 22.04, Ubuntu 24.04, Debian 11,
# and Debian 12.
- name: Copy nftables.conf
ansible.builtin.template:
src: nftables.conf.j2
dest: /etc/nftables.conf
owner: root
mode: "0644"
notify:
- restart nftables
- restart fail2ban
- name: Create /etc/nftables extra config directory
ansible.builtin.file:
path: /etc/nftables
state: directory
owner: root
mode: "0755"
- name: Copy extra nftables configuration files
ansible.builtin.copy:
src: "{{ item.src }}"
dest: /etc/nftables/{{ item.src }}
owner: root
group: root
mode: "0644"
force: "{{ item.force }}"
loop:
- { src: firehol_level1-ipv4.nft, force: false }
notify:
- restart nftables
- restart fail2ban
- name: Copy nftables update scripts
ansible.builtin.template:
src: update-firehol-nftables.sh.j2
dest: /usr/local/bin/update-firehol-nftables.sh
mode: "0755"
owner: root
group: root
- name: Remove deprecated data and scripts
ansible.builtin.file:
path: "{{ item }}"
state: absent
loop:
- /etc/nftables/spamhaus-ipv4.nft
- /etc/nftables/spamhaus-ipv6.nft
- /etc/nftables/abuseipdb-ipv4.nft
- /etc/nftables/abuseipdb-ipv6.nft
- /etc/nftables/abusech-ipv4.nft
- /usr/local/bin/update-abusech-nftables.sh
- /usr/local/bin/update-spamhaus-nftables.sh
- /etc/systemd/system/update-abusech-nftables.service
- /etc/systemd/system/update-abusech-nftables.timer
- /etc/systemd/system/update-spamhaus-nftables.service
- /etc/systemd/system/update-spamhaus-nftables.timer
- /usr/local/bin/aggregate-cidr-addresses.pl
notify:
- restart nftables
- restart fail2ban
- name: Copy nftables systemd units
ansible.builtin.copy:
src: "{{ item }}"
dest: /etc/systemd/system/{{ item }}
mode: "0644"
owner: root
group: root
loop:
- update-firehol-nftables.service
- update-firehol-nftables.timer
register: nftables_systemd_units
# need to reload to pick up service/timer/environment changes
- name: Reload systemd daemon
ansible.builtin.systemd: # noqa no-handler
daemon_reload: true
when: nftables_systemd_units is changed
- name: Start and enable nftables update timers
ansible.builtin.systemd:
name: "{{ item }}"
state: started
enabled: true
loop:
- update-firehol-nftables.timer
- name: Start and enable nftables
ansible.builtin.systemd:
name: nftables
state: started
enabled: true
# vim: set sw=2 ts=2:

View File

@ -4,24 +4,27 @@
# client. # client.
- name: Set timezone - name: Set timezone
when: timezone is defined and ansible_service_mgr == 'systemd' when:
command: /usr/bin/timedatectl set-timezone {{ timezone }} - timezone is defined
- ansible_service_mgr == 'systemd'
community.general.timezone:
name: "{{ timezone }}"
tags: timezone tags: timezone
# Apparently some cloud images don't have this installed by default. From what # 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 # I can see on existing servers, systemd-timesyncd is a standalone package on
# Ubuntu 20.04 and Debian 11. # Ubuntu 20.04 and Debian 11.
- name: Install systemd-timesyncd - name: Install systemd-timesyncd
when: (ansible_distribution == 'Ubuntu' and ansible_distribution_version is version('20.04', '==')) or when: (ansible_distribution == 'Ubuntu' and ansible_distribution_version is version('20.04', '==')) or (ansible_distribution == 'Debian' and ansible_distribution_version
(ansible_distribution == 'Debian' and ansible_distribution_version is version('11', '==')) is version('11', '>='))
apt: name=systemd-timesyncd state=present cache_valid_time=3600 ansible.builtin.apt: name=systemd-timesyncd state=present cache_valid_time=3600
- name: Start and enable systemd's NTP client - name: Start and enable systemd's NTP client
when: ansible_service_mgr == 'systemd' 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 - name: Uninstall ntp on modern Ubuntu/Debian
apt: name=ntp state=absent ansible.builtin.apt: name=ntp state=absent
when: ansible_service_mgr == 'systemd' when: ansible_service_mgr == 'systemd'
# vim: set ts=2 sw=2: # vim: set ts=2 sw=2:

View File

@ -1,39 +1,49 @@
--- ---
- name: Configure Debian packages
block:
# 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
- block: - name: Configure apt mirror
- name: Configure apt mirror ansible.builtin.template: src=sources.list.j2 dest=/etc/apt/sources.list owner=root group=root mode=0644
template: src=sources.list.j2 dest=/etc/apt/sources.list owner=root group=root mode=0644 when:
when: ansible_architecture != 'armv7l' - ansible_architecture != 'armv7l'
- not weird_debian_sources_stat
- name: Set fact for base packages - name: Set fact for base packages
set_fact: ansible.builtin.set_fact:
base_packages: base_packages:
- git - git
- git-lfs - git-lfs
- tmux - tmux
- iotop - iotop
- htop - htop
- strace - strace
- cron-apt - safe-rm
- safe-rm - debian-goodies
- debian-goodies - mosh
- mosh - python3-pycurl # for ansible's apt_repository
- python3-pycurl # for ansible's apt_repository - vim
- vim - unzip
- unzip - apt-transport-https # for https support in apt
- apt-transport-https # for https support in apt - gnupg2
- gnupg2 - zstd
- zstd - rsync
- lsof
- unattended-upgrades
- name: Install base packages - name: Install base packages
apt: name={{ base_packages }} state=present update_cache=yes cache_valid_time=3600 ansible.builtin.apt: name={{ base_packages }} state=present cache_valid_time=3600
- name: Configure cron-apt - name: Remove cron-apt
import_tasks: cron-apt.yml ansible.builtin.import_tasks: cron-apt.yml
tags: cron-apt tags: cron-apt
- name: Install tarsnap - name: Install tarsnap
import_tasks: tarsnap.yml ansible.builtin.import_tasks: tarsnap.yml
tags: packages tags: packages
# vim: set sw=2 ts=2: # vim: set sw=2 ts=2:

View File

@ -1,106 +1,60 @@
--- ---
- name: Configure Ubuntu packages
block:
- 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'
- block: - name: Upgrade base OS
- name: Configure apt mirror ansible.builtin.apt: upgrade=dist cache_valid_time=3600
template: src=sources.list.j2 dest=/etc/apt/sources.list owner=root group=root mode=0644
when: ansible_architecture != 'armv7l'
- name: Upgrade base OS - name: Set Ubuntu base packages
apt: upgrade=dist update_cache=yes cache_valid_time=3600 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: Set Ubuntu base packages - name: Install base packages
set_fact: ansible.builtin.apt: pkg={{ ubuntu_base_packages }} state=present cache_valid_time=3600
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
- name: Install base packages - name: Disable annoying Canonical spam in MOTD
apt: pkg={{ ubuntu_base_packages }} state=present update_cache=yes cache_valid_time=3600 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
# We have to remove snaps one by one in a specific order because some depend - name: Disable annoying Canonical spam in MOTD
# on others. Only after that can we remove the corresponding system packages. ansible.builtin.systemd: name={{ item }} state=stopped enabled=no
- name: Remove lxd snap when: ansible_service_mgr == 'systemd'
snap: name=lxd state=absent loop:
when: ansible_distribution_version is version('20.04', '==') - motd-news.service
ignore_errors: yes - motd-news.timer
- name: Remove core18 snap - name: Configure cron-apt
snap: name=core18 state=absent ansible.builtin.import_tasks: cron-apt.yml
when: ansible_distribution_version is version('20.04', '==') tags: cron-apt
ignore_errors: yes
- name: Remove snapd snap - name: Install tarsnap
snap: name=snapd state=absent ansible.builtin.import_tasks: tarsnap.yml
when: ansible_distribution_version is version('20.04', '==')
ignore_errors: yes
- 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)
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
apt: name={{ ubuntu_annoying_packages }} state=absent purge=yes
- 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
systemd: name={{ item }} state=stopped enabled=no
when: ansible_service_mgr == 'systemd'
loop:
- motd-news.service
- motd-news.timer
- name: Configure cron-apt
import_tasks: cron-apt.yml
tags: cron-apt
- name: Install tarsnap
import_tasks: tarsnap.yml
tags: packages tags: packages
# vim: set sw=2 ts=2: # vim: set sw=2 ts=2:

View File

@ -1,9 +1,9 @@
--- ---
- name: Zero .ssh/authorized_keys for provisioning user - 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 - 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: with_fileglob:
# use descriptive names for keys, like: aorth-mzito-rsa.pub # use descriptive names for keys, like: aorth-mzito-rsa.pub
- ssh-pub-keys/*.pub - ssh-pub-keys/*.pub

View File

@ -1,20 +1,46 @@
--- ---
# SSH configs don't change in Debian minor versions # SSH configs don't change in Debian minor versions
- name: Reconfigure /etc/ssh/sshd_config - 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' when: ansible_distribution == 'Debian'
notify: reload sshd notify: reload sshd
# Ubuntu is the only distro we have where SSH version is very different from 14.04 -> 14.10, # Ubuntu is the only distro we have where SSH version is very different from 14.04 -> 14.10,
# ie with new ciphers supported etc. # ie with new ciphers supported etc.
- name: Reconfigure /etc/ssh/sshd_config - 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' when: ansible_distribution == 'Ubuntu'
notify: reload sshd 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 - name: Remove DSA and ECDSA host keys
file: name=/etc/ssh/{{ item }} state=absent ansible.builtin.file: name=/etc/ssh/{{ item }} state=absent
loop: loop:
- ssh_host_dsa_key - ssh_host_dsa_key
- ssh_host_dsa_key.pub - ssh_host_dsa_key.pub

View File

@ -1,24 +1,45 @@
--- ---
- name: Add Tarsnap apt mirror - name: Check tarsnap apt signing key
template: src=tarsnap_sources.list.j2 dest=/etc/apt/sources.list.d/tarsnap.list owner=root group=root mode=0644 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 register: add_tarsnap_apt_repository
when: ansible_architecture != 'armv7l' when: ansible_architecture != 'armv7l'
- name: Add GPG key for Tarsnap
apt_key: id=0xBF75EEAB040E447C url=https://pkg.tarsnap.com/tarsnap-deb-packaging-key.asc state=present
register: add_tarsnap_apt_key
- name: Update apt cache - name: Update apt cache
apt: ansible.builtin.apt: # noqa no-handler
update_cache: yes update_cache: true
when: when: (download_tarsnap_signing_key.status_code is defined and download_tarsnap_signing_key.status_code == 200) or add_tarsnap_apt_repository is changed
add_tarsnap_apt_key is changed or
add_tarsnap_apt_repository is changed
- name: Install tarsnap - name: Install tarsnap
apt: pkg=tarsnap cache_valid_time=3600 ansible.builtin.apt:
pkg: tarsnap
cache_valid_time: 3600
- name: Copy tarsnaprc - 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: # vim: set sw=2 ts=2:

View File

@ -2,13 +2,9 @@
enabled = true enabled = true
# See: /etc/fail2ban/filter.d/nginx-botsearch.conf # See: /etc/fail2ban/filter.d/nginx-botsearch.conf
filter = nginx-botsearch filter = nginx-botsearch
{% if (ansible_distribution == 'Debian' and ansible_distribution_major_version is version('11', '>=')) or (ansible_distribution == 'Ubuntu' and ansible_distribution_version is version('20.04', '>=')) %}
# Integrate with nftables # Integrate with nftables
banaction=nftables[type=allports] banaction=nftables[type=allports]
{% else %} backend = pyinotify
# Integrate with firewalld and ipsets
banaction = firewallcmd-ipset
{% endif %}
logpath = /var/log/nginx/*-access.log logpath = /var/log/nginx/*-access.log
# Try to find a non-existent wp-login.php once and get banned. Tough luck. # Try to find a non-existent wp-login.php once and get banned. Tough luck.
maxretry = 1 maxretry = 1

View File

@ -2,13 +2,8 @@
enabled = true enabled = true
# See: /etc/fail2ban/filter.d/sshd.conf # See: /etc/fail2ban/filter.d/sshd.conf
filter = sshd filter = sshd
{% if (ansible_distribution == 'Debian' and ansible_distribution_major_version is version('11', '>=')) or (ansible_distribution == 'Ubuntu' and ansible_distribution_version is version('20.04', '>=')) %}
# Integrate with nftables # Integrate with nftables
banaction=nftables[type=allports] banaction=nftables[type=allports]
{% else %}
# Integrate with firewalld and ipsets
banaction = firewallcmd-ipset
{% endif %}
backend = systemd backend = systemd
maxretry = {{ fail2ban_maxretry }} maxretry = {{ fail2ban_maxretry }}
findtime = {{ fail2ban_findtime }} findtime = {{ fail2ban_findtime }}

View File

@ -5,47 +5,18 @@
flush ruleset flush ruleset
# Lists updated daily by update-spamhaus-nftables.sh # List updated daily by update-firehol-nftables.sh
include "/etc/nftables/spamhaus-ipv4.nft" include "/etc/nftables/firehol_level1-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: # Notes:
# - tables hold chains, chains hold rules # - tables hold chains, chains hold rules
# - inet is for both ipv4 and ipv6 # - inet is for both ipv4 and ipv6
table inet filter { table inet filter {
set spamhaus-ipv4 { set firehol_level1-ipv4 {
type ipv4_addr type ipv4_addr
# if the set contains prefixes we need to use the interval flag # if the set contains prefixes we need to use the interval flag
flags interval flags interval
elements = $SPAMHAUS_IPV4 elements = $FIREHOL_LEVEL1_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 { chain input {
@ -55,13 +26,7 @@ table inet filter {
ct state invalid counter drop comment "Early drop of invalid connections" 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" ip saddr @firehol_level1-ipv4 counter drop comment "Early drop of incoming packets matching firehol_level1-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" iifname lo accept comment "Allow from loopback"
@ -81,12 +46,8 @@ table inet filter {
ip6 saddr ::/0 ct state new tcp dport 443 counter accept comment "Allow HTTPS" ip6 saddr ::/0 ct state new tcp dport 443 counter accept comment "Allow HTTPS"
{% endif %} {% endif %}
ip saddr 0.0.0.0/0 ct state new udp dport 60001 counter accept comment "Allow mosh" ip saddr 0.0.0.0/0 ct state new udp dport 60001-60003 counter accept comment "Allow mosh"
ip saddr 0.0.0.0/0 ct state new udp dport 60002 counter accept comment "Allow mosh" ip6 saddr ::/0 ct state new udp dport 60001-60003 counter accept comment "Allow mosh"
ip saddr 0.0.0.0/0 ct state new udp dport 60003 counter accept comment "Allow mosh"
ip6 saddr ::/0 ct state new udp dport 60001 counter accept comment "Allow mosh"
ip6 saddr ::/0 ct state new udp dport 60002 counter accept comment "Allow mosh"
ip6 saddr ::/0 ct state new udp dport 60003 counter accept comment "Allow mosh"
{# Extra rules #} {# Extra rules #}
{% if extra_iptables_rules is defined %} {% if extra_iptables_rules is defined %}
@ -109,12 +70,6 @@ table inet filter {
chain output { chain output {
type filter hook output priority 0; type filter hook output priority 0;
ip daddr @spamhaus-ipv4 counter drop comment "Drop outgoing packets matching spamhaus-ipv4 list" ip daddr @firehol_level1-ipv4 counter drop comment "Drop outgoing packets matching firehol_level1-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,81 +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>
<rule>
<source ipset="spamhaus-ipv4"/>
<drop/>
</rule>
<rule>
<source ipset="spamhaus-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

@ -1,5 +0,0 @@
{% if ansible_distribution == 'Ubuntu' %}
deb http://security.ubuntu.com/ubuntu {{ ansible_distribution_release }}-security main restricted universe multiverse
{% elif ansible_distribution == 'Debian' %}
deb http://security.debian.org/debian-security {{ ansible_distribution_release }}/updates main contrib non-free
{% endif %}

View File

@ -56,7 +56,11 @@ AuthorizedKeysFile .ssh/authorized_keys
#IgnoreRhosts yes #IgnoreRhosts yes
# To disable tunneled clear text passwords, change to no here! # 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 #PermitEmptyPasswords no
# Change to yes to enable challenge-response passwords (beware issues with # Change to yes to enable challenge-response passwords (beware issues with
@ -122,7 +126,7 @@ Subsystem sftp /usr/lib/openssh/sftp-server
# AllowTcpForwarding no # AllowTcpForwarding no
# PermitTTY no # PermitTTY no
# ForceCommand cvs server # ForceCommand cvs server
# Based on the ssh-audit profile for OpenSSH 8.4, but with but with all algos # 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 # 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. # the new (2018) CNSA suite is 256 bits and up.
@ -131,8 +135,12 @@ Subsystem sftp /usr/lib/openssh/sftp-server
# See: https://en.wikipedia.org/wiki/Commercial_National_Security_Algorithm_Suite # See: https://en.wikipedia.org/wiki/Commercial_National_Security_Algorithm_Suite
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes256-ctr Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes256-ctr
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com 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 KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha256
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes256-ctr
# only allow shell access by provisioning user {% if ssh_allowed_users is defined and ssh_allowed_users %}
AllowUsers {{ provisioning_user.name }} # 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

@ -1,21 +1,23 @@
# $OpenBSD: sshd_config,v 1.101 2017/03/14 07:19:07 djm Exp $
# This is the sshd server system-wide configuration file. See # This is the sshd server system-wide configuration file. See
# sshd_config(5) for more information. # sshd_config(5) for more information.
# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin # 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 # The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where # OpenSSH is to specify options with their default value where
# possible, but leave them commented. Uncommented options override the # possible, but leave them commented. Uncommented options override the
# default value. # default value.
Include /etc/ssh/sshd_config.d/*.conf
#Port 22 #Port 22
#AddressFamily any #AddressFamily any
#ListenAddress 0.0.0.0 #ListenAddress 0.0.0.0
#ListenAddress :: #ListenAddress ::
#HostKey /etc/ssh/ssh_host_rsa_key #HostKey /etc/ssh/ssh_host_rsa_key
#HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key HostKey /etc/ssh/ssh_host_ed25519_key
# Ciphers and keying # Ciphers and keying
@ -54,12 +56,16 @@ AuthorizedKeysFile .ssh/authorized_keys
#IgnoreRhosts yes #IgnoreRhosts yes
# To disable tunneled clear text passwords, change to no here! # 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 #PermitEmptyPasswords no
# Change to yes to enable challenge-response passwords (beware issues with # Change to yes to enable challenge-response passwords (beware issues with
# some PAM modules and threads) # some PAM modules and threads)
ChallengeResponseAuthentication no KbdInteractiveAuthentication no
# Kerberos options # Kerberos options
#KerberosAuthentication no #KerberosAuthentication no
@ -75,13 +81,13 @@ ChallengeResponseAuthentication no
# Set this to 'yes' to enable PAM authentication, account processing, # Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will # and session processing. If this is enabled, PAM authentication will
# be allowed through the ChallengeResponseAuthentication and # be allowed through the KbdInteractiveAuthentication and
# PasswordAuthentication. Depending on your PAM configuration, # PasswordAuthentication. Depending on your PAM configuration,
# PAM authentication via ChallengeResponseAuthentication may bypass # PAM authentication via KbdInteractiveAuthentication may bypass
# the setting of "PermitRootLogin without-password". # the setting of "PermitRootLogin prohibit-password".
# If you just want the PAM account and session checks to run without # If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication # PAM authentication, then enable this but set PasswordAuthentication
# and ChallengeResponseAuthentication to 'no'. # and KbdInteractiveAuthentication to 'no'.
UsePAM yes UsePAM yes
#AllowAgentForwarding yes #AllowAgentForwarding yes
@ -94,13 +100,12 @@ X11Forwarding no
PrintMotd no PrintMotd no
#PrintLastLog yes #PrintLastLog yes
#TCPKeepAlive yes #TCPKeepAlive yes
#UseLogin no
#PermitUserEnvironment no #PermitUserEnvironment no
#Compression delayed #Compression delayed
#ClientAliveInterval 0 #ClientAliveInterval 0
#ClientAliveCountMax 3 #ClientAliveCountMax 3
#UseDNS no #UseDNS no
#PidFile /var/run/sshd.pid #PidFile /run/sshd.pid
#MaxStartups 10:30:100 #MaxStartups 10:30:100
#PermitTunnel no #PermitTunnel no
#ChrootDirectory none #ChrootDirectory none
@ -122,12 +127,20 @@ Subsystem sftp /usr/lib/openssh/sftp-server
# PermitTTY no # PermitTTY no
# ForceCommand cvs server # ForceCommand cvs server
# Originally from: https://stribika.github.io/2015/01/04/secure-secure-shell.html # Based on the ssh-audit profile for OpenSSH 9.2, but with but with all algos
# ... but with ciphers and MACs with < 256 bits removed, as NSA's Suite B now # with less than 256 bits removed, as NSA's Suite B removed them years ago and
# does away with these! See: https://www.nsa.gov/ia/programs/suiteb_cryptography/index.shtml # 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 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 MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com
KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256 KexAlgorithms sntrup761x25519-sha512@openssh.com,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 {% if ssh_allowed_users is defined and ssh_allowed_users %}
AllowUsers {{ provisioning_user.name }} # 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 #IgnoreRhosts yes
# To disable tunneled clear text passwords, change to no here! # 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 #PermitEmptyPasswords no
# Change to yes to enable challenge-response passwords (beware issues with # Change to yes to enable challenge-response passwords (beware issues with
@ -122,7 +126,6 @@ Subsystem sftp /usr/lib/openssh/sftp-server
# AllowTcpForwarding no # AllowTcpForwarding no
# PermitTTY no # PermitTTY no
# ForceCommand cvs server # ForceCommand cvs server
PasswordAuthentication yes
# Originally from: https://stribika.github.io/2015/01/04/secure-secure-shell.html # 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 # ... but with ciphers and MACs with < 256 bits removed, as NSA's Suite B now

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

@ -0,0 +1,65 @@
#!/usr/bin/env bash
#
# update-firehol-nftables.sh v0.0.1
#
# Download FireHOL lists and load them into nftables sets.
#
# See: https://iplists.firehol.org/
#
# Copyright (C) 2025 Alan Orth
#
# SPDX-License-Identifier: GPL-3.0-only
# Exit on first error
set -o errexit
firehol_level1_ipv4_set_path=/etc/nftables/firehol_level1-ipv4.nft
function download() {
echo "Downloading $1"
wget -q -O - "https://iplists.firehol.org/files/$1" > "$1"
}
download firehol_level1.netset
if [[ -f "firehol_level1.netset" ]]; then
echo "Processing FireHOL Level 1 list"
firehol_level1_ipv4_list_temp=$(mktemp)
firehol_level1_ipv4_set_temp=$(mktemp)
# Filter blank lines, comments, and bogons we use inside the LAN, DMZ, and
# for local services like systemd-resolved and others on localhost. Ideally
# these are blocked already at the WAN side by network administrators.
cat firehol_level1.netset \
| sed \
-e '/^$/d' \
-e '/^#.*/d' \
-e '/^127\.0\.0\.0\/8/d' \
> "$firehol_level1_ipv4_list_temp"
echo "Building firehol_level1-ipv4 set"
cat << NFT_HEAD > "$firehol_level1_ipv4_set_temp"
#!/usr/sbin/nft -f
define FIREHOL_LEVEL1_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," >> "$firehol_level1_ipv4_set_temp"
done < $firehol_level1_ipv4_list_temp
echo "}" >> "$firehol_level1_ipv4_set_temp"
install -m 0600 "$firehol_level1_ipv4_set_temp" "$firehol_level1_ipv4_set_path"
rm -f "$firehol_level1_ipv4_list_temp" "$firehol_level1_ipv4_set_temp"
fi
echo "Reloading nftables"
/usr/bin/systemctl reload nftables.service
rm -v firehol_level1.netset

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 # Based on my running of mysqltuner.pl on a host with three WordPress databases
# #

View File

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

View File

@ -1,55 +1,109 @@
--- ---
- name: Add GPG key for MariaDB repo - name: Remove MariaDB key from apt-key
apt_key: id=0x177F4010FE56CA3336300305F1656F24C74CD1D8 url=https://mariadb.org/mariadb_release_signing_key.asc ansible.builtin.apt_key:
register: add_mariadb_apt_key id: "013577200103762554506315430003013705453362230723150730"
tags: mariadb, packages state: absent
tags:
- packages
- mariadb
- name: Add MariaDB 10.5 repo - name: Check MariaDB package signing key
template: src=mariadb.list.j2 dest=/etc/apt/sources.list.d/mariadb.list owner=root group=root mode=0644 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 register: add_mariadb_apt_repository
tags: mariadb, packages tags:
- packages
- mariadb
- name: Update apt cache - name: Update apt cache
apt: ansible.builtin.apt: # noqa no-handler
update_cache: yes update_cache: true
when: when: (download_mariadb_signing_key.status_code is defined and download_mariadb_signing_key.status_code == 200) or add_mariadb_apt_repository is changed
add_mariadb_apt_key is changed or tags:
add_mariadb_apt_repository is changed - packages
- mariadb
- name: Install mariadb-server - name: Install mariadb-server
apt: name={{ item }} state=present cache_valid_time=3600 ansible.builtin.apt:
loop: name: [mariadb-server, python3-pymysql]
- mariadb-server state: present
- python3-pymysql # for ansible cache_valid_time: 3600
tags: mariadb, packages tags: mariadb, packages
- name: Create system my.cnf - 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: notify:
- restart mariadb - restart mariadb
tags: mariadb tags: mariadb
# See: https://docs.ansible.com/ansible/latest/collections/community/mysql/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 - 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: loop:
- 127.0.0.1 - 127.0.0.1
- ::1 - ::1
tags: mariadb tags: mariadb
- name: Create .my.conf file with root credentials - 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 tags: mariadb
# See: https://docs.ansible.com/ansible/latest/collections/community/mysql/mysql_db_module.html # See: https://docs.ansible.com/ansible/latest/collections/community/mysql/mysql_db_module.html
- name: Create MariaDB database(s) - name: Create MariaDB database(s)
mysql_db: db={{ item.name }} state=present encoding=utf8mb4 login_unix_socket={{ mariadb_login_unix_socket }} community.mysql.mysql_db:
db: "{{ item.name }}"
state: present
encoding: utf8mb4
login_unix_socket: "{{ mariadb_login_unix_socket }}"
loop: "{{ mariadb_databases }}" loop: "{{ mariadb_databases }}"
when: mariadb_databases is defined when: mariadb_databases is defined
tags: mariadb tags: mariadb
- name: Create MariaDB user(s) - name: Create MariaDB user(s)
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 }} 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 }}" loop: "{{ mariadb_databases }}"
when: mariadb_databases is defined when: mariadb_databases is defined
tags: mariadb 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

@ -1,4 +1,4 @@
--- ---
# file: roles/munin/handlers/main.yml # ansible.builtin.file: roles/munin/handlers/main.yml
- name: restart munin-node - 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 - name: Configure munin scraper
import_tasks: munin.yml ansible.builtin.import_tasks: munin.yml
tags: munin tags: munin
- name: Configure munin listener - name: Configure munin listener
import_tasks: munin-node.yml ansible.builtin.import_tasks: munin-node.yml
tags: munin-node tags: munin-node

View File

@ -1,25 +1,25 @@
--- ---
- name: Install munin-node - name: Install munin-node
apt: name=munin-node state=present ansible.builtin.apt: name=munin-node state=present
tags: packages tags: packages
# some nice things to have for munin-node on Ubuntu # some nice things to have for munin-node on Ubuntu
# libwww-perl: for munin's nginx_status check # libwww-perl: for munin's nginx_status check
- name: Install munin-node deps - name: Install munin-node deps
apt: name=libwww-perl state=present ansible.builtin.apt: name=libwww-perl state=present
tags: packages tags: packages
- name: Create munin-node.conf - 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: notify:
- restart munin-node - restart munin-node
- name: Configure 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: notify:
- restart munin-node - restart munin-node
- name: Start 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: # vim: set ts=2 sw=2:

View File

@ -1,9 +1,9 @@
--- ---
- name: Install munin package - name: Install munin package
apt: name=munin state=present ansible.builtin.apt: name=munin state=present
tags: packages tags: packages
- name: Create munin configuration file - 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: # vim: set ts=2 sw=2:

View File

@ -1,44 +1,44 @@
--- ---
# file: roles/nginx/defaults/main.yml # ansible.builtin.file: roles/nginx/defaults/main.yml
# path config # path config
nginx_confd_path: /etc/nginx/conf.d nginx_confd_path: /etc/nginx/conf.d
# parent directory of vhost roots # parent directory of vhost roots
nginx_root_prefix: /var/www nginx_root_prefix: "{{ web_root_prefix }}"
# 1 hour timeout # 1 day timeout
nginx_ssl_session_timeout: 1h nginx_ssl_session_timeout: 1d
# 10MB -> 40,000 sessions # 10MB -> 40,000 sessions
nginx_ssl_session_cache: shared:SSL:10m nginx_ssl_session_cache: shared:SSL:10m
# 1400 bytes to fit in one MTU (default is 16k!) nginx_ssl_buffer_size: 4k
nginx_ssl_buffer_size: 1400
nginx_ssl_dhparam: /etc/ssl/certs/dhparam.pem nginx_ssl_dhparam: /etc/ssl/certs/dhparam.pem
nginx_ssl_protocols: 'TLSv1.2 TLSv1.3' nginx_ssl_protocols: TLSv1.2 TLSv1.3
nginx_ssl_ecdh_curve: X25519:prime256v1:secp384r1
# DNS resolvers for OCSP stapling (default to Cloudflare public DNS) # DNS resolvers for OCSP stapling (default to Cloudflare public DNS)
# See: https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_stapling # 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]
# HTTP Strict-Transport-Security header, recommended by Google to be ~1 year # HTTP Strict-Transport-Security header, recommended by Google to be ~1 year
# in seconds, see: https://hstspreload.org/ # in seconds, see: https://hstspreload.org/
nginx_hsts_max_age: 31536000 nginx_hsts_max_age: 31536000
# install acme.sh? # install acme.sh?
# True unless you're in development and using "localhost" + snakeoil certs # true unless you're in development and using "localhost" + snakeoil certs
use_letsencrypt: True use_letsencrypt: true
# Directory root for Let's Encrypt certs # Directory root for Let's Encrypt certs
letsencrypt_root: /etc/ssl letsencrypt_root: /etc/ssl
# Location where to save initial acme.sh script. After installation the script # Location where to save initial acme.sh script. After installation the script
# will automatically create its home in the /root/.acme.sh directory (including # will automatically create its home in the /root/.acme.sh directory (including
# a copy of the script itself). # a copy of the script itself). The initial script is not needed after.
letsencrypt_acme_script: /root/acme.sh letsencrypt_acme_script_temp: /root/acme.sh
letsencrypt_acme_home: /root/.acme.sh letsencrypt_acme_home: /root/.acme.sh
# stable is 1.20.x # stable is 1.26.x
# mainline is 1.21.x # mainline is 1.27.x
nginx_version: mainline nginx_version: mainline
# vim: set ts=2 sw=2: # vim: set ts=2 sw=2:

View File

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

View File

@ -1,61 +1,90 @@
--- ---
# Use acme.sh instead of certbot because they only support installation via # Use acme.sh instead of certbot because they only support installation via
# snap now. # snap now.
- block: - block:
- name: Remove certbot - name: Remove certbot
apt: ansible.builtin.apt:
name: certbot name: certbot
state: absent state: absent
- name: Remove old certbot post and pre hooks for nginx - name: Remove old certbot post and pre hooks for nginx
file: ansible.builtin.file:
dest: "{{ item }}" dest: "{{ item }}"
state: absent state: absent
with_items: with_items:
- /etc/letsencrypt/renewal-hooks/pre/stop-nginx.sh - /etc/letsencrypt/renewal-hooks/pre/stop-nginx.sh
- /etc/letsencrypt/renewal-hooks/post/start-nginx.sh - /etc/letsencrypt/renewal-hooks/post/start-nginx.sh
- name: Download acme.sh - name: Check if acme.sh is installed
get_url: ansible.builtin.stat:
url: https://raw.githubusercontent.com/acmesh-official/acme.sh/master/acme.sh path: "{{ letsencrypt_acme_home }}"
dest: "{{ letsencrypt_acme_script }}" register: acme_home
mode: 0700
- name: Prepare Let's Encrypt well-known directory - name: Download acme.sh
file: ansible.builtin.get_url:
state: directory url: https://raw.githubusercontent.com/acmesh-official/acme.sh/master/acme.sh
path: /var/lib/letsencrypt/.well-known dest: "{{ letsencrypt_acme_script_temp }}"
owner: root mode: "0700"
group: nginx register: acme_download
mode: g+s when: not acme_home.stat.exists
- name: Copy systemd service to renew Let's Encrypt certs # Run the "install" for acme.sh so it creates the .acme.sh dir (currently I
template: # have to chdir to the /root directory where the script exists or else it
src: renew-letsencrypt.service.j2 # fails. Ansible runs it, but the script can't find itself...).
dest: /etc/systemd/system/renew-letsencrypt.service - name: Install acme.sh
mode: 0644 ansible.builtin.command:
owner: root cmd: "{{ letsencrypt_acme_script_temp }} --install --no-profile --no-cron"
group: root creates: "{{ letsencrypt_acme_home }}/acme.sh"
chdir: /root
register: acme_install
when: acme_download is changed
- name: Copy systemd timer to renew Let's Encrypt certs - name: Remove temporary acme.sh script
copy: ansible.builtin.file:
src: renew-letsencrypt.timer dest: "{{ letsencrypt_acme_script_temp }}"
dest: /etc/systemd/system/renew-letsencrypt.timer state: absent
mode: 0644 when:
owner: root - acme_install.rc is defined
group: root - acme_install.rc == 0
# always issues daemon-reload just in case the service/timer changed - name: Set default certificate authority for acme.sh
- name: Start and enable systemd timer to renew Let's Encrypt certs ansible.builtin.command:
systemd: cmd: "{{ letsencrypt_acme_home }}/acme.sh --set-default-ca --server letsencrypt"
name: renew-letsencrypt.timer
state: started
enabled: yes
daemon_reload: yes
when: (ansible_distribution == 'Ubuntu' and ansible_distribution_version is version('20.04', '==')) - name: Prepare Let's Encrypt well-known directory
or (ansible_distribution == 'Debian' and ansible_distribution_version is version('11', '==')) ansible.builtin.file:
state: directory
path: /var/lib/letsencrypt/.well-known
owner: root
group: nginx
mode: g+s
- 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 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
# 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 tags: letsencrypt
# vim: set ts=2 sw=2: # vim: set ts=2 sw=2:

View File

@ -1,40 +1,69 @@
--- ---
- name: Add nginx.org apt signing key - name: Remove nginx apt signing key from apt-key
apt_key: id=0x573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62 url=https://nginx.org/keys/nginx_signing.key state=present ansible.builtin.apt_key:
register: add_nginx_apt_key id: "053473772654754373614404074646527257655730117366337542"
tags: nginx, packages state: absent
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"
checksum: sha256:55385da31d198fa6a5012d40ae98ecb272a6c4e8fffffba94719ffd3e87de37a
register: download_nginx_signing_key
tags:
- packages
- nginx
- name: Add nginx.org repo - 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 register: add_nginx_apt_repository
tags: nginx, packages tags:
- nginx
- packages
- name: Update apt cache - name: Update apt cache
apt: ansible.builtin.apt: # noqa no-handler
update_cache: yes update_cache: true
when: when: (download_nginx_signing_key.status_code is defined and download_nginx_signing_key.status_code == 200) or add_nginx_apt_repository is changed
add_nginx_apt_key is changed or
add_nginx_apt_repository is changed
- name: Set nginx packages - name: Install nginx
set_fact: ansible.builtin.apt:
nginx_packages: pkg: nginx
- nginx cache_valid_time: 3600
- ssl-cert # for ssl-cert-snakeoil.pem in nginx state: present
tags: nginx, packages tags:
- nginx
- name: Install nginx packages - packages
apt: pkg={{ nginx_packages }} cache_valid_time=3600 state=present
tags: nginx, packages
- name: Copy nginx.conf - 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: notify:
- reload nginx - reload nginx
tags: nginx tags: nginx
- name: Copy extra nginx configs - 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: loop:
- extra-security.conf - extra-security.conf
- fastcgi_cache - fastcgi_cache
@ -43,41 +72,61 @@
tags: nginx tags: nginx
- name: Remove default nginx vhost - 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 tags: nginx
- name: Create fastcgi cache dir - 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 tags: nginx
- name: Configure nginx virtual hosts - name: Configure nginx virtual hosts
include_tasks: vhosts.yml ansible.builtin.include_tasks: vhosts.yml
when: nginx_vhosts is defined when: nginx_vhosts is defined
tags: nginx tags: nginx
- name: Configure WordPress - name: Configure WordPress
include_tasks: wordpress.yml ansible.builtin.include_tasks: wordpress.yml
when: nginx_vhosts is defined when: nginx_vhosts is defined
tags: wordpress tags: wordpress
- name: Configure blank nginx vhost - 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: notify:
- reload nginx - reload nginx
tags: nginx tags: nginx
- name: Configure munin vhost - 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: notify:
- reload nginx - reload nginx
tags: nginx tags: nginx
- name: Start and enable nginx service - name: Start and enable nginx service
systemd: name=nginx state=started enabled=yes ansible.builtin.systemd:
name: nginx
state: started
enabled: true
tags: nginx tags: nginx
- name: Configure Let's Encrypt - name: Configure Let's Encrypt
include_tasks: letsencrypt.yml ansible.builtin.include_tasks: letsencrypt.yml
tags: letsencrypt tags: letsencrypt
# vim: set ts=2 sw=2: # vim: set ts=2 sw=2:

View File

@ -1,23 +1,29 @@
--- ---
- block: - block:
- name: Configure https vhosts - name: Configure https vhosts
template: src=vhost.conf.j2 dest={{ nginx_confd_path }}/{{ item.domain_name }}.conf mode=0644 owner=root group=root ansible.builtin.template: src=vhost.conf.j2 dest={{ nginx_confd_path }}/{{ item.domain_name }}.conf mode=0644 owner=root group=root
loop: "{{ nginx_vhosts }}" loop: "{{ nginx_vhosts }}"
notify: notify:
- reload nginx - reload nginx
- name: Download 4096-bit RFC 7919 dhparams - name: Generate self-signed TLS cert
get_url: 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
url: https://raw.githubusercontent.com/internetstandards/dhe_groups/master/ffdhe4096.pem -out /etc/ssl/certs/nginx-snakeoil.crt -extensions v3_ca creates=/etc/ssl/certs/nginx-snakeoil.crt
checksum: sha256:64852d6890ff9e62eecd1ee89c72af9af244dfef5b853bcedea3dfd7aade22b3 notify:
dest: "{{ nginx_ssl_dhparam }}" - reload nginx
notify:
- reload nginx
- name: Create vhost document roots - name: Download 4096-bit RFC 7919 dhparams
file: path={{ nginx_root_prefix }}/{{ item.domain_name }} state=directory mode=0755 owner=nginx group=nginx ansible.builtin.get_url:
loop: "{{ nginx_vhosts }}" url: https://raw.githubusercontent.com/internetstandards/dhe_groups/master/ffdhe4096.pem
checksum: sha256:64852d6890ff9e62eecd1ee89c72af9af244dfef5b853bcedea3dfd7aade22b3
dest: "{{ nginx_ssl_dhparam }}"
notify:
- reload nginx
# 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 tags: nginx
# vim: set ts=2 sw=2: # vim: set ts=2 sw=2:

View File

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

View File

@ -11,14 +11,16 @@ server {
return 444; return 444;
} }
server { server {
listen 443 ssl http2 default_server; listen 443 ssl default_server;
listen [::]:443 ssl http2 default_server; listen [::]:443 ssl default_server;
http2 on;
server_name _; server_name _;
# self-signed "snakeoil" certificate from ssl-cert package # self-signed "snakeoil" certificate
ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem; ssl_certificate /etc/ssl/certs/nginx-snakeoil.crt;
ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key; ssl_certificate_key /etc/ssl/private/nginx-snakeoil.key;
ssl_session_timeout {{ nginx_ssl_session_timeout }}; ssl_session_timeout {{ nginx_ssl_session_timeout }};
ssl_session_cache {{ nginx_ssl_session_cache }}; ssl_session_cache {{ nginx_ssl_session_cache }};

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 #} {# helper variables and per-site defaults that we can't set in role defaults #}
{% set domain_name = item.domain_name %} {% set domain_name = item.domain_name %}
{# assume HSTS is off unless a vhost explicitly sets it to True #} {# assume HSTS is off unless a vhost explicitly sets it to true #}
{% set enable_hsts = item.enable_hsts | default(False) %} {% set enable_hsts = item.enable_hsts | default(false) %}
{# first, check if the current vhost has a custom cert (perhaps self-signed) #} {# 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 %} {% if item.tls_certificate_path is defined and item.tls_key_path is defined %}
@ -27,27 +27,19 @@
ssl_dhparam {{ nginx_ssl_dhparam }}; ssl_dhparam {{ nginx_ssl_dhparam }};
ssl_protocols {{ nginx_ssl_protocols }}; ssl_protocols {{ nginx_ssl_protocols }};
ssl_ecdh_curve {{ nginx_ssl_ecdh_curve }};
ssl_ciphers "{{ tls_cipher_suite }}"; ssl_ciphers "{{ tls_cipher_suite }}";
ssl_prefer_server_ciphers on; ssl_prefer_server_ciphers off;
{# OSCP stapling only works with real certs #} {# 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... # OCSP stapling...
ssl_stapling on; ssl_stapling on;
ssl_stapling_verify on; ssl_stapling_verify on;
resolver {{ nginx_ssl_stapling_resolver }}; resolver {{ nginx_ssl_stapling_resolver }};
{% endif %} {# end: use_letsencrypt #} {% endif %} {# end: use_letsencrypt #}
# nginx does not auto-rotate session ticket keys: only a HUP / restart will do so and {% if enable_hsts == true %}
# when a restart is performed the previous key is lost, which resets all previous
# sessions. The fix for this is to setup a manual rotation mechanism:
# http://trac.nginx.org/nginx/changeset/1356a3b9692441e163b4e78be4e9f5a46c7479e9/nginx
#
# Note that you'll have to define and rotate the keys securely by yourself. In absence
# of such infrastructure, consider turning off session tickets:
ssl_session_tickets off;
{% if enable_hsts == True %}
# Enable this if you want HSTS (recommended, but be careful) # 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 # Include all subdomains and indicate to Google that we want this pre-loaded in Chrome's HSTS store
# See: https://hstspreload.appspot.com/ # See: https://hstspreload.appspot.com/

View File

@ -3,17 +3,17 @@
{% if ansible_distribution == 'Ubuntu' %} {% if ansible_distribution == 'Ubuntu' %}
{% if nginx_version == "stable" %} {% 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" %} {% 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 %} {% endif %}
{% elif ansible_distribution == 'Debian' %} {% elif ansible_distribution == 'Debian' %}
{% if nginx_version == "stable" %} {% 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" %} {% 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 %}
{% endif %} {% endif %}

View File

@ -4,9 +4,16 @@
{% set domain_name = item.domain_name %} {% set domain_name = item.domain_name %}
{% set domain_aliases = item.domain_aliases | default("") %} {% set domain_aliases = item.domain_aliases | default("") %}
{# assume optional features are off unless a vhost explicitly sets them #} {# assume optional features are off unless a vhost explicitly sets them #}
{% set enable_hsts = item.enable_hsts | default(False) %} {% set enable_hsts = item.enable_hsts | default(false) %}
{% set has_wordpress = item.has_wordpress | default(False) %} {% set has_wordpress = item.has_wordpress | default(false) %}
{% set needs_php = item.needs_php | default(False) %} {% set needs_php = item.needs_php | default(false) %}
{% set has_gitea = item.has_gitea | default(false) %}
{# Allow sites to override the document root #}
{% if item.document_root is defined %}
{% set document_root = item.document_root %}
{% else %}
{% set document_root = (nginx_root_prefix, domain_name) | ansible.builtin.path_join %}
{% endif %}
# http -> https vhost # http -> https vhost
server { server {
@ -25,36 +32,36 @@ server {
} }
server { server {
listen 443 ssl http2; listen 443 ssl;
listen [::]:443 ssl http2; listen [::]:443 ssl;
http2 on;
{# Allow sites to override the nginx document root #} root {{ document_root }};
{% if item.document_root is defined %}
root {{ item.document_root }};
{% else %}
root {{ nginx_root_prefix }}/{{ domain_name }};
{% endif %}
{# will only work if the TLS cert covers the domain + aliases, like example.com and www.example.com #} {# will only work if the TLS cert covers the domain + aliases, like example.com and www.example.com #}
server_name {{ domain_name }} {{ domain_aliases }}; 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; access_log /var/log/nginx/{{ domain_name }}-access.log;
error_log /var/log/nginx/{{ domain_name }}-error.log; error_log /var/log/nginx/{{ domain_name }}-error.log;
{% include 'https.j2' %} {% include 'https.j2' %}
{% if has_wordpress == True %} {% if has_wordpress == true %}
{% include 'wordpress.j2' %} {% include 'wordpress.j2' %}
{% endif %} {% endif %}
{% if has_gitea == true %}
{% include 'gitea.j2' %}
{% endif %}
error_page 500 502 503 504 /50x.html; error_page 500 502 503 504 /50x.html;
location = /50x.html { location = /50x.html {
root /usr/share/nginx/html; root /usr/share/nginx/html;
} }
{% if has_wordpress == True or needs_php == True %} {% if has_wordpress == true or needs_php == true %}
location ~ [^/]\.php(/|$) { location ~ [^/]\.php(/|$) {
# Zero-day exploit defense. # Zero-day exploit defense.
# http://forum.nginx.org/read.php?2,88845,page=3 # http://forum.nginx.org/read.php?2,88845,page=3
@ -70,17 +77,8 @@ server {
# See: https://httpoxy.org/ # See: https://httpoxy.org/
fastcgi_param HTTP_PROXY ""; fastcgi_param HTTP_PROXY "";
{# As of Ubuntu 16.04 and Debian 9, the PHP-FPM configs are the same #} {% if ansible_distribution == 'Debian' and ansible_distribution_major_version is version('12', '==') %}
{% 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/php8.2-fpm-{{ domain_name }}.sock;
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', '==')) or (ansible_distribution == 'Debian' and ansible_distribution_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;
{% endif %} {% endif %}
fastcgi_index index.php; fastcgi_index index.php;
# set script path relative to document root in server block # set script path relative to document root in server block
@ -94,7 +92,7 @@ server {
fastcgi_cache_bypass $http_pragma $wordpress_logged_in; fastcgi_cache_bypass $http_pragma $wordpress_logged_in;
fastcgi_no_cache $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) # 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 # Include all subdomains and indicate to Google that we want this pre-loaded in Chrome's HSTS store
# See: https://hstspreload.appspot.com/ # See: https://hstspreload.appspot.com/
@ -108,7 +106,7 @@ server {
include extra-security.conf; include extra-security.conf;
} }
{% if has_wordpress == True %} {% if has_wordpress == true %}
# Check if a user is logged in # Check if a user is logged in
# if so, set $wordpress_logged_in = 1 # if so, set $wordpress_logged_in = 1
# otherwise, set $wordpress_logged_in = 0 # otherwise, set $wordpress_logged_in = 0

View File

@ -5,7 +5,7 @@
location / { location / {
try_files $uri $uri/ /index.php?$args; 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) # 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 # Include all subdomains and indicate to Google that we want this pre-loaded in Chrome's HSTS store
# See: https://hstspreload.appspot.com/ # See: https://hstspreload.appspot.com/
@ -16,7 +16,7 @@
location ~* \.(?:ico|css|js|gif|jpe?g|png|svg)$ { location ~* \.(?:ico|css|js|gif|jpe?g|png|svg)$ {
add_header Cache-Control "max-age=604800"; 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) # 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 # Include all subdomains and indicate to Google that we want this pre-loaded in Chrome's HSTS store
# See: https://hstspreload.appspot.com/ # See: https://hstspreload.appspot.com/

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 # default is on, but turn it off because of protection in nginx vhosts
cgi_fix_pathinfo: 0 cgi_fix_pathinfo: 0

View File

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

View File

@ -1,35 +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: install_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,35 +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: install_php
# vim: set ts=2 sw=2:

View File

@ -1,35 +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.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
# 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: install_php
# vim: set ts=2 sw=2:

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -1,428 +0,0 @@
{% set domain_name = item.domain_name %}
; Start a new pool named '{{ domain_name }}'.
; the variable $pool can be 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.3-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
; 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
; core dump and ptrace the process for the pool user.
; Default Value: no
; process.dumpable = yes
; 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.3/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:
; The strftime(3) format must be encapsuled 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
; %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
; Decorate worker output with prefix and suffix containing information about
; the child that writes to the log and if stdout or stderr is used as well as
; log level and time. This options is used only if catch_workers_output is yes.
; Settings to "no" will output data as written to the stdout or stderr.
; Default value: yes
;decorate_workers_output = no
; 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,11 +19,16 @@
; Default Value: none ; Default Value: none
;prefix = /path/to/pools/$pool ;prefix = /path/to/pools/$pool
; Unix user/group of processes ; Unix user/group of the child processes. This can be used only if the master
; Note: The user is mandatory. If the group is not set, the default user's group ; process running user is root. It is set after the child process is created.
; will be used. ; The user and group can be specified either by their name or by their numeric
user = nginx ; IDs.
group = nginx ; 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 = {{ webserver }}
group = {{ webserver }}
; The address on which to accept FastCGI requests. ; The address on which to accept FastCGI requests.
; Valid syntaxes are: ; Valid syntaxes are:
@ -35,20 +40,22 @@ group = nginx
; (IPv6 and IPv4-mapped) on a specific port; ; (IPv6 and IPv4-mapped) on a specific port;
; '/path/to/unix/socket' - to listen on a unix socket. ; '/path/to/unix/socket' - to listen on a unix socket.
; Note: This value is mandatory. ; Note: This value is mandatory.
listen = /run/php/php7.4-fpm-{{ domain_name }}.sock listen = /run/php/php8.2-fpm-{{ domain_name }}.sock
; Set listen(2) backlog. ; Set listen(2) backlog.
; Default Value: 511 (-1 on FreeBSD and OpenBSD) ; Default Value: 511 (-1 on Linux, FreeBSD and OpenBSD)
;listen.backlog = 511 ;listen.backlog = 511
; Set permissions for unix socket, if one is used. In Linux, read/write ; 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 ; permissions must be set in order to allow connections from a web server. Many
; BSD-derived systems allow connections regardless of permissions. ; BSD-derived systems allow connections regardless of permissions. The owner
; Default Values: user and group are set as the running user ; and group can be specified either by name or by their numeric IDs.
; mode is set to 0660 ; Default Values: Owner is set to the master process running user. If the group
listen.owner = nginx ; is not set, the owner's group is used. Mode is set to 0660.
listen.group = nginx listen.owner = {{ webserver }}
listen.group = {{ webserver }}
;listen.mode = 0660 ;listen.mode = 0660
; When POSIX Access Control Lists are supported you can set them using ; When POSIX Access Control Lists are supported you can set them using
; these options, value is a comma separated list of user/group names. ; these options, value is a comma separated list of user/group names.
; When set, listen.owner and listen.group are ignored ; When set, listen.owner and listen.group are ignored
@ -63,6 +70,10 @@ listen.group = nginx
; Default Value: any ; Default Value: any
;listen.allowed_clients = 127.0.0.1 ;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) ; 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) ; 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 ; 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 ; Default Value: no set
; process.priority = -19 ; process.priority = -19
; Set the process dumpable flag (PR_SET_DUMPABLE prctl) even if the process user ; Set the process dumpable flag (PR_SET_DUMPABLE prctl for Linux or
; or group is differrent than the master process user. It allows to create process ; 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. ; core dump and ptrace the process for the pool user.
; Default Value: no ; Default Value: no
; process.dumpable = yes ; process.dumpable = yes
@ -94,6 +106,8 @@ listen.group = nginx
; state (waiting to process). If the number ; state (waiting to process). If the number
; of 'idle' processes is greater than this ; of 'idle' processes is greater than this
; number then some children will be killed. ; 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 ; ondemand - no children are created at startup. Children will be forked when
; new requests will connect. The following parameter are used: ; new requests will connect. The following parameter are used:
; pm.max_children - the maximum number of children that ; pm.max_children - the maximum number of children that
@ -129,6 +143,12 @@ pm.min_spare_servers = 1
; Note: Mandatory when pm is set to 'dynamic' ; Note: Mandatory when pm is set to 'dynamic'
pm.max_spare_servers = 3 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. ; The number of seconds after which an idle process will be killed.
; Note: Used only when pm is set to 'ondemand' ; Note: Used only when pm is set to 'ondemand'
; Default Value: 10s ; Default Value: 10s
@ -141,7 +161,7 @@ pm.max_spare_servers = 3
;pm.max_requests = 500 ;pm.max_requests = 500
; The URI to view the FPM status page. If this value is not set, no URI will be ; 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; ; pool - the name of the pool;
; process manager - static, dynamic or ondemand; ; process manager - static, dynamic or ondemand;
; start time - the date and time FPM has started; ; start time - the date and time FPM has started;
@ -231,7 +251,7 @@ pm.max_spare_servers = 3
; last request memory: 0 ; last request memory: 0
; ;
; Note: There is a real-time FPM status monitoring sample web page available ; Note: There is a real-time FPM status monitoring sample web page available
; It's available in: /usr/share/php/7.4/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 ; 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 ; 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 ; Default Value: not set
;pm.status_path = /status ;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 ; 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 ; URI will be recognized as a ping page. This could be used to test from outside
; that FPM is alive and responding, or to ; that FPM is alive and responding, or to
@ -271,13 +307,13 @@ pm.max_spare_servers = 3
; %d: time taken to serve the request ; %d: time taken to serve the request
; it can accept the following format: ; it can accept the following format:
; - %{seconds}d (default) ; - %{seconds}d (default)
; - %{miliseconds}d ; - %{milliseconds}d
; - %{mili}d ; - %{milli}d
; - %{microseconds}d ; - %{microseconds}d
; - %{micro}d ; - %{micro}d
; %e: an environment variable (same as $_ENV or $_SERVER) ; %e: an environment variable (same as $_ENV or $_SERVER)
; it must be associated with embraces to specify the name of the env ; 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 ; - server specifics like: %{REQUEST_METHOD}e or %{SERVER_PROTOCOL}e
; - HTTP headers like: %{HTTP_HOST}e or %{HTTP_USER_AGENT}e ; - HTTP headers like: %{HTTP_HOST}e or %{HTTP_USER_AGENT}e
; %f: script filename ; %f: script filename
@ -306,14 +342,30 @@ pm.max_spare_servers = 3
; %s: status (response code) ; %s: status (response code)
; %t: server time the request was received ; %t: server time the request was received
; it can accept a strftime(3) format: ; 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) ; %T: time the log has been written (the request has finished)
; it can accept a strftime(3) format: ; 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 ; %u: remote user
; ;
; Default: "%R - %u %t \"%m %r\" %s" ; 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 ; The log file for slow requests
; Default Value: not set ; Default Value: not set
@ -372,7 +424,7 @@ pm.max_spare_servers = 3
; Redirect worker stdout and stderr into main error log. If not set, stdout and ; 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. ; 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). ; process time (several ms).
; Default Value: no ; Default Value: no
;catch_workers_output = yes ;catch_workers_output = yes

View File

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

Some files were not shown because too many files have changed in this diff Show More