Mot-clé - réseau

Fil des billets

mercredi 30 octobre 2013

Crypter une partition et l'ouvrir sans crainte d'un keylogger

Nous allons utiliser dm-crypt+LUKS qui se basent sur les outils de cryptographie présents normalement dans le noyau linux. On pourra faire le reproche à cette solution de ne pas permettre mettre en place un déni plausible (i.e. ouvrir une partition avec des données à l'apparence normale sous la contrainte, TrueCrypt le permet).

Création de la partition

La partition à crypter se nomme : /dev/sdaX Choisissons le chiffrement aes-xts-plain avec un taille de clé de 512 bits :

cryptsetup luksFormat -c aes-xts-plain -s 512 /dev/sdaX

Le système demande une 'passphrase' que l'on choisira bien sûr longue, avec de nombreux caractères accentués, des chiffres, des majuscules, des signes de ponctuation... Attention à ne pas perdre la 'passphrase' car sans elle, point de salut !

Puis accédons au périphérique :

cryptsetup luksOpen /dev/sdaX zonecryptee

et formatons l'espace comme souhaité puis montons le :

mkfs.ext3 /dev/mapper/zonecryptee
mount -t ext3 /dev/mapper/zonecryptee /mnt/dossiercrypte/

Pour fermer la partition cryptée :

umount /mnt/dossiercrypte/
cryptsetup luksClose zonecryptee

Pour obtenir des informations sur la partition crypée, on fera :

cryptsetup luksDump /dev/sdaX

Ajouter une clé pour accéder à la partition

Grâce à LUKS, on peut saisir plusieurs clés (jusqu'à 8) pour accéder à un même espace crypé. Commençons par générer une longe clé aléatoire :

dd if=/dev/urandom of=keyfile bs=1024 count=4

et ajoutons cette clé à l'espace crypté :

cryptsetup luksAddKey /dev/sdaX keyfile

On pourra désormais ouvrir l'espace, sans saisir la 'passphrase' secrète et sans crainte d'un keylogger ou d'une caméra qui filmerait nos mains sur le clavier, grâce à la commande :

cryptsetup --key-file=keyfile luksOpen /dev/sdaX zonecryptee

Après ouverture, la clé peut être retirée du système (elle n'est nécessaire qu'à l'ouverture) afin de limiter son exposition aux regards. Bien sûr, il ne faut pas perdre le fichier 'keyfile' et le conserver en sûreté ! S'il était compromis, on pourrait révoquer la clé avec la commande :

cryptsetup luksRemoveKey /dev/sdaX

Refermer la partition

Là rien ne change :

umount /mnt/dossiercrypte/
cryptsetup luksClose zonecryptee

Protégez-vous bien !

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

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 !

mercredi 16 octobre 2013

Apache derrière un 'reverse proxy' : la magie du X-Forwarded-For

Si votre serveur Web se trouve "caché" derrière un "reverse proxy" ou toute forme de "load balancer", alors vous serez peut-être embêté en constatant que les logs d'accès d'Apache ne mentionnent par défaut que l'adresse du proxy comme adresse d'origine... Ennuyeux !

Heureusement, les esprits ingénieux qui ont conçu les "reverse proxies" ont pensé à ajouter aux paquets transmis le drapeau "X-Forwarded-For". Il suffit alors de demander à votre serveur web de prendre en compte l'IP spécifiée dans ce champ comme origine de la communication !

Dans le cas d'Apache2, la configuration intiale qui était :

LogFormat "%v:%p %h %l %u %t "%r" %>s %O "%{Referer}i" "%{User-Agent}i"" vhost_combined
LogFormat "%h%l %u %t "%r" %>s %O "%{Referer}i" "%{User-Agent}i"" combined
LogFormat "%h %l %u %t "%r" %>s %O" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent

devient (on remplace %h par %{X-Forwarded-For}i) :

LogFormat "%v:%p %{X-Forwarded-For}i %l %u %t "%r" %>s %O "%{Referer}i" "%{User-Agent}i"" vhost_combined
LogFormat "%{X-Forwarded-For}i %l %u %t "%r" %>s %O "%{Referer}i" "%{User-Agent}i"" combined
LogFormat "%{X-Forwarded-For}i %l %u %t "%r" %>s %O" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent

Pour les logs d'erreur (importants par exemple pour permettre à fail2ban, ou un autre démon du genre, d'agir), la version 2.2 d'Apache ne permet malheureusement pas de prendre en compte un format spécifique pour les logs. Il semble que cela soit corrigé dans la version 2.4 d'Apache (cf. ici). Si vous utilisez la version 2.2, alors il faudra installer le module rpaf :

aptitude install libapache2-mod-rpaf
a2enmod rpaf

puis dans /etc/apache2/conf.d/mod_rpaf :

RPAFenable On
RPAFsethostname On
RPAFproxy_ips a.b.c.d e.f.g.h
RPAFheader X-Forwarded-For

en remplaçant a.b.c.d et e.f.g.h par les adresses du reverse proxy. RPAF va veiller, dans les logs d'erreur, à remplacer l'adresse du 'reverse proxy' par l'adresse du client telle que signalée dans "X-Forwarded-For".

Et le tour est joué !

Enregistrer les logs de Pound avec rsyslog et logrorate

Pound est un reverse proxy fort pratique. Par défaut, aucun log des connexions n'est enregistré mais cela se paramètre...

Voici une configuration fonctionnelle sur Debian.

Dans /etc/pound/pound.cfg :

LogFacility     local0
LogLevel        1

Dans /etc/rsyslog.d/pound.conf :

local0.* -/var/log/pound.log

et dans /etc/rsyslog.conf :

*.*;auth,authpriv.none              -/var/log/syslog

devient :

*.*;auth,authpriv.none,local0.none              -/var/log/syslog

Dans /var/log, on crée le fichier de log (et on en modifie les droits si nécessaire) :

touch /var/log/pound.log
chown rood:adm /var/log/pound.log

On redémarre alors les 2 services rsyslog et pound :

service rsyslog restart
service pound restart

Envie de rotation ?

Les logs de Pound peuvent rapidement atteindre des tailles phénoménales s'il gère des traffics importants. A surveiller donc sur les premières journées d'utilisation ! Le cas échéant, on peut utiliser une rotation de log pour garder les données des quelques derniers jours et éviter la disparaition de l'espace libre sur un serveur !

Dans /etc/logrotate.d/pound :

/var/log/pound.log {
        daily
        missingok
        rotate 7
        compress
        copytruncate
        notifempty
        create 640 root root
}

vendredi 11 octobre 2013

Reverse IPv6 avec DNSMasq, chez Online.net

Comme raconté ici, le postmaster de Google a adopté une position très stricte de rejet de tout courriel provenant d'un serveur SMTP se connectant en IPv6 mais ne disposant pas de champ 'reverse' concordant.

On peut déplorer cette très grande rigidité et s'en étonner, surtout dans une période d'adoption progressive de l'IPv6. Pour ceux dont le fournisseur d'accès (plus précisément le fournisseur de votre bloc d'adresses IPv6) ne donne aucun moyen d'avoir un 'reverse', une solution temporaire est proposée ici : connexion en IPv4 à Google.

Dans le cas d'Online.net, la possibilité d'une délégation DNS est apparue récemment en production. Elle permet d'indiquer à quel serveur DNS se raccrocher pour effectuer la translation de nom inverse (i.e. d'adresse IP vers nom de domaine) pour les adresses du bloc.

Etape 1 : disposer d'un serveur DNS capable de répondre aux requêtes "reverse"

La grande référence du DNS est bind, mais on peut également monter ce petit service en moins de 10 lignes de configuration avec DNSMasq (dont je parlais déjà ici).

On installe dnsmasq par

aptitude install dnsmasq

et voici un exemple de configuration complète :

log-facility=/var/log/dnsmasq.log
log-queries
no-resolv
no-hosts
ptr-record=0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0.h.g.f.e.d.c.b.a.1.0.0.2.ip6.arpa,monreverse1.domain.tld
ptr-record=1.0.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0.h.g.f.e.d.c.b.a.1.0.0.2.ip6.arpa,monreverse2.domain.tld

Les paramètres log-facility et log-queries indiquent que l'on souhaite garder une trace de toutes les requêtes DNS dans /var/log/dnsmasq.log

no-resolv et no-host ainsi que l'absence de paramètre server indiquent que l'on ne souhaite répondre positivement qu'aux requêtes correspondant à l'un des enregistrements mentionnés dans le fichier de configuration.

Et enfin, sont indiqués les 2 enregistrements PTR qui correspondent à 2 adresse IPv6 pour lesquelles on souhaite avoir un reverse IPv6.

La première adresse est 2001:abcd:efgh:100:: et la seconde est 2001:abcd:efgh:100::101. On voit que l'adresse est mentionnée dans l'enregistrement PTR en l'écrivant "à l'envers" et en séparant chaque caractère (y compris les 0 que la convention nous permet de ne pas faire apparaître dans les adresses IPv6) par un point.

Etape 2 :

On rend ce serveur DNS très simple (et capable de ne répondre qu'à ces 2 requêtes reverse IPv6) accessible à l'adresse dns.domain.tld. Si on est placé derrière un firewall, on n'oubliera pas d'ouvrir le port 53 en TCP et en UDP.

Etape 3 : paramétrer la délégation DNS chez le fournisseur du bloc IPv6

Cette étape diffère selon le fournisseur du bloc IPv6. Chez Online, il faut se rendre dans la console, onglet "Serveur" puis "Paramétrage du réseau". On choisit le bloc IPv6 de son choix et on clique sur l'option "Paramétrer la délégation DNS". On saisit alors l'adresse du serveur DNS capable de répondre aux éventuelles requêtes reverse IPv6.

Délégation DNS chez Online

Etape 4 : on peut à nouveau écrire aux destinataires de GMail

Si on expédie un message à un destinataire @gmail.com, quelques secondes plus tard, on voit apparaître dans les logs la requête DNS suivante :

Oct 6 14:04:59 dnsmasq[21288]: query[PTR] 
1.0.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0.h.g.f.e.d.c.b.a.1.0.0.2.ip6.arpa **from 74.125.18.211**

74.125.18.211 est une adresse (IPv4 !) de Google qui vient s'enquérir du reverse IPv6. Et le courriel est expédié sans encombre !

Bons paramétrages de reverse IPv6 à tous !

mardi 10 septembre 2013

Partager un fichier, le faire disparaître après partage et savoir (approximativement) qui l'a téléchargé

J'utilise souvent demo.ovh.eu (le service de partage mis en place par OVH, qui, contrairement à beaucoup d'autres, n'oblige pas à visualiser des publicités) pour partager aisément des fichiers sur internet. Toutefois, je souhaiterais parfois que le fichier soit effacé après téléchargement et savoir quand celui-ci a été téléchargé. Certains services proposent sans doute cela et l'outil Jyraphe (dont le développement est stoppé ?) le permet. Je vous propose toutefois une solution maison toute simple à mettre en place et extrêmement simpliste à déployer sur serveur web + PHP !

Soit le fichier mon_archive.7z à proposer au téléchargement. Soit /var/www/ la racine du serveur web accessible sur le net. On place le fichier mon_archive.7z dans un dossier /var/www/hidden/ qu'un fichier .htaccess protège de toute ouverture. On place ensuite le code suivant dans un fichier /var/www/telechargement-ici_chaîne_unique_non_devinable.php :

<?php
    $yourfile = "hidden/mon_archive.7z";

    if (file_exists($yourfile)) {
        $file_name = basename($yourfile);

        header("Content-Type: application/zip");
        header("Content-Disposition: attachment; filename=$file_name");
        header("Content-Length: " . filesize($yourfile));

        readfile($yourfile);
        unlink($yourfile);
        if (file_exists($yourfile)) {
            mail('moi@courriel.fr', 'Fichier téléchargé mais pas supprimé !', 'Le fichier "'.$file_name.'" a bien été téléchargé par '.$_SERVER["REMOTE_ADDR"].' et n\'a pas été supprimé.');
        }
        else {
            mail('moi@courriel.fr', 'Fichier téléchargé et supprimé !', 'Le fichier "'.$file_name.'" a bien été téléchargé par '.$_SERVER["REMOTE_ADDR"].' et a été supprimé.');
        }
    }
    else {
        print "Unknown file...";
        mail('moi@courriel.fr', 'Tentative de téléchargement infructueuse.', 'Qqn ('.$_SERVER["REMOTE_ADDR"].') a tenté en vain de télécharger le fichier "'.$yourfile.'".');
    }
    exit;
?>

Le fichier php propose donc le fichier au téléchargement quand l'utilisateur appelle https://monserveur/telechargement-1g2j0a7j8.php puis l'efface du serveur et vous préviens (par courriel) que le téléchargement a eu lieu. Il enregistre également l'adresse IP de la personne qui a effectué le téléchargement (certes, c'est très approximatif comme identification). Le mot de passe est en fait la chaîne arbitrairement complexe et longue placée dans l'URL pour accéder au fichier .php permettant le téléchargement.

On pourrait améliorer encore la sécurité en récupérant le mot de passe (la chaîne arbitraire) dans un paramètre GET (?pass=1g2j0a7j8 par exemple) et bannir une IP qui ferait plus de 3 ou 4 tentatives d'accès infructueuses.

Le cahier des charges est respecté, ce n'est pas tout à fait automatique mais ça ne devrait pas être trop difficile à scripter si vous avez de nombreux fichiers de la sorte à mettre à disposition. Et surtout, votre archive (peut-être très confidentielle) ne transite pas sur un serveur tierce.

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 !

dimanche 9 juin 2013

Transformer un Raspberry Pi en passerelle vers Hubic d'OVH : Nginx, script Toorop & Cloudfuse

10 mars 2014 - Attention, il semble que le code de https://github.com/Toorop/HubicSwiftGateway ne soit plus fonctionnel aujourd'hui... Il faudrait vraisemblablement se rabattre vers https://github.com/oderwat/hubic2swiftgate...

Hubic est une intéressante offre de stockage en ligne proposée par OVH, le champion français de l'hébergement web. Elle dispose notamment d'un bon rapport qualité/prix (60€ HT/an pour 500 Go). Mais elle souffre de plusieurs défauts : pas de client Linux disponible au moment de l'écriture de ces lignes, et le client Windows/MacOs se résume à un client de synchronisation comme le client d'ownCloud ou celui de Dropbox et peut être insuffisant pour réaliser des sauvegarde de données (par exemple des photos).

Voici une reprise de plusieurs bonnes idées glanées sur le net pour pallier ces défauts : nous allons transformer un Raspberry Pi en passerelle Hubic ce qui permettra à tous les périphériques du réseau local d'accéder à Hubic en se passant du client d'OVH.

Introduction technique

Hubic s'appuie (si la presse spécialisée dit vrai) sur OpenStack, et plus précisément sur OpenStack Object Storage encore appelé Swift. Il est donc possible de se connecter à Hubic à l'aide d'un client swift que l'on pourra installer sur son système avec son gestionnaire de paquets préféré (pour les non-linuxiens, Cyberduck intègre normalement les fonctionnalités d'un client swift).

Toutefois, OVH a ajouté à Hubic une couche d'authentification qui n'est pas gérée par défaut par les clients swift. Heureusement entrent alors en jeu les talents de Toorop et son fort utile script que nous allons déployer plus bas.

Un script PHP pour passer l'étape d'authentification

Toorop a développé un script fort utile qui se charge de l'authentification auprès d'Hubic et permet ensuite une "libre" communication avec un client swift. Le script en question est codé en PHP et est disponible ici : https://github.com/Toorop/HubicSwiftGateway.

Installons d'abord un serveur web + PHP sur le Raspberry Pi (que l'on considèrera dans la suite propulsé par Raspbian, dérivée de Debian). Par souci de légèreté, nous déploierons ici Nginx :

aptitude install nginx php5-fpm

puis téléchargeons le script de Toorop :

cd /var/www
git clone https://github.com/Toorop/HubicSwiftGateway.git
cp -R /var/www/HubicSwiftGateway-master/src/www /var/www/HubicSwiftGateway

et créons un nouvel hôte virtuel dans la configuration de nginx qui pointera vers /var/www/HubicSwiftGateway :

touch /etc/nginx/sites-available/hubicgw

Le fichier de configuration pourra contenir :

server {
       server_name hubicgw.raspberry.lan;
       root /var/www/HubicSwiftGateway;
       index index.html index.htm index.php;

       location ~ \.php$ {
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                fastcgi_pass unix:/var/run/php5-fpm.sock;
                fastcgi_index index.php;
                include fastcgi_params;
        }
}

On active cet hôte virtuel par :

cd /etc/nginx/sites-enabled
ln -s ../sites-available/hubicgw

et on redémarre nginx :

service nginx restart

La première étape est passée : si on appelle dans le navigateur hubicgw.raspberry.lan alors le système devrait répondre "Headers AUTH_USER and/or AUTH_KEY are missing" ce qui est normal et atteste d'un bon fonctionnement du script php. Le travail sur le Raspberry Pi s'achève ici : il est fin prêt à jouer le rôle de passerelle vers Hubic.

Se connecter alors avec le client swift

A partir de maintenant, les actions sont à effectuer sur les postes depuis lesquels on souhaite accéder à Hubic. On peut dès lors se connecter à Hubic à l'aide du client swift que l'on aura préalablement installé sur la machine de son choix (par ex. aptitude install swift sous Debian) :

swift -A http://hubicgw.raspberry.lan/ -U login_hubic -K motdepasse_hubic

(bien sûr, si le réseau local sur lequel on se trouve n'est pas parfaitement sécurisée Wifi, CPL..., on veillera à activer une connexion https pour éviter que des oreilles indiscrètes ne viennent écouter notre login et notre mot de passe Hubic !)

Simplifier l'accès grâce à cloudfuse

Nous allons poursuivre en installant sur le poste local le petit utilitaire cloudfuse que l'on trouvera ici : https://github.com/redbo/cloudfuse. Une fois téléchargé, il faut le compiler et l'installer par :

./configure
make
make install

On créera alors un fichier .cloudfuse à la racine du compte utilisateur :

username=login_hubic
authurl=http://hubicgw.raspberry.lan
cache_timeout=20

et la commande suivante permettra d'effectuer le montage de l'accès hubic comme un dossier classique de votre ordinateur :

cloudfuse /mnt/hubic/ api_key=password_hubic

Il nous est dès lors possible de naviguer au sein de l'espace hubic depuis le gestionnaire de fichiers favori.

Faire ses sauvegardes avec rsync sur Hubic

Tout est en place pour la dernière étape : nous pouvons désormais utiliser rsync (fameux logiciel unix de sauvegarde) pour synchroniser notre répertoire de photos avec sa sauvegarde en ligne :

rsync -var --size-only /path/to/my/photos /mnt/hubic/default/mon/dossier/photos

Bonnes sauvegardes !

jeudi 6 juin 2013

"Stress test" pour une application Web - cas pratique sur Raspberry

Ceux qui auront lu mon précédent article ne seront pas étonnés si j'annonce que j'ai tout récemment déployé une application web (Zend Framework 1 + Doctrine 2 + PHP5 + MySQL) sur un (petit - euh... enfin normalement petit) Raspberry Pi (modèle B). Toutefois, je décidai d'étudier plus avant le système mis en place en le soumettant à un 'stress test' simulant un fort afflux d'utilisateurs effectuant diverses requêtes au sein de l'application.

Les applications de 'stress test' ne manquent pas et j'avais déjà entendu parler de JMeter et Tsung. Mais pour ce test, je décidai d'utiliser Gatling : logo-Gatling-StressTool.png

Gatling (open source, disponible sur http://gatling-tool.org/) est codé en Scala et s'exécute sans difficulté dans un environnement disposant d'une machine virtuelle Java. Pas d'installation nécessaire : on décompresse l'archive et les binaires de l'application sont disponibles dans /bin/.

Mise en place d'un scénario de stress : à la main...

Les scénarios de test de Scala sont à créer et placer dans /user-files/simulations dans des fichiers scala. La structure de base d'un fichier est la suivante :

import com.excilys.ebi.gatling.core.Predef._
import com.excilys.ebi.gatling.http.Predef._
import com.excilys.ebi.gatling.jdbc.Predef._
import Headers._
import akka.util.duration._
import bootstrap._
import assertions._

class SimulationWithFollowRedirect extends Simulation {
  val scn = scenario("My scenario")
            .exec(http("My Page")
              .get("http://mywebsite.com/page.html"))
  
  setUp(scn.users(1))
}

Il est donc possible en Scala de coder la liste des actions qu'effectueront les utilisateurs virtuels (des requêtes GET, des requêtes POST, le lancement de certaines routines PHP...). A la fin du fichier, la simulation est lancée par

  setUp(scn.users(x))

où x (entier naturel strictement positif) représentera le nombre d'utilisateurs qui seront simulés concurremment sur l'application.

Mise en place d'un scénario de stress : en automatique pour aller plus vite !

L'écriture du scénario "à la main" est très souple mais un petit peu complexe. Il existe donc un petit utilitaire (recorder) particulièrement pratique qui peut venir à notre rescousse. Il s'agit d'une application qui vient se positionner comme un proxy sur le navigateur web et qui enregistre toutes les opérations effectuées par le navigateur directement sous la forme d'un fichier Simulation.scala utilisable par Gatling.

Le 'recorder' se lance par :

sh bin/recorder.sh

Si les ports du proxy (HTTP/HTTPS, spécifiés en haut à gauche) conviennent, on clique sur 'Start' et désormais l'application enregistrera tout mouvement réalisé au travers du proxy.

Gatling-recorder.png

Une fois l'enregistrement terminé, on peut bien sûr modifier le scénario de simulation (suppression des pauses non nécessaires, suppression de certaines étapes...) en éditant le fichier MaSimulationDuJour.scala qui aura été créé dans /user-files/simulations. On peut notamment augmenter le nombre d'utilisateurs qui seront simulés :

  setUp(scn.users(100))

et on peut simuler une montée en charge progressive par la commande finale :

  setUp(scn.users(100).ramp(200)

qui signifie que 100 utilisateurs se connecteront progressivement pendant 200 secondes (soit 1 nouvel utilisateur toutes les 2 secondes). Bien sûr, si votre serveur répond bien et que la durée de simulation est courte alors il est possible que vous n'ayez jamais 100 utilisateurs connectés en même temps (car une fois que l'utilisateur simulé a terminé toutes les étapes alors il se déconnecte à moins que vous ne paramétriez des boucles). Le rapport d'analyse (cf. infra) vous permettra de bien visualiser ce phénomène.

Lancement du stress test

On lance donc gatling

sh bin/gatling.sh

qui propose de choisir la simulation à lancer. Et c'est parti !

L'état d'avancement du 'stress test' s'affiche dans la console. Une fois celui-ci terminé, un rapport est généré et est accessible dans le dossier /results/.

Voici un petit aperçu d'un rapport obtenu (sur un PC de bureau 4 coeurs +4 Go de RAM) : Gatling_-_stresstest1.png Gatling_-_stresstest2.png

Conclusion du stress test

Sur mon Raspberry Pi, je suis un peu déçu car dès 10 utilisateurs en concurrence les accès à la base de données et les requêtes pour les contenus non statiques mettent un temps long (les moyennes vont de 20 à 40 secondes selon les requêtes) à s'exécuter... Je m'attendais à ce que la Raspberry Pi ne tienne pas bien la charge mais je pensais la limite atteinte moins vite. C'est également le signe que le code de l'application n'est pas optimisé pour une exécution très légère et très économe en ressources ! Il va me falloir plonger dans le code pour optimer tout cela !

Très bonne journée à tous et bons 'stress tests' !

dimanche 26 mai 2013

Mieux paramétrer le serveur DHCP du modem TG788 distribué par OVH à ses cients ADSL

OVH distribue à ses clients ADSL (et VDSL2 !) le modem TG788 (modem/routeur Thomson compatible VDSL2). Si vous aussi vous trouvez que les options de paramétrage du serveur DHCP (en IPv4) ne sont pas suffisantes, alors rassurez-vous car il existe de bien plus nombreuses possibilités via telnet.

Dans une console (sous Linux) ou bien dans Putty (sous Windows), on se connecte au modem :

telnet 192.168.1.254

Utilisateur : Administrator
Password : *****************

et là c'est tout un monde de commandes qui est ouvert.

Par exemple, pour supprimer un bail DHCP et le remplacer par un nouveau bail (par exemple pour choisir l'IP affectée à un appareil) :

dhcp server lease list
dhcp server lease delete clientid=00:23:4d:xx:xx:xx 
dhcp server lease add clientid=00:23:4d:xx:xx:xx pool=LAN_private addr=192.168.1.100 leasetime=0 
saveall

et bien sûr de nombreuses autres options de paramétrage du serveur DHCP sont disponibles. Je n'ai pas trouvé sur le web le guide de référence du modem TG788 mais ai trouvé celui du TG576. Il y a toutefois fort à parier que la plupart des commandes sont similaires (cf TG576 CLI guide).

Wake on Lan - carte mère P7P55D et chipset Realtek RTL8111/8168B PCI Express Gigabit Ethernet controller

Si vous possédez une carte mère P7P55D ou bien toute autre carte dotée d'un chipset RTL8111/8168B PCI Express Gigabit Ethernet controller alors il est possible que le Wake on Lan (ou WOL) ne fonctionne pas sans quelques manipulations. Détaillons-les ensemble ici !

Etape 1 : permettre le WOL dans le BIOS

Les options et leurs intitulés peuvent évoluer d'un BIOS (d'une carte) à l'autre. Dans une P7P55D d'Asus, il faut aller dans Power > APM configuration > Wake-up by PCIe devices (Enabled). Une fois le BIOS bien paramétré, on redémarre le poste.

Etape 2 : envoyer le bon paramètre à la carte avec le driver Realtek

Il semble que le driver realtek fourni par défaut dans le noyau 3.2 (expédié en ce moment avec Debian testing alias Jessie) ne permette pas le WOL. Il faut donc télécharger la dernière version du driver ici ou bien ici. L'installation se déroule sans aucune difficulté en suivant les actions recommandées dans le fichier exécutable autorun.sh. La procédure conduit à la mise en place d'un nouveau module (dont on pourra vérifier le bon chargement par

lsmod | grep "r8168"

Pour enfoncer le clou, assurons-nous que le module r8169 (du noyau par défaut, qui ne permettait pas le WOL) ne se lance pas : éditons /etc/modprobe.d/blacklist.conf et ajoutant la ligne

#Stop r8169 loading so that r8168 will 
blacklist r8169

Nous pouvons alors vérifier que le WOL est bien activable comme détaillé ici :

sudo ethtool eth0 | grep "Wake"

qui doit retourner :

	Supports Wake-on: pumbg
	Wake-on: g

Wake-on: g signifie que le matériel répond bien et que le WOL est activé.

S'il ne l'est pas, voici la commande à exécuter :

ethtool -s eth0 wol g

Il est possible qu'il faille ré-exécuter cette commande après chaque redémarrage du système (non persistence de l'information) et des méthodes intelligentes pour ce faire sont décrites ici.

Etape 3 : en profiter

Vous pouvez désormais allumer votre ordinateur à distance à l'aide d'un 'Magic packet' envoyé par exemple par l'application etherwake en précisant l'adresse MAC de votre poste (sous la forme aa:bb:00:11:22:33) :

etherwake aa:bb:00:11:22:33

mercredi 26 décembre 2012

Demander aux robots de ne pas indexer un site internet

Il y a certains sites que l'on ne souhaite pas voir apparaître sur les moteurs de recherche - il faut donc expliquer aux moteurs de recherche qu'ils n'ont pas être indexés.

Facile, il suffira de créer un fichier robots.txt à la racine du site avec ce contenu :

User-agent: *
Disallow: /

dimanche 4 mars 2012

Nullmailer s'emballe

Si on lance Nullmailer (un Mail Transfer Agent très simple qui redirige les messages vers un SMTP externe par exemple) alors que le nom de la machine est mauvais, on risque de trouver dans ses logs l'erreur suivante :

Mar  4 08:46:38 mon-desktop nullmailer[4412]: smtp: Failed: 450 4.1.8 <root@mon-desktop.mon-desktop>: Sender address rejected: Domain not found

Pas de panique : il suffit de modifier le /etc/hostname de la machine pour paramétrer un domaine routable.

Ensuite, il peut être nécessaire de purger les anciens messages qui sont dans la file d'attente de nullmailer avec un expéditeur erroné : toute la queue est stockée dans /var/spool/nullmailer/queue. Donc :

cd /var/spool/nullmailer/queue
rm *

Et voilà, nullmailer ne devrait plus poser de problèmes désormais !

dimanche 12 juin 2011

Faire du ruby sur le web sans Rails : Sinatra

Sinatra peut être considéré comme une boîte à outil web pour Ruby très légère. Si Rails est bourré de fonctionnalités qui rendent la vie facile, il est parfois un peu démesuré d'utiliser Rails quand on veut juste exécuter un script Ruby et en afficher le résultat en ligne.

Une solution plus légère que Rails est Sinatra. [|http://www.sinatrarb.com/||http://www.sinatrarb.com/

Sinatra est un gem à ajouter à l'installation courante de Ruby :

gem install sinatra

On écrit alors le script en spécifiant les routes dans le code, par exemple :

#monApp.rb
require 'sinatra'

get '/hi' do
  "Hello World!"
end

get '/generate/:arg'
  generate(params[:arg])
end

def generate (arg)
  str=""
  5.times {
    str=str+","+arg
  }
  str
end

Ce code contient 2 routes : la première qui est appelée sur http://$host/hi et la seconde sur http://$host/generate/text.

On peut exécuter le script de manière locale en exécutant :

ruby -rubygems monApp.rb

(par défaut, le serveur de test est lancé sur http://localhost:4567)

Pour exécuter l'application via Passenger dans Apache, on ajoute dans le répertoire courant : - un dossier public (mkdir public) - un dossier tmp (mkdir tmp) - un fichier config.ru

qui contient par exemple le code suivant :

require 'rubygems'
require 'sinatra'
require '/path/to/myApp.rb'

root_dir = File.dirname(__FILE__)

set :environment, ENV['RACK_ENV'].to_sym
set :root,        root_dir
set :app_file,    File.join(root_dir, 'myApp.rb')
disable :run

run Sinatra::Application

On ajoute alors un VirtualHost convenable dans la configuration d'Apache et Passenger sert l'application Sinatra !

dimanche 15 mai 2011

Pound se plaint !

Pound est un petit outil qui peut faciliter la vie de l'administrateur d'un serveur web. C'est un proxy inverse (reverse proxy), répartiteur de charge (load balancer) et un gestionnaire HTTPS à placer en amont de serveurs Web (HTTPS front-end server).

Si les fonctions de répartition de charge ne concerneront pas les petites installations, il peut toutefois rendre bien des services pour gérer l'accès HTTPS à des serveurs web qui par exemple ne supportent pas HTTPS. Pound est capable d'échanger en HTTPS avec le client, de décrypter les messages et de les envoyer ensuite en clair au serveur sous-jacent (donc le message ne transite en clair que dans une partie normalement sécurisée du réseau). Pour l'utilisateur distant, la connexion transite dans le canal HTTPS de manière tout à fait transparente.

Un petit outil intéressant sur lequel vous pourrez tout apprendre en vous rendant ici : http://www.apsis.ch/pound/

Toutefois, après son installation, j'ai observé pound se plaindre dans le /var/log/syslog de mon système.

May 15 12:49:59 host pound: libgcc_s.so.1 must be installed for pthread_cancel to work
May 15 12:49:59 host pound: MONITOR: worker exited on signal 6, restarting...

Après vérification, libgcc_s.so.1 était pourtant bien disponible sur le système... Et pound s'obstinait à ne pas le trouver.

L'explication était en fait toute simple - j'avais activé le chroot dans la configuration de pound (afin de durcir l'installation) :

RootJail        "mon-dossier-chroot/pound"

et c'est donc dans ce dossier que pound cherchait la librairie libgcc !

Pour contenter pound, il m'a alors suffi de copier (ou lier) la librairie libgcc dans "mon-dossier-chroot/pound/lib/libgcc_s.so.1" et voilà Pound satisfait qui ne s'est plus plaint.

page 2 de 2 -