Site original : blog'o'm0le
Je vous raconte comment j'ai failli envoyé un bug report à Debian 🙂
TL;DR: Une dépendances manquante pour le paquet sendemail m’empêchait d'envoyer des mail via TLS.
Dans notre architecture, nous avons un serveur sous XEN, et différentes VM pour différentes fonctions, dont une "WEB" (pour les sites), une "DATA" et enfin une "MAIL" qui est notre serveur mail.
Je voulais changer de méthode d'envoi de mail en local, je suis donc passé au package sendEmail (pas sendmail donc) pour avoir l'auth STARTTLS. Mais, pour une raison inexpliquée, certaines VM arrivaient à envoyer des mails et d'autre non.
Première chose, vérifier les logs;
depuis la VM WEB (impossible d'envoyer un mail) :
sendemail -u subject -m message -f user@domain.tld -t user@domain.tld -s mailserver -xu user@domain.tld -xp password -vvvv DEBUG => Connecting to mailserver DEBUG => My IP address is: 10.0.1.1 DEBUG => evalSMTPresponse() - Checking for SMTP success or error status in themessage: 220 mailserver ESMTP Postfix (Debian/GNU) DEBUG => evalSMTPresponse() - Found SMTP success code: 220 SUCCESS => Received: 220 mailserver ESMTP Postfix (Debian/GNU) INFO => Sending: EHLO WEB DEBUG => evalSMTPresponse() - Checking for SMTP success or error status in themessage: 250-mailserver, 250-PIPELINING, 250-SIZE 502400000, 250-ETRN, 250-STARTTLS, 250-ENHANCEDSTATUSCODES, 250-8BITMIME, 250 DSN DEBUG => evalSMTPresponse() - Found SMTP success code: 250 SUCCESS => Received: 250-mailserver, 250-PIPELINING, 250-SIZE 502400000, 250-ETRN, 250-STARTTLS, 250-ENHANCEDSTATUSCODES, 250-8BITMIME, 250 DSN DEBUG => The remote SMTP server supports TLS :) NOTICE => Authentication not supported by the remote SMTP server! INFO => Sending: MAIL FROM:user@domain.tld DEBUG => evalSMTPresponse() - Checking for SMTP success or error status in themessage: 530 5.7.0 Must issue a STARTTLS command first DEBUG => evalSMTPresponse() - Found SMTP error code: 530 ERROR => Received: 530 5.7.0 Must issue a STARTTLS command first
depuis la VM DATA (où les mails fonctionnaient sans problème) :
# sendemail -u subject -m message -f user@domain.tld -t user@domain.tld -s mailserver -xu user@domain.tld -xp password -vvvv DEBUG => Connecting to mailserver DEBUG => My IP address is: 10.0.1.2 DEBUG => evalSMTPresponse() - Checking for SMTP success or error status in themessage: 220 mailserver ESMTP Postfix (Debian/GNU) DEBUG => evalSMTPresponse() - Found SMTP success code: 220 SUCCESS => Received: 220 mailserver ESMTP Postfix (Debian/GNU) INFO => Sending: EHLO DATA DEBUG => evalSMTPresponse() - Checking for SMTP success or error status in themessage: 250-mailserver, 250-PIPELINING, 250-SIZE 502400000, 250-ETRN, 250-STARTTLS, 250-ENHANCEDSTATUSCODES, 250-8BITMIME, 250 DSN DEBUG => evalSMTPresponse() - Found SMTP success code: 250 SUCCESS => Received: 250-mailserver, 250-PIPELINING, 250-SIZE 502400000, 250-ETRN, 250-STARTTLS, 250-ENHANCEDSTATUSCODES, 250-8BITMIME, 250 DSN DEBUG => The remote SMTP server supports TLS :) DEBUG => Starting TLS INFO => Sending: STARTTLS DEBUG => evalSMTPresponse() - Checking for SMTP success or error status in themessage: 220 2.0.0 Ready to start TLS DEBUG => evalSMTPresponse() - Found SMTP success code: 220 SUCCESS => Received: 220 2.0.0 Ready to start TLS DEBUG => TLS: Using cipher: ECDHE-RSA-AES256-GCM-SHA384 DEBUG => TLS session initialized :) INFO => Sending: EHLO DATA [...]
Dans les deux cas, le serveur supporte TLS, mais le "STARTTLS" n'est pas envoyé depuis ma VM WEB.
Les configurations et les accès/restrictions étant les mêmes, gnutls installé sur les deux machines, j'ai commencé à rédiger mon bug report en m'aidant de : https://www.debian.org/Bugs/Reporting
L'une des étapes du rapport de bug debian est d'envoyer les infos du package, dont l'une d'elle (https://www.debian.org/Bugs/Reporting#findpkgver) est :
dpkg --status
Bien m'en a pris, car j'ai pu me rendre compte de cette intéressante ligne :
# dpkg --status sendemail
Package: sendemail
[...]
Suggests: libio-socket-ssl-perl, libnet-ssleay-perl
Effectivement, ces deux paquets ne sont pas des dépendances, mais des suggestions …. néanmoins très indispensable pour envoyer des mails en TLS 🙂
J'ai pu régler mon bug et m’éviter de passer pour un idiot à remplir un rapport de bug inutile…
Voilà voilà, en suivant le pas de Tuxicoman nous nous sommes concertés et force est de constater qu'on s'en fout un peu des logs / statistiques..
Surtout si c'est pour compter les gens qui n'ont PAS de bloqueur de pub (a priori, la grosse majorité de l'auditoire du blog, non ?)
Bref, on retire Piwik/Matomo, mis en place ici en février 2012. Ça file quand même ..
Juste pour le fun, voici quelques stats, sorties de nulle part :
Je ne vais pas faire d'interprétation parce qu'au final... on s'en fout toujours, non ?
PS : en résumé, m0le-o-blog est sans pub (depuis toujours) et sans tracker !
Tant qu'à faire un peu de ménage sur notre dédié, je me suis décidé à changer de mode de backup en passant à Borg.
Dans mon cas, j'utilise un script sur mon synology qui récupère son IP public et qui l'envoie dans un fichier "ip_syn" sur le serveur m0le periodiquement
Tout se passe depuis l'interface web, il faut s'assurer que l'utilisateur a le droit dans un dossier, disons /Backup (monté dans /volume1/Backup/)
Pour que la connexion par clé ssh fonctionne, il faut :
On peut s'en sortir en exécutant ces commandes :
chmod 755 /var/services/homes/<user> chmod 700 /var/services/homes/<user>/.ssh chmod 600 /var/services/homes/<user>/.ssh/* chown -R <user>:users /var/services/homes/<user>/.ssh
Il faut également s'assurer que ces deux lignes soit décommenté dans /etc/ssh/sshd_config:
PubkeyAuthentication yes AuthorizedKeysFile .ssh/authorized_keys
Pour installer les dépendances sous Debian:
m0le# apt install sshfs
On passe à la génération de la clé ssh + l'envoi sur le synology
m0le# ssh-keygen -t rsa -b 4096 // Je genère une clé sans passphrase (pour automatiser le montage avec sshfs) m0le# ssh-copy-id <user>@<ip_synology> -p <port> // j'envoie la clé vers le synology m0le# ssh <user>@<ip_synology> -p <port> // Je vérifie que j'arrive bien à me connecter au server, sans demander de mot de passe.
On teste l'existence d'un dossier "Backup" accessible sur le synology
backup@synology$ cd Backup // j'utilise mon utilisateur dédié "backup" backup@synology Backup$ touch test // Je crée un fichier
On crée enfin le répertoire local pour monter le répertoire Backup avec sshfs
m0le# mkdir -p /mnt/syno // Je créer le repertoire pour le montage via SSHFS m0le# sshfs <user>@<ip_synology>/Backup/ /mnt/syno -p <port> // je monte le dossier Backup de mon synology sur le server m0le m0le# ls -l /mnt/syno // Si le fichier "test" s'affiche, c'est tout bon ! m0le# rm /mnt/syno/test // J'en ai plus besoin
On va dabord créer un repo qui va héberger nos "archives".
(les archives stockeront nos fichiers, le repo est l'endroit ou seront inventorier ces archives)
m0le# apt install borgbackup // installation de borgbackup m0le# borg init --encryption=repokey /mnt/syno/<repo> // création du repo en prenant soin de créer un mot de passe ! m0le# borg create /mnt/syno/<repo>::test /etc/ // Je créer une sauvegarde du dossier "/etc" dans un archive nommé "test" dans mon repo "/mnt/syno/<repo>"
Faire des tests et les supprimer
m0le# borg create --stats /mnt/syno/<repo>::test2 /etc/ // Je crée une deuxième archive "test2" du dossier /etc/ : Ca devrait être bcp plus rapide car "test" existe déjà. m0le# borg list /mnt/syno/<repo>::test2 // Si je liste le contenu du dossier "/etc", c'est tout bon ! m0le# borg delete /mnt/syno/<repo>::test // Je supprimer mes tests m0le# borg delete /mnt/syno/<repo>::test2 // Je supprimer mes tests
Si tout va bien jusqu'ici, c'est qu'on a de quoi créer des archives Borg (manuellement pour l'instant), sur un repertoire de notre synology via sshfs.
Plutôt pas mal, on va donc automatiser ça ! Voilà ce que le script (cf source) fait :
Évidemment, il faudra faire vos modifs comme celles que j'ai apportées par rapport à la source (cf les paramètres au debut)
#!/bin/bash # Mount parameters mount="/mnt/syno/" # Borg parameters repo="/mnt/syno/m0le" pass="legrosmotdepasse!!" backup_dir="/etc /root /usr/local/bin" # Synology parameters syno_user="backup" syno_ip=`cat /home/ip_syn` syno_port="22" syno_dir="/Backup/" # Setting this, so the repo does not need to be given on the commandline: export BORG_REPO=${repo} # Setting this, so you won't be asked for your repository passphrase: export BORG_PASSPHRASE=${pass} # or this to ask an external program to supply the passphrase: export BORG_PASSCOMMAND='pass show backup' # some helpers and error handling: info() { printf "\n%s %s\n\n" "$( date )" "$*" >&2; } trap 'echo $( date ) Backup interrupted >&2; exit 2' INT TERM info "Mount ${mount} from ssh://${syno_user}@${syno_ip}:${syno_port}/${syno_dir}" sshfs ${syno_user}@${syno_ip}:${syno_dir} ${mount} -p ${syno_port} info "Starting backup: ${backup_dir}" # Backup the most important directories into an archive named after # the machine this script is currently running on: borg create \ --verbose \ --filter AME \ --list \ --stats \ --show-rc \ --compression lz4 \ --exclude-caches \ --exclude '/home/*/.cache/*' \ --exclude '/var/cache/*' \ --exclude '/var/tmp/*' \ \ ::'{hostname}-{now}' \ $backup_dir \ backup_exit=$? info "Pruning repository" # Use the `prune` subcommand to maintain 7 daily, 4 weekly and 6 monthly # archives of THIS machine. The '{hostname}-' prefix is very important to # limit prune's operation to this machine's archives and not apply to # other machines' archives also: borg prune \ --list \ --prefix '{hostname}-' \ --show-rc \ --keep-daily 7 \ --keep-weekly 4 \ --keep-monthly 6 \ prune_exit=$? # use highest exit code as global exit code global_exit=$(( backup_exit > prune_exit ? backup_exit : prune_exit )) info "Unmounting ${mount}" umount ${mount} if [ ${global_exit} -eq 1 ]; then info "Backup and/or Prune finished with a warning" fi if [ ${global_exit} -gt 1 ]; then info "Backup and/or Prune finished with an error" fi exit ${global_exit}
Il ne reste plus qu'à exécuter le script, vérifier l'archive et son contenu et enfin rajouter un petit cron qui va bien 😉
Petite note de service : j'ai mis en place notre certificat wildcard pour m0le.net via letsencrypt de façon relativement simple.
Grosso modo, il n'y a plus qu'un certificat pour tous les sous-domaines que nous utilisons (ainsi qu'un certificat pour m0le.net tout cours)
Je devais :
Voici en gros la manip (sous Debian) :
# certbot --version
# certbot certonly --manual -d *.m0le.net --preferred-challenges dns-01 --server https://acme-v02.api.letsencrypt.org/directory
# certbot -delete --cert-name sub.m0le.net //autant de fois que de sous domaine
[Edit 08/04/2018] en version 0.22.2: certbot delete --cert-name sub.m0le.net
Et bim, je ne dois renouveler plus que deux certificats (un pour m0le.net, un pour *.m0le.net)... Merci letsencrypt !
Retour sur la réalisation des cartes réalisées pour Rue89 Strasbourg lors des deux tours des régionales 2015. Objectif : rendre compte, sur une même interface, des résultats électoraux aux niveaux communal, département et régional.
5 200 communes, dix départements, trois régions : ce sont des chiffres-clés de l'Alsace-Champagne-Ardenne-Lorraine (ACAL), nouvelle région administrative créée fin 2014.
Les élections qui ont déterminé la composition du nouveau conseil régional ont été l'occasion de tenter de la cartographie très ambitieuse chez Rue89 Strasbourg. Je vais tenter un résumé le plus exhaustif possible des différentes étapes de ce boulot.
La principale source d'inspiration de ces cartes est ce très bel exemple d'analyse électorale proposée par le Huffington Post, et codée avec la fameuse librairie D3js.
L'application du Huffington repose sur le principe d'un entonnoir : on propose à l'internaute deux niveaux de lecture, avec d'un côté le vote des 300 communes du Massachussets, et de l'autre les 14 comtés de cet Etat.
Huffington Post
Les résultats des plus grands territoires apparaissent comme une synthèse des communes qui les composent, un peu comme si on les avait lâchés dans un entonnoir.
On observe des bastions démocrates et républicains bien délimités au niveau communal, ce qui se ressent sur les résultats cantonaux.
Huffington Post
A l'échelle de l'ACAL, on passait à un niveau bien plus costaud, avec près de 5 200 villes à cartographier. L'échelle départementale d'à peine dix unités me paraissait trop faible, tandis que l'échelle cantonale, plus proche de l'application du Huffington, ne me paraissait pas la plus compréhensible.
Bref, trois niveaux commençaient à émerger pour les futures élections régionales : les communes, les départements, et les régions.
A ce stade, il était temps de se pencher sur la faisabilité technique de la chose.
En furetant un peu, je suis tombé sur ce gabarit avec code source directement inspiré de la carte du Huffington. Ca m'a suffi pour commencer les tests avec mes propres fichiers géographiques, soigneusement préparés sur le logiciel QGis.
Sans faire un récap' de tous les atermoiements techniques, j'en ai appris plus sur l'option CSS "hidden", qui contrairement au "opacity" de l'exemple, permet de masquer toutes les options d'un calque.
Il y a également eu quelques lignes de code dédiées à un effet de zoom sur les communes de chaque département, directement calqué sur cet exemple publié par le créateur de D3 lui-même.
L'idée était d'encourager l'exploration des données en permettant à l'utilisateur d'accéder à des communes trop petites pour être consultées depuis la vue d'ensemble.
Une des options ajoutées à ce stade a été l'affichage des sous-préfectures seulement lorsqu'un département est zoomé pour offrir des repères supplémentaires.
Une fois le squelette prêt, le plus dur restait à faire : le connecter à des données, dans l'idée de traiter en direct les résultats de ces élections régionales.
Une fois le modèle de carte prêt à être montré, je l'ai envoyé à Tom Wersinger, développeur chez Rue89, pour lui demander son avis.
Tom nous avait déjà filé un précieux coup de main au moment des élections départementales, où on avait pu apprécier la puissance d'un parser en PHP codé par ses soins.
Pour le dire vite, il permet de traduire un tableur Google en json, en paramétrant (assez) simplement quelques options comme l'identifiant de la feuille Google.
Dès que la connexion est établie entre le parser et le tableur, un petit F5 permet de générer une nouvelle version du json. Un nouveau rafraîchissement sur la carte et le tour est joué. Sans douleur, donc !
Comme on passait quand même à une échelle largement supérieure à celle des départementales, je voulais m'assurer que le parser supporterait la charge.
Tom a eu la gentillesse de m'aider dans cette tâche sur son temps libre, avec en plus :
Et après plusieurs heures de codage intensif, nous sommes arrivés à une carte du second tour de la dernière présidentielle optimale, bien reliée à une feuille de calcul Google :
Cliquez sur l'image pour l'agrandir
Restait plus, à ce stade, qu'à nous assurer d'avoir des données régulièrement mises à jour le jour J. Là, ça s'est un peu compliqué, car :
Mais heureusement, le Ministère de l'Intérieur allait fournis à la presse des XML mis à jour tous les quarts d'heure. La principale difficulté consistait à convertir ce format composé de balises en tableur prêt à être copié/collé dans Google Drive.
Je dois reconnaître que ce n'est pas franchement mon domaine, contrairement au camarade Ettore Rizza. Ettore a écrit un script directement taillé pour les XML de l'ACAL.
Une fois digéré par Open Refine, on obtenait grâce à ce script des données bien propres et prêtes à être téléchargées au format CSV.
Plus qu'à mettre en oeuvre tout ça le grand soir venu 🙂
Dans l'ensemble, tout s'est passé sans encombre, mais il faut quand même signaler quelques embûches et aspects perfectibles, notamment :
Ce travail de longue haleine a payé avec des audiences plutôt bonnes pour ce genre d'événements sur Rue89 S : 18 000 vues pour le premier tour, et à peu près la moitié pour le second.
Nous avons également réussir à corriger le tir pour les faiblesses repérées lors du premier tour (notamment les villes manquantes) pour pouvoir optimiser le traitement live.
J'ai également codé une nouvelle version de la carte pour le second tour, en intégrant un dégradé selon le pourcentage du vainqueur. Concrètement, cela nous a permis de passer de ça :
Cliquez sur l'image pour accéder à la page du premier tour
A ça :
Cliquez sur l'image pour accéder à la page du second tour
Petite fierté strictement perso : notre carte du premier tour s'est retrouvé dans le Top 10 hebdomadaire du Global Investigative Journalism Network. Pour la petite histoire, c'est la seconde fois de l'année 🙂 !
Le template codé avec Tom va maintenant nous permettre d'étudier en profondeur l'ACAL, territoire plein de disparités comme en témoignent ces "cartes de force" du PS, du FN et des Républicains :
Bref, ça promet pour 2016 !
J'en profite pour remercier une nouvelle fois les excellents Tom, Ettore et Joël pour leur précieuse aide !
PS : le code source de la carte du premier tour sera bientôt publié.