Dans le cadre de gozmail, nous proposons également l’hébergement de blogs pour nos adhérents. Nous utilisons wordpress car il dispose d’une fonctionnalité qui permet de créer un réseau de sites. Ainsi, chaque adhérent dispose de sonsite.log.bzh et ne peut pas aller fouiner chez son voisin.
Au bout d’un moment, nous nous sommes dit que ça serait pas mal d’avoir du
SSL. Premièrement parce que ça évite d’envoyer son mot de passe en clair,
deuxièmement parce que le chiffrement devient de plus en plus nécessaire
dans notre monde actuel. Comme l’asso n’a pas spécialement envie de payer
un certificat global *.log.bzh, nous avons décidé d’utiliser let’s encrypt
et de mettre chaque nom de domaine dans le certificat. Jusqu’à présent il
s’agissait d’un cron qui tournait tous les jours et redemandait un
certificat si un nouveau site a été créé. En soit ça ne marche pas si mal,
mais tout nouveau site se retrouve avec un mauvais certificat le premier
jour, on peut faire mieux.
Il faut donc régénérer le certificat au moment de la création du compte.
Pour ça nous pouvions soit utiliser les hooks de wordpress (et donc se
taper du code en PHP, et personne n’a envie de faire du PHP), soit écrire
un petit wrapper shell qui crée un compte wordpress en se basant sur wp-cli puis lance la tambouille let’s
encrypt avec acme-tiny.
Le script que je vous propose ici part donc du principe que ces deux
projets sont utilisables sur la machine depuis laquelle vous le lancez. Les
chemins sont spécifiques à log.bzh, vous devrez donc les modifier en
fonction de vos besoins. Il faudra également modifier les variables
$DBUSER
, $DBPASS
et $DBNAME
.
#!/bin/sh
usage() {
cat <<EOF
Usage of $0:
-h, --help Print this help
-u, --user User name
Create a site \$user.log.bzh
-e, --email User’s mail
EOF
}
die() {
echo "$@" >&2
exit 1
}
nargs=$(($#/2))
OPTS=$(getopt -o u:,e:,h -l user:,email:,help -- "$@") || die
if [ $# -eq 0 ]; then
>&2 usage
exit 1
fi
eval set -- "$OPTS"
while :; do
case "$1" in
-h | --help) usage;
exit 0;;
-u | --user) USER="$2";
shift 2;;
-e | --email) EMAIL="$2";
shift 2;;
--) shift; break;;
esac
done
PASSWORD="$(head -c 12 /dev/urandom | base64)"
if [ $nargs -ne 2 ]; then
>&2 printf "Error, username or email not specified\n"
>&2 usage
exit 1
fi
cd /var/www/html/log.bzh
su www-data -s /bin/sh -c "wp site create --slug=$USER --email=$EMAIL" || die "Error while creating site"
su www-data -s /bin/sh -c "wp user update $USER --user_pass=$PASSWORD" || die "Error while setting password"
cd $OLDPWD
DBUSER="coucou"
DBPASS="je"
DBNAME="teste"
# Very ugly code here.
# Just for memory, because insane ;)
#openssl req -nodes -sha256 -newkey rsa:4096 \
# -keyout /etc/ssl/nginx/blogs.log.bzh.key \
# -out /etc/ssl/nginx/blogs.log.bzh.csr -subj "/" -reqexts SAN \
# -config <(cat /etc/ssl/blogs.cnf \
# <(printf '[SAN]\nsubjectAltName=DNS:log.bzh,DNS:www.log.bzh,'; \
# while read fqdn; do printf "DNS:${fqdn},"; done < \
# <(echo 'SELECT domain FROM wp_blogs;' | mysql -u $DBUSER -p$DBPASS $DBNAME \
# | sed -e '1d' | grep -v "^log\.bzh$") | sed 's/,$//'; printf '\n'))
# A bit less ugly
( printf '[SAN]\nsubjectAltName=DNS:log.bzh,DNS:www.log.bzh,'; \
echo 'SELECT domain FROM wp_blogs;' | \
mysql -u $DBUSER -p$DBPASS $DBNAME | \
sed -e '1d' | \
grep -v '^log\.bzh$' | \
while read fqdn; do \
printf "DNS:${fqdn},"; \
done | \
sed 's/,$//'; printf '\n') | \
cat /etc/ssl/blogs.cnf - | \
openssl req \
-nodes \
-sha256 \
-newkey rsa:4096 \
-keyout /etc/ssl/nginx/blogs.log.bzh.key \
-out /etc/ssl/nginx/blogs.log.bzh.csr \
-subj "/" \
-reqexts SAN \
-config /dev/stdin \
|| die "Error while getting site list"
acme_tiny.py --account-key /usr/local/var/lib/sslle/account.key \
--csr /etc/ssl/nginx/blogs.log.bzh.csr --acme-dir /var/www/le-challenges/ > \
/etc/ssl/nginx/blogs.log.bzh.crt || die "Error while signing certificate"
cat /etc/ssl/nginx/blogs.log.bzh.crt \
/etc/ssl/certs/lets-encrypt-x3-cross-signed.pem > \
/etc/ssl/nginx/blogs.log.bzh-chained.crt || die "Error while chaining certificate"
service nginx reload || die "Error while reloading nginx"
SUBJECT=$(perl -wse "use utf8; use Encode qw(encode); print encode(\"MIME-Q\",\
\"Votre site https://${USER}.log.bzh vient d’être créé\");")
echo "From: Admins log.bzh <log@gozmail.bzh>
To: $EMAIL
Cc: Admins log.bzh <log@gozmail.bzh>
Content-Type: text/plain; charset=UTF-8
Subject: $SUBJECT
Bonjour,
Votre site vient d’être créé. Son adresse est https://${USER}.log.bzh
Pour vous connecter, rendez-vous sur https://${USER}.log.bzh/wp-admin/
Votre identifiant est $USER
Votre mot de passe est $PASSWORD
Cordialement,
--
Les admins de log.bzh" | /usr/sbin/sendmail -f log@gozmail.bzh -t
exit 0
# À la base je voulais la faire simple, j’ai glissé chef.