Mot-clé - sécurité

Fil des billets

dimanche 27 octobre 2013

Fail2ban veille sur Dotclear, Wordpress et Piwik

Avec les bonnes règles, on peut demander à fail2ban de surveiller un certain nombre de services et de repérer toute tentative d'accès frauduleuse par force brute (i.e. essai de nombreuses combinaisons utilisateur/mot de passe possibles).

On crée d'abord un nouveau fichier de filtre dans /etc/fail2ban/filter.d/bruteforce.conf qui contient :

[Definition]
failregex = <insert here a regex to match in the log files> 
ignoreregex =

Il ne reste plus qu'à spécifier les règles (par expression régulière) nécessaires pour détecter les comportements coupables !

Pour protéger dotclear par exemple, on utilisera la règle suivante :

monblog.mondomain.tld:80 <HOST> - - .* "POST /admin/auth.php HTTP/1.1" 200

Pour Wordpress, on pourra utiliser celle-là :

monblog.mondomain.tld:80 <HOST> - - .* "POST /wp-login.php HTTP/1.1" 200

Et pour Piwik, celle-ci pourra faire l'affaire :

monpiwik.mondomain.tld:80 <HOST> - - .* "POST / HTTP/1.1" 200

Les dernières étapes consistent à ajouter une section dans le fichier /etc/fail2ban/jail.local pour utiliser ces nouveaux filtres et surveiller le fichier de log d'apache !

[apache-services-bruteforce]
enabled  = true
port     = http,https
filter   = bruteforce
logpath = /var/log/apache2/other_vhosts_access.log
maxretry = 8

samedi 26 octobre 2013

Entretenir et sécuriser Roundcube avec logrotate et fail2ban

Roundcube entrepose certaines informations dans le dossier logs/ à la racine de l'installation. Le fichier 'errors' contiendra par exemple la trace des tentatives d'accès avec mot de passe erroné.

Pour éviter que ce fichier ne grossisse trop sans surveillance, nous allons : - mettre en place une rotation des logs avec logrotate - surveiller le log avec fail2ban pour bannir toute IP qui tenterait de forcer le passage en multipliant les essais de nom d'utilisateur et de mot de passe.

La rotation des logs

Dans /etc/logrotate.d/roundcube, on placera le paramétrage (assez explicite) suivant :

/var/www/roundcube/logs/errors {
        weekly
        missingok
        rotate 8
        compress
        notifempty
        create 640 www-data www-data
}

et le tour est joué.

On pourra appliquer la même rotation au fichier /var/www/roundcube/logs/sendmail si la volumétrie de votre webmail le nécessite !

Surveillance avec fail2ban

Nous allons créer un nouveau filtre dans /etc/fail2ban/filter.d/roundcube.conf :

[Definition]
failregex = Login failed for .*. from <HOST>

ou, si l'on est placé derrière un Proxy qui transmet la "vraie" adresse d'origine dans le champ X-Forwarded-For :

[Definition]
failregex = Login failed for .*. from .*.(X-Forwarded-For: <HOST>)

et une nouvelle règle :

[roundcube]
enabled  = true
port     = http,https
filter   = roundcube
action   = iptables46-multiport[name=apache, port="http,https", protocol=tcp]
logpath  = /var/www/roundcube/logs/errors
maxretry = 6

(attention, la règle d'action iptables46 correspond à une astuce temporaire pour ajouter le support de l'IPv6 à Fail2ban comme décrit ici)

et désormais, toute tentative d'accès répétée conduira à l'exclusion de l'IP douteuse !

dimanche 20 octobre 2013

fail2ban et IPv6

Fail2ban est un outil indispensable pour surveiller les tentatives d'accès frauduleuses à des serveurs. Quand un nombre déterminé d'actions offensantes ont été vues (dans les logs de vos serveurs SSH, FTP, HTTP...), alors fail2ban bannit l'IP mal intentionnée (grâce à iptables).

Malheureusment, la version 0.8.6 de fail2ban ne supporte que l'IPv4. Des travaux sont en cours à ce sujet et la version 0.9 (qui sera libérée bientôt) devrait contenir tout le nécessaire. En attendant, il existe un petit script que l'on peut déployer en suivant les instructions détaillées ici : http://www.crazyws.fr/dev/systeme/fail2ban-et-ipv6-sur-votre-serveur-debian-squeeze-MG970.html

Pour archive, je recopie aussi les grandes étapes à effectuer :

cd /root
wget http://thanatos.trollprod.org/sousites/fail2banv6/fail2ban-ipv6.tar.bz2
mkdir fail2ban-ipv6
tar xvjf fail2ban-ipv6.tar.bz2 -C fail2ban-ipv6

puis on sauvegarde les fichiers qui ont être patchés :

cd /usr/share/fail2ban/server
cp filter.py filter.py.withoutipv6
cp failregex.py failregex.py.withoutipv6

on teste le déploiement du patch :

cd /usr/share/fail2ban/server/
patch -p0 --dry-run < /root/fail2ban-ipv6/patchfilter.patch
patch -p0 --dry-run < /root/fail2ban-ipv6/regex.patch

puis on l'applique pour de vrai :

patch -p0 < /root/fail2ban-ipv6/patchfilter.patch
patch -p0 < /root/fail2ban-ipv6/regex.patch

et on rajoute les fichiers de configuration nécessaires :

cp /root/fail2ban-ipv6/ip64tables.sh /usr/bin/
chmod 755 /usr/bin/ip64tables.sh
cp /root/fail2ban-ipv6/iptables46-multiport.conf /etc/fail2ban/action.d/
chmod 644 /etc/fail2ban/action.d/iptables46-multiport.conf

On peut alors re-paramétrer les services à surveiller...

Pour SSH par exemple :

[ssh]
enabled = true
filter = sshd
action = iptables46-multiport[name=ssh, port=ssh, protocol=tcp]
logpath = /var/log/auth.log
maxretry = 6

ou pour Apache (en utilisant la spécificité du multi-port) :

[apache]
enabled = true
filter = http,https
action = iptables46-multiport[name=ssh, port="http,https", protocol=tcp]
logpath = /var/log/apache*/*error.log
maxretry = 6

vendredi 18 octobre 2013

Votre service est-il en ligne ou hors ligne ? Le savoir sans délai avec Monit.

La grande frousse pour de nombreux administrateurs (enfin j'imagine), c'est la panne d'un système critique (généralement un samedi matin) qui passe inaperçue... Je vais vous présenter ici le petit utilitaire 'monit' qui, tout simplement, vous permettra de recevoir des notifications en cas de panne d'un de vos services. Et d'effectuer un ensemble de réactions ! C'est très certainement l'allié indispensable aux côtés de Munin que je présentais dernièrement !

Monit (à ne pas confondre avec M/Monit qui est son grand-frère non libre) est un ingénieux petit logiciel auquel on donne des missions de surveillance et des actions à effectuer lorsque certains comportements sont constatés. Je ne résiste pas à la tentation de recopier ici la bannière trouvée sur le site de monit : Monit, barking at daemons!

Un cas typique d'utilisation est le suivant : vous avez un processus P qui doit tourner sur votre machine mais que vous craignez voir s'arrêter... Vous pouvez demander à monit de vérifier toutes les X minutes que ce processus tourne toujours et le redémarrer si monit le trouve éteint. Dans ce cas, vous exécuterez monit sur le serveur qui propulse le processus à surveiller.

Autre scénario : votre serveur HTTP tourne sur l'adresse 2000:aaaa:bbbb:: et le port 80 et vous voulez vous assurer qu'il est toujours joignable. Monit peut se connecter à cette IP (ping) et dialoguer avec le service (voire même effectuer des requêtes HTTP complètes et évaluer la réponse) pour déterminer s'il est vivant. Et cela peut également fonctionner pour surveiller un FTP, un IMAP, un serveur OpenVPN... Dans ce cas, on hébergera monit sur le serveur local ou bien à distance si l'on souhaite également détecter une perte de connectivité (attention toutefois au cas de la coupure du serveur chargé de la surveillance !).

Et Monit permet bien plus encore : vérifier la présence d'un fichier, vérifier les droits sur un dossier, vérifier que la charge CPU ou la mémoire vive n'ont pas éteint des niveaux trop élevés et agir si nécessaire... Monit voit et agit !

L'installation de monit s'effectue (sous Debian) par un classique :

aptitude install monit

Pour le paramétrage, on parcourra d'abord /etc/monit/monitrc :

# Vérifier l'état des services toutes les 2 minutes
set daemon 120
# Raconter le quotidien dans un fichier
set logfile /var/log/monit.log
# Communiquer avec l'ami SMTP pour envoyer des courriels d'alerte
set mailserver monsmtp.domain.tld username "Moi" password "MonMDP" using tlsv1
# Choisir l'expéditeur de son choix quand Monit nous parle
set mail-format { from: monit@monserveur.domain.tld }
# Choisir à qui les alertes sont envoyées
set alert mon@courriel.fr
# Inclure les éléments de configuration compris dans /etc/monit/conf.d/
include /etc/monit/conf.d/*

On pourra s'occuper du ménage concernant le fichier de log (/var/log/monit.log) à l'aide de logrotate comme expliqué ici (section 'envie de rotation?').

Entrons alors dans le vif du paramétrage...

check host monsite.domain.tld with address a.b.c.d
 if failed icmp type echo count 3 with timeout 3 seconds then alert
 if failed port 80 protocol http with timeout 15 seconds then alert
 if failed port 1194 type udp with timeout 15 seconds then alert

La routine ci-dessous ne fait qu'envoyer des alertes : (i) si le serveur ne répond plus au ping, (ii) si un serveur web ne répond plus sur le port 80 et (iii) si un service ne répond pas en UDP sur le port 1194 (OpenVPN par exemple). Monit exécute chaque test les uns après les autres. Lorsqu'un test échoue au sein d'un groupe alors les tests suivants ne sont pas effectués. Monit envoie automatiquement un message lorsque le service est perdu et prévient également (c'est bien aimable de sa part) quand le service est rétabli.

Plus ardu :

check process apache with pidfile /usr/local/apache/logs/httpd.pid
  start program = "/etc/init.d/httpd start" with timeout 60 seconds
  stop program  = "/etc/init.d/httpd stop"
  if cpu > 60% for 2 cycles then alert
  if cpu > 80% for 5 cycles then restart
  if totalmem > 200.0 MB for 5 cycles then restart
  if children > 250 then restart
  if loadavg(5min) greater than 10 for 8 cycles then stop
  if failed host www.tildeslash.com port 80 protocol http
      and request "/somefile.html"
      then restart
  if failed port 443 type tcpssl protocol http
     with timeout 15 seconds
     then restart
  if 3 restarts within 5 cycles then timeout
  depends on apache_bin
  group server

Le script ci-dessous adopte le comportement suivant :

  • une alerte est émise sur la charge CPU est supérieure à 60% au cours de 2 vérifications successives
  • le serveur Apache est redémarré si la charge CPU est supérieure à 80% au cours de 5 vérifications successives
  • le serveur Apache est redémarré si la mémoire consommée est supérieure à 200 MB au cours de 5 vérifications successives
  • le serveur Apache est redémarré si plus de 250 processus fils sont détectés
  • le serveur Apache est stoppé (pas redémarré) si la charge est supérieure à 10 pendant 8 vérifications
  • le serveur Apache est redémarré si l'hôte www.tildeslash.com ou l'appel du fichier somefile.html échouent
  • le serveur Apache est redémarré si l'accès en HTTPS n'est pas disponible
  • et enfin si 3 redémarrages sont constatés en 5 cycles alors on passe à une alerte de niveau supérieur (timeout)

Je ne couvre ici qu'une faible part des possibles et je vous invite à explorer ! Un superbe outil à mettre dans toutes les mains !

Forcer la bascule vers HTTPS derrière un 'reverse proxy'

Pound (déjà évoqué à de nombreuses reprises dans ces lignes) est un 'reverse proxy' (et aussi un 'load balancer' si on souhaite utiliser ces fonctionnalités) très efficace... Il peut notamment gérer toutes les connexions en HTTPS vers vos serveurs web, les décrypter et ensuite les distribuer (bien sûr ce n'est à faire que sur un réseau local hermétique aux oreilles indiscrètes !) en HTTP à vos différents serveurs.

Selon les configurations, on acceptera les connexions en HTTP ou HTTPS ou seulement l'une ou l'autre. Parfois, on souhaite récupérer les utilisateurs qui se connectent en HTTP et les renvoyer automatiquement vers HTTPS.

Il faut alors demander au serveur web sous-jacent de réécrire les adresses, ce qui, sous Apache, se fait de la façon suivante :

        RewriteEngine on
        RewriteCond %{HTTP:X-Forwarded-Proto} !https
        RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R,L]

On notera que la réécriture ne s'applique que dans les cas où le drapeau 'X-Forwarded-Proto' n'est pas déjà HTTPS.

On peut bien sûr restreindre ce paramétrage à certains dossiers seulement (même si généraliser le HTTPS aujourd'hui serait une bonne pratique).

Pour restreindre cette ré-écrire (et donc ne forcer la connexion en HTTPS) que sur certains dossiers, on pourra inclure ces instructions dans un champ Directory :

        <Directory /var/www/appli/admin>
                RewriteEngine on
                RewriteCond %{HTTP:X-Forwarded-Proto} !https
                RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
        </Directory>

Ne laissez plus vos mots de passe transités en clair sur le net ! Forcez HTTPS a minima sur les zones sensibles !

dimanche 8 septembre 2013

DNS local et filtrage DNS tout simplement

Il est très simple de mettre en place un petit DNS local dans un environnement domestique (ou professionnel de petite taille). Les avantages peuvent être nombreux : accélérer (un peu) la connexion à internet en gardant en cache les résultats des requêtes DNS les plus fréquentes (soyons toutefois réalistes, le gain restera modeste), attribuer des noms résolus à chacun de vos périphériques et... bloquer certains sites par filtrage DNS .

Le filtrage DNS a l'avantage de concerner tous les périphériques connectés au réseau et d'interdire également la connexion en HTTPS aux sites choisis, ce que le filtrage simple par URL ne permet pas en HTTPS. Ce type de filtrage pourra être pratique pour interdire l'accès à certains sites et couper certains serveurs de publicité. Il existe également des listes de sites aux contenus choquants en libre accès sur le net (souvent générées pour SquidGuard) que l'on pourra également réutiliser. Un utilisateur pourra bien sûr contourner ce filtrage en spécifiant des serveurs DNS différents ou en utilisant un proxy ou tunnel de son choix.

Pour la mise en place du filtrage DNS, déployons le logiciel dnsmasq qui est à la fois un serveur DHCP et un serveur DNS. Bien sûr, la fonction DHCP peut-être désactivée si elle est déjà réalisée par un autre service sur le réseau. Toutefois, notons que dnsmasq ne pourra alors pas automatiquement inclure dans les DNS les entrées correspondantes aux noms d'hôte des périphériques connectés (et auxquels une adresse a été attribuée par DHCP).

DNSMasq

Commençons par installer dnsmasq avec le sélecteur de paquet de son choix - l'exemple ci-dessous est valable pour Debian ou les distributions dérivées : aptitude install dnsmasq

Nous allons ensuite paramétrer le service dans /etc/dnsmasq.conf :

Paramétrage du DNS

  • Par défaut, dnsmasq cherche à effectuer la résolution de nom en consultant les associations du fichier /etc/hosts et en relayant les requêtes aux serveurs DNS spécifiés dans /etc/resolv.conf (ces 2 fichiers se trouvant sur la machine hébergeant dnsmasq). Si ce comportement ne vous sied pas, il est possible de commander à dnsmasq de ne pas prendre en compte ces fichiers (toute la configuration sera donc faite dans /etc/dnsmasq.conf)
no-resolv
no-hosts
  • On précise ensuite l'adresse des serveurs DNS à qui il faut relayer toute requête que dnsmasq n'aura pas su résoudre en local :
server=8.8.8.8
server=8.8.4.4
  • On ajoute ensuite les entrées spécifiques que l'on souhaite voir résolues par dnsmasq :
address=/site-interdit.com/192.168.1.1
address=/autre-site-interdit.biz/192.168.1.1

Les 2 sites mentionnés seront donc résolus vers 192.168.1.1. On peut imaginer que 192.168.1.1 héberge un serveur web qui affichera une page signalant à l'utilisateur le blocage.

  • Pour activer le cache DNS, on prendra le soin d'ajouter la ligne :
cache-size=500

500 requêtes sont donc toujours conservées en mémoire par dnsmasq. A modifier à votre volonté selon la RAM disponible et le nombre de requêtes reçues...

  • Et pour activer les logs et garder une trace de toutes les requêtes DNS reçues (par exemple pour analyser l'utilisation du cache et son optimisation) :
log-facility=/var/log/dnsmasq.log
log-queries

Paramétrage du DHCP

  • Voici maintenant le paramétrage du DHCP si l'on décide d'utiliser cette fonctionnalité. On commencera par définir les adresses que le serveur peut allouer ainsi que la durée de renouvellement :
dhcp-range=192.168.1.5,192.168.1.199,255.255.255.0,12h
  • On pourra ensuite ajouter des adresses fixes pour certains hôtes reconnus par leur adresse MAC :
dhcp-host=00:00:ab:cd:ef:12,ordinateur1,192.168.1.5
dhcp-host=00:00:ab:cd:ef:34,ordinateur2,192.168.1.6
  • Le serveur DHCP peut également communiquer à tous les clients l'adresse de la passerelle vers internet :
dhcp-option=option:router,192.168.a.b

Pour expliquer à tous les clients d'utiliser dnsmasq comme seul serveur DNS, on ajoutera finalement :

dhcp-option=6,192.168.c.d

en remplaçant bien sûr 192.168.c.d par l'adresse à laquelle dnsmasq répondra !

  • Last but not least, il faut bien sûr que le serveur DNS soit accessible. Donc il faudra faire le nécessaire pour que le pare-feu accepte les communications entrantes et sortantes sur le port 53. Si le pare-feu est iptables, voilà qui devrait faire l'affaire :
iptables -A INPUT -p udp --sport 53 -j ACCEPT
iptables -A INPUT -p udp --dport 53 -j ACCEPT
iptables -A OUTPUT -p udp --sport 53 -j ACCEPT
iptables -A OUTPUT -p udp --dport 53 -j ACCEPT

Voilà votre petit serveur DHCP et DNS accessible sur votre réseau local avec les éventuels raccourcis ou filtrages de vos choix !

samedi 11 mai 2013

Lynis pour mieux sécuriser un serveur Linux

J'ai découvert tout récemment un petit utilitaire fort pratique pour évaluer la sécurité d'un serveur Linux. Bien sûr, il ne faut pas s'attendre à tout repérer avec ce genre d'outils - mais gageons que les optimisations les plus importantes seront signalés !

L'utilitaire s'appelle lynis, développé par Michael Boelen, http://www.rootkit.nl/projects/lynis.html. Il se trouve assez certainement dans les dépôts de votre distribution.

Une fois installé, on lancera un scan par la commande :

lynis --check-all -Q

Le rapport d'exécution est assez explicite et vous signalera les points à corriger sans tarder ainsi que des suggestions pour renforcer la sécurité.

Je l'ajoute à ma trousse à outils d'administrateur !

page 2 de 2 -