infra/README.md

443 lines
12 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Playbooks Ansible de lAFPy
On découpe nos *playbooks* Ansible par rôles :
- `pycon.yml`: Pour les pycon.fr
- `backup.yml`: Configure rsnapshot pour sauvegarder nos serveurs.
- ...
En partant de là, on peut utiliser les commandes suivantes :
Après avoir cloné ce repo, installé Ansible (dans un venv), installez
les roles nécessaires via :
- ansible-galaxy install julienpalard.nginx
Récupérez le secret dans [afpy/pass](https://github.com/AFPy/pass/):
git clone https://github.com/AFPy/pass/
PASSWORD_STORE_DIR=pass/infra pass Ansible-Vault > ~/.ansible-afpy-vault
Puis pour jouer les *playbooks* :
- Pour tout relancer : `ansible-parallel *.yml`
- Pour configurer les PyCons : `ansible-playbook pycons.yml`
## Faire, ne pas faire
Faire : Configurer les machines :
- `apt install`,
- fichiers de configuration,
- créer les utilisateurs,
- é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,
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 nom :
- discuss.afpy.org,
- bbb.afpy.org,
- www.afpy.org,
-
## deb2.afpy.org
♥ Machine sponsorisée par Gandi ♥
Cest un VPS `V-R4 2 CPUs · 4 GB RAM`.
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) (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://munin.afpy.org
## bbb2.afpy.org
♥ Machine sponsorisée par Gandi ♥
Cest un VPS `V-R8 4 CPUs · 8 GB RAM`.
Cest une Ubuntu 18.04 (cest imposé par BBB).
Elle nest **pas** gérée par Ansible, cest un peu particulier BBB,
mais le serveur `turn` l'est, et le playbook `turn.yml` configure
quand même un fichier sur BBB.
D'ailleurs pour tester la configurtion turn/stun:
https://docs.bigbluebutton.org/administration/turn-server#test-your-turn-server
Jy ai appliqué un poil de ssh-hardening :
AuthenticationMethods publickey
LogLevel VERBOSE
Ensuite jai [rsync les enregistrements depuis le bbb
précédent](https://docs.bigbluebutton.org/2.2/customize.html#transfer-published-recordings-from-another-server).
Puis jai sauvegardé/restauré la DB de greenlight :
# Sur lancienne 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 lancienne 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 soccuper 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 quexim et le firewall (attention cest peut-être `ufw`)
les acceptent.
## backup1.afpy.org
♥ Machine sponsorisée par Gandi ♥
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 7 mai 2023 via :
ssh root@backup1.afpy.org sh check-afpy.sh
Dernière vérification de `silence` (chez Julien) le 7 mai 2023 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 bbb 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
♥ Machine sponsorisée par Gandi ♥
Cest un « Gandi VPS V-R1 » 1 CPU, 1 GB RAM, 25 GB disk.
Cest la machine derrière `git.afpy.org`, déployée via `gitea.yml`.
### Mise à jour
Pour faire une mise à jour, se connecter en root à la machine puis exécuter :
systemctl start gitea-backup.service
backupopts="-c /etc/gitea/app.ini --file /var/backups/gitea/before-upgrade.zip" gitea-upgrade.sh
(Oui, je sais, ça fait deux sauvegardes, une par nous (avec un
`pg_dump`), une par le script de gitea dont le SQL nest pas aussi
propre que celui généré par `pg_dump`).
Une fois la mise à jour terminée, il est de bon goût de mettre à jour
`gitea_version` dans `gitea.yml`.
### Sauvegardes
Les données sont sauvegardées automatiquement via rsync sur
`backup1.afpy.org` (voir `backup.yml`).
Côté VPS Gandi on a aussi un snapshot du volume tous les jours.
### Restaurer une sauvegarde
Procédure testée le 2022-11-29 par [mdk](https://git.afpy.org/mdk).
Voici la procédure pour restaurer une sauvegarde sur une nouvelle
machine « from scratch ».
#### Commander une nouvelle machine
Typiquement chez Gandi une `V-R1: 1 CPU · 1 GB RAM`, avec une Debian
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 puisquil faudra le changer à la fin.
#### Autoriser à se ssh en root
ssh debian@giteatest.afpy.org sudo cp /home/debian/.ssh/authorized_keys /root/.ssh/
#### Ajouter la machine dans linventaire Ansible
Ça devra donc ressembler à :
```ini
[gitea]
gitea2.afpy.org
```
On peut probablement supprimer lautre qui ne marche plus...
#### Lancer Ansible
`ansible-playbook gitea.yml`
#### rsync la sauvegarde
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
Donc, depuis gitea2:
cd /var/lib/gitea/
rsync -vah backup1.afpy.org:/srv/backups/rsnapshot_afpy/daily.0/git.afpy.org/var/backups/gitea/ ./
systemctl stop gitea
rm -fr data custom
unzip gitea.zip
rm gitea.zip
mv app.ini /etc/gitea/app.ini
mv repos data/gitea-repositories
chown -R git:git .
sudo --user git psql -d gitea < gitea.sql
rm gitea.sql
Puis passer le playbook `gitea.yml` pour remettre les bons droits partout (le playbook démarrera aussi `gitea`).
#### Tester et mettre à jour git.afpy.org
Un rapide test peut être effectué via :
curl --resolve git.afpy.org:IP_DE_LA_NOUVELLE_MACHINE https://git.afpy.org
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
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.
<details>
<summary>
Voici la procédure
</summary>
- Ajouter les enregistrements A et AAAA de la machine.
- Baisser le TTL du CNAME `discuss.afpy.org`.
- 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 lancienne machine, faire une sauvegarde, soit via https://discuss.afpy.org/admin/backups, soit :
```
./launcher enter app
discourse backup
exit
```
- Copier une sauvegarde dans `/var/discourse/shared/standalone/backups/default/`.
- Restaurer la sauvegarde :
```
cd /var/discourse
./launcher enter app
discourse enable_restore
discourse restore afpy-2023-01-31-215204-v20230130053144.tar.gz
exit
```
Bien tester lenvoi demails.
</details>
# Rôles utilisés
On utilies ces rôles Ansible :
## roles/nginx
Ce rôle configure un nginx avec Letsencrypt en DNS-01 via lAPI Gandi (nos domaines étant chez Gandi).
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 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).
## common
*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).
## exim
Le playbook exim configure une clé DKIM et signe les mails avec. Mais un humain doit la propager sur les DNS.
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 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'