Mot-clé - adminsys

Fil des billets

dimanche 3 juillet 2016

Des statistiques libres avec Rstudio, déployé en quelques minutes

R est un puissant outil et langage d'analyse statistique. S'il est possible d'installer tout le nécessaire à l'utilisation de R sur un poste, Rstudio est une plaisante alternative avec une utilisation via le navigateur des outils hébergés sur un serveur. Cela peut se révéler pratique pour éviter un déploiement sur des postes clients et permettre aux utilisateurs de travailler sur leurs données en tout lieu.

Nous allons voir ici comment installer Rstudio en quelques étapes faciles.

Installation de base

On considère être sur une version de Debian stable (par ex. actuellement Jessie).

apt install r-base
apt install gdebi-core
wget https://download2.rstudio.org/srtudio-server-0.99.902-amd64.deb
gdebi rstudio-serveur-0.99.902-amd64.deb

Il est possible que la version la plus récente de rstudio-server ne soit pas celle donnée ici. C’est pourquoi il est conseillé de visiter https://www.rstudio.com/products/rstudio/download-server/.

À l'issue de cette étape, le serveur Rstudio doit être actif et accessible sur le port 8787 : http://localhost:8787 (on remplacera localhost par le nom d'hôte ou l'adresse IP routable de la machine si elle est distante).

Plaçons Apache en reverse proxy devant

On considère ici qu'Apache est déjà présent sur la machine, sinon on l'installera par apt install apache2.

Dans le fichier /etc/apache2/sites-available/rstudio.conf, on place le contenu suivant :

<VirtualHost *:80>
  ServerName rstudio.domaine.tld
  <Proxy *>
    Allow from localhost
  </Proxy>
 
  ProxyPassMatch ^/p/([0-9]+)/(websocket|.*/websocket)/$ ws://localhost:8787/p/$1/$2/
  ProxyPass / http://localhost:8787/
  ProxyPassReverse / http://localhost:8787/
  ProxyRequests Off
</VirtualHost>

On active alors le module proxy d'Apache puis le site :

a2enmod proxy_http
service apache2 restart
a2ensite rstudio.conf

Et dans /etc/rstudio/rserver.conf, on place la ligne suivante :

www-address=127.0.0.1

Un petit coup de certbot pour l'HTTPS

Récupérons maintenant un certificat HTTPS via Certbot :

certbot –apache

Le tour est joué, rstudio est désormais accessible derrière https://rstudio.domaine.tld

Autorisations d'accès à Rstudio

Pour la gestion des profils, Rstudio utilise les utilisateurs locaux de la machine. Nous allons ajouter la ligne suivante dans /etc/rstudio/rserver.conf :

auth-required-user-group=rstudio-users

Ainsi, seuls les utilisateurs faisant partie du groupe rstudio-users pourront utiliser Rstudio. Il ne reste plus qu'à créer les utilisateurs et les placer dans le bon groupe !

P.S. Merci à Brendan qui m'a aidé pour ce déploiement et cet article !

samedi 4 juin 2016

vnstat sur Raspberry Pi pour surveiller le trafic réseau

Nous allons voir ici comment installer vnstat pour surveiller le trafic réseau et afficher une petite page de synthèse sur l'utilisation du trafic. Cela peut-être utile par exemple pour mesurer le trafic traversant une passerelle Raspberry Pi construite tel que raconté ici.

vnstat en ligne de commande

Tout commence avec (e.g. sous Raspbian Jessie) :

apt install vnstat vnstati

Demandons alors à vnstat de créer une base de données du trafic pour l'interface que l'on veut surveiller :

vnstat -i eth0 -u

Désormais, un appel à la commande vnstat affiche en ligne de commande une synthèse sur le trafic réseau :

vnstat -u #Mise à jour des informations
vnstat #Affichage de la synthèse
Database updated: Sat Jun  4 13:02:00 2016

   eth0 since 29/05/16

          rx:  136.26 MiB      tx:  411.92 MiB      total:  548.18 MiB

   monthly
                     rx      |     tx      |    total    |   avg. rate
     ------------------------+-------------+-------------+---------------
       May '16    134.72 MiB |  410.23 MiB |  544.94 MiB |    1.67 kbit/s
       Jun '16      1.55 MiB |    1.69 MiB |    3.24 MiB |    0.09 kbit/s
     ------------------------+-------------+-------------+---------------
     estimated         8 MiB |       8 MiB |      16 MiB |

   daily
                     rx      |     tx      |    total    |   avg. rate
     ------------------------+-------------+-------------+---------------
      29/05/16    134.72 MiB |  410.23 MiB |  544.94 MiB |   51.67 kbit/s
         today      1.55 MiB |    1.69 MiB |    3.24 MiB |    0.57 kbit/s
     ------------------------+-------------+-------------+---------------
     estimated         1 MiB |       1 MiB |       2 MiB |

vnstat sur une page web

vnstati est une commande parente de vnstat qui génère une image de synthèse plutôt qu'un tableau. Pratique pour nous, êtres humains, qui aimons la bigarrure ! Alors demandons à vnstati de nous géréner quelques images à l'aide de ce script que l'on pourra placer dans cron :

#!/bin/bash
vnstat -u -i eth0
vnstati -s -i eth0 -o /var/www/html/summary.png
vnstati -h -i eth0 -o /var/www/html/hourly.png
vnstati -d -i eth0 -o /var/www/html/daily.png
vnstati -t -i eth0 -o /var/www/html/top10.png
vnstati -m -i eth0 -o /var/www/html/monthly.png

Et pour afficher ces images, nous allons utiliser une petite page web et nginx :

apt install nginx

puis remplaçons la page par défaut /var/www/html/index.nginx-debian.html par index.html contenant :

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Statistics</title>
</head>

<body>
<h2 align="center">Network Statistics</h2>
<hr align="center">
<p align="center"><img src="summary.png" alt="Summary"/><br/>
  Summary
</p>
<hr align="center">
<p align="center"><img src="hourly.png" alt="Traffic stats on a hourly basis for the last 24 hours "/><br/>
  Traffic stats on a hourly basis for the last 24 hours
</p>
<hr align="center">
<p align="center"><img src="daily.png" alt="Traffic stats on a daily basis for the last 30 days"/><br/>
  Traffic stats on a daily basis for the last 30 days
</p>
<hr align="center">
<p align="center"><img src="monthly.png" alt="Traffic stats on a monthly basis for the last 12 months"/><br/>
  Traffic stats on a monthly basis for the last 12 months
</p>
<hr align="center">
<p align="center"></p>
<p align="center"><img src="top10.png" alt="All time top 10 traffic days"/><br/>
  All time top 10 traffic days</p>
<hr align="center">
</body>
</html>

et si l'on pointe un navigateur vers l'adresse IP du Raspberry Pi, on voit alors s'afficher :

Screenshot_2016-06-04_15-28-00.png

Un Raspberry Pi en passerelle IPv4, pour surveiller des flux réseaux par exemple

Nous allons voir dans ce billet comment paramétrer un Rasperry Pi pour qu'il joue le rôle de passerelle IPv4. Attention, avec son interface ethernet 100 Mbps et sa puissance limitée, il est évident que le montage présenté ici peut convenir dans un environnement domestique mais sans doute pas au-delà.

Matériel

Prenons donc un Raspberry Bi (muni de Raspbian Jessie) et munissons-le d'un port ethernet USB. Le Pi dispose alors de 2 interfaces ethernet eth0 et eth1 :

pi-bi-eth.jpg

Il n'est pas obligatoire d'avoir deux interfaces réseaux mais cela est plus commode et permet un suivi plus fin du trafic (avec une seule interface, tout ce qui rentre ressort par la même interface et il est dès lors plus délicat de comparer flux entrants et flux sortants puisqu'ils s'annulent au niveau de l'interface unique.

Paramétrage du réseau

Attribuons des paramétrages réseau fixes à eth0 et eth1 dans /etc/dhcpcd.conf comme expliqué ici :

interface eth0
static ip_address=192.168.1.235/24
static routers=192.168.1.1
static domain_name_servers=192.168.1.1

interface eth1
static ip_address=192.168.1.234/24

L'interface eth0 est paramétrée avec une IP fixe et utilise comme passerelle de sortie le routeur local (192.168.1.1 dans cet exemple). L'interface eth1 se voit attribuer seulement une adresse IP fixe mais pas de passerelle de sortie. Ainsi, la seule route vers l'extérieur passe au travers d'eth0, ce que nous confirme la commande ip route :

default via 192.168.1.1 dev eth0  metric 202 #La sortie par défaut via eth0, pas de sortie via eth1 !
192.168.1.0/24 dev eth0  proto kernel  scope link  src 192.168.1.235  metric 202 
192.168.1.0/24 dev eth1  proto kernel  scope link  src 192.168.1.234  metric 203

Il faut maintenant permettre au Raspberry Pi de faire transiter les paquets d'une interface à une autre. Pour ce faire, nous allons activer cette ligne dans /etc/sysctl.conf :

net.ipv4.ip_forward=1

et on ajoutera également ces 3 lignes pour s'assurer que le Raspberry Pi n'enseigne pas aux périphériques autour de lui à le "by-passer" (ce qu'un routeur fait par défaut pour garantir la performance et éviter les noeuds inutiles) :

net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.eth0.send_redirects = 0
net.ipv4.conf.eth1.send_redirects = 0

Pour activer cette configuration, on peut redémarrer ou exécuter :

sysctl -p

Désormais, le Raspberry Pi est capable de faire passer les communications d'eth1 à eth0 mais la route retour ne passe pas nécessairement par le Pi (le routeur n'a aucune raison, lui, de faire transiter le trafic retour vers le Pi s'il peut accéder directement au périphérique final ; évidemment ce cas ne se présente pas si le schéma de câblage fait du Pi le seul lien physique vers la porte de sortie).

Pour forcer la retour par le Pi, on exécutera cette commande iptables :

iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

Désormais, tout ce qui sort par eth0 voit son adresse source modifiée (filtre MASQUERADE appliquée en POSTROUTING) pour correspondre à l'adresse du Pi : au retour les paquets passeront donc forcément par le Pi qui renverra ensuite vers la bonne destination.

Et sur les périphériques ?

Sur chaque périphérique, il est alors possible d'indiquer comme passerelle l'adresse IP du Pi sur eth1 soit 192.168.1.234 dans cet exemple. Chacun saura comment indiquer à son DHCP local si nécessaire de transporter cette information plutôt que celle par défaut. Dès lors, le Pi devient le point de passage obligé du trafic réseau.

Pour quoi faire ?

Par exemple, nous pouvons maintenant examiner le flux traversant, mesurer le débit avec iftop, couper l'accès à internet à certaines heures, ... On pourra par exemple installer vnstat sur le Pi pour afficher des statistiques d'usage de la bande passante. Les idées ne manquent pas :-)

Passer de letsencrypt-auto à certbot, pas de problème

Let's Encrypt gagne en maturité et voici deux nouvelles importantes :

  • la période bêta est terminée (et avec elle certaines limites d'usage disparaissent)
  • le client letsencrypt-auto devient certbot et bénéficie d'une nouvelle maison
  • et la procédure de renouvellement est désormais beaucoup mieux gérée par le client

Place à certbot!

Si, comme moi, vous utilisiez letsencrypt-auto synchronisé depuis le dépôt Git du client, pas de panique, la transition vers certbot s'effectue sans problème.

D'abord, c'est l'occasion d'utiliser les dépôts Debian qui contiennent désormais certbot. Sur Jessie, pour installer certbot, on utilisera la commande suivante :

apt-get install certbot -t jessie-backports

Et ensuite ? Et bien il n'y a qu'à remplacer les appels vers letsencrypt-auto par des appels vers certbot ! Facile ! A noter que le paquet Debian vient avec un renouvellement automatique paramétré dans /etc/cron.d/certbot, il sera facile de commenter la ligne active si cela ne correspond pas à votre besoin.

Et les renouvellements ?

Comme je l'annonçais en introduction, les renouvellements sont maintenant bien mieux gérés par le client certbot.

La commande

certbot renew

réalisera le renouvellement de tous les certificats qui le nécessitent sur la base des paramétrages contenus dans /etc/letsencrypt/renewal/mon.domaine.tld.conf. On pourra tester le renouvellement sans l'exécuter à l'aide de l'option supplémentaire --dry-run. Enfin, il est possible de paramétrer une action à effectuer avant ou après chaque renouvellement à l'aide des options --pre-hook, --post-hook, --renew-hook. Au moment où j'écris ces lignes, il ne semble pas possible de paramétrer ces options dans les fichiers de renouvellement de configuration mais cela viendra peut-être !

Bons renouvellements !

mercredi 1 juin 2016

Git 2.8+ sur Debian Jessie pour Gitlab 8.5

Si vous hébergez Gitlab sur Debian Jessie, alors la mise à jour de la version 8.4 à la version 8.5 vous aura sans doute demandé une version de Git plus récente que Git 2.1.4 actuellement disponible sur Jessie. Pas de panique : il est possible presque sans effort d'installer une version plus récente de Git depuis les dépôts testing/stretch.

Dans /etc/apt/sources.list, on ajoute ces lignes :

deb http://debian.mirrors.ovh.net/debian/ stretch main
deb-src http://debian.mirrors.ovh.net/debian/ stretch main

deb http://security.debian.org/ stretch/updates main
deb-src http://security.debian.org/ stretch/updates main

Il faut ensuite indiquer à la distribution l'ordre de priorité d'installation en plaçant dans un fichier /etc/apt/preferences.d/mes_priorites (le nom du fichier est tout à fait personnalisable) le contenu suivant :

ackage: *
Pin: release l=Debian-Security
Pin-Priority: 1000

Package: *
Pin: release a=stable
Pin-Priority: 999

Package: *
Pin: release a=testing
Pin-Priority: 50

Package: *
Pin: release a=unstable
Pin-Priority: 50

A ce stade, la commande apt update doit rapatrier les informations de la version testing/stretch mais ne doit pas automatiquement proposer une mise à jour car la priorité donnée à testing (& unstable) est bien moindre que celle donnée à la branche stable.

Pour forcer alors l'installation de la version de Git disponible dans testing/stretch, il faut exécuter :

apt install git/stretch git-man/stretch

dimanche 29 mai 2016

IP statique sur Raspbian Jessie : DHCPCD fait la loi !

Sur Raspbian Jessie, le système n'obéit pas au classique /etc/network/interfaces quand il s'agit de paramétrer le réseau ! Inutile donc de vous escrimer (comme moi) à modifier les paramétrages de ce fichier pour basculer vers une adresse statique au lieu du DHCP par défaut !

En effet, sur Raspbian Jessie, le réseau est paramétré par le service DHCPCD. C'est donc à son niveau qu'il faut agir.

Ainsi, pour attribuer une IP fixe au Pi, ouvrons le fichier /etc/dhcpcd.conf et ajoutons ces lignes à la fin du fichier :

interface eth0
static ip_address=192.168.1.234/24
static routers=192.168.1.1
static domain_name_servers=192.168.1.1

dimanche 15 mai 2016

Scripts Munin pour Jirafeau

Si vous utilisez Jirafeau sur votre serveur pour partager des documents, vous serez peut-être contents d'avoir un suivi rapide du nombre de fichiers partagés et du volume total qu'occupent les fichiers de Jirafeau sur votre serveur.

jirafeau_nb-day.png

Rien de plus simple avec Munin !

Créons un premier plugin pour mesurer le nombre de fichiers

Sur la machine porteuse du client (node) Munin, nous allons créer un nouveau script dans le fichier /etc/munin/plugins/jirafeau-nb :

#!/bin/sh
case $1 in
   config)
        cat <<'EOM'
graph_title Jirafeau, number of files
graph_vlabel Nb of files
nbfiles.label Nb of files
EOM
        exit 0;;
esac

printf "nbfiles.value "
echo $(($(find /path/to/jirafeau/var-abcdefghiklmnop/files -type f |wc -l)*1/2))

Il faudra rendre le script exécutable par

chmod a+x /etc/munin/plugins/jirafeau-nb

puis le tester avec munin par

munin-run jirafeau-nb

et enfin redémarrer le client Munin

service munin-node restart

Créons un second plugin pour mesurer l'espace total occupé par les fichiers

On pratique comme au-dessus pour le script dont le contenu est :

#!/bin/sh
case $1 in
   config)
        cat <<'EOM'
graph_title Jirafeau, size of files in Kb
graph_vlabel Size of files in Kb
sizefiles.label Size
EOM
        exit 0;;
esac

printf "sizefiles.value "
du -hsk /path/to/jirafeau/var-abcdefghiklmnop/files |cut -f1

Et hop le tour est joué !

samedi 14 mai 2016

RIP demo.ovh.eu, alternatives open source

Pour partager des fichiers temporairement avec des amis/collaborateurs/proches, j'utilisais fréquemment l'outil demo.ovh.eu. Cet outil avait pour avantage d'être "share & forget" ce qui est idéal pour un document partagé que l'on ne veut pas conserver soi-même.

Malheureusement OVH a décidé d'éteindre demo.ovh.eu et d'inciter les gens à utiliser la plateforme Hubic (qui est très bien mais il est pénible de se connecter et de partager une photo que l'on ne veut pas conserver et qui peut être supprimée quelques jours après le partage).

J'ai donc cherché un outil équivalent Open Source et suis tombé sur Uguu qui répondait à mon cahier des charges mais qui était compliqué à déployer car il contenait tous ses paramètres "en dur" dans le code.

J'ai donc 'forké' Uguu et livre la communauté une version d'Uguu plus facile à déployer et paramétrer : https://github.com/pierre-alain-b/Uguu/

Screenshot_2016-05-14_12-16-35.png

Et d'ailleurs, le mainteneur de la version initiale a accepté le 'Pull request' et a fusionné toutes mes modifications dans l'arbre principal de développement, il est peut-être donc même préférable de se rendre ici : https://github.com/nokonoko/Uguu.

En espérant qu'il puisse rendre service à d'autres !

Et si Uguu ne vous convient pas, il y a aussi :

Merci à François B. pour ces suggestions !

lundi 28 mars 2016

LemonLDAP::NG et Let's Encrypt

Nous allons voir dans ce court article comment obtenir des certificats Let's Encrypt pour des services LemonLDAP::NG. Les chemins d'accès évoqués dans la suite correspondent à une installation de LemonLDAP::NG sur Debian Jessie à partir du paquet officiel fourni sur les dépôts de LemonLDAP::NG.

Étape 1 : obtenir un certificat pour le Manager

Nous allons commencer par autoriser l'accès au dossier .well-known dans lequel Let's Encrypt travaille (pour mémoire, il y place une clé qu'un serveur externe vient interroger, permettant ainsi d'affirmer que le demandeur gère le domaine). D'abord dans la configuration d'Apache, dans le fichier /etc/apache2/sites-available/manager-apache2.conf, nous allons remplacer la ligne

RewriteCond "%{REQUEST_FILENAME}" "!^/(?:static|doc|fr-doc|lib).*"

par

RewriteCond "%{REQUEST_FILENAME}" "!^/(?:static|\.well-known|doc|fr-doc|lib).*"

Puis, dans le manager lui-même, il faut demander à LemonLDAP::NG de ne pas bloquer l'accès au même dossier .well-known aux utilisateurs non authentifiés. Ainsi, il faut se rendre dans Virtual Hosts -> manager.mondomaine.fr -> Access rule, et ajouter une nouvelle règle :

  • Regular expression: ^/\.well-known
  • Rule: skip

Screenshot_2016-03-28_06-02-19.png

Dès lors, Let's Encrypt devrait être capable d'accéder à la clé placée dans .well-known. Nous pouvons donc démarrer le processus avec le client Let's Encrypt :

certbot certonly --renew-by-default -a webroot --webroot-path /usr/share/lemonldap-ng/manager/ -d manager.mondomaine.fr

Étape 2 : obtenir un certificat pour le portail d'authentification

Facile :

certbot certonly --renew-by-default -a webroot --webroot-path /var/lib/lemonldap-ng/portal/ -d auth.mondomaine.fr

Étape 3 : obtenir un certificat pour une application placée derrière LemonLDAP::NG

Si l'application est protégée derrière LemonLDAP::NG, il faut commencer par indiquer à LemonLDAP::NG de laisser transiter les requêtes vers le dossier .well-known. A l'image de ce qui a été fait pour le manager, il faut se rendre dans Virtual Hosts -> manager.mondomaine.fr -> Access rule, et ajouter une nouvelle règle :

  • Regular expression: ^/\.well-known
  • Rule: skip

Puis tout simplement (si l'application sous-jacente ne filtre pas les accès à .well-known) :

certbot certonly --renew-by-default -a webroot --webroot-path /var/www/mon-app -d mon-app.mondomaine.fr

dimanche 20 mars 2016

ownCloud/Nextcloud, Pound et MKCALENDAR

A compter de la version 9.0, ownCloud/Nextcloud utilise le mot clé MKCALENDAR dans l'application Calendrier. Ce mot clé est utilisé pour provoquer la création d'un nouveau calendrier/nouvel agenda sur l'interface en ligne. Or, ce mot HTTP n'est pas reconnu dans la version de Pound, le load balancer, disponible sur Debian Jessie.

Première approche de solution

On peut noter que ce point a été traité par les développeurs de Debian ici. Ainsi, la version 2.6-6.1, disponible sur Debian Testing/Unstable accepte le mot clé MKCALENDAR.

Il est donc possible d'installer le paquet de Testing/Unstable (à condition d'avoir bien paramétré /etc/apt/sources.list et /etc/apt/preferences) à l'aide de la commande :

apt-get -t unstable install pound

Seconde approche de solution

La version de Pound utilisée dans Jessie et Sid est pour l'instant la version 2.6 qui souffre de certaines faiblesses (même si les mainteneurs ont fait un travail formidable pour prendre en compte les bugs critiques et améliorer la sécurité). Dès lors, certains préféreront peut-être utiliser la version 2.7 stable disponible mais non proposée par Debian pour le moment.

Il faudra alors compiler manuellement Pound (ce qui n'est pas très compliqué). Mais stupeur, la version 2.7 de Pound ne supporte pas MKCALENDAR. Il faut donc patcher le fichier config.h pour inclure MKCALENDAR ! Là encore ce n'est pas bien compliqué.

Bonne compilation de Pound !

ownCloud/Nextcloud 9 : activer le cache APCu pour améliorer (un peu) les performances

Pour améliorer les performances d'ownCloud/Nextcloud, il est très facile d'activer un memcache facilement en quelques actions seulement :

  • on installe le paquet php5-apcu avec la commande (sous Debian, sinon il faudra adapter le gestionnaire de paquet et le nom du paquet) :
apt install php5-apcu
  • on redémarre Apache :
service apache2 restart
  • on ajoute alors cette ligne dans le fichier de configuration d'ownCloud/Nextcloud :
'memcache.local' => '\OC\Memcache\APCu',

Et le tour est joué !

mercredi 16 mars 2016

Fail2ban pour protéger Samba de Locky

Face à la menace du "ransomware" Locky, j'ai décidé de protéger les données de mon serveur Samba à l'aide de Fail2ban. L'idée est simple : si des mouvements pouvant correspondre à une action de Locky sont détectés, alors l'IP à l'origine de l'action est bannie du serveur Samba.

Étape 1 : activer l'audit dans Samba

Samba dispose de puissantes fonctions d'audit qui permettent de garder trace de toutes les opérations sur un partage. Elles s'activent à l'aide des options full_audit dans le fichier /etc/samba/smb.conf. Attention toutefois à la volumétrie que cela peut représenter : si le serveur Samba est très sollicité, la taille des logs sera fort importante (surtout si l'on suit l'événement "open" qui est déclenché régulièrement lors de toute navigation sur le partage Samba) !

Plaçons donc le paramétrage suivante dans la section "Global" du fichier de configuration de Samba (/etc/samba/smb.conf par défaut) :

full_audit:priority = notice
full_audit:facility = local5
full_audit:success = mkdir rmdir rename unlink open
full_audit:prefix = %u|%I|%S

puis redémarrons Samba :

service samba restart

et voilà le fichier /var/log/samba/audit.log qui se remplit et recense tous les mouvements sur le serveur Samba. Une bonne rotation des logs sera nécessaire pour ne pas se faire piéger ! Attention également à la petite perte de performance que cette écriture régulière demandera.

Étape 2 : paramétrer le nouveau filtre d'exclusion pour Fail2ban

Nous allons demander à Fail2ban de bannir tout ordinateur qui effectuerait une opération sur fichier *.locky ou *.xxx sur le serveur. On crée le fichier /etc/fail2ban/filter.d/antilocky.conf suivant :

[Definition]
failregex = \|<HOST>\|NomDePartage\|.*\|ok\|.*\.(locky|xxx|mp3)

ignoreregex =

en remplaçant "NomDePartage" par le nom du partage Samba concerné.

Étape 3 : paramétrer une nouvelle prison dans Fail2ban

On paramètre comme il se doit Fail2ban dans /etc/fail2ban/jail.local en ajoutant notamment la section suivante :

[antilocky]
enabled = true
filter  = antilocky
backend = auto
logpath = /var/log/samba/audit.log
maxretry  = 2
banaction = iptables-allports
port = all

On peut alors redémarrer Fail2ban par :

service fail2ban restart

et vérifier dans les logs /var/log/fail2ban.log que la nouvelle prison se charge correctement.

Et voilà Fail2ban prêt à bannir tout ordinateur qui se connecterait au serveur Samba en manipulant des fichiers *.locky ou *.xxx. Evidemment il peut y avoir des faux positifs. Il est donc recommandé d'être vigilant et d'activer peut-être la notification par courriel des bannissements de ce type pour être en mesure de débannir dans le cas d'un faux positif et d'intervenir sur le poste infecté s'il s'avère qu'une réelle infection est en cours.

Étape 4 : limitations

La principale limitation est l'usage de l'extension de nom de fichier comme critère de signalement. Si des variantes du virus adoptent d'autres extensions (par exemple .pdf) alors il ne sera plus possible de détecter l'action frauduleuse de la sorte. On pourra éventuellement suivre le nombre d'opérations sur le partage Samba et alerter l'administrateur lorsque de trop nombreuses opérations de suppression sont en cours...

samedi 27 février 2016

Tomato : utiliser la puissance d'iptables pour contrôler les flux sur les différentes interfaces

Voici quelques lignes à introduire dans la configuration d'un routeur/point d'accès propulsé par Tomato (dont on a déjà parlé dans ces articles) pour interdire aux périphériques branchés sur une interface d'accéder à certains sous-réseaux. Cela peut être pratique lorsque l'on veut interdire à certains périphériques (par exemple des périphériques connectés sur un réseau "invité") d'accéder à certaines ressources locales.

La petite subtilité est la suivante : il est nécessaire d'introduire les règles nouvelles en amont des règles existantes. Et pour ce faire, il faut donc utiliser l'option '-I' d'iptables en précisant la ligne à laquelle on souhaite insérer la nouvelle commande.

Ainsi :

iptables -P FORWARD DROP
iptables -I FORWARD 1 -i br0 -j ACCEPT
iptables -I FORWARD 2 -i br1 -d 192.168.0.0/16 -j REJECT
iptables -I FORWARD 3 -i br1 -j ACCEPT

conduit au comportement suivant :

  • par défaut tout est rejeté
  • on accepte tout en provenance de l'interface br0 (par exemple un Wifi 'maître des lieux')
  • on refuse tous les accès den provenance de l'interface br1 (par exemple un Wifi 'invité') à destination des IPs du sous-réseau 192.168.0.0/16
  • on accepte tout le reste de l'interface br1

Voilà, le tour est joué,

lundi 1 février 2016

Letsencrypt : renouveler intelligemment malgré les limites de la bêta

Depuis Mai 2016, le service Let's Encrypt n'est plus en bêta et les limitations de la bêta évoquées ici ne sont plus mordantes !

Depuis Mai 2016, le client letsencrypt est devenu certbot (https://certbot.eff.org/) ! les commandes évoquées plus bas sont sans doute valables en remplaçant letsencrypt-auto par certbot ! Il faut aussi noter que le client certbot dispose désormais de fonctions de renouvellement plus élaborées qu'auparavant ! Cet article est conservé pour archive et inspiration.

Letsencrypt se présente comme le futur du chiffrement sur internet. Bien que déjà fonctionnel, le service offert est encore en phase de test (bêta) et par conséquent certaines contraintes s'appliquent aux usagers testeurs. Parmi ces contraintes, les 2 les plus bloquantes sont :

  • pas de système de renouvellement automatique pour le moment (c'est prévu, vivement !)
  • limite imposée de 5 certificats par domaine par semaine (i.e. qu'il faut attendre une semaine pour pouvoir créer des certificats pour un nouveau sous-domaine d'un domaine qui possède déjà 5 certificats de sous-domaine)

Pour Letsencrypt qui émet des certificats à la validité courte de 3 mois, le renouvellement doit être fait régulièrement et il correspond ni plus ni moins à l'édition d'un nouveau certificat.

La contrainte évoquée plus haut est bloquante pour le renouvellement : en effet il n'est pas possible de renouveler plus de 5 certificats par semaine pour un même domaine...

Principe du renouvellement à terme

A terme, un système de renouvellement automatique sera intégré à Letsencrypt et il suffira de lancer tous les 2 mois (par exemple via cron) la commande demandant le renouvellement de tous les certificats en approche de péremption. Vivement cela !

Une méthode fonctionnelle aujourd'hui

Aujourd'hui, à nous de créer l'automatisme qui va bien et qui permettra aussi de contourner la limite des 5 renouvellements par semaine (en réalisant un roulement). Nous allons détailler ici un script qui, appelé chaque semaine, :

  • détecte les certificats qui ont moins de 30 jours de validité (2592000 secondes)
  • demande le renouvellement de chaque certificat dans ce cas

Voici le code du script :

#!/bin/bash
declare -a list=(
"/etc/letsencrypt/live/domaine1.tld;certbot certonly --renew-by-default -a webroot --webroot-path /path/to/domaine1/website -d domaine1.tld -d www.domaine1.tld"
"/etc/letsencrypt/live/sous.domaine1.tld;certbot certonly --renew-by-default -a webroot --webroot-path /path/to/sous/domaine1/website -d sous.domaine1.tld -d www.sous.domaine1.tld"
"/etc/letsencrypt/live/domaine2.tld;certbot certonly --renew-by-default -a webroot --webroot-path /path/to/domaine2/website -d domaine2.tld -d www.domaine2.tld"
)

for line in "${list[@]}"
do
	IFS=";" read -ra stuff <<< $line
	folder=${stuff[0]}
	command=${stuff[1]}
        if openssl x509 -checkend 2592000 -noout -in $folder/fullchain.pem
        then
                echo "Nothing to do for $folder"
        else
                $command
                rm -f $folder/total.pem
                cat $folder/fullchain.pem $folder/privkey.pem > $folder/total.pem
                echo "Done for $folder"
        fi
done

Rapidement :

  • on commence par lister dans un tableau chaque domaine dont il faut s'occuper (en indiquant le chemin correspondant à ce domaine dans le dossier /etc/letsencrypt/live/) et, séparée par ";", la commande Letsencrypt utilisée pour le renouvellement. Il s'agit de la même commande que pour la création initiale du certificat sauf que l'on ajoute l'option "--renew-by-default"
  • on parcourt ensuite le tableau élément par élément :
    • en vérifiant l'âge du certificat (avec openssl)
    • en lançant la commande de renouvellement s'il est trop proche de la péremption

Si l'on utilise Letsencrypt avec Pound, on ajoutera 2 actions :

  • remplacer le fichier .pem utilisé par Pound par la nouvelle version obtenue
  • redémarrer Pound

Le script devient alors :

#!/bin/bash
declare -a list=(
"/etc/letsencrypt/live/domaine1.tld;certbot certonly --renew-by-default -a webroot --webroot-path /path/to/domaine1/website -d domaine1.tld -d www.domaine1.tld"
"/etc/letsencrypt/live/sous.domaine1.tld;certbot --renew-by-default -a webroot --webroot-path /path/to/sous/domaine1/website -d sous.domaine1.tld -d www.sous.domaine1.tld"
"/etc/letsencrypt/live/domaine2.tld;certbot certonly --renew-by-default -a webroot --webroot-path /path/to/domaine2/website -d domaine2.tld -d www.domaine2.tld"
)

for line in "${list[@]}"
do
	IFS=";" read -ra stuff <<< $line
	folder=${stuff[0]}
	command=${stuff[1]}
        if openssl x509 -checkend 2592000 -noout -in $folder/fullchain.pem
        then
                echo "Nothing to do for $folder"
        else
                $command
                rm -f $folder/total.pem
                cat $folder/fullchain.pem $folder/privkey.pem > $folder/total.pem
                echo "Done for $folder"
        fi
done
service pound restart

Archive

Dans une ancienne version de ce billet, on utilisait le morceau de script suivant se basant sur la date de dernière modification du fichier de certificat plutôt que d'utiliser openssl, mais c'est moins propre. Pour archivage, voici le test qui était alors utilisé (renouvellement des certificats plus vieux que 60 jours) :

	timesincelastchange=$(expr $(expr $(date +%s) - $(date +%s -r $folder/fullchain.pem )) / 86400)
	if [ $timesincelastchange -gt 60 ]
	then
		$command
		echo "Done for $folder"
	else
		echo "Nothing to do for $folder"
	fi

Dé-bannir une adresse IP avec Fail2ban

fail2ban-client set JAILNAME unbanip IPADDRESS

où l'on remplacera JAILNAME par le nom de la "jail" de Fail2ban à l'origine du bannissement et IPADDRESS par l'adresse bannie.

Par exemple :

fail2ban-client set ssh unbanip 1.2.3.4

Fail2ban & NAT avec des règles PREROUTING

Par défaut, les règles de Fail2ban s'appliquent à la chaîne INPUT. Or cette dernière chaîne n'est pas consultée lors de redirections de paquets avec des règles de type NAT (PREROUTING).

Pour que l'action de Fail2ban soit efficace, il faut alors lui indiquer d'inscrire les adresses à bannir dans la chaîne FORWARD qui est consultée dans le cas d'une redirection NAT.

Concrètement, dans /etc/fail2ban/jail.local, dans la section de son choix, on ajoute la ligne :

chain    = FORWARD

Et le tour est joué !

lundi 28 décembre 2015

Let's Encrypt et Gitlab

Pour permettre la génération d'un certificat avec Let's Encrypt pour Gitlab, il m'a été nécessaire d'effectuer les opérations suivantes :

  • Modifier la gestion des fichiers d'assets dans gitlab/config/environments/production.rb,
config.serve_static_assets = true
  • Redémarrer Gitlab par
service gitlab restart
  • Puis effectuer la génération du certificat avec le script Let's Encrypt en pointant le webroot vers le dossier public :
certbot certonly -a webroot --webroot-path /path/to/gitlab/public -d mongit.domaine.tld

dimanche 20 décembre 2015

Let's Encrypt et le load-balancer Pound

Pound est un reverse-proxy et un load-balancer libre fort performant. Il est très pratique en frontal d'un ensemble de services web et peut notamment se charger d'effectuer la compression TLS des flux. Il est bien sûr possible de l'utiliser avec Let's Encrypt tel que décrit ici.

Pour ce faire, imaginons que nous venons de lancer la commande suivante :

certbot certonly -a webroot --webroot-path /var/www/mon-site/ -d mondomaine.tld

Un nouveau dossier a été créé : /etc/letsencrypt/live/mondomaine.tld/. Il contient le certificat et également la clé privée utilisée pour ce certificat. Afin que Pound fonctionne, il faut regrouper le certificat et la clé privée dans un même fichier :

cat /etc/letsencrypt/live/mondomaine.tld/fullchain.pem /etc/letsencrypt/live/mondomaine.tld/privkey.pem > /etc/letsencrypt/live/mondomaine.tld/total.pem

et il faut alors référencer le fichier total.pem dans la configuration de Pound :

ListenHTTPS
	Address 2001:2002:2003:2004::
        Port    443
	Cert	    "/etc/letsencrypt/live/mondomaine.tld/total.pem"

et il ne reste plus qu'à redémarrer Pound par :

service pound restart

samedi 19 décembre 2015

Utiliser Let’s Encrypt avec ownCloud/Nextcloud, Piwik, Dotclear, Drupal, Wordpress, des applications Rails et des sites statiques !

Depuis le début du mois, il est possible d'utiliser "Let's Encrypt" pour obtenir des certificats TLS/SSL pour sécuriser ses sites et services en ligne (bien que le système soit toujours annoncé en bêta). Ce matin, je décidais donc de m'y mettre et de remplacer mes certificats StartSSL.

Depuis Mai 2016, le service Let's Encrypt n'est plus en bêta et les limitations de la bêta évoquées ici ne sont plus mordantes !

Depuis Mai 2016, le client letsencrypt est devenu certbot (https://certbot.eff.org/) ! les commandes évoquées plus bas sont sans doute valables en remplaçant letsencrypt-auto par certbot !

Première étape : comprendre le fonctionnement

Le principe est assez simple et n'est pas très différent de celui déjà rencontré pour l'obtention de certificats auprès des opérateurs "classiques" (les StartSSL et consors). Classiquement, (i) on démontre la possession réelle du nom de domaine, (ii) on génère une clé privée et une clé publique et on transmet la clé publique à l'opérateur de certification qui (iii) fournit en retour un certificat attestant le lien entre le nom de domaine et la paire de clés crypto utilisées pour l'établissement de communications sécurisées. Avec Letsencrypt, ces étapes ont lieu mais automatiquement. Dans l'utilisation commune, Letsencrypt vient avec un script Python (letsencrypt-auto) qui va faire tout le travail :

  • le script va créer un fichier mondomaine.tld/.well-known/acme-challenge/chaîne-choisie-au-hasard et le serveur distant cherchera à accéder à ce fichier pour authentifier la possession/maîtrise du domaine mondomaine.tld
  • puis le script génère et échange les clés cryptographiques avec l'autorité de certification Letsencrypt
  • et le certificat est rapatrié
  • enfin, dans certains cas, le script se charge même de l'installer !

Par rapport à ce qui est fourni habituellement par les acteurs privés :

  • la chaîne de bout en bout est plus transparente et libre
  • le certificat est gratuit
  • le certificat n'a une validité que de 90 jours (mais le renouvellement est gratuit et peut être géré automatiquement par le script tous les 2 mois par exemple)
  • les certificats n'autorisent pas les wildcards (e.g. *.mondomaine.tld) ce qui a déjà été fort amplement débattu partout sur le web mais ne semble pas devoir changer.

Deuxième étape : installer Let’s Encrypt

Nous allons commencer par le cas simple d'un site statique. Le script letsencrypt se télécharge sur la machine d'hébergement à l'aide de git :

git clone https://github.com/letsencrypt/letsencrypt
cd letsencrypt

puis on peut lancer le script (qui va effectuer les installations supplémentaires nécessaires) par :

./letsencrypt-auto

Cela fonctionne très bien sur Debian Jessie et sans doute les autres systèmes récents (c'est la version de Python qui semble être un des facteurs limitants pour les "vieilles" distributions). On reviendra sur ce point plus loin.

Troisième étape : utiliser Let’s Encrypt pour un site statique

Commençons par le cas simple d'un site statique hébergé dans /var/www/mon-site/ et servi par Apache.

./letsencrypt-auto certonly -a webroot --webroot-path /var/www/mon-site/ -d mondomaine.tld

certonly car nous demandons à Let’s Encrypt de générer le certificat et de s'arrêter là (donc de ne pas l'installer lui-même). -a webroot car nous indiquons à Let’s Encrypt où se trouve la racine du site afin qu'il puisse y placer le fichier de "challenge" (.well-known/acme-challenge/chaîne-choisie-au-hasard). Et -d mondomaine.tld pour indiquer le domaine. Il est possible d'indiquer plusieurs domaines s'ils partagent le même webroot par exemple :

./letsencrypt-auto certonly -a webroot --webroot-path /var/www/mon-site/ -d mondomaine.tld -d www.mondomaine.tld

Dans ce cas le certificat contiendra les 2 domaines en SAN (Subject Alternative Names).

Au premier lancement, le script demande de saisir l'adresse courriel qui sera rattachée au compte (et qui recevra les éventuelles notifications de péremption des domaines non renouvelés).

Et hop, le script travaille et un certificat tout neuf (et valide !) est déposé dans /etc/letsencrypt/live/mondomaine.tld/fullchain.pem. La clé privée correspondante se trouve dans /etc/letsencrypt/live/mondomaine.tld/privkey.pem. Ce certificat peut alors être utilisé comme il l'a toujours été (par ex. appelé dans la configuration d'Apache ou de votre load balancer) - je détaille ici comment l'utiliser avec le load balancer Pound.

Let’s Encrypt et un blog dotclear

Aucune surprise ni difficulté avec dotclear :

./letsencrypt-auto certonly -a webroot --webroot-path /chemin/vers/blog/dotclear -d blog.bandinelli.net

et hop, /etc/letsencrypt/live/blog.bandinelli.net/fullchain.pem est créé ! Une commande pour un certificat, c'est classe et pratique !

Let’s Encrypt et Piwik

Aucune surprise ni difficulté avec Piwik :

./letsencrypt-auto certonly -a webroot --webroot-path /chemin/vers/racine/piwik -d piwik.mondomaine.tld

et hop, /etc/letsencrypt/live/piwik.mondomaine.tld/fullchain.pem est créé !

Let’s Encrypt et Wordpress

Aucune surprise ni difficulté avec Wordpress :

./letsencrypt-auto certonly -a webroot --webroot-path /chemin/vers/racine/wordpress -d mondomaine.tld

et hop, /etc/letsencrypt/live/mondomaine.tld/fullchain.pem est créé !

Let’s Encrypt et Drupal 7

Une petite astuce est nécessaire ici : par défaut le moteur de Drupal demande au serveur web de réécrire toutes les adresses et empêche l'accès à certaines adresses. Ainsi, le fichier .htaccess se trouvant à la racine d'un site Drupal contient la ligne suivante :

RewriteRule "(^|/)\." - [F]

Cette ligne ordonne à Apache de renvoyer vers la page "Accès interdit" toute requête qui débuterait par ".". Il faut bien évidemment désactiver cette sécurité pour Letsencrypt :

RewriteCond %{REQUEST_URI} !^/.well-known/acme-challenge/.*
RewriteRule "(^|/)\." - [F]

La condition RewriteCond désactive la redirection qui suit pour le challenge de letsencrypt seulement.

Une fois cela effectué, on peut utiliser la commande classique pour obtenir le certificat valide dans /etc/letsencrypt/live/mondomaine.tld/fullchain.pem :

./letsencrypt-auto certonly -a webroot --webroot-path /chemin/vers/site/drupal/ -d mondomaine.tld

Let’s Encrypt et ownCloud/Nextcloud

Une petite astuce est nécessaire ici : par défaut le moteur d'ownCloud demande au serveur web de réécrire toutes les adresses et empêche l'accès à certaines adresses. Ainsi, le fichier .htaccess se trouvant à la racine d'une instance ownCloud/Nextcloud contient la ligne suivante :

RewriteRule ^(\.|autotest|occ|issue|indie|db_|console).* - [R=404,L]

elle renvoie vers 404 tous les appels à un chemin démarrant par ".". Il est bien sûr nécessaire de désactiver cette ligne conditionnellement :

RewriteCond %{REQUEST_URI} !^/.well-known/acme-challenge/.*
RewriteRule ^(\.|autotest|occ|issue|indie|db_|console).* - [R=404,L]

Ensuite, sans surprise, pour obtenir le certificat valide dans /etc/letsencrypt/live/mondomainecloud.tld/fullchain.pem :

./letsencrypt-auto certonly -a webroot --webroot-path /chemin/vers/owncloud/ -d mondomainecloud.tld

Let’s Encrypt et une application Ruby on Rails

Aucune surprise ni difficulté avec une application Ruby on Rails servie en production par Unicorn, à condition de bien choisir le dossier public comme webroot :

./letsencrypt-auto certonly -a webroot --webroot-path /chemin/vers/application/public -d domaine.tld

et hop, /etc/letsencrypt/live/domaine.tld/fullchain.pem est créé !

Let’s Encrypt sur une vieille distribution ?

Si Let's Encrypt ne peut être lancé sur votre machine de production car elle dispose de versions trop anciennes des fichiers, rien n'est perdu ! Il est en effet possible de fournir au script un webroot qui serait par exemple partagé via SSH ! Par exemple :

apt install sshfs
mkdir /mnt/webroot-distant
sshfs user@machine:/path/to/webroot /mnt/webroot-distant
./letsencrypt-auto certonly -a webroot --webroot-path /mnt/webroot-distant -d mondomaine.tld

Conclusion

Très efficace et rapide, comment ne pas tomber sous le charme de Letsencrypt ? Il reste à valider : la procédure de renouvellement et la pérennité dans le temps de la structure. Pour y aider, on peut toujours faire un petit don sur la page d'accueil de Let’s Encrypt !

vendredi 18 décembre 2015

Asterisk : automatiser un redémarrage hebdomadaire

Pour forcer un redémarrage hebdomadaire d'Asterisk, vous pouvez utiliser la commande suivante :

/usr/sbin/asterisk -r -x "core restart gracefully"

ou encore

/usr/sbin/asterisk -r -x "core restart now"

si vous ne voulez pas attendre la fin des appels en cours (cela provoquera une coupure des appels en cours !)

Pour que le redémarrage s'effectue une fois par semaine, à 2h52 du matin, voici la ligne que vous pourrez introduire dans /etc/crontab :

25 2    * * 7   root    /usr/sbin/asterisk -r -x "core restart gracefully"

- page 1 de 3