Compare commits

...

119 Commits
main ... main

Author SHA1 Message Date
Julien Palard 197a38e2db
cfp-2024 → cfp 2024-04-19 16:44:15 +02:00
Julien Palard 92c370a067
Spam spam spam. 2024-04-19 16:43:53 +02:00
Julien Palard c15eb8b321
bump woodpecker 2024-04-18 13:26:14 +02:00
Julien Palard c94f4b223e
the 1s default was not always long enough. 2024-04-18 13:26:01 +02:00
Julien Palard 41ed7ac254
gitea spam 2024-04-18 13:25:33 +02:00
Marc Debureaux b9f446ad5b
Moved pretalx vagrant file and remove meta 2024-04-04 08:33:20 +02:00
Marc Debureaux c8e33b20af
Faulty redis configuration for pretalx 2024-04-03 22:03:09 +02:00
Marc Debureaux aaa9731a70
Add cron to pretalx requirements 2024-04-03 21:43:46 +02:00
Marc Debureaux db38131076
Pretalx role files 2024-04-03 21:26:47 +02:00
Marc Debureaux 08db1c1366
Pretalx role 2024-04-03 21:23:45 +02:00
Marc Debureaux ead6df299f
Pretalx domain 2024-04-03 21:18:38 +02:00
Marc Debureaux 6bcb185dc4
Pretalx role 2024-04-03 21:11:29 +02:00
Julien Palard a6c3a22a8e
ntp conflicts with systemd on bookworm. 2024-03-23 08:48:08 +01:00
Julien Palard 9f31f39f68
Spammers 2024-03-23 08:47:28 +01:00
Julien Palard a8ca55755d
Bump gitea 2024-03-23 08:47:15 +01:00
Julien Palard 92eb527c80
Hello pretalx. 2024-03-20 22:36:47 +01:00
Julien Palard 28df2e24e5
gitea: spammer 2024-03-19 07:28:20 +01:00
Julien Palard dec6f0d0ea
merge spammers 2024-03-19 07:26:12 +01:00
Julien Palard 2f8f311aed
spammers 2024-03-19 07:25:38 +01:00
Julien Palard 3ec2faf8f7
gitea: Spammers. 2024-03-13 18:59:26 +01:00
Julien Palard 32fe826b71
Spammers 2024-03-07 18:17:58 +01:00
Julien Palard ac93bb958a
Bump gitea. 2024-02-28 10:46:11 +01:00
Julien Palard 7991eb4c24
spammers 2024-02-27 14:47:14 +01:00
Julien Palard 304f6e5699
Bump gitea. 2024-02-27 14:47:02 +01:00
Julien Palard 6e44d88976
Email and IPv6, damned. 2024-02-26 15:46:26 +01:00
Julien Palard 19b5776760
Damned, cloud-init is messing with /etc/hosts... 2024-02-26 10:42:30 +01:00
Julien Palard 5db7cca782
Ensure exim is configured for PonyConf. 2024-02-26 10:42:10 +01:00
Julien Palard 5a4a557369
Those are just for discourse. 2024-02-26 10:41:54 +01:00
Julien Palard ca577509d5
git.afpy.org: block spammers (damned I'm on holidays, why you spam now?) 2024-02-22 11:22:45 +01:00
Julien Palard bcb5f9f508
git.afpy.org: block spammers (damned I'm on holidays, why you spam now?) 2024-02-21 18:05:00 +01:00
Julien Palard a93c7034b4
bump woodpecker 2024-02-12 11:58:22 +01:00
Julien Palard b02f084f85
spammers 2024-02-12 11:58:12 +01:00
Julien Palard 607e1b38ec
Bump gitea. 2024-02-12 11:58:01 +01:00
Lucie Anglade 0f3f906c21 Add ssh key 2024-02-12 09:49:43 +00:00
Julien Palard 7640ac7ee9
Move gitea deny list to group_var to avoid the backup playbook to forgot them. 2024-02-02 09:27:33 +01:00
Julien Palard 0daf51953a
CSPs 2024-02-02 09:04:55 +01:00
Julien Palard 24a55603cb
Try harder to disable IPv6 for exim. 2024-02-02 09:04:50 +01:00
Julien Palard cb128c25f2
CSPs 2024-02-02 09:04:34 +01:00
Julien Palard 1546584dfd
fix title 2024-02-02 09:04:16 +01:00
Julien Palard 728e0bf807
Au revoir BBB ☹ 2024-01-31 23:27:37 +01:00
Julien Palard 74f93f2b6c
gitea: a spammer. 2024-01-28 23:57:16 +01:00
Julien Palard 2108e76828
Bump woodpecker to 2.2.2. 2024-01-25 23:01:59 +01:00
Julien Palard 2d8b3f2528
Block spammers. 2024-01-18 18:31:55 +01:00
Julien Palard a8f1e23624
Bump gitea. 2024-01-18 18:31:45 +01:00
Julien Palard 9da25244bf
gitea: It's 2024, time to bump your keys.
https://infosec.mozilla.org/guidelines/key_management.html
2024-01-07 22:24:13 +01:00
Julien Palard 5bbd617bf7
mdk: Slowly deprecating old 2048 RSA keys. 2024-01-07 17:06:13 +01:00
Julien Palard b7aaa68ccc
Hello PyConFR 2024! 2024-01-07 16:39:38 +01:00
Julien Palard cc9acf1022
Move gitea backup cron away from the crowd. 2024-01-06 10:08:24 +01:00
Julien Palard 52423bbb2f
spammers 2024-01-06 10:08:05 +01:00
Julien Palard 22aa347e36
Upgrade gitea. 2024-01-06 10:07:54 +01:00
Julien Palard 26478f1cfa
Checked backups. 2024-01-04 13:57:12 +01:00
Julien Palard 3017c68c10
FIX: woodpecker-agent needs to store its config somewhere. 2023-11-29 11:42:01 +01:00
Julien Palard 0c3b686e23
woodpecker: Restart an agent when it dies. 2023-11-27 21:40:42 +01:00
Julien Palard 24932a2695
Hello CFP-2024 2023-11-27 21:40:28 +01:00
Julien Palard 390a0c0bf0
CSP handlers are floody in case users do have some plugins, that make the logs unreadable. 2023-11-27 21:40:10 +01:00
Julien Palard 313ce5ab06
Bump woodpecker to 2.0.0. 2023-11-24 09:01:25 +01:00
Julien Palard 3973403841
Gitea: fix path, see https://github.com/go-gitea/gitea/pull/25907 2023-11-17 14:40:55 +01:00
Julien Palard ffc6040c5e
Upgraded gitea. 2023-11-17 14:31:13 +01:00
Julien Palard 18cecf95e2
Woodpecker at gentilsnuages changed its public IP. 2023-11-09 11:45:18 +01:00
Julien Palard c737c7c59e
Checked backups. 2023-11-03 14:13:47 +01:00
Julien Palard 2cdcee019e
Blocked a lot of gitea spammers. 2023-11-02 11:47:04 +01:00
Julien Palard 75e0d4f254
Had to resize partition of gitea. 2023-11-02 11:46:32 +01:00
Julien Palard ced426b2fa
gitea: Ban ip range from which users are setting mirrors with tons of issues, each linking to spam. 2023-10-18 11:19:27 +02:00
Julien Palard 8c7698f7fc
No longer needed. 2023-09-11 14:07:06 +02:00
Julien Palard 8dc61dc81b
Bump gitea. 2023-09-09 17:44:02 +02:00
Julien Palard 24d8d05b40
Bumped gitea. 2023-07-24 14:00:26 +02:00
Julien Palard 7d150c5ac4
gitea: Deprecated config 2023-07-24 13:59:54 +02:00
Julien Palard fc285d6afe
logs.afpy.org from B to A+ on Mozilla Observatory. 2023-07-23 16:55:43 +02:00
Julien Palard c1770f90fe
CPS for logs.afpy.org 2023-07-23 12:12:27 +02:00
Julien Palard 169c154931
gitea: spammers have more than one IP. 2023-07-21 12:13:56 +02:00
Julien Palard fcd5ab3500
Bump woodpecker. 2023-07-19 11:18:08 +02:00
Julien Palard 99505005c9
Bump gitea. 2023-07-17 14:41:55 +02:00
Julien Palard aa55da5c62
gitea: Blacklist spammer. 2023-07-13 09:19:56 +02:00
Julien Palard 02e46e5bcf
Just for chromium.
see:
https://discuss.afpy.org/t/pyconfr-2023-annoncer-les-videos-sur-pyvideos-org/1448/8
2023-07-05 12:00:14 +02:00
Julien Palard c3368b60f5
Backup checks. 2023-07-02 11:59:36 +02:00
Julien Palard 767c8d3429
CSP reporting is unusable: browser extensions being blocked flood the most. 2023-06-14 16:11:14 +02:00
Julien Palard e22ba8af0f
backup: gitea.zip was not copied properly (was copied during its creation) 2023-06-01 17:26:22 +02:00
Julien Palard 3b88cf7ddf
gitea: Backup way before rsnapshot take the file, not at the same time! 2023-06-01 17:22:36 +02:00
Julien Palard 2f022adbdd
FIX: Allow interactive SVG in https://www.pycon.fr/2023/fr/news.html. 2023-05-30 16:20:19 +02:00
Julien Palard 99a644e2d2
Et paf. 2023-05-07 15:30:50 +02:00
Julien Palard 96b259631e
No longer needed, the admin zone has a password. 2023-05-07 15:30:30 +02:00
Julien Palard 4c085f551f
I just checked backups. 2023-05-07 15:30:07 +02:00
Julien Palard 7bb3f0f457
Discourse: install data explorer. 2023-04-15 08:51:27 +02:00
Julien Palard ad2a397f30
Bump gitea 2023-04-13 21:28:08 +02:00
Julien Palard 0885ec7c08
discord-irc-sync: https://github.com/Hackndo/discord-irc-sync/issues/12 fixed. 2023-04-13 15:33:01 +02:00
Julien Palard ff1aa89843
discord-irc-sync broke, see https://github.com/Hackndo/discord-irc-sync/issues/12. 2023-04-11 18:49:48 +02:00
Julien Palard 976a8a2608
FIX one CSP in AFPy.org/admin/, there's still inline styles. 2023-04-11 18:45:39 +02:00
Julien Palard 60b09a457f
Merci gentils nuages. 2023-04-10 22:25:20 +02:00
Julien Palard b2f72bf7e1
hkis: I rotated the runners for a big upgrade. 2023-04-10 22:25:01 +02:00
Julien Palard 05dabf5eef
Hello gentilsnuages.fr 2023-04-10 16:53:32 +02:00
Julien Palard b5aff22409
CSP CSP CSP 2023-04-07 22:56:27 +02:00
Julien Palard a90a2b7d43
Playing with CSP reporting. 2023-04-06 09:47:05 +02:00
Julien Palard 60d71bd8eb
Playing with CSP report-to/report-uri. 2023-04-06 00:03:55 +02:00
Julien Palard 1bba7b29ed
Backuping new Discourse instance. 2023-04-04 09:32:02 +02:00
Julien Palard 0baa5f00b0
Add self to salt-fr deployers. 2023-03-31 15:05:55 +02:00
Julien Palard 09533d6429
Bump PonyConf venv too. 2023-03-30 15:23:45 +02:00
Julien Palard 64a2738d0a
When Python changes, venv break. It should help. 2023-03-30 14:52:05 +02:00
Julien Palard ee0f40e918
dl.afpy.org: Longer length for file names.
Else, without seeing if it's an .mp4 or a .torrent, it's hard to choose.
2023-03-30 11:09:54 +02:00
Julien Palard 93dd1bb5b2
woodpecker: Split playbook. 2023-03-29 18:01:18 +02:00
Julien Palard 4727fd177a
woodpecker: Set self as admin, open to all orgs. 2023-03-29 17:39:22 +02:00
Julien Palard c4843a33cf
Move handwritten things to a playbook. 2023-03-28 16:01:09 +02:00
Julien Palard 194c4c1296
typo 2023-03-28 15:02:12 +02:00
Julien Palard 114836d3bd
Move var to group_Vars/ to have it on all playbooks. 2023-03-28 15:02:05 +02:00
Julien Palard 98a90c947d
Comfort. 2023-03-28 15:01:39 +02:00
Julien Palard 00703bfc2d
I use this for my .venv/ 2023-03-28 15:01:25 +02:00
Julien Palard 75b5e7e2e9
https://github.com/munin-monitoring/munin/issues/1521 2023-03-28 15:01:12 +02:00
Julien Palard c0793b34a4
apt_all is broken on (old?) Ubuntu. 2023-03-28 14:11:57 +02:00
Julien Palard 7c2c8b7775
backup: Lower rsnapshot verbosity: the machine can't send emails anyway, 2023-03-28 13:51:57 +02:00
Julien Palard 01e719e6ed
Proofreading README file. 2023-03-28 13:47:33 +02:00
Julien Palard d77fbf0b6c
md syntax 2023-03-28 13:34:16 +02:00
Julien Palard 6d14a8dfd7
Documenting Woodpeckers. 2023-03-28 12:33:52 +02:00
Julien Palard 2effab3a36
Moving Woodpecker out of my Rasberry Pi. 2023-03-28 00:08:15 +02:00
Julien Palard 9b8c5536f4
gitea: Ajout d'un lien vers 'licences libres'. 2023-03-27 11:43:32 +02:00
Julien Palard 7589df21b3
salt-fr: Content-Security-Policy. 2023-03-23 11:15:33 +01:00
Julien Palard 0a6cd8910d
Bump gitea. 2023-03-21 23:07:18 +01:00
Julien Palard 1365744351
Avoid Python buffering between Python and systemd logs. 2023-03-19 10:42:52 +01:00
Julien Palard fe8d80971b
Bump gitea. 2023-03-05 16:54:18 +01:00
Julien Palard d4c74a252c
CSP on photos.afpy.org 2023-03-05 16:53:55 +01:00
Florian Guillet 4163e91032 dl: Add myself to dl and add corresponding ssh keys (#7)
Pour simplifier la centralisation des fichiers graphiques pour la pycon, j'aurais besoin d'avoir accès à la machine :)

Co-authored-by: Florian Guillet <florian@eno.do>
Reviewed-on: AFPy/infra#7
Co-authored-by: Florian Guillet <merwyn@noreply.localhost>
Co-committed-by: Florian Guillet <merwyn@noreply.localhost>
2023-02-15 15:34:01 +00:00
63 changed files with 1900 additions and 535 deletions

13
.gitignore vendored
View File

@ -1,5 +1,3 @@
.venv
# Created by https://www.gitignore.io/api/ansible
# Edit at https://www.gitignore.io/?templates=ansible
@ -61,5 +59,14 @@ flycheck_*.el
# network security
/network-security.data
# End of https://www.gitignore.io/api/emacs
.envrc
# GitHub meta
.github
# Python venv
.venv
# Vagrant config
.vagrant

313
README.md
View File

@ -1,4 +1,4 @@
# Survol des playbooks Ansible
# Playbooks Ansible de lAFPy
On découpe nos *playbooks* Ansible par rôles :
@ -20,73 +20,113 @@ Récupérez le secret dans [afpy/pass](https://github.com/AFPy/pass/):
Puis pour jouer les *playbooks* :
- Pour tout relancer : `ansible-parallel *.yml`
- Pour configurer les PyCons : `ansible-playbook pycons.yml`
- Pour tout relancer : `ansible-parallel *.yml`
- Pour configurer les PyCons : `ansible-playbook pycons.yml`
## Faire, ne pas faire
Faire : Configurer les machines :
Faire : Configurer les machines :
- `apt install`,
- fichiers de configuration,
- créer les utilisateurs,
- éventuellement un premier `git clone` pour que ça marche si c'est un site statique.
- éventuellement un premier `git clone` pour que ça marche si cest un site statique.
Ne pas faire :
- Deployer. En dehors de l'éventuel premier git clone,
c'est le rôle de la CI (Github Actions, ...), pas de nos playbooks.
- Deployer. En dehors de léventuel premier git clone,
cest le rôle de la CI (Github Actions, ...), pas de nos playbooks.
# Servers
La distinction services/serveurs :
- Un serveur contient un nombre dans son nom : deb2.afpy.org,
bbb2.afpy.org, …
- Un service ne contient pas de chiffre dans son hostname :
discuss.afpy.org, bbb.afpy.org, www.afpy.org, …
- Un serveur contient un nombre dans son nom :
- deb2.afpy.org,
- gitea1.afpy.org,
- woodpecker1.afpy.org,
- …
- Un service ne contient pas de chiffre dans son nom :
- www.afpy.org,
- git.afpy.org,
- woodpecker.afpy.org,
- …
Une machine peut contenir un ou plusieurs services (un sil est
"gros", plusieurs sils sont « néglibeables » (comme un site
statique).
## deb2.afpy.org
♥ Machine sponsorisée par Gandi ♥
C'est un VPS `V-R4 2 CPUs · 4 GB RAM`.
Cest un VPS `V-R4 2 CPUs · 4 GB RAM`.
Elle héberge les services suivants :
Elle héberge surtout des sites statiques, mais pas que :
- https://www.afpy.org ([source](https://github.com/AFPy/site))
- [https://*.pycon.fr/*](https://pycon.fr/) (que des sites statiuques)
- Alain le bot IRC du canal #afpy ([source](https://github.com/AFPy/alain))
- La gate [IRC](https://afpy.org/irc)—[Discord](https://afpy.org/discord)
- https://www.afpy.org ([source](https://github.com/AFPy/site)).
- [https://\*.pycon.fr/\*](https://pycon.fr/) (que des sites statiuques).
- Alain le bot IRC du canal #afpy ([source](https://github.com/AFPy/alain)).
- La gate [IRC](https://afpy.org/irc)—[Discord](https://afpy.org/discord) (un [discord-irc-sync](https://github.com/Hackndo/discord-irc-sync)).
- https://dl.afpy.org: un *directory listing* nginx des vidéos de nos conférences.
- https://logs.afpy.org: Les logs du salon IRC #afpy ([source](https://github.com/AFPy/AfpyLogs/))
- https://logs.afpy.org: Les logs du salon IRC #afpy ([source](https://github.com/AFPy/AfpyLogs/)).
- https://munin.afpy.org
## bbb2.afpy.org
♥ Machine sponsorisée par Gandi ♥
C'est un VPS `V-R8 4 CPUs · 8 GB RAM`.
## backup1.afpy.org
♥ Machine sponsorisée par Gandi ♥
C'est un « Gandi Cloud V5 » à Bissen au Luxembourg avec 512MB de RAM
Cest un « Gandi Cloud V5 » à Bissen au Luxembourg avec 512MB de RAM
et 512GB de disque, il sauvegarde (via rsnapshot) les autres machines
(voir `backup.yml`).
Dernière vérification de `backup1.afpy.org` le 2 janvier 2023 via :
Dernière vérification de `backup1.afpy.org` le 4 janvier 2024 via :
ssh root@backup1.afpy.org sh check-afpy.sh
Dernière vérification de `silence` (chez Julien) le 2 janvier 2023 via :
Dernière vérification de `silence` (chez Julien) le 4 janvier 2024 via :
ssh root@silence sh /srv/backups/check-afpy.sh
<details>
<summary>
Le script `check-afpy.sh`.
</summary>
```bash
#!/bin/sh
BASE=/srv/backups/rsnapshot_afpy
for machine in deb git discuss
do
echo "# $machine.afpy.org"
echo
rsnapshot-diff -H "$BASE/weekly.0/$machine.afpy.org" "$BASE/daily.0/$machine.afpy.org"
echo
echo
done
echo '# discuss.afpy.org'
echo
ls -lahtr $BASE/daily.0/discuss.afpy.org/var/discourse/shared/standalone/backups/default/ | sed 's/^/ /'
echo
echo
echo '# logs.afpy.org'
echo
ls -lahtr $BASE/daily.0/deb.afpy.org/var/www/logs.afpy.org/ | tail | sed 's/^/ /'
echo
echo
echo '# git.afpy.org'
echo
ls -lahtr $BASE/daily.0/git.afpy.org/var/backups/gitea/ | sed 's/^/ /'
```
</details>
## gitea1.afpy.org
@ -131,13 +171,13 @@ machine « from scratch ».
#### Commander une nouvelle machine
Typiquement chez Gandi une `V-R1: 1 CPU · 1 GB RAM`, avec une Debian
11, n'oubliez pas d'y mettre une clé SSH.
11, noubliez pas dy mettre une clé SSH.
#### Nommer la machine
Typiquement `gitea2.afpy.org`, configurer les DNS, en profiter pour
réduire le TTL de git.afpy.org puisqu'il faudra le changer à la fin.
réduire le TTL de git.afpy.org puisquil faudra le changer à la fin.
#### Autoriser à se ssh en root
@ -145,7 +185,7 @@ réduire le TTL de git.afpy.org puisqu'il faudra le changer à la fin.
ssh debian@giteatest.afpy.org sudo cp /home/debian/.ssh/authorized_keys /root/.ssh/
#### Ajouter la machine dans l'inventaire Ansible
#### Ajouter la machine dans linventaire Ansible
Ça devra donc ressembler à :
@ -154,7 +194,7 @@ réduire le TTL de git.afpy.org puisqu'il faudra le changer à la fin.
gitea2.afpy.org
```
On peut probablement supprimer l'autre qui ne marche plus...
On peut probablement supprimer lautre qui ne marche plus...
#### Lancer Ansible
@ -164,8 +204,8 @@ On peut probablement supprimer l'autre qui ne marche plus...
#### rsync la sauvegarde
J'utilise du `ssh agent forwarding`, si vous n'en utilisez-pas vous
aurez peut-être à rsync sur votre machine d'abord.
Jutilise du `ssh agent forwarding`, si vous nen utilisez-pas vous
aurez peut-être à rsync sur votre machine dabord.
Adapté de : https://docs.gitea.io/en-us/backup-and-restore/#restore-command-restore
@ -195,14 +235,46 @@ Un rapide test peut être effectué via :
Puis il faut mettre à jour le CNAME de git.afpy.org pour le faire pointer vers la nouvelle machine.
## woodpecker1.afpy.org
♥ Machine sponsorisée par Gandi ♥
Cest un « Gandi VPS V-R1 » 1 CPU, 1 GB RAM, 25 GB disk.
Cest [Woodpecker CI](https://woodpecker.afpy.org) lié à notre [forge](https://git.afpy.org).
Il ne fait tourner aucune tâche, ce sont les agents qui font tourner
les tâches. Si vous avez une machine de libre, vous êtes invités à
proposer un agent. Il suffit de :
- Installer une Debian.
- Y ajouter nos [authorized_keys](https://git.afpy.org/AFPy/infra/src/branch/main/group_vars/all/authorized_keys).
- Nous donner son IP.
Un agent na pas besoin dIPv4, donc une vieille machine recyclée
planquée chez vous sans NAT mais avec de lIPv6 ça suffit. Pas de
Raspberry PI par contre, nous navons pour le moment pas de tâches à
faire tourner sur arm64.
### boole.mdk.woodpecker-agents.afpy.org
♥ Machine sponsorisée par Julien Palard ♥
Cest un vieux laptop à moi, 4 cœurs, 8GB de RAM, planqué sous mon bureau.
Il sert uniquement dagent au Woodpecker, et cest pour le moment le seul.
## discourse1.afpy.org
♥ Machine sponsorisée par Gandi ♥
C'est un VPS `V-R4 2 CPUs · 4 GB RAM`.
Cest un VPS `V-R4 2 CPUs · 4 GB RAM`.
Elle héberge https://discuss.afpy.org une instance Discourse.
### Déplacement du Discourse vers une nouvelle machine
Le 31 janvier 2023 Julien a déplacé le Discourse de deb2 à discourse1.
@ -214,13 +286,13 @@ Voici la procédure
- Ajouter les enregistrements A et AAAA de la machine.
- Baisser le TTL du CNAME `discuss.afpy.org`.
- Mettre à jour le SPF pendant qu'on y est.
- Mettre à jour le SPF pendant quon y est.
- Configurer le reverse DNS de la nouvelle machine.
- Côté Ansible, ajouter la machine au groupe `[discourse]` dans le fichier `inventory`.
- Copier sa clé ssh sur la machine dans `/root/.ssh/authorized_keys`.
- Lancer `ansible-playbook discuss.yml`.
- Lancer à la main dans `/var/discourse/`: `./launcher rebuild app` (ça prend ~10mn).
- Sur l'ancienne machine, faire une sauvegarde, soit via https://discuss.afpy.org/admin/backups, soit :
- Sur lancienne machine, faire une sauvegarde, soit via https://discuss.afpy.org/admin/backups, soit :
```
./launcher enter app
discourse backup
@ -241,22 +313,22 @@ Bien tester lenvoi demails.
</details>
# Ansible
# Rôles utilisés
On utilies ces rôles Ansible :
## roles/nginx
Ce rôle configure un nginx avec Letsencrypt en DNS-01 via l'API Gandi (nos domaines étant chez Gandi).
Ce rôle configure un nginx avec Letsencrypt en DNS-01 via lAPI Gandi (nos domaines étant chez Gandi).
L'avantage du DNS-01 c'est qu'on peut configurer un nouveau serveur **avant** que le DNS ne pointe sur lui.
Lavantage du DNS-01 cest quon peut configurer un nouveau serveur **avant** que le DNS ne pointe sur lui.
## julienpalard.nginx
Ce rôle configure un nginx avec Letsencrypt en HTTP-01, on l'utilise
assez peu maintenant, on l'utilise là où on ne peut pas faire de
Ce rôle configure un nginx avec Letsencrypt en HTTP-01, on lutilise
assez peu maintenant, on lutilise là où on ne peut pas faire de
DNS-01 (pour `fr.pycon.org` par exemple).
Voir la [doc](https://github.com/JulienPalard/ansible-role-nginx).
@ -264,146 +336,47 @@ Voir la [doc](https://github.com/JulienPalard/ansible-role-nginx).
## common
*common* est un rôle "de base" permettant d'avoir une conf "normale"
*common* est un rôle "de base" permettant davoir une conf "normale"
sur toutes nos machines (emacs et vim installés, nos authorized-keys,
pas de mlocate, hostname propre, firewall, ce genre de broutilles).
## BBB
## exim
Hébergé sur bbb2.afpy.org chez Gandi.
Le playbook exim configure une clé DKIM et signe les mails avec. Mais
un humain doit la propager sur les DNS.
J'y ai appliqué un poil de ssh-hardening :
AuthenticationMethods publickey
LogLevel VERBOSE
Ensuite j'ai [rsync les enregistrements depuis le bbb
précédent](https://docs.bigbluebutton.org/2.2/customize.html#transfer-published-recordings-from-another-server).
Puis j'ai sauvegardé/restauré la DB de greenlight :
# Sur l'ancienne machine :
docker exec greenlight_db_1 /usr/bin/pg_dumpall -U postgres -f /var/lib/postgresql/data/dump.sql
# Sur la nouvelle machine :
# Copier la sauvegarde sur le nouveau serveur :
cd ~root/greenlight
rsync bbb.afpy.org:/root/greenlight/db/production/dump.sql ./
docker-compose down
rm -fr db
# Configurer le même mot de passe dans .env et docker-compose.yml que l'ancienne machine
# En profiter pour vérifier le SAFE_HOSTS dans le .env.
docker-compose up -d
# Attendre un peu avec un top sous les yeux que ça se termine vraiment
docker exec greenlight_db_1 /usr/local/bin/psql -U postgres -c "DROP DATABASE greenlight_production;"
mv dump.sql db/production/
docker exec greenlight_db_1 /usr/local/bin/psql -U postgres -f /var/lib/postgresql/data/dump.sql
rm db/production/dump.sql
docker-compose down
docker-compose up -d # Il va s'occuper de la migration
docker-compose logs -f # pour voir si tout va bien
`rsync` des certificats TLS aussi :
rsync -vah bbb.afpy.org:/etc/letsencrypt/ /etc/letsencrypt/
Ça a pris un petit :
sed s/sd-106563.dedibox.fr/bbb.afpy.org/ /etc/nginx/sites-available/bigbluebutton
Il faut attendre un moment avec un `top` qui tourne, ruby a tout plein
de truc a faire avant de démarrer.
### BBB password reset
Pour accepter le password reset, BBB doit avoir :
ALLOW_MAIL_NOTIFICATIONS=true
dans /root/greenlight/.env
(Pour relire le `.env`: `cd /root/greenlight; docker-compose down && docker-compose up -d`)
Pour vérifier la conf :
docker run --rm --env-file .env bigbluebutton/greenlight:v2 bundle exec rake conf:check
Il y a des chances que ça ne passe pas, il faut laisser les mails
sortir de leur conteneur Docker (par défaut il utilise sendmail DANS
le conteneur).
Il faut configurer le `.env` tel que:
SMTP_SERVER=172.17.0.1
SMTP_PORT=25
SMTP_DOMAIN=greenlight.afpy.org
SMTP_SENDER=bbb@afpy.org
Puis vérifier qu'exim et le firewall (attention c'est peut-être `ufw`)
les acceptent.
### Configuration TURN/STUN
L'installation de BBB n'étant pas gérée par Ansible, pour le moment la
conf TURN/STUN est faite à la main, c'est la seule chose à faire, elle
ressemble à :
```xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
">
<bean id="stun0" class="org.bigbluebutton.web.services.turn.StunServer">
<constructor-arg index="0" value="stun:turn.afpy.org"/>
</bean>
<bean id="turn0" class="org.bigbluebutton.web.services.turn.TurnServer">
<constructor-arg index="0" value="[redacte]"/>
<constructor-arg index="1" value="turns:turn.afpy.org:443?transport=tcp"/>
<constructor-arg index="2" value="86400"/>
</bean>
<bean id="stunTurnService" class="org.bigbluebutton.web.services.turn.StunTurnService">
<property name="stunServers">
<set>
<ref bean="stun0" />
</set>
</property>
<property name="turnServers">
<set>
<ref bean="turn0" />
</set>
</property>
<property name="remoteIceCandidates">
<set>
</set>
</property>
</bean>
</beans>
```
dans `/usr/share/bbb-web/WEB-INF/classes/spring/turn-stun-servers.xml`.
# DKIM
Le playbook exim configure une clé DKIM et signe les mails avec. Mais un humain doit la propager sur les DNS.
Le nom d'hote est le nom du serveur, donc pour `deb2`,
Le nom dhote est le nom du serveur, donc pour `deb2`,
`d=deb2.afpy.org`, et le selecteur vaut le nom de domaine avec des
`-`, soit `s=deb2-afpy-org`.
TL;DR la configuration qu'il faut faire ressemble à :
TL;DR la configuration quil faut faire ressemble à :
deb2-afpy-org._domainkey.deb2.afpy.org. IN TXT "v=DKIM1; k=rsa; p=MIG...QAB"
La clé publique se situe dans `/etc/exim4/dkim/*.pem` et est donc récupérable via :
ssh root@deb2.afpy.org cat /etc/exim4/dkim/deb2-afpy-org.pem | grep -v ^- | tr -d '\n'
Côté IPv6 cest pas joli :
- Gandi ne nous fournit pas de /64 en IPv6, notre /64 se fait donc
régulièrement bloquer à cause des voisins. cf. https://slash64.net/.
- Certaines de nos machines nont que de lIPv6 (backup1, lagent
woodpecker chez mdk).
- Certains MX nont pas dIPv6 du tout (protonmail, galae, …).
Résultat :
- Faire passer les mails des machines IPv6-only par des machines qui
ont une IPv4 ne marche pas, lIPv6 étant désactivé sur les exim à
cause de labsence de /64, pour les forcer à délivrer en IPv4.
- Nos machines en IPv6 nenvoient pas demail, du tout.
# Tâches
## Redimentionner un disque sur un VPS
- Agrandir le volume via l'interface web,
- agrandir la partition via `growpart /dev/xvda 1`,
- agrandir le filesystem via `resize2fs /dev/xvda1`.

23
Vagrantfile vendored Normal file
View File

@ -0,0 +1,23 @@
Vagrant.configure("2") do |config|
config.vm.provider :virtualbox do |v|
v.name = "pretalx"
v.memory = 2048
v.cpus = 2
v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
v.customize ["modifyvm", :id, "--ioapic", "on"]
end
config.vm.define :pretalx do |pretalx|
pretalx.vm.hostname = "pretalx.local"
pretalx.vm.box = "debian/bookworm64"
pretalx.vm.network :private_network, ip: "192.168.56.10"
pretalx.vm.network :forwarded_port, guest: "80", host: "8000"
pretalx.vm.network :forwarded_port, guest: "443", host: "8443"
pretalx.vm.provision "ansible" do |ansible|
ansible.compatibility_mode = "2.0"
ansible.playbook = "pretalx.yml"
ansible.become = true
end
end
end

View File

@ -20,20 +20,7 @@
- name: Install requirements
apt:
state: present
name: [nginx, python3-passlib, sudo] # passlib to generate htpasswd
- name: Generate AFPy admin htpasswd
htpasswd:
path: "/etc/nginx/afpy.org.htpasswd"
name: "{{ item.username }}"
password: "{{ item.password }}"
owner: root
group: www-data
mode: 0640
loop: "{{ afpy_org_admins }}"
loop_control:
label: "{{ item.username }}"
notify: reload nginx
name: [nginx, sudo]
- name: Setup afpy.org
include_role: name=nginx
@ -64,6 +51,11 @@
root /var/www/afpy.org/;
include snippets/letsencrypt-afpy.org.conf;
index index.html;
# font-src 'self' for afpy.org/admin/ which loads fonts like:
# https://www.afpy.org/admin/static/bootstrap/bootstrap4/fonts/fontawesome-webfont.eot?#iefix&v=4.7.0
add_header Content-Security-Policy "default-src 'none'; font-src 'self'; img-src 'self'; style-src 'self'; script-src 'self'; frame-ancestors 'self'; frame-src https://www.helloasso.com https://web.libera.chat;";
add_header X-Content-Type-Options "nosniff";
location /discord
{
return 301 https://discord.gg/qaxq8tVcjx;
@ -95,13 +87,6 @@
return 301 https://discuss.afpy.org/c/emplois.rss;
}
location /admin/ {
auth_basic "Administration";
auth_basic_user_file afpy.org.htpasswd;
include proxy_params;
proxy_pass http://unix:/run/afpy-org/website.sock;
}
location ~ ^/doc/python/(.*)$ {return 301 https://docs.python.org/fr/$1;}
location = /logo.png { return 301 https://www.afpy.org/static/images/logo.svg; }
location = /posts/emplois { return 301 https://www.afpy.org/emplois; }
@ -152,6 +137,12 @@
dest: /home/afpy-org/src/
update: yes
- name: Setup or upgrade venv
become: true
become_user: afpy-org
command: python3 -m venv --upgrade-deps /home/afpy-org/venv
changed_when: False
- name: pip install AFPy website
become: true
become_user: afpy-org
@ -223,7 +214,12 @@
nginx_path: /var/www/salt-fr.afpy.org
nginx_domain: salt-fr.afpy.org
nginx_certificates: [salt-fr.afpy.org]
nginx_public_deploy_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHVrME7+AYhM4n6opE5gVJbWsZHLETucV2wV+kDvnLk3"
nginx_public_deploy_key: |
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHVrME7+AYhM4n6opE5gVJbWsZHLETucV2wV+kDvnLk3
{{ authorized_keys['mdk'] | join(LF) }}
nginx_extra: |
add_header Content-Security-Policy "default-src 'none'; font-src https://cdnjs.cloudflare.com; img-src 'self' https://www.gravatar.com; style-src 'self' 'unsafe-inline' https://cdnjs.cloudflare.com; script-src 'self' https://cdnjs.cloudflare.com; frame-ancestors 'self';";
add_header X-Content-Type-Options "nosniff";
- name: Setup nantes.afpy.org
include_role: name=nginx
@ -273,6 +269,8 @@
{
listen [::]:443 ssl http2; listen 443 ssl http2;
server_name photos.afpy.org;
add_header Content-Security-Policy "default-src 'none'; img-src 'self'; style-src 'self'; script-src 'self'; frame-ancestors 'self';";
add_header X-Content-Type-Options "nosniff";
include snippets/letsencrypt-photos.afpy.org.conf;
root /var/www/photos.afpy.org/;
}

View File

@ -53,6 +53,12 @@
dest: ~alain/src/
notify: restart alain
- name: Setup or upgrade venv
become: true
become_user: alain
command: python3 -m venv --upgrade-deps /home/alain/venv
changed_when: False
- name: Alain s'installe dans sa maison
become: true
become_user: alain

View File

@ -2,3 +2,7 @@
inventory = inventory
nocows = 1
vault_password_file = ~/.ansible-afpy-vault
# allow_world_readable_tmpfiles = true
[ssh_connection]
ssh_args = -C -o ControlMaster=auto -o ControlPersist=3600s

View File

@ -17,27 +17,17 @@
rsnapshot_name: afpy
rsnapshotted_hosts: "{{ groups.rsnapshotted }}"
rsnapshot_backups:
- remote: bbb2.afpy.org:/srv/
path: bbb.afpy.org/
- remote: bbb2.afpy.org:/home/
path: bbb.afpy.org/
- remote: bbb2.afpy.org:/etc/
path: bbb.afpy.org/
- remote: bbb2.afpy.org:/root/greenlight/db/
path: bbb.afpy.org/
- remote: bbb2.afpy.org:/var/bigbluebutton/
path: bbb.afpy.org/
- remote: deb2.afpy.org:/srv/
path: deb.afpy.org/
- remote: deb2.afpy.org:/home/
path: deb.afpy.org/
- remote: deb2.afpy.org:/etc/
path: deb.afpy.org/
- remote: deb2.afpy.org:/var/discourse/shared/standalone/backups/
path: deb.afpy.org/
- remote: deb2.afpy.org:/var/www/
path: deb.afpy.org/
- remote: gitea1.afpy.org:/var/backups/
path: git.afpy.org/
- remote: discourse1.afpy.org:/var/discourse/shared/standalone/backups/
path: discuss.afpy.org/

49
bye_bbb.yml Normal file
View File

@ -0,0 +1,49 @@
---
- hosts: webservers
tasks:
- name: Basic setup
include_role: name=common
- name: Setup bbb parking
include_role: name=nginx
vars:
nginx_owner: bbb
nginx_domain: bbb.afpy.org
nginx_certificates: ['bbb.afpy.org']
nginx_path: /var/www/bbb/
nginx_conf: |
server
{
listen [::]:80; listen 80;
server_name bbb.afpy.org;
return 301 https://$host$request_uri;
}
server
{
listen [::]:443 ssl http2; listen 443 ssl http2;
server_name bbb.afpy.org;
include snippets/letsencrypt-bbb.afpy.org.conf;
root /var/www/bbb/;
charset utf-8;
location /b {
return 301 /;
}
}
- name: Copy bbb redirect file
copy:
src: bbb.html
dest: /var/www/bbb/index.html
owner: root
mode: 0644
- name: Copy bbb redirect style file
copy:
src: pico.classless.min.css
dest: /var/www/bbb/pico.classless.min.css
owner: root
mode: 0644

View File

@ -13,14 +13,24 @@
git:
repo: https://github.com/Hackndo/discord-irc-sync.git
dest: ~/src/
notify: restart discord-irc-sync
- name: Setup or upgrade venv
become: true
become_user: discord-irc-sync
command: python3 -m venv --upgrade-deps /home/discord-irc-sync/venv/
changed_when: False
notify: restart discord-irc-sync
- name: Install discord-irc-sync requirements
become: true
become_user: discord-irc-sync
pip:
requirements: /home/discord-irc-sync/src/requirements.txt
state: latest
virtualenv_command: /usr/bin/python3 -m venv
virtualenv: "/home/discord-irc-sync/venv/"
notify: restart discord-irc-sync
- name: Configure discord-irc-sync
copy:
@ -66,7 +76,7 @@
[Service]
Type=simple
ExecStart=/home/discord-irc-sync/venv/bin/python /home/discord-irc-sync/src/discord-irc-sync.py /home/discord-irc-sync/config.json
ExecStart=/home/discord-irc-sync/venv/bin/python -u /home/discord-irc-sync/src/discord-irc-sync.py /home/discord-irc-sync/config.json
User=discord-irc-sync
Group=discord-irc-sync
WorkingDirectory=/home/discord-irc-sync/src/

4
dl.yml
View File

@ -7,6 +7,7 @@
- hs-157
- pilou
- entwanne
- merwyn
tasks:
- name: Basic setup
@ -89,12 +90,13 @@
root /var/www/dl.afpy.org/;
add_header Content-Security-Policy "default-src 'none'; style-src 'unsafe-inline'; frame-ancestors 'self'";
add_header Content-Security-Policy "default-src 'none'; style-src 'unsafe-inline'; frame-ancestors 'self'; media-src 'self'";
add_header X-Content-Type-Options "nosniff";
location /
{
fancyindex on;
fancyindex_exact_size off; # Output human-readable file sizes.
fancyindex_name_length 150;
}
}

70
files/bbb.html Normal file
View File

@ -0,0 +1,70 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<title>Au revoir BigBlueButton</title>
<meta property="og:title" content="Au revoir BigBlueButton" />
<meta property="og:type" content="website" />
<meta property="og:locale" content=fr />
<meta property="og:description" content="AFPys BigBlueButton was here." />
<meta property="og:url" content="https://bbb.afpy.org" />
<meta property="og:image" content="https://www.afpy.org/static/images/logo.svg" />
<meta name="viewport" content= "width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@1/css/pico.classless.min.css">
</head>
<body>
<header>
<hgroup>
<h1>Au revoir BigBlueButton</h1>
<p>So Long, and Thanks for All the Fish.</p>
</hgroup>
<nav>
<ul role="listbox">
<li><a href="https://www.afpy.org/irc">IRC</a></li>
<li><a href="https://www.afpy.org/discord">Discord</a></li>
<li><a href="https://www.afpy.org/docs/a-propos">Lasso</a></li>
<li><a href="https://git.afpy.org">Git</a></li>
<li><a href="https://discuss.afpy.org/upcoming-events">Évènements</a></li>
</ul>
</nav>
</header>
<main>
<section id="bye">
<h2>Fermé depuis le 31 janvier 2024</h2>
<p>
Linstance BBB de lAFPy est fermée : elle était trop peu utilisée en
regard des ressources (humaines et matérielles) quelle utilisait
(voir <a href="https://discuss.afpy.org/t/jitsi-ou-big-blue-button/1872">
ce thread</a>).
</p>
</section>
<section id="alternatives">
<h2>Alternatives</h2>
<p>
Il existe beaucoup dautres services de visioconférences,
grâce au
collectif <a href="https://chatons.org/">CHATONS</a> :
<ul>
<li><a href="https://meet.evolix.org/">https://meet.evolix.org/</a></li>
<li><a href="https://video.le-filament.com">https://video.le-filament.com</a></li>
<li><a href="https://conference.facil.services/">https://conference.facil.services/</a></li>
<li><a href="https://jitsi.hadoly.fr/">https://jitsi.hadoly.fr/</a></li>
<li><a href="https://framatalk.org">https://framatalk.org</a></li>
</ul>
ainsi que <a href="https://www.chatons.org/search/by-service?service_type_target_id=117">de nombreux autres</a>.
</p>
</section>
<section id="backups">
<h2>Et mes enregistrements ?</h2>
<p>
Nous avons une sauvegarde du serveur, si vous aviez un
enregistrement sur notre BBB, il doit être possible de
lextraire de la sauvegarde (mais on a pas encore essayé),
faites-nous signe sur <a href="https://discuss.afpy.org">le
forum</a>, pinguez @mdk.
</p>
</section>
</main>
</body>
</html>

5
files/pico.classless.min.css vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -1,8 +1,11 @@
---
- hosts: gitea
roles:
- common
- gitea
vars:
gitea_version: "1.17.4" # To upgrade, read the README file first.
gitea_version: "1.21.9" # To upgrade, read the README file first.
gitea_internal_token: !vault |
$ANSIBLE_VAULT;1.1;AES256
65396439373538656633396363313333663233343661643739633135306131613434353335353634
@ -14,5 +17,11 @@
39346334353266613234363664643030303565313065313334333833383337623637366132663435
61386535353635386339383731323464323135366362613734393833386632393166393261373433
61363664376330343465656431316163396533326634643636326537383032323636
roles: [common, gitea]
gitea_oauth2_jwt_secret: !vault |
$ANSIBLE_VAULT;1.1;AES256
64323839343261376362643130326334643964383535373531303164643966313463393530323437
3631646666313136373431326162356438393964643937310a613364653034383465376166633162
65643135623837326464396666313339633961366638656130323463626437623134313139663732
6664313665393739350a633638303235396639373866643863613865623061643364323963376532
64356262633634613730306230653962366132393733363739363232316461343164636436323130
3037633332343439363132323163323239383634313439336262

View File

@ -5,11 +5,17 @@ authorized_keys:
entwanne: []
hs-157:
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILQxDNqPx1uYblrbeliQZ5scDPFuMElTRBJmjUFwUMUB hs-157@jirafenn-2021-04-06
lameche:
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC9+fKl4utb+I3mTMbie19gYa7ulAHFK6dzfRBfx7qdfnKqEOXpldSW5Vdo3A9myS99e69X9MNZ//p44tVMGGDZgg6ns20ItmgpoFtbPMkWWZAfoAxoy3DbW5a9wtuqz1OB74qGe71ZVCt8Po0yVUAY1YsUkrfxurJNEkbHZK4L8n174Kb9EakkMbXOqcNoOdbJ1e7hBW3GX51903PSlUlYxma+cYkDqBSxd/yxJ3tDfibCYF06FLbcGA9NtU9wVHIifJOahk7gYCavoWe+rfBeb226G401TVi2gdWQw4qDCyvWh0X67pyeSEGvXH0Vh0XLSoRKCzqENM0qZaMskjcT lameche@sushi
marc:
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDVLcQld0qXYkStjCjkOLvoAk80iFwOPWY1Nv2EzU6P8o2dxOaHBuO1YcaB7XmK6rP1bf4xjOQtlhDGCSZ7lIM3H8gEHTfsVw3odbaoq/B0NpP8j+PL4YMJMzY+SUXZTILYUiJ3uuR064z21mpNcNWwWY/2NM6k7h93AOfxNo6ZxO460sHOlAlHNqlsyUGhtIWndCTAQ1wpT2YMWo/y8HCwizYGZz4HQ04nVTK9DLftb7bBxaqTtiPnx+VzYsRg1Ma1OvBggehL6iiXu6xpyXarRx99n3SVO8ptx/rmaX3tyB2ZN2kcxAYHscgh2vRrVm6BWmSF1XXuf2Vu35Lo0K510Jd92gbkBVair7ZtR6hFcNhDHfA87mhdqvld3XwL9/D93ZSGo4FCSJb0xdq4HtpsMVE20yEiDyOe7KeShbur3YYzdZAAmvhTaUyjfm9qReIS/OoAIePZvTNiX3/sbVwdDMzXp+6C17aGFGZ2ONug63Rs0ePdVmYUgFnm26tYfznuQwZcRlCEJwlMI2nYaKQk0GG1NbzHrZZdnCIujav0Ncdpi2RZgb4nlWX66mO16HcYpheMGpClBDxya9FM6ga7WFc72Z0xHfB1HTemEN/qlA1hroNK/DuRJzT/oxp7rd2YhcunmXrucKX4/KlkA0FcNbNY/sVsF2dr4oGBr3pzvQ== marc@debureaux.fr
mdk:
mdk:
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDKA7DgTQ0G7+kdsX0lIUOAAOllwGSCu8s8TxPvr/61Y8q+pIO5mrZycI0xYcKP5NZaABqlFyXUUNfLj7RLqteBxqq2QZP4NOJ1MutYRIkzJ9YW0f565jHaOqSguz0MY+1sCHtuEPiUUZoNexkKN7SIx60SfoaMEvGjAj46txA7VFbJUuKcJtA1Yvmn0C0KoXUUQ/G+JqvjQ7QuKLQYdTZ8S9OEvNaqNfwNSwvy1/LCnuajFw0O+H5bz7AcS5Iuj+9k8wgHPK1a1rQEdteOcn2XBCvta/VOVlFLv6/9K3iU3EJ1pyaZ88UkuJef8aWnH/AJGaF2gLqUbBuL+UeXyD41 julien+yubikey4@palard.fr
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8vv8vwmbyhFEa0chj8LklnnY6DRLKj2OM0NgaMTd9SsrtBeLMqTt34pU+kKl6/9EIe9P8Z1/fWFyOiTsE7Khf3rkNsoILPmEV14i18Bvtp4nMtljqZaKVkAcRjPvo7flRWNxxL2Zbo+BEr3wVCl3Sc6YV8oQzCwVPKf34AB39b+PW4f3580Aqcd4Ci6zca0Ol95tLDv1slX1A7QcpoZAne8kj5h6bb4cC7FLBC9+xOSKmzoLOlP7LsyxaUUGRyi/FeMoma1VES65aIJ5U23GtZrzZI3tKz+vpQvOVaozNTDkNLiiJkjd3Ew1I10wArpZixjwSndP8CvGFyJc1XUXZ julien+yubikey5@palard.fr
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE6WpbQWtaYmGwrBo9mR0wGTHiz4hc2o5OXVzLI6A4wB julien+2024@palard.fr
merwyn:
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDSRv2KVwVVi3STucTuD8NkwVrWUkdBZkTHtoWqXNc8xOXG9sycLjTzCFJwD8JESXvPWSlx51kidPxAa5HCnsxdN3FxQiSjljREDzEtA1QqmzDz8gYSUz+F7HQOfR0r8MO76EDqDuwWaxdSdQP27jhlMMGaaZLEVPK+ETebPWOcgz+H+R7cWOUaxdRTlaemlgMr2/JNgcuW+2olsKgS2w4SOywukrLLq4/pV6bYuDM1aOTY6RKSJBskx7PX65eZlE1Fkfp7Df9aKsZihe847vHJcfq4TTdIqSb1PWRbtbfvFo+iwfcg2Ed6c2Iv4RR6SUDNIjKxz+xxJ0NlDEr/3vt5 merwyn@yubikey4
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDSnlArgFt0oW8irIxnHoGJKKpP7JlpTewtOd88B41JWQHPDxADbydJ0Cb6dHTL/eAxzEJl5rkEANcMOY+SxmuF7Y93DEBRwbMTmCREijhBgI1tvhwirNBOFUiUHLTF1ISfhvNZdnjB2i2xgx/3L0RGq9Zw6/uLLlzijkeSQf8u4nopvJAmVjQFOoHbGOcHQCawjZhL1arw3prVw/U4DGKmZ64L97ZbbOFgNE2kHOINXhb69TTgsJ64QfVHpvhtx/DJGcDTDsDd426JijgK6LPDM+u2QoMsgUP/lsHt04qG5PeaAwJXCgoJw6xJapascabw5vFREyec1l/xCb3S7Kut merwyn@yubikey5
pilou:
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC1FuL8/1P24e+kGtn4Ko1Yh0JL/bN0fnat8GSVGggJcxhuTSw6JLLSSkvFe2Kk8h0ymKNXrEwS925dS4p8QDlkj5NM54kSqty3cBAHbcMDsXqTu0qG8UKl5kpf13VKtlSbyVzMMBUyQ4Q9hlbr1CsB58tx5TcpL2q6sh8jvzh3Scux6h1N5RcwrStNnD5A4wJZzk+o7ETm3l5mFmB5ytT+k61eANVyPtnpt4U09R6eBABo/d/gkjNdZyfg7tEzAHESgYl8eV/SLmsKndyPQyp0vkCTdWH4CfTFNJ4FdAQ/InUNrLReySuwxmyIIVNle3gS3ClYcEPUvBVmzIjIufLDfSKnLHGBK0mv+QDiShEHRweQ2DlU4xqb3LH24das+f3hHXMxXi+tPvJ0jHm9y0xaVZvFKrU/NDaAHgUphGhjWGWOyjcYsNMIbfkFOXftMzGQFDY1DSfuz10T/wk0Z+MZXQrX9i2JYe65L+VveeyJIM7B/3bk35fqtP2bZ0hcyiD3MmbNg8U0WYhzXjK0yiPnb6yvajI8tMYMZNXKRokJIrkK6WSHprJKDpYlgFuE9mve2RdLH05X8XYKZVtR6pEyks8sGH4U9k7yAWw+AU7G4754vx/wbcGCucw1JrAzY8g9o1w84wFaH78IX6Nb5Tz5kGNxxTPRwMcLpUf0jA2B4w== pilou@smartcard
rsnapshot:

View File

@ -1,8 +1,6 @@
---
admin_email: julien@python.org
exim4_local_interfaces: '127.0.0.1;172.17.0.1'
exim4_relay_nets: '172.16.0.0/12'
exim4_sendonly_email_aliases:
- regexp: '^root'
line: "root: {{ admin_email }}"
@ -19,3 +17,4 @@ admins:
- rsnapshot
root_authorized_keys: "{{ admins | map('extract', authorized_keys)|flatten|join('\n') }}"
LF: "\n"

View File

@ -1,50 +1,58 @@
$ANSIBLE_VAULT;1.1;AES256
66356133363737656337653838386162613236333735343431366635323734633535336232653266
3230363039623865333366353264336532386637613639320a373337363362326535336365316634
37356632373936333165646363356536343066393938653734316535303562666431623033376535
3132666337323864330a653138363465383462393936323963386163336634353964386561326337
32376165353534636438346235346230303830383162336165386538323265393363636462653737
62343534646632643661666365356366633963626161373366353636656262323865336138383661
64393063633133353732363861313034393963323633303962303365323863336333343039633932
35303861393235306361316131383361613034343134343834373665313538333031623264386264
33303564373637346531656639653539613064326639373833646163666363643139336636343730
36376339333031616434396534336235653764643137633735333834633465653561633631363365
32666637373734613839633661313438366538303263333731366535396663363334646539623265
63666333313063393935636438323061646236323333346434653532623030636432326337373837
63373739646337666636663930643864633366646135373238303265663831666536303562613631
39336336363130313633313664366530336632353238663732363164643936376139353362363366
33333630663134336662623031303331666237363934343863626163366232613131663462376237
62343638636664633735386264636233303465316364616138343439663338613531636337303364
64376432323163616433343234323537303765303134303034306465623164616165386334633361
39333239396337663731623334353433353631376566303738356335643661303135396134636437
31356566623439323234636231643062383866346530383237643661623634326633396565393564
62643636666262303865393632643063643235393236376130656532383931323366386231356636
63396539353335393864396463386435353335663330656332626430663364623036313163373638
33386237636634306565393338626238343331303533643663323037313838326266393261633539
61316338623236663061333964636362333264393239396235656161623739373234363533303636
61353131323866383736376437333134623633346436343363306132346530313830373464663133
33313166326261313763613332316539393964326464656164663136323464623839643939323832
37663732353061363165306666386532353962373130633563363138363433313763393866633737
37653537663563306665383537366162353965626332343837373666323036613438343264386437
33613065346537373339613637376133643566653466653461636666623539613665306339303134
66643862613332383331323931616533313365386435346339633133373065313339646638313434
36343364346462396337333365623766636165626362643864356234383432316232663866646636
33623361626562353466663262643439383838306165623036353837613665326534353932636133
38643837326362326238306632663533366134636364633633353631373032386361386363346361
32656436643364356336323432653866323235393265613837366430623562376331386633346161
36346234636134366334613338626565613237646462633839303832646637323530613931653264
36373533386266393363326662656439613564643666346338653965623339613232353535363961
36383734653464383336326261383130386134663865636232623738663832653032663531646437
63666362663064663362393637626139613933336162333362366664373639383835633463336330
62356439616361646439626430336437656138343037356637633731633230633435303531633534
30383130373731633630663638626331636135656461373835643262316539393665663632626537
62386331346362393663663634373632663530343565316163383937313433346562336338386266
65633635626337373462386537303535663231383063353162316361396139636565396137616238
35626331613436323561626438356364306566646232333031353066656164373138343731393765
32653365653937613463363433623032373464326137366339356330383637373530663436623763
36333836306366356131303165326666613666376665643864376339623731316365623361663537
36303035323136316264323734396164313539303434386531386134316537653836646233376634
39663939633236626330386635613265626532396132366165666662343039633538333639373166
66306338313263303761363430356630383231633236663864323238356135633162386461313064
31373538646235343066353661353032363166336336396530656233656531616537303139333337
3265
66333366323536383862373662656136623334643332643539323163353463663362336330366531
3061313365383335306337353562623762316333653131300a356638656165386531353864663763
65396233663939636435336330353262313165623534363065336164623339623233643733393161
3035383531643937350a616437613338623063653761366365313865396363666161666435373739
61626264353335656539313635353531633963623232356362343735306263626138363265323137
38353232656231303761623934376362626437653235326635393565306438336634633033336537
62666463336364353233363961663338353231663832316432666539373432616463663430363332
65616464303239656265663039626230653066346565663765396639393039636536313266633735
62393262656565363633333231343030306532323831323736633563656535373864353165393864
31663265396331646163303064383662383137643861306436373334653164376335383731633763
37326439613032383031643139323766636165363032373132653230373262646461366233373465
61356632343430633636383333346366623233353364313331326564366362633364643964306336
63356564313332303533643061313939303131353065616264646332313037646665356431663964
32313663623634356638393135333661643031616338663533336362333139383866326637356434
32333033393264363863373535626536643265636339373031623639323266343865656663343864
62653663666238623731326563316439336134326465333630316439663433306265613537616661
39396136313964613566323163386462633362643536613633333734383836393832323232353236
61383133373339346335346239373165656330353931646534326563313930333530326166336536
38613339346330313539333131313931386366323565353232326565396537613961333638376137
36656434333236653738343961643365643135663966633630373635623139636332316230663837
36643432616662373964333531653962633562383266353835643838626266613437653265363930
36343164626463643633386638363561303966353564666162386439353564363665353462386365
35373832613632643062306164383530656436363361666631326161616435323139393461343964
31303132306633646264393937363131626265353230636339613661333664343936383862303438
63333466346163663735643766333239383436626163646663383332613133396161633836663930
61643966373634333839316332623934373338356139633164346437303435313932323134653835
62356130383464663030393533343635626661663261313633386530353538623862643764376565
33613535363362336237316363626565623634636431393235313730333036663538343763363533
64323465663334613264366462326331633261663165616361636131656261653131363932643365
62636462323262653963643334633365636165343838353737363261376230613536383763343934
34663135363763396432623733633735343939333134316166333939633337336532343531613066
39356236656337623133396261326134343939386361386131376534623237653831363230393763
32613965303437616530356166323734326539613832333162623266366134316364326630303739
36626536396337333730356339396666316430336664616431366639383262373238326464653634
30326438396363383336346134633538396164666633616565373565343566353234376239656263
32313536333366346637653531386233623038316137333238373063323865626132383531626163
37333232303262303063386664633637306339643336346664356438336637343838333630613731
39306135323064323864666134333733633036666161323331383761373366366537356162346530
30326430653264616335343136633536326533353536386464373330623063653733663661313631
38323766663566323834343230633434396666366134656135333634346163656365323638373730
34623834636466663237333664343730373530663362666463303064623832636539316464356363
63653664306532306133653039363537316134356235313236313734323330613466343462633635
36326362306438303032353962613033623361316264343732643962373136383239383865616465
62346533373337623030393733653936643361333663336262363061636538333436346237653762
63313539663930303237323937366561343039636130613766613731663966363236343362633535
36653534383235623839613534336539333066326562636134336533336134313036386364356435
63623235666134363565383435323564306436323936393864336234633731653162393135623931
61323333303264356531643638346432393963373334366438396165333131613065343333626536
36373166376664316364656535396461653539643639303030616661626339623064396338626330
30313461343438633836353633333737393666616366643963373336346366613339613736363261
39303638623732653662333037333333303166333565383633636434386134316230653437336334
64633864666463646438326162363063656431366334303164626161363033323933306666316661
65616138303062396434336138653633363830633064623930323532316461633663363061643034
39356432306264303238663136636363386662633961616138383632383261373237376565343834
64333839313333313863613762313732303235636135363432383037633666313763656638393832
37313635373134643132663233643835646234646631376534343165383736363361396631396234
34363563613965386262303632333665663761386534366462373265323831666634

View File

@ -0,0 +1,4 @@
---
exim4_local_interfaces: '127.0.0.1;172.17.0.1'
exim4_relay_nets: '172.16.0.0/12'

43
group_vars/gitea/vars Normal file
View File

@ -0,0 +1,43 @@
---
nft_deny_list: |
ip saddr 122.161.0.0/16 counter drop comment "2023-07-13: user profile spam"
ip saddr 198.16.70.27 counter drop comment "2023-10-20: spam via /repo/migrate"
ip saddr 198.16.74.204 counter drop comment "2023-10-22: spam via /repo/migrate"
ip saddr 198.16.76.27 counter drop comment "2023-10-23: spam via /repo/migrate"
ip saddr 207.244.71.81 counter drop comment "2023-10-19: spam via /repo/migrate"
ip saddr 23.106.56.35 counter drop comment "2023-10-21: spam via /repo/migrate"
ip saddr 23.106.56.37 counter drop comment "2023-10-22: spam via /repo/migrate"
ip saddr 23.106.56.43 counter drop comment "2023-10-20: spam via /repo/migrate"
ip saddr 23.106.56.53 counter drop comment "2023-10-21: spam via /repo/migrate"
ip saddr 31.210.37.22 counter drop comment "2023-10-17: spam via /repo/migrate"
ip saddr 31.210.37.25 counter drop comment "2023-10-24: spam via /repo/migrate"
ip saddr 31.210.37.91 counter drop comment "2023-10-25: spam via /repo/migrate"
ip saddr 31.210.37.89 counter drop comment "2023-10-18: spam via /repo/migrate"
ip saddr 103.96.104.21 counter drop comment "2023-10-21: spam via issues on its own repo"
ip6 saddr 2001:67c:2628:647:13::f counter drop comment "2023-10-19: spam via /repo/migrate"
ip saddr 185.215.185.38 counter drop comment "2023-12-14: creates tons of user profiles but never log into them."
ip saddr 124.29.214.85 counter drop comment "2023-12-17: user profile spam"
ip6 saddr 2a09:81:200:aaaa:f816:3eff:fea6:e75f counter drop comment "2024-01-18: creates user profiles but never log into them."
ip saddr 192.144.39.21 counter drop comment "2024-01-18: creates user profiles but never log into them."
ip saddr 85.239.34.81 counter drop comment "2024-02-04: creates user profiles but never log into them."
ip saddr 117.241.81.47 counter drop comment "2024-02-12: user profile spam"
ip saddr 213.232.235.91 counter drop comment "2024-02-20: user profile spam"
ip saddr 103.48.197.154 counter drop comment "2024-02-22: user profile spam"
ip saddr 120.56.188.46 counter drop comment "2024-02-27: user profile spam"
ip saddr 193.168.141.21 counter drop comment "2024-03-05: user profile spam"
ip saddr 51.15.37.232 counter drop comment "2024-03-11: user profile spam"
ip6 saddr 2001:bc8:1640:296::0/64 counter drop comment "2024-03-12: user profile spam"
ip saddr 103.82.120.0/22 counter drop comment "Multiple hosts spamming by creating user profiles"
ip saddr 103.138.192.117 counter drop comment "2024-03-17: user profile spam"
ip6 saddr 2406:d00:aaaa::/48 counter drop comment "2024-03-19: user profile spam"
ip saddr 45.86.86.0/24 counter drop comment "2024-03-19: user profile spam"
ip saddr 223.233.84.200 counter drop comment "2024-03-19: spamming issues withs hundreds of links"
ip saddr 113.203.193.155 counter drop comment "2024-03-19: user profile spam"
ip saddr 94.103.188.103 counter drop comment "2024-03-22: user profile spam"
ip saddr 78.40.116.193 counter drop comment "2024-03-22: user profile spam"
ip saddr 159.253.120.5 counter drop comment "2024-03-22: user profile spam"
ip saddr 176.123.0.0/21 counter drop comment "2024-03-31: created 108 unactivated accounts"
ip saddr 43.225.192.242 counter drop comment "2024-04-04: advertising in user profile"
ip saddr 117.216.199.83 counter drop comment "2024-04-16: advertising in user profile"
ip saddr 37.221.65.103 counter drop comment "2024-04-17: user profile spam"
ip saddr 168.100.10.122 counter drop comment "2024-04-18: user profile spam"

View File

@ -0,0 +1,4 @@
---
nft_extra: ip saddr 45.13.107.8 accept comment "gentilsnuages.fr"

View File

@ -1,4 +0,0 @@
---
nft_extra: |
udp dport 16384-32768 counter accept comment "FreeSWITCH/HTML5 RTP streams"

102
http-to-xmpp.yml Normal file
View File

@ -0,0 +1,102 @@
---
- hosts: http_to_xmpp
vars:
user: http-to-xmpp
home: /home/http-to-xmpp/
xmpp_jid: 'afpy@chapril.org'
xmpp_dest_jid: 'mdk@chapril.org'
xmpp_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
31393038346161613063653031313232633461373937656433363364656131376330316461666664
3363636533376632646239393364623762653535343563310a353434666166626232363339313235
39303566363935613138663536343236643964663838343839616562393732633034393938383430
6361613237666235390a653332373339636262663633363833666237653538646439363766383536
3738
tasks:
- name: A user for the HTTP to XMPP gate
user:
name: "{{ user }}"
system: true
- name: A venv for the HTTP to XMPP gate
become: true
become_user: "{{ user }}"
command: python3 -m venv --upgrade-deps {{ home }}/venv
changed_when: False
- name: Install http-to-xmpp
notify: restart gate
become: true
become_user: "{{ user }}"
pip:
name:
- "http-to-xmpp>=0.2"
- pytz
virtualenv_command: /usr/bin/python3 -m venv
virtualenv: "{{ home }}/venv/"
- name: Setup http-to-xmpp.afpy.org
include_role: name=nginx
vars:
nginx_owner: "{{ user }}"
nginx_domain: http-to-xmpp.afpy.org
nginx_certificates: [http-to-xmpp.afpy.org]
nginx_conf: |
server
{
listen [::]:80; listen 80;
server_name http-to-xmpp.afpy.org;
return 301 https://$host$request_uri;
}
server
{
listen [::]:443 ssl http2; listen 443 ssl http2;
server_name http-to-xmpp.afpy.org;
include snippets/letsencrypt-http-to-xmpp.afpy.org.conf;
index index.html;
location /
{
include proxy_params;
proxy_pass http://localhost:1985;
}
}
- name: Service for http-to-xmpp
notify: restart gate
copy:
dest: /etc/systemd/system/http-to-xmpp.service
mode: 0600
content: |
[Unit]
Description=HTTP to XMPP gateway
After=network.target
[Service]
Type=simple
Environment="XMPP_JID={{ xmpp_jid }}"
Environment="XMPP_PASSWORD={{ xmpp_password }}"
Environment="XMPP_DEST_JID={{ xmpp_dest_jid }}"
ExecStart={{ home }}/venv/bin/http-to-xmpp
User={{ user }}
WorkingDirectory={{ home }}
Restart=on-failure
[Install]
WantedBy=multi-user.target
- service:
name: http-to-xmpp
enabled: yes
state: started
daemon_reload: yes
handlers:
- name: restart gate
systemd:
daemon_reload: true
state: restarted
name: http-to-xmpp

View File

@ -1,9 +1,18 @@
[pretalx]
pretalx1.afpy.org
[gitea]
gitea1.afpy.org
[pastebins]
deb2.afpy.org
[woodpeckers]
woodpecker1.afpy.org
[woodpecker_agents]
boole.mdk.woodpecker-agents.afpy.org
[muninservers]
deb2.afpy.org
@ -13,15 +22,11 @@ deb2.afpy.org
[discourse]
discourse1.afpy.org
[turn]
turn1.afpy.org
[dl]
deb2.afpy.org
[rsnapshotted]
deb2.afpy.org
bbb2.afpy.org
gitea1.afpy.org
discourse1.afpy.org
@ -31,6 +36,9 @@ backup1.afpy.org
[alains]
deb2.afpy.org
[http_to_xmpp]
deb2.afpy.org
[ponyconfs]
deb2.afpy.org

View File

@ -25,6 +25,10 @@
listen [::]:443 ssl http2; listen 443 ssl http2;
server_name logs.afpy.org;
include snippets/letsencrypt-logs.afpy.org.conf;
add_header Content-Security-Policy "default-src 'none'; style-src 'self'; script-src 'self';";
add_header X-Content-Type-Options "nosniff";
add_header X-Frame-Options DENY;
location /
{
include proxy_params;
@ -51,10 +55,16 @@
become: true
become_user: logs-afpy-org
git:
repo: https://github.com/AFPy/AfpyLogs/
repo: https://git.afpy.org/AFPy/AfpyLogs/
dest: /home/logs-afpy-org/src/
update: yes
- name: Setup or upgrade venv
become: true
become_user: logs-afpy-org
command: python3 -m venv --upgrade-deps /home/logs-afpy-org/venv/
changed_when: False
- name: pip install logs.afpy.org website
become: true
become_user: logs-afpy-org

View File

@ -32,6 +32,12 @@
- name: Copy AFPy theme
command: cp -a /home/makemake/themes/afpy /home/makemake/src/themes/
- name: Setup or upgrade venv
become: true
become_user: makemake
command: python3 -m venv --upgrade-deps /home/makemake/venv/
changed_when: False
- name: install makemake requirements
become: true
become_user: makemake

View File

@ -37,10 +37,10 @@
munin_extra_hosts: |
[hkis04.hackinscience.org]
address [2001:4b98:dc0:43:216:3eff:fe1e:a9f0]
[bot01.hackinscience.org]
address [2001:4b98:dc0:43:216:3eff:fe41:d21a]
[bot02.hackinscience.org]
address [2001:4b98:dc0:43:216:3eff:fea8:e01c]
[bot03.hackinscience.org]
address bot03.hackinscience.org
[bot04.hackinscience.org]
address bot04.hackinscience.org
roles:
- munin_server

18
pafpy.yml Normal file
View File

@ -0,0 +1,18 @@
---
- hosts: pastebins
vars:
pasteque_user: pafpy
pasteque_host: p.afpy.org
pasteque_display_name: PAFPy
pasteque_secret: !vault |
$ANSIBLE_VAULT;1.1;AES256
34633632386637336235333266343363643938333831366363383230353465393139663530343337
6166376138306132613931663237306538373763346665320a333763656230306236616161316433
35666533373639626536356439363662653930353666316466343966666163623066626365376532
6432633138306636620a316635333466626230613239393335383566336137316138393037653836
31363936353533323735663631613433323531643733383065313435306337363937613236396234
30376637346531643331356261643366313034393338653862343561393736366234643862326537
38326633633661653061626532666436646161616566353439623434623436666462336564346235
65366233626263316138
roles: [common, pasteque]

View File

@ -5,8 +5,6 @@
ponyconf_sites:
- domain: 'cfp-2023.pycon.fr'
authenticator: gandi
- domain: '2023.cfp.roscon.fr'
authenticator: nginx
ponyconf_user: ponyconf
ponyconf_home: "/home/{{ ponyconf_user }}"
ponyconf_imap_password: !vault |
@ -26,6 +24,9 @@
30386264356266373033383436383462333038656133363530313161646632353366393631393036
363439633164376438376431373935643634
tasks:
- name: Basic setup
include_role: name=common
- name: Install dependencies
apt:
state: present
@ -38,25 +39,25 @@
home: "{{ ponyconf_home }}"
system: true
- name: PonyConf nginx redirection
- name: cfp-2024 is now a pretalx instance
include_role: name=nginx
vars:
nginx_domain: "cfp.pycon.fr"
nginx_certificates: ["cfp.pycon.fr"]
nginx_domain: "cfp-2024.pycon.fr"
nginx_certificates: ["cfp-2024.pycon.fr"]
nginx_conf: |
server
{
listen [::]:80; listen 80;
server_name cfp.pycon.fr;
return 301 https://cfp-2023.pycon.fr$request_uri;
server_name cfp-2024.pycon.fr;
return 301 https://$host$request_uri;
}
server
{
listen [::]:443 ssl http2; listen 443 ssl http2;
server_name cfp.pycon.fr;
include snippets/letsencrypt-cfp.pycon.fr.conf;
return 301 https://cfp-2023.pycon.fr$request_uri;
server_name cfp-2024.pycon.fr;
include snippets/letsencrypt-cfp-2024.pycon.fr.conf;
return 301 https://cfp.pycon.fr$request_uri;
}
- name: PonyConf nginx config
@ -99,6 +100,12 @@
dest: "{{ ponyconf_home }}/src/"
notify: restart ponyconf
- name: Setup or upgrade venv
become: true
become_user: "{{ ponyconf_user }}"
command: python3 -m venv --upgrade-deps "{{ ponyconf_home }}/venv/"
changed_when: False
- name: Setup PonyConf venv
become: true
become_user: "{{ ponyconf_user }}"

85
pretalx.yml Normal file
View File

@ -0,0 +1,85 @@
---
- hosts: pretalx
become: true
tasks:
- name: Basic setup
include_role: name=common
- name: Update apt cache
apt:
update_cache: true
- name: Install dependencies
package:
name:
- acl
- cron
- nginx
- python3-pip
state: latest
- name: Remove nginx default site
file:
name: "/etc/nginx/sites-enabled/default"
state: absent
- name: Prepare Let's Encrypt configuration
file:
name: "/etc/nginx/snippets/letsencrypt-cfp.pycon.fr.conf"
state: touch
- hosts: pretalx
become: true
roles:
- anxs.postgresql
- pretalx
- nginx
vars:
nginx_owner: pretalx
nginx_domain: cfp.pycon.fr
nginx_certificates: [cfp.pycon.fr]
pretalx_domain: "cfp.pycon.fr"
pretalx_git_version: "v2024.1.0"
pretalx_admin_mail: "president@afpy.org"
pretalx_mail_from: "noreply@afpy.org"
pretalx_mail_host: "mail.gandi.net"
pretalx_mail_port: 465
pretalx_mail_tls: "False"
pretalx_mail_ssl: "True"
pretalx_mail_user: "cfp@pycon.fr"
pretalx_mail_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
66393662376362313833356630353764323934666561316337356531663761343239373663643137
3939306166383561396136303637653961613830636639310a396237393764396566313436663062
35326135326334613363353633623034613063326239663232663033646335363930333763326131
3731396233613339330a663330616134633937366136613932393361363434616433663765373063
30353439616663633734656230353736656633653532373665653237656263376536
postgresql_databases:
- name: "{{ pretalx_database_name }}"
owner: "{{ pretalx_database_user }}"
postgresql_users:
- name: "{{ pretalx_database_user }}"
pass: "{{ pretalx_database_password }}"
postgresql_locale: "C.UTF-8"
postgresql_ctype: "C.UTF-8"
pretalx_database_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
31336432383663353535613030653335333439633131663464623062386261626562613736333863
3334633665363363663536663532613066396434623265610a613031396434393837616461616265
38653530333030323636633235326366313632663939363234643736376164333137643930326538
3232626539333630390a663137393538333861313964323836646664363338373638633835633835
36303735303665643231666133333839313865376466616564373361653262353564303238343230
3130343830336162356531303862363963613336653630633830
pretalx_secret_key: !vault |
$ANSIBLE_VAULT;1.1;AES256
66343230623535386434396234623361366436393732626139356539336261636437373130303937
3465346362306435303964653364373137333664646363310a373639616539343561616261663863
66633438376366336265653965336264636562376538386430326265633863616238623338613735
3131663931386236630a366239653864323663323435623630376234653239373832623033613036
38616435383036623065333832383437326438613932363739636534383432306562306164643364
6662346530626638613532623962306662303232626266643861
pretalx_redis: "redis://127.0.0.1:6379/0"
pretalx_nginx: true
pretalx_nginx_path: "/etc/nginx/sites-enabled/"
pretalx_nginx_force_https: true
pretalx_nginx_http_only: false
pretalx_admin_email: "{{ vault_pretalx_admin_email }}"
pretalx_admin_password: "{{ vault_pretalx_admin_password }}"
pretalx_orga_name: "AFPy"
pretalx_orga_slug: "afpy"

View File

@ -10,6 +10,7 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINbgxOufHY7SxQrJNTlHmye+xeNHBA1O5SGtGhGeOVZM
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIvF5rwjx5lpjzH6B4Uce9kZhz260kkwzYvIieR189Q1
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFRY4/MaxUs8+mTrCKCXpHiXdrTjpNK9MqIpSpdLtxST pyconfr-2023
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMcZWATyNJmSIejI/yugxAdtvif3aK5jc518NAiK0nEo pyconfr-2024
tasks:
- name: Basic setup
include_role: name=common
@ -45,7 +46,7 @@
root /var/www/pycon.fr/;
charset utf-8;
location = / {
return 302 https://www.pycon.fr/2023$request_uri;
return 302 https://www.pycon.fr/2024$request_uri;
}
location ~ ^/2021 {
return 301 https://www.pycon.fr/2023/;
@ -54,7 +55,13 @@
return 301 https://www.pycon.fr/2023/;
}
location ~ ^/2023/ {
add_header Content-Security-Policy "default-src 'none'; frame-ancestors 'self'; form-action 'none'; base-uri 'none'; frame-src 'self' https://framacarte.org; font-src 'self'; img-src 'self' https://openstreetmap.fr; script-src 'self' https://framasoft.org https://framacarte.org; style-src 'self'";
add_header Content-Security-Policy "default-src 'none'; object-src 'self'; frame-ancestors 'self'; form-action 'none'; base-uri 'none'; frame-src 'self' https://framacarte.org; font-src 'self'; img-src 'self' https://openstreetmap.fr; script-src 'self' 'unsafe-inline' https://framasoft.org https://framacarte.org; style-src 'self' 'unsafe-inline'";
add_header Strict-Transport-Security "max-age=63072000";
add_header X-Content-Type-Options "nosniff";
}
location ~ ^/2024/ {
add_header Content-Security-Policy "default-src 'none'; object-src 'self'; frame-ancestors 'self'; form-action 'none'; base-uri 'none'; frame-src 'self' https://framacarte.org; font-src 'self'; img-src 'self' https://openstreetmap.fr; script-src 'self' 'unsafe-inline' https://framasoft.org https://framacarte.org; style-src 'self' 'unsafe-inline'";
add_header Content-Security-Policy-Report-Only "default-src 'none'; object-src 'self'; frame-ancestors 'self'; form-action 'none'; base-uri 'none'; frame-src 'self' https://framacarte.org; font-src 'self'; img-src 'self' https://openstreetmap.fr; script-src 'self' https://framasoft.org https://framacarte.org; style-src 'self'";
add_header Strict-Transport-Security "max-age=63072000";
add_header X-Content-Type-Options "nosniff";
}

View File

@ -1,3 +1,4 @@
---
nft_extra: ""
nft_deny_list: ""

View File

@ -4,20 +4,31 @@
hostname:
name: "{{ inventory_hostname_short }}"
- name: Configure localhots
- name: Configure localhost
lineinfile:
path: /etc/hosts
regexp: '^127\.0\.0\.1'
line: "127.0.0.1 localhost"
owner: root
group: root
mode: 0644
- name: Configure FQDN
lineinfile:
path: /etc/hosts
regexp: '^127\.0\.1\.1'
line: "127.0.1.1 {{ inventory_hostname }} {{ inventory_hostname_short }}"
- name: Check if cloud-init is installed
ansible.builtin.stat:
path: /etc/cloud/cloud.cfg.d/
register: cloud_cfg
- name: Stop cloud-init to change hostname and /etc/hosts
when: cloud_cfg.stat.isdir is defined and cloud_cfg.stat.isdir
copy:
content: |
# Managed by Ansible
preserve_hostname: true
manage_etc_hosts: false
dest: /etc/cloud/cloud.cfg.d/02_ansible.cfg
owner: root
group: root
mode: 0644
@ -39,6 +50,7 @@
flush table inet filter
define V4_NEIGHBORS = {
127.0.0.1,
{% for host in groups["all"] %}
{% if hostvars[host]['ansible_facts']['default_ipv4'] %}
{{ hostvars[host]['ansible_facts']['default_ipv4']['address'] }}, # {{ hostvars[host]['ansible_facts']['nodename'] }}
@ -47,6 +59,7 @@
}
define V6_NEIGHBORS = {
::1,
{% for host in groups["all"] %}
{% if hostvars[host]['ansible_facts']['default_ipv6'] %}
{{ hostvars[host]['ansible_facts']['default_ipv6']['address'] }}, # {{ hostvars[host]['ansible_facts']['nodename'] }}
@ -61,6 +74,7 @@
ct state established,related accept
icmp type echo-request counter accept
icmpv6 type echo-request counter accept
{{ nft_deny_list }}
ip saddr $V4_NEIGHBORS accept
ip6 saddr $V6_NEIGHBORS accept
@ -80,13 +94,10 @@
- service: name=nftables enabled=yes state=started daemon_reload=yes
- name: Update via apt (mandatory on first run)
apt:
update_cache: yes
cache_valid_time: 86400
- name: Install some usefull packages
apt:
update_cache: yes
cache_valid_time: 3600
state: present
name:
- aptitude
@ -97,7 +108,6 @@
- man
- ncdu
- needrestart
- ntp
- python3
- python3-dev
- python3-pip
@ -117,6 +127,7 @@
mode: 0600
owner: root
group: root
create: yes
marker: "# {mark} ANSIBLE MANAGED BLOCK (SSH keys for root user)"
- name: Ensure mlocate and locate are not installed

View File

@ -6,7 +6,7 @@
##
## After making changes to this file, you MUST rebuild
## /var/discourse/launcher rebuild app
## Rebuild WILL cause ~10mn of downtime.
## Rebuild WILL cause ~13mn of downtime.
##
## visit http://www.yamllint.com/ to validate this file as needed
@ -54,6 +54,7 @@ hooks:
- git clone https://github.com/discourse/docker_manager.git
- git clone https://github.com/discourse/discourse-calendar.git
- git clone https://github.com/discourse/discourse-solved.git
- git clone https://github.com/discourse/discourse-data-explorer.git
## Any custom commands to run after building
run:

View File

@ -1,5 +1,5 @@
---
exim4_sendonly_fqdn: '{{ ansible_fqdn }}'
exim4_sendonly_fqdn: '{{ inventory_hostname }}'
exim4_sendonly_smarthost: ''
exim4_sendonly_username: ''

View File

@ -82,4 +82,14 @@
group: root
mode: 0644
notify: reload exim4
register: config_exim
# 2024: We can't use IPv6 to send email because Gandi don't provide us
# with a /64. See https://slash64.net/.
- name: Configure exim to avoid IPv6
copy:
dest: /etc/exim4/conf.d/main/90_disable_ipv6
content: 'disable_ipv6 = true'
owner: root
group: root
mode: 0644
notify: reload exim4

View File

@ -28,4 +28,3 @@ dc_use_split_config='true'
dc_hide_mailname='true'
dc_mailname_in_oh='true'
dc_localdelivery='mail_spool'
disable_ipv6='true'

View File

@ -28,7 +28,8 @@
Qui peut utiliser cette forge ?
</h1>
<p class="large">
Tout le monde !
Tout le monde !<br/>
Mais uniquement des projets sous <a href="https://www.afpy.org/docs/cgu#licence-libre">licences libres</a>.
</p>
</div>
</div>
@ -45,13 +46,14 @@
<div class="eight wide center column">
<h1 class="hero ui icon header">
<svg viewBox="0 0 16 16" class="svg octicon-code" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M4.72 3.22a.75.75 0 0 1 1.06 1.06L2.06 8l3.72 3.72a.75.75 0 1 1-1.06 1.06L.47 8.53a.75.75 0 0 1 0-1.06l4.25-4.25zm6.56 0a.75.75 0 1 0-1.06 1.06L13.94 8l-3.72 3.72a.75.75 0 1 0 1.06 1.06l4.25-4.25a.75.75 0 0 0 0-1.06l-4.25-4.25z"></path></svg>
On peut y stocker n'importe quel projet ?
Et vous avez de la CI ?
</h1>
<p class="large">
Uniquement des projets sous licences libres.
Oui !! C'est un <a href="https://woodpecker.afpy.org">Woodpecker</a> hébergé par <a href="https://gandi.net">Gandi</a>. Les agents sont hébergés par <a href="https://gentilsnuages.fr">Gentils Nuages</a> à Lyon et <a href="https://mdk.fr">mdk</a> à Carrières-sur-Seine.
</p>
</div>
</div>
<br/><br/><hr/><br/>
<div class=center>
<h2>Les fingerprints du serveur sont:</h2>
<pre style="text-align: left">

View File

@ -52,7 +52,7 @@
Description=Daily gitea backup
[Timer]
OnCalendar=*-*-* 03:00:00
OnCalendar=*-*-* 05:42:00
- name: Start backup timer
service: name=gitea-backup.timer state=started daemon_reload=yes

View File

@ -39,7 +39,7 @@
- name: favicon
copy:
src: icon.svg
dest: /var/lib/gitea/custom/public/img/favicon.svg
dest: /var/lib/gitea/custom/public/assets/img/favicon.svg
owner: root
group: root
mode: 0644
@ -48,7 +48,7 @@
- name: logo
copy:
src: icon.svg
dest: /var/lib/gitea/custom/public/img/logo.svg
dest: /var/lib/gitea/custom/public/assets/img/logo.svg
owner: root
group: root
mode: 0644

View File

@ -130,6 +130,10 @@
include snippets/letsencrypt-git.afpy.org.conf;
client_max_body_size 16M;
add_header Content-Security-Policy-Report-Only "default-src 'self'; connect-src 'self'; font-src 'self' data:; form-action 'self'; img-src 'self' https: data:; manifest-src 'self' data:; object-src 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; worker-src 'self'";
# See add_header Content-Security-Policy-Report-Only "
add_header X-Content-Type-Options "nosniff";
# location /_/static/assets/ {
# alias /var/lib/gitea-static/public/;
# }

View File

@ -1,58 +1,61 @@
APP_NAME = Le Gitea de l'AFPy
RUN_USER = git
RUN_MODE = prod
WORK_PATH = /var/lib/gitea
[ui]
SHOW_USER_EMAIL = false
[database]
DB_TYPE = postgres
HOST = /run/postgresql/
NAME = gitea
USER =
PASSWD =
SCHEMA =
DB_TYPE = postgres
HOST = /run/postgresql/
NAME = gitea
USER =
PASSWD =
SCHEMA =
SSL_MODE = disable
CHARSET = utf8
PATH = /var/lib/gitea/data/gitea.db
LOG_SQL = false
CHARSET = utf8
PATH = /var/lib/gitea/data/gitea.db
LOG_SQL = false
[repository]
ROOT = /var/lib/gitea/data/gitea-repositories
DEFAULT_PRIVATE = public
DEFAULT_PUSH_CREATE_PRIVATE = false
ENABLE_PUSH_CREATE_USER = true
ENABLE_PUSH_CREATE_ORG = true
[server]
SSH_DOMAIN = git.afpy.org
DOMAIN = git.afpy.org
HTTP_PORT = 3000
ROOT_URL = https://git.afpy.org/
OFFLINE_MODE = true
DISABLE_SSH = false
SSH_PORT = 22
SSH_DOMAIN = git.afpy.org
DOMAIN = git.afpy.org
HTTP_PORT = 3000
ROOT_URL = https://git.afpy.org/
OFFLINE_MODE = true
DISABLE_SSH = false
SSH_PORT = 22
LFS_START_SERVER = false
OFFLINE_MODE = false
[mailer]
ENABLED = true
FROM = gitea@afpy.org
MAILER_TYPE = sendmail
ENABLED = true
FROM = gitea@afpy.org
PROTOCOL = sendmail
SENDMAIL_PATH = /usr/sbin/sendmail
SENDMAIL_ARGS = "--"
SENDMAIL_ARGS = --
[service]
REGISTER_EMAIL_CONFIRM = true
ENABLE_NOTIFY_MAIL = true
DISABLE_REGISTRATION = false
ALLOW_ONLY_EXTERNAL_REGISTRATION = false
ENABLE_CAPTCHA = false
REQUIRE_SIGNIN_VIEW = false
DEFAULT_KEEP_EMAIL_PRIVATE = false
REGISTER_EMAIL_CONFIRM = true
ENABLE_NOTIFY_MAIL = true
DISABLE_REGISTRATION = false
ALLOW_ONLY_EXTERNAL_REGISTRATION = false
ENABLE_CAPTCHA = true
REQUIRE_SIGNIN_VIEW = false
DEFAULT_KEEP_EMAIL_PRIVATE = false
DEFAULT_ALLOW_CREATE_ORGANIZATION = true
DEFAULT_ENABLE_TIMETRACKING = true
NO_REPLY_ADDRESS = noreply.localhost
DEFAULT_ENABLE_TIMETRACKING = true
NO_REPLY_ADDRESS = noreply.localhost
[picture]
DISABLE_GRAVATAR = true
DISABLE_GRAVATAR = true
ENABLE_FEDERATED_AVATAR = true
[openid]
@ -64,36 +67,29 @@ PROVIDER = db
COOKIE_SECURE = true
[log]
MODE = console
LEVEL = info
MODE = console
LEVEL = info
ROOT_PATH = /var/lib/gitea/log
ROUTER = console
# [i18n]
# see https://github.com/go-gitea/gitea/issues/21199
# LANGS = fr_FR,en_US
# NAMES = Français,English
[packages]
ENABLED: true
LIMIT_TOTAL_OWNER_SIZE: 200 MB
LIMIT_SIZE_COMPOSER: 0
LIMIT_SIZE_CONAN: 0
LIMIT_SIZE_CONTAINER: 0
LIMIT_SIZE_GENERIC: 0
LIMIT_SIZE_HELM: 0
LIMIT_SIZE_MAVEN: 0
LIMIT_SIZE_NPM: 0
LIMIT_SIZE_NUGET: 0
LIMIT_SIZE_PUB: 0
LIMIT_SIZE_PYPI: 200 MB
LIMIT_SIZE_RUBYGEMS: 0
LIMIT_SIZE_VAGRANT: 0
[repository]
DEFAULT_PUSH_CREATE_PRIVATE = false
ENABLE_PUSH_CREATE_USER = true
ENABLE_PUSH_CREATE_ORG = true
ENABLED = true
LIMIT_TOTAL_OWNER_SIZE = 200 MB
LIMIT_SIZE_COMPOSER = 0
LIMIT_SIZE_CONAN = 0
LIMIT_SIZE_CONTAINER = 0
LIMIT_SIZE_GENERIC = 0
LIMIT_SIZE_HELM = 0
LIMIT_SIZE_MAVEN = 0
LIMIT_SIZE_NPM = 0
LIMIT_SIZE_NUGET = 0
LIMIT_SIZE_PUB = 0
LIMIT_SIZE_PYPI = 200 MB
LIMIT_SIZE_RUBYGEMS = 0
LIMIT_SIZE_VAGRANT = 0
[repository.pull-request]
DEFAULT_MERGE_STYLE = merge
@ -102,18 +98,16 @@ DEFAULT_MERGE_STYLE = merge
DEFAULT_TRUST_MODEL = committer
[security]
INSTALL_LOCK = true
INTERNAL_TOKEN = {{ gitea_internal_token }}
INSTALL_LOCK = true
INTERNAL_TOKEN = {{ gitea_internal_token }}
PASSWORD_HASH_ALGO = pbkdf2
LOGIN_REMEMBER_DAYS = 90
[markup.restructuredtext]
ENABLED = true
FILE_EXTENSIONS = .rst
RENDER_COMMAND = "timeout 30s pandoc +RTS -M512M -RTS -f rst"
RENDER_COMMAND = timeout 30s pandoc +RTS -M512M -RTS -f rst
IS_INPUT_FILE = false
[ssh.minimum_key_sizes]
ED25519 = 256
ECDSA = 256
RSA = 1023
[oauth2]
JWT_SECRET = {{ gitea_oauth2_jwt_secret }}

View File

@ -48,12 +48,15 @@
dest: /etc/munin/plugins/apt_all
state: link
notify: munin
when: ansible_facts["distribution"] == "Debian" and ansible_facts["distribution_release"] == "bullseye"
- name: Remove native munin apt update
# It is no longer supported
# and raises errors.
# The doc tells to use APT::Periodic::Update-Package-Lists "1"; instead.
ansible.builtin.lineinfile:
path: /etc/cron.d/munin-node
# It does not work on Ubuntu, it's giving:
# E: The value 'stable' is invalid for APT::Default-Release as such a release is not available in the sources
# E: The value 'testing' is invalid for APT::Default-Release as such a release is not available in the sources
# E: The value 'unstable' is invalid for APT::Default-Release as such a release is not available in the sources
file:
path: /etc/munin/plugins/apt_all
state: absent
regexp: '/etc/munin/plugins/apt_all update'
notify: munin
when: not(ansible_facts["distribution"] == "Debian" and ansible_facts["distribution_release"] == "bullseye")

View File

@ -1,7 +1,7 @@
---
certbot_authenticator: gandi
nginx_extra: ''
nginx_conf: |
server
{
@ -17,7 +17,7 @@ nginx_conf: |
charset utf-8;
server_name {{ nginx_domain }};
include snippets/letsencrypt-{{ nginx_domain }}.conf;
root {{ nginx_path }};
index index.html;
{{ nginx_extra }}
}

View File

@ -6,6 +6,10 @@
dest: /etc/ssl/certs/dhparam.pem
mode: 0644
- name: Setup or upgrade venv
command: python3 -m venv --upgrade-deps /root/certbot-venv/
changed_when: False
- name: Prepare certbot+gandi venv
pip:
chdir: /root/
@ -25,6 +29,7 @@
- "certbot<2" # See https://github.com/certbot/certbot/issues/9485
- "acme<2" # See https://github.com/certbot/certbot/issues/9485
- "certbot-plugin-gandi"
- "certbot-nginx" # In case there's a "certbot_authenticator == 'nginx'"
- name: Setup Gandi credentials
copy:
@ -42,7 +47,7 @@
when: certbot_authenticator == 'gandi'
- name: Generate TLS certificates via nginx
command: /root/certbot-venv/bin/certbot certonly --nginx --cert-name {{ nginx_domain | quote }} -n --agree-tos -d {{ nginx_certificates | join(",") | quote }} -m {{ admin_email | quote }}
command: /root/certbot-venv/bin/certbot certonly --nginx --nginx-sleep-seconds 10 --cert-name {{ nginx_domain | quote }} -n --agree-tos -d {{ nginx_certificates | join(",") | quote }} -m {{ admin_email | quote }}
register: certbot
changed_when: '"no action taken." not in certbot.stdout'
when: certbot_authenticator == 'nginx'
@ -122,6 +127,7 @@
copy:
content: "{{ nginx_conf }}"
dest: "/etc/nginx/conf.d/{{ nginx_domain }}.conf"
when: nginx_conf is defined and nginx_domain is defined
notify: reload nginx
- name: WWW directory

View File

@ -0,0 +1,7 @@
---
- name: reload nginx
service: name=nginx state=reloaded
- name: restart pasteque
service: name=pasteque state=restarted

View File

@ -0,0 +1,141 @@
---
- name: Setup nginx
include_role: name=nginx
vars:
nginx_owner: "{{ pasteque_user }}"
nginx_domain: "{{ pasteque_host }}"
nginx_certificates: ["{{ pasteque_host }}"]
nginx_conf: |
server
{
listen [::]:80; listen 80;
server_name {{ pasteque_host }};
return 301 https://$host$request_uri;
}
server
{
listen [::]:443 ssl http2; listen 443 ssl http2;
server_name {{ pasteque_host }};
include snippets/letsencrypt-{{ pasteque_host }}.conf;
add_header Content-Security-Policy "default-src 'self'";
add_header X-Frame-Options DENY;
add_header X-XSS-Protection "1; mode=block";
charset utf-8;
location /::/static
{
alias /home/{{ pasteque_user }}/static/;
expires 30d;
}
location /
{
proxy_pass http://unix:/run/{{ pasteque_user }}/pasteque.sock;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
- name: Clone pasteque
become: true
become_user: "{{ pasteque_user }}"
notify: restart pasteque
git:
repo: https://git.afpy.org/AFPy/pasteque
dest: "/home/{{ pasteque_user }}/src/"
update: yes
- name: Setup or upgrade venv
become: true
become_user: "{{ pasteque_user }}"
command: python3 -m venv --upgrade-deps "/home/{{ pasteque_user }}/venv"
changed_when: False
- name: Install gunicorn in venv
become: true
become_user: "{{ pasteque_user }}"
pip:
name: gunicorn
virtualenv_command: "/usr/bin/python3 -m venv"
virtualenv: "/home/{{ pasteque_user }}/venv/"
- name: Install dependencies in venv
become: true
become_user: "{{ pasteque_user }}"
notify: restart pasteque
pip:
requirements: "/home/{{ pasteque_user }}/src/requirements.txt"
virtualenv_command: "/usr/bin/python3 -m venv"
virtualenv: "/home/{{ pasteque_user }}/venv/"
- name: Create static/ directory
file:
path: /home/{{ pasteque_user }}/static/
state: directory
owner: "{{ pasteque_user }}"
group: "{{ pasteque_user }}"
mode: 0755
- name: Configure Pasteque
notify: restart pasteque
copy:
dest: "/home/{{ pasteque_user }}/src/local_settings.py"
content: |
DISPLAY_NAME = '{{ pasteque_display_name }}'
SECRET_KEY = '{{ pasteque_secret }}'
ALLOWED_HOSTS = ['{{ pasteque_host }}']
TIME_ZONE = 'Europe/Paris'
LANGUAGE_CODE = 'en-US'
DEBUG = False
COMPRESS_ENABLED = False
STATIC_ROOT = "/home/{{ pasteque_user }}/static/"
ADMINS = (("mdk", "julien+pafpy@palard.fr"),)
- name: Migrate db
become: true
become_user: "{{ pasteque_user }}"
notify: restart pasteque
command: "/home/{{ pasteque_user }}/venv/bin/python manage.py migrate"
args:
chdir: "/home/{{ pasteque_user }}/src"
register: migrate_result
changed_when: '" Applying " in migrate_result.stdout'
- name: Collectstatic
become: true
become_user: "{{ pasteque_user }}"
notify: restart pasteque
command: "/home/{{ pasteque_user }}/venv/bin/python manage.py collectstatic --noinput"
args:
chdir: "/home/{{ pasteque_user }}/src"
register: collectstatic_result
changed_when: '"Copying " in collectstatic_result.stdout'
- name: Configure systemd
notify: restart pasteque
copy:
dest: /etc/systemd/system/pasteque.service
content: |
[Unit]
Description=Le pastebin de l'AFPy
After=network.target
[Service]
User={{ pasteque_user }}
Group={{ pasteque_user }}
RuntimeDirectory={{ pasteque_user }}
WorkingDirectory=/home/{{ pasteque_user }}//src/
ExecStart=/home/{{ pasteque_user }}/venv/bin/gunicorn -t 120 -w 1 --bind unix:/run/{{ pasteque_user }}/pasteque.sock webtools.wsgi
[Install]
WantedBy=multi-user.target
- name: Start pasteque
service: name=pasteque enabled=yes state=started daemon_reload=yes

View File

View File

@ -0,0 +1,7 @@
skip_list:
- fqcn[action]
- fqcn[action-core]
- yaml[line-length]
exclude_paths:
- .github

View File

@ -0,0 +1,66 @@
---
# Use if you have more than one instance on your server, for example for
# seamless updates (sharing a database) or separate instances.
pretalx_instance_identifier: "main"
pretalx_system_user: "pretalx"
pretalx_system_home: "/home/{{ pretalx_system_user }}"
pretalx_database_backend: postgresql
pretalx_database_name: pretalx_{{ pretalx_instance_identifier }}
pretalx_database_user: pretalx_{{ pretalx_instance_identifier }}
pretalx_database_password: false
pretalx_database_host: localhost
pretalx_database_port: 5432
pretalx_staticfiles_directory: "{{ pretalx_system_home }}/pretalx_{{ pretalx_instance_identifier }}/static"
pretalx_data_dir: "{{ pretalx_system_home }}/pretalx_{{ pretalx_instance_identifier }}/data"
pretalx_media_dir: "{{ pretalx_system_home }}/pretalx_{{ pretalx_instance_identifier }}/media"
pretalx_virtualenv: "{{ pretalx_system_home }}/pretalx_{{ pretalx_instance_identifier }}/venv"
pretalx_python: "{{ pretalx_virtualenv }}/bin/python"
pretalx_webserver_group: www-data
pretalx_domain: localhost
pretalx_url: https://{{ pretalx_domain }}
pretalx_core_modules: ""
pretalx_admin_mail: ""
pretalx_mail_from: admin@localhost
pretalx_mail_host: localhost
pretalx_mail_port: 25
pretalx_mail_tls: "False"
pretalx_mail_ssl: "True"
pretalx_mail_user: None # if set to None do not use authentication
pretalx_mail_password: None
pretalx_service_workers: 4 # https://docs.gunicorn.org/en/stable/settings.html?highlight=max-requests#workers
pretalx_service_workers_max_requests: 1200 # https://docs.gunicorn.org/en/stable/settings.html?highlight=max-requests#max-requests
pretalx_service_workers_max_requests_jitter: 50 # https://docs.gunicorn.org/en/stable/settings.html?highlight=max-requests#max-requests-jitter
pretalx_nginx: false
pretalx_nginx_path: false
pretalx_nginx_force_https: false # Set to true if you want this role to take care of HTTPS upgrades, leave false if your nginx configuration handles this already
pretalx_cert_root: /etc/ssl/letsencrypt/certs # for Nginx configuration
pretalx_nginx_http_only: false
pretalx_redis: false
pretalx_celery: true
pretalx_celery_backend: "redis://127.0.0.1:6379/1"
pretalx_celery_broker: "redis://127.0.0.1:6379/2"
pretalx_version: latest
pretalx_git_version: ""
pretalx_git_url: "https://github.com/pretalx/pretalx.git"
pretalx_plugins: null
pretalx_cron: true
pretalx_alternate_domains: null # can be a string like "location1 location2"
pretalx_additional_config: null # string that will be appended to the cfg file without further modifications
pretalx_admin_email: ""
pretalx_admin_password: ""
pretalx_orga_name: ""
pretalx_orga_slug: ""

View File

@ -0,0 +1,86 @@
---
- name: Reload systemd services
systemd:
daemon_reload: true
- name: Install pretalx plugins
shell: cd {{ pretalx_system_home }}/plugins/{{ item.name }} && {{ pretalx_python }} setup.py develop --user
with_items: "{{ pretalx_plugins }}"
become: true
become_user: "{{ pretalx_system_user }}"
changed_when: true
- name: Run pretalx migrations
command: "{{ pretalx_python }} -m pretalx migrate"
become: true
become_user: "{{ pretalx_system_user }}"
changed_when: true
- name: Run pretalx static collection
command: "{{ pretalx_python }} -m pretalx collectstatic --noinput"
become: true
become_user: "{{ pretalx_system_user }}"
changed_when: true
- name: Compile pretalx styles
command: "{{ pretalx_python }} -m pretalx regenerate_css"
become: true
become_user: "{{ pretalx_system_user }}"
changed_when: true
- name: Copy static manifest
shell: "cp -f {{ pretalx_staticfiles_directory }}/staticfiles.json {{ pretalx_staticfiles_directory }}/pretalx-manifest.json"
become: true
become_user: "{{ pretalx_system_user }}"
changed_when: true
- name: Compile messages for plugins
shell: cd {{ pretalx_system_home }}/plugins/{{ item.name }} && make
with_items: "{{ pretalx_plugins }}"
become: true
become_user: "{{ pretalx_system_user }}"
changed_when: true
- name: Rebuild pretalx files
command: "{{ pretalx_python }} -m pretalx rebuild --npm-install"
become: true
become_user: "{{ pretalx_system_user }}"
changed_when: true
- name: Initialize pretalx
command: "{{ pretalx_python }} -m pretalx init --noinput"
become: true
become_user: "{{ pretalx_system_user }}"
changed_when: true
environment:
- DJANGO_SUPERUSER_EMAIL: "{{ pretalx_admin_email }}"
- DJANGO_SUPERUSER_PASSWORD: "{{ pretalx_admin_password }}"
- PRETALX_INIT_ORGANISER_NAME: "{{ pretalx_orga_name }}"
- PRETALX_INIT_ORGANISER_SLUG: "{{ pretalx_orga_slug }}"
- name: Restart pretalx service
service:
name: pretalx@{{ pretalx_instance_identifier }}
state: restarted
- name: Restart worker service
service:
name: pretalx-worker@{{ pretalx_instance_identifier }}
state: restarted
when: pretalx_celery
- name: Restart redis
service:
name: redis
state: restarted
when: pretalx_redis
- name: Reload nginx
service:
name: nginx
state: reloaded
- name: Restart pretalx socket
service:
name: pretalx@{{ pretalx_instance_identifier }}.socket
state: restarted

View File

@ -0,0 +1,22 @@
---
- name: Install system requirements
import_tasks: requirements.yml
- name: Detect installed system Python version
command: |
python3 -c "import sys; (major, minor) = sys.version_info[0:2]; print(f'{major}.{minor}')"
args:
creates: nothing
changed_when: false
# become: true
# become_user: "{{ pretalx_system_user }}"
when: pretalx_system_python_version is not defined
register: pretalx_python_version_info_major_minor
- name: Define installed system Python version variable
set_fact:
pretalx_system_python_version: "{{ pretalx_python_version_info_major_minor.stdout }}"
when: pretalx_system_python_version is not defined
- name: Install pretalx itself
import_tasks: package.yml

View File

@ -0,0 +1,269 @@
---
- name: Create a pretalx user
user:
name: "{{ pretalx_system_user }}"
state: present
system: true
tags:
- pretalx
- name: Create required directories
file:
path: "{{ item }}"
state: directory
owner: "{{ pretalx_system_user }}"
group: "{{ pretalx_webserver_group }}"
mode: "0750"
recurse: true
with_items:
- "{{ pretalx_staticfiles_directory }}"
- "{{ pretalx_data_dir }}"
- "{{ pretalx_media_dir }}"
- "{{ pretalx_virtualenv }}"
tags:
- pretalx
- name: Install redis client
pip:
name: django_redis
state: latest # noqa package-latest
virtualenv: "{{ pretalx_virtualenv }}"
become: true
become_user: "{{ pretalx_system_user }}"
when: pretalx_redis or pretalx_celery
tags:
- pretalx
- pretalx-install
- name: Install gunicorn
pip:
name: gunicorn
state: latest # noqa package-latest
virtualenv: "{{ pretalx_virtualenv }}"
become: true
become_user: "{{ pretalx_system_user }}"
tags:
- pretalx
- pretalx-install
- name: Configure pretalx
template:
src: pretalx.cfg.j2
dest: "{{ pretalx_system_home }}/.pretalx.cfg"
mode: "0600"
notify:
- Restart pretalx service
- Restart worker service
- Run pretalx migrations
- Rebuild pretalx files
- Compile pretalx styles
become: true
become_user: "{{ pretalx_system_user }}"
tags:
- pretalx
- pretalxupdate
- name: Set pretalx_extra to "[postgres]" if using postgresql database
set_fact:
pretalx_extra: "[postgres]"
when: pretalx_database_backend == 'postgresql'
tags:
- pretalx
- pretalxupdate
- name: Set pretalx_extra to "[mysql]" if using mysql database
set_fact:
pretalx_extra: "[mysql]"
when: pretalx_database_backend == 'mysql'
tags:
- pretalx
- pretalxupdate
- name: Set pretalx_extra to "" if using other database
set_fact:
pretalx_extra: ""
when: pretalx_extra is not defined
tags:
- pretalx
- pretalxupdate
- name: Install pretalx (latest)
pip:
name: "pretalx{{ pretalx_extra }}"
state: latest # noqa package-latest
virtualenv: "{{ pretalx_virtualenv }}"
notify:
- Restart pretalx service
- Restart worker service
- Run pretalx migrations
- Run pretalx static collection
- Copy static manifest
- Rebuild pretalx files
- Compile pretalx styles
- Initialize pretalx
when: (pretalx_version == 'latest') and not (pretalx_git_version)
become: true
become_user: "{{ pretalx_system_user }}"
tags:
- pretalx
- pretalxupdate
- name: Install pretalx (versioned)
pip:
name: "pretalx{{ pretalx_extra }}"
version: "{{ pretalx_version }}" # noqa package-lastest
virtualenv: "{{ pretalx_virtualenv }}"
notify:
- Restart pretalx service
- Restart worker service
- Run pretalx migrations
- Run pretalx static collection
- Copy static manifest
- Rebuild pretalx files
- Compile pretalx styles
- Initialize pretalx
when: (pretalx_version != 'latest') and not pretalx_git_version
become: true
become_user: "{{ pretalx_system_user }}"
tags:
- pretalx
- pretalxupdate
- name: Install pretalx (git)
pip:
name: "git+{{ pretalx_git_url }}@{{ pretalx_git_version }}#egg=pretalx{{ pretalx_extra }}"
state: forcereinstall
virtualenv: "{{ pretalx_virtualenv }}"
notify:
- Restart pretalx service
- Restart worker service
- Run pretalx migrations
- Run pretalx static collection
- Copy static manifest
- Rebuild pretalx files
- Compile pretalx styles
- Initialize pretalx
when: pretalx_git_version | length > 0
become: true
become_user: "{{ pretalx_system_user }}"
changed_when: true
tags:
- pretalx
- pretalxupdate
- name: Make sure plugin directory exists
file:
path: "{{ pretalx_system_home }}/plugins"
state: directory
owner: "{{ pretalx_system_user }}"
recurse: true
when: pretalx_plugins
tags:
- pretalx
- name: Install pretalx plugins
git:
repo: "{{ item.repository }}"
dest: "{{ pretalx_system_home }}/plugins/{{ item.name }}"
version: "{{ item.version if item.version is defined else 'main' }}"
key_file: "{{ pretalx_system_home }}/.ssh/id_rsa"
accept_hostkey: true
become: true
become_user: "{{ pretalx_system_user }}"
with_items: "{{ pretalx_plugins }}"
when: pretalx_plugins
notify:
- Restart pretalx service
- Restart worker service
- Run pretalx migrations
- Run pretalx static collection
- Copy static manifest
- Rebuild pretalx files
- Compile pretalx styles
- Install pretalx plugins
tags:
- pretalx
- pretalxupdate
- name: Install systemd socket
template:
src: pretalx.socket.j2
dest: /etc/systemd/system/pretalx@{{ pretalx_instance_identifier }}.socket
mode: "0644"
notify:
- Reload systemd services
- Restart pretalx socket
tags:
- pretalx
- name: Install systemd service
template:
src: pretalx.service.j2
dest: /etc/systemd/system/pretalx@{{ pretalx_instance_identifier }}.service
mode: "0644"
notify:
- Reload systemd services
- Restart pretalx service
- Restart worker service
tags:
- pretalx
- name: Install worker service
template:
src: pretalx-worker.service.j2
dest: /etc/systemd/system/pretalx-worker@{{ pretalx_instance_identifier }}.service
mode: "0644"
notify:
- Reload systemd services
- Restart worker service
when: pretalx_celery
tags:
- pretalx
- name: Start pretalx socket
service:
name: pretalx@{{ pretalx_instance_identifier }}.socket
state: started
enabled: true
tags:
- pretalx
- name: Start systemd service
service:
name: pretalx@{{ pretalx_instance_identifier }}
state: started
enabled: true
tags:
- pretalx
- name: Start worker service
service:
name: pretalx-worker@{{ pretalx_instance_identifier }}
state: started
enabled: true
when: pretalx_celery
tags:
- pretalx
- name: Install nginx config
template:
src: nginx.conf
dest: "{{ pretalx_nginx_path }}/pretalx_{{ pretalx_instance_identifier }}.conf"
mode: "0644"
when: pretalx_nginx
notify:
- Reload nginx
tags:
- nginx
- pretalx
- pretalxnginx
- name: Install runperiodic cronjob
cron:
minute: "40"
name: Run pretalx{{ pretalx_instance_identifier }} periodic task
user: "{{ pretalx_system_user }}"
job: "{{ pretalx_python }} -m pretalx runperiodic"
when: pretalx_cron
tags:
- pretalx

View File

@ -0,0 +1,3 @@
---
- name: Install system requirements
include_tasks: requirements_{{ ansible_os_family | lower }}.yml

View File

@ -0,0 +1,43 @@
---
- name: Install dependencies
pacman:
name:
- python
- git
- npm
state: present
notify:
- Reload systemd services
tags:
- pretalx
- name: Install sqlite
pacman:
name:
- sqlite
state: present
notify:
- Reload systemd services
when: pretalx_database_backend != 'postgresql' and pretalx_database_backend != 'mysql'
tags:
- pretalx
- name: Install redis
pacman:
name:
- redis
state: present
notify:
- Restart redis
when: pretalx_redis
tags:
- pretalx
- name: Start and enable redis
service:
name: redis
state: started
enabled: true
when: pretalx_redis
tags:
- pretalx

View File

@ -0,0 +1,40 @@
---
- name: Install Python 3
apt:
name:
- python3
- python3-dev
- python3-wheel
- virtualenv
state: present
tags:
- pretalx
- name: Install other dependencies
apt:
name:
- gcc
- gettext
- git
- npm
state: present
tags:
- pretalx
- name: Install sqlite
apt:
name:
- sqlite3
state: present
when: pretalx_database_backend != 'postgresql' and pretalx_database_backend != 'mysql'
tags:
- pretalx
- name: Install redis
apt:
name:
- redis-server
state: present
when: pretalx_redis
tags:
- pretalx

View File

@ -0,0 +1,81 @@
upstream pretalx_{{ pretalx_instance_identifier }}_server {
server unix:/run/gunicorn/pretalx_{{ pretalx_instance_identifier }} fail_timeout=0;
}
proxy_cache_path /tmp/nginx-pretalx-{{ pretalx_instance_identifier }} levels=1:2 keys_zone=pretalx_static_{{ pretalx_instance_identifier }}:10m inactive=60m max_size=250m;
{% if pretalx_nginx_force_https and not pretalx_nginx_http_only %}
server {
listen 80;
listen [::]:80;
server_name {{ pretalx_domain }}{% if pretalx_alternate_domains %} {{ pretalx_alternate_domains }}{% endif %};
return 301 https://$host$request_uri;
}
{% endif %}
{% if pretalx_nginx_http_only %}
server {
listen 80;
listen [::]:80;
server_name {{ pretalx_domain }}{% if pretalx_alternate_domains %} {{ pretalx_alternate_domains }}{% endif %};
{% else %}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name {{ pretalx_domain }}{% if pretalx_alternate_domains %} {{ pretalx_alternate_domains }}{% endif %};
# ssl on;
# ssl_certificate {{ pretalx_cert_root }}/{{ pretalx_domain }}/fullchain.pem;
# ssl_certificate_key {{ pretalx_cert_root }}/{{ pretalx_domain }}/privkey.pem;
# proxy_set_header X-Forwarded-Proto https;
include snippets/letsencrypt-{{ pretalx_domain }}.conf;
{% endif %}
access_log /var/log/nginx/pretalx_{{ pretalx_instance_identifier }}.access.log;
error_log /var/log/nginx/pretalx_{{ pretalx_instance_identifier }}.error.log;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# If you decide to turn gzip on, turn it off explicitly for ~ (*.)/schedule/export/(*.)
# or your export pages won't show their (working, existing) etags.
# You'd think that gzip_proxied no_etag; would work. It doesn't.
gzip off;
location /static/ {
access_log off;
alias {{ pretalx_staticfiles_directory }}/;
}
location /static/CACHE/ {
gzip on;
expires 30d;
add_header Cache-Control public;
add_header Pragma public;
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
proxy_cache pretalx_static_{{ pretalx_instance_identifier }};
proxy_ignore_headers Cache-Control;
proxy_cache_valid any 60m;
add_header X-Proxy-Cache $upstream_cache_status;
alias {{ pretalx_staticfiles_directory }}/CACHE/;
}
location /media/ {
gzip on;
alias {{ pretalx_media_dir }}/;
add_header Content-Disposition 'attachment';
}
location / {
proxy_pass http://pretalx_{{ pretalx_instance_identifier }}_server;
}
client_max_body_size 32M;
}

View File

@ -0,0 +1,15 @@
[Unit]
Description=pretalx %I background worker
After=network.target
[Service]
User={{ pretalx_system_user }}
Group={{ pretalx_system_user }}
ExecStart={{ pretalx_virtualenv }}/bin/celery -A pretalx.celery_app worker -l info
WorkingDirectory={{ pretalx_virtualenv }}/lib/python{{ pretalx_system_python_version }}/site-packages/pretalx
Restart=on-failure
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,45 @@
[filesystem]
static = {{ pretalx_staticfiles_directory }}
media = {{ pretalx_media_dir }}
data = {{ pretalx_data_dir }}
[database]
backend = {{ pretalx_database_backend }}
name = {{ pretalx_database_name }}
user = {{ pretalx_database_user }}
password = {{ pretalx_database_password }}
host = {{ pretalx_database_host }}
port = {{ pretalx_database_port }}
[site]
url = {{ pretalx_url }}
{% if pretalx_secret_key %}secret = {{ pretalx_secret_key }}{% endif %}
{% if pretalx_core_modules %}core_modules = {{ pretalx_core_modules }}{% endif %}
[mail]
from = {{ pretalx_mail_from }}
host = {{ pretalx_mail_host }}
port = {{ pretalx_mail_port }}
{% if pretalx_mail_user %}user = {{ pretalx_mail_user }}{% endif %}
{% if pretalx_mail_password %}password = {{ pretalx_mail_password }}{% endif %}
tls = {{ pretalx_mail_tls }}
ssl = {{ pretalx_mail_ssl }}
{% if pretalx_celery -%}
[celery]
backend = {{ pretalx_celery_backend }}
broker = {{ pretalx_celery_broker }}
{%- endif %}
{% if pretalx_redis %}
[redis]
location = {{ pretalx_redis }}
session = True
{% endif %}
{% if pretalx_admin_mail %}
[logging]
email = {{ pretalx_admin_mail }}
{% endif %}
{% if pretalx_additional_config %}{{ pretalx_additional_config }}{% endif %}

View File

@ -0,0 +1,12 @@
[Unit]
Description=pretalx %I server application
Requires=pretalx@%i.socket
After=network.target
[Service]
User={{ pretalx_system_user }}
Group={{ pretalx_system_user }}
WorkingDirectory={{ pretalx_virtualenv }}/lib/python{{ pretalx_system_python_version }}/site-packages/pretalx
ExecStart={{ pretalx_virtualenv }}/bin/gunicorn --bind unix:/run/gunicorn/pretalx_%i --workers {{ pretalx_service_workers }} --max-requests {{ pretalx_service_workers_max_requests }} --max-requests-jitter {{ pretalx_service_workers_max_requests_jitter }} pretalx.wsgi
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID

View File

@ -0,0 +1,8 @@
[Unit]
Description=pretalx_%I gunicorn socket
[Socket]
ListenStream=/run/gunicorn/pretalx_%i
[Install]
WantedBy=sockets.target

View File

@ -12,7 +12,7 @@ retain daily 6
retain weekly 4
retain monthly 12
retain yearly 42
verbose 3
verbose 2
loglevel 3
logfile /var/log/rsnapshot_{{ rsnapshot_name }}.log
lockfile /var/run/rsnapshot_{{ rsnapshot_name }}.pid

104
turn.yml
View File

@ -1,104 +0,0 @@
---
- hosts: turn
vars:
turnserver_secret: !vault |
$ANSIBLE_VAULT;1.1;AES256
61643630616332343933343663623032346565636431613332373031663834616662343763353863
3165323337616264353335613036396663356666666333310a333530383736376134646332633638
37633763623039326364356661616436663136623838343734316633373936353465636538353366
6236356562343335370a356530353563353865383635643239666438323365346137626634356533
31633538363865323066323166323564633439326538386230323132663032653731303165623132
3064313963616432383936626437313566653637313130666430
tasks:
- name: Basic setup
include_role: name=common
vars:
nft_extra: |
tcp dport {3478, 5349} counter accept comment "coturn listening port"
udp dport {3478, 5349} counter accept comment "coturn listening port"
udp dport 32769-65535 counter accept comment "relay ports range"
- name: Install coturn and certbot
apt:
name: [coturn, certbot]
state: present
- name: Get TLS certificate
command: certbot certonly --standalone --preferred-challenges http -d turn.afpy.org -n --agree-tos -m {{ letsencrypt_email | quote }}
register: certbot
changed_when: '"no action taken." not in certbot.stdout'
- name: Ensure coturn can read certs
file:
path: /etc/letsencrypt/renewal-hooks/deploy
state: directory
mode: 0755
- name: Configure certbot renewal hook for coturn
copy:
dest: /etc/letsencrypt/renewal-hooks/deploy/coturn
mode: 0755
content: |
#!/bin/bash -e
for certfile in fullchain.pem privkey.pem ; do
cp -L /etc/letsencrypt/live/turn.afpy.org/"${certfile}" /etc/turnserver/"${certfile}".new
chown turnserver:turnserver /etc/turnserver/"${certfile}".new
mv /etc/turnserver/"${certfile}".new /etc/turnserver/"${certfile}"
done
systemctl kill -sUSR2 coturn.service
- name: Configure turnserver
blockinfile:
path: /etc/turnserver.conf
block: |
fingerprint
use-auth-secret
static-auth-secret={{turnserver_secret}}
realm=afpy.org
cert=/etc/turnserver/fullchain.pem
pkey=/etc/turnserver/privkey.pem
# From https://ssl-config.mozilla.org/ Intermediate, openssl 1.1.0g, 2020-01
cipher-list="ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384"
dh-file=/etc/turnserver/dhp.pem
no-cli
no-tlsv1
no-tlsv1_1
no-loopback-peers
no-multicast-peers
notify: restart coturn
- name: Create dph.pem file directory
file:
path: /etc/turnserver
state: directory
mode: 0755
- name: Create dph.pem file
command: openssl dhparam -dsaparam -out /etc/turnserver/dhp.pem 2048
args:
creates: etc/turnserver/dhp.pem
- name: Create coturn service directory
file:
path: /etc/systemd/system/coturn.service.d
state: directory
mode: 0755
- name: Configure coturn service override
copy:
dest: /etc/systemd/system/coturn.service.d/override.conf
content: |
[Service]
LimitNOFILE=1048576
AmbientCapabilities=CAP_NET_BIND_SERVICE
Restart=always
notify: restart coturn
handlers:
- name: restart coturn
systemd:
name: coturn
state: restarted
daemon_reload: true

85
woodpecker-agent.yml Normal file
View File

@ -0,0 +1,85 @@
- hosts: woodpecker_agents
vars:
- WOODPECKER_VERSION: "2.4.1"
- WOODPECKER_AGENT_SECRET: "{{ vault_woodpecker_agent_secret }}"
tasks:
- name: Basic setup
include_role: name=common
- name: Install requirements
package:
name: docker.io
- name: Download woodpecker agent
get_url:
dest: /root/
url: "https://github.com/woodpecker-ci/woodpecker/releases/download/v{{WOODPECKER_VERSION}}/woodpecker-agent_{{WOODPECKER_VERSION}}_amd64.deb"
mode: 0644
owner: root
group: root
- name: Install woodpecker agent
apt:
deb: "/root/woodpecker-agent_{{WOODPECKER_VERSION}}_amd64.deb"
state: present
notify: restart woodpecker agent
- name: Create woodpecker agent group
group:
name: woodpecker-agent
state: present
- name: Woodpecker agent user
user:
system: true
password: '!'
home: /var/lib/woodpecker-agent
shell: /bin/bash
group: woodpecker-agent
groups: docker
name: woodpecker-agent
- name: Create woodpecker config directory
file:
path: /etc/woodpecker/
state: directory
owner: woodpecker-agent
group: woodpecker-agent
mode: 0750
- name: woodpecker agent systemd service
notify: restart woodpecker agent
copy:
dest: /etc/systemd/system/woodpecker-agent.service
content: |
[Unit]
Description=Woodpecker agent
After=network.target
[Service]
User=woodpecker-agent
Group=woodpecker-agent
WorkingDirectory=/var/lib/woodpecker-agent/
Environment="WOODPECKER_AGENT_SECRET={{ WOODPECKER_AGENT_SECRET }}"
Environment="WOODPECKER_SERVER=woodpecker.afpy.org:9000"
ExecStart=/usr/local/bin/woodpecker-agent
PrivateTmp=true
Restart=always
RestartSec=30s
[Install]
WantedBy=multi-user.target
- name: Run Woodpecker agent
service:
name: woodpecker-agent
enabled: yes
state: started
daemon_reload: yes
handlers:
- name: restart woodpecker agent
systemd:
name: woodpecker-agent
daemon-reload: true
state: restarted

View File

@ -2,69 +2,128 @@
- hosts: woodpeckers
vars:
- WOODPECKER_VERSION: "2.4.1"
- WOODPECKER_AGENT_SECRET: "{{ vault_woodpecker_agent_secret }}"
- WOODPECKER_GITEA_SECRET: "{{ vault_woodpecker_gitea_secret }}"
- WOODPECKER_GITEA_CLIENT: "78903dbe-f90e-4c8d-947a-f6839a1d11c9"
handlers:
- name: restart woodpecker
service:
name: woodpecker
state: restarted
daemon_reload: yes
- name: restart woodpecker agent
service:
name: woodpecker-agent
state: restarted
daemon_reload: yes
tasks:
- name: Install requirements
package:
name: docker.io
- name: Basic setup
include_role: name=common
- name: Setup nginx
include_role: name=nginx
vars:
nginx_domain: woodpecker.afpy.org
nginx_certificates: ['woodpecker.afpy.org']
nginx_conf: |
server
{
listen [::]:80; listen 80;
server_name woodpecker.afpy.org;
access_log /var/log/nginx/woodpecker.afpy.org-access.log;
error_log /var/log/nginx/woodpecker.afpy.org-error.log;
return 301 https://woodpecker.afpy.org$request_uri;
}
server
{
listen [::]:443 ssl; listen 443 ssl;
server_name woodpecker.afpy.org;
access_log /var/log/nginx/woodpecker.afpy.org-access.log;
error_log /var/log/nginx/woodpecker.afpy.org-error.log;
include snippets/letsencrypt-woodpecker.afpy.org.conf;
client_max_body_size 16M;
location / {
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
- name: Download woodpecker
get_url:
dest: /root/
url: "https://github.com/woodpecker-ci/woodpecker/releases/download/v{{WOODPECKER_VERSION}}/woodpecker-server_{{WOODPECKER_VERSION}}_amd64.deb"
mode: 0644
owner: root
group: root
- name: Install woodpecker
apt:
deb: "/root/woodpecker-server_{{WOODPECKER_VERSION}}_amd64.deb"
state: present
notify: restart woodpecker
- name: Create woodpecker group
group:
name: woodpecker
state: present
- name: Woodpecker user
user:
system: true
password: '!'
home: /var/lib/woodpecker
shell: /bin/bash
group: woodpecker
name: woodpecker
- name: Create SQLite directory
file:
path: '/var/lib/woodpecker'
state: directory
mode: 0755
owner: woodpecker
group: woodpecker
- name: Create woodpecker directory
file:
path: '/root/woodpecker'
state: directory
mode: 0755
# See https://woodpecker-ci.org/docs/administration/vcs/gitea
- name: Setup a docker-compose file
- name: woodpecker systemd service
notify: restart woodpecker
copy:
dest: /root/woodpecker/docker-compose.yml
mode: 0644
dest: /etc/systemd/system/woodpecker.service
content: |
version: '3'
[Unit]
Description=Woodpecker
After=network.target
services:
woodpecker-server:
image: woodpeckerci/woodpecker-server:latest
ports:
- 8000:8000
volumes:
- woodpecker-server-data:/var/lib/woodpecker/
environment:
- WOODPECKER_OPEN=false
- WOODPECKER_ORGS=AFPy
- WOODPECKER_HOST=https://woodpecker.afpy.org
[Service]
User=woodpecker
Group=woodpecker
WorkingDirectory=/var/lib/woodpecker/
Environment="WOODPECKER_AGENT_SECRET={{ WOODPECKER_AGENT_SECRET }}"
Environment="WOODPECKER_ADMIN=mdk"
Environment="WOODPECKER_LOG_LEVEL=debug"
Environment="WOODPECKER_OPEN=true"
Environment="WOODPECKER_HOST=https://woodpecker.afpy.org"
Environment="WOODPECKER_GITEA=true"
Environment="WOODPECKER_GITEA_URL=https://git.afpy.org"
Environment="WOODPECKER_GITEA_CLIENT={{WOODPECKER_GITEA_CLIENT}}"
Environment="WOODPECKER_GITEA_SECRET={{WOODPECKER_GITEA_SECRET}}"
ExecStart=/usr/local/bin/woodpecker-server
PrivateTmp=true
- WOODPECKER_GITEA=true
- WOODPECKER_GITEA_URL=https://git.afpy.org
- WOODPECKER_GITEA_CLIENT=0e954b08-6ac1-42ce-a647-432007bb564d
- WOODPECKER_GITEA_SECRET=gto_m5tfx3lgsq25wzmcn6vxyp2sxbladk3fdwlabixukhyus4lzhs6q
- WOODPECKER_AGENT_SECRET={{WOODPECKER_AGENT_SECRET}}
volumes:
woodpecker-server-data:
[Install]
WantedBy=multi-user.target
- name: Run Woodpecker server
docker_compose:
project_src: woodpecker
# The agent conf could look like:
# woodpecker-agent:
# image: woodpeckerci/woodpecker-agent:latest
# command: agent
# restart: always
# depends_on:
# - woodpecker-server
# volumes:
# - /var/run/docker.sock:/var/run/docker.sock
# environment:
# - WOODPECKER_SERVER=woodpecker-server:9000
# - WOODPECKER_AGENT_SECRET=${WOODPECKER_AGENT_SECRET}
service:
name: woodpecker
enabled: yes
state: started
daemon_reload: yes