Serveur web à la maison : raspberry pi
Installation du Raspberry Pi
Matériel à acheter
- Raspberry Pi modèle B (le modèle A ne possède pas de port éthernet)
- Une carte SD rapide et de marque (éviter les noname)
- Un transformateur µUSB 5V et >700mA (certaines alimentations de téléphones portables font l'affaire, mais pas celle de mon Samsung)
- Éventuellement un boîtier
- Clavier USB
- Cable HDMI
Tout ça se trouve sans problème dans la boutique officielle. Pour la carte SD, je l'ai achetée ailleurs et c'est une SanDisk 32Go qui se vante de faire du 30Mo/s en lecture.
Le tout monte la facture à ~80€.
Installation du système
J'ai décidé, parmi les systèmes proposés, d'installer Raspbian Wheezy qui n'est, vous l'aurez deviné, qu'une adaptation de Debian Wheezy 7. Celle-ci se récupère sur le site officiel[1]. Pensez à vérifier que l'image téléchargée est bien intègre en vérifiant sa somme SHA-1 via sha1sum raspbian.img.
Ensuite, insérez la carte SD dans votre orifice favori. Notez son chemin grâce, par exemple, à la commande df -h, puis démontez-la. Si son chemin est par exemple /dev/sdf1, lancez la commande dd bs=4M if=/chemin/de/raspbian.img of=/dev/sdf. Avant de retirer la carte, un petit coup de sync pour vider les tampons.
Enfichez la carte SD dans le Raspberry Pi, branchez-y un câble éthernet, un clavier USB et un écran HDMI. Lors de la mise sous tension, le système devrait booter correctement. Lors du premier démarrage, le système lance automatiquement l'utilitaire raspi-config, qui vous permet de régler quelques options intéressantes de la machine. En l'occurence, si comme moi vous avez opté pour une carte SD d'un volume supérieur aux 4GB recommandés, vous pouvez choisir l'option expand_rootfs pour que la partition / s'étende à toute la carte. Pensez à configurer la disposition de votre clavier avec l'option configure_keyboard, un mot de passe solide avec l'option change_pass, la langue avec change_locale, et votre fuseau horaire avec change_timezone. Activez le serveur SSH avec l'option ssh, et désactivez le lancement du serveur X au démarrage avec l'option boot_behaviour. Enfin, allouez seulement 16MB de RAM à la puce graphique avec l'option memory_split et vérifiez que l'overclock est bien désactivé avec l'option overclock. Et voilà, c'est bon pour la configuration de base, vous pouvez redémarrer.
Pour vous aider à installer les services que l'on est en droit d'attendre d'un "serveur" il existe un script développé par Thuban dont la version "up-to-date" se télécharge avec la commande : $ hg clone http://hg.yeuxdelibad.net/hostathome La discussion concernant ce script à l'adresse suivante http://www.debian-fr.org/hostathome-script-d-installation-de-serveur-t45969.html?sid=4610dc845fbc40485fb9adcca4688ea5
Accès root
Pour le moment, vous pouvez accéder au compte root avec la commande sudo su. Le reste de la configuration est à effectuer en tant que root.
Configuration d'SSH
À ce stade, le serveur SSH est activé mais pas encore configuré. Si vous ne voulez pas vous coltiner des tentatives incessantes d'invasion coréennes par le port 22 (port par défaut d'SSH), vous avez tout intérêt à vous pencher un peu sur le fichier /etc/ssh/sshd_config, le temps de modifier la ligne Port pour régler un autre port que le 22 (au choix entre 1 et 65536, en évitant les ports déjà utilisés : 21, 22, 80, 443 et 3306) et la ligne PermitRootLogin pour changer yes en no. Ajoutez aussi à la fin du fichier la ligne AllowUsers pi, pour n'autoriser que votre utilisateur à se connecter à SSH. Pour finir, service ssh restart.
Attribution d'un IP fixe
Pour pouvoir se connecter au serveur depuis votre poste habituel, c'est mieux de savoir à quelle adresse IP toquer. Pour ça, il faut simplement configurer le serveur en IP fixe (qui s'oppose à l'habituel DHCP). Côté serveur, il suffit d'éditer /etc/network/interfaces de la façon suivante :
auto lo iface lo inet loopback iface eth0 inet static address 192.168.0.x gateway 192.168.0.x netmask 255.255.255.0
Où address est l'IP interne que vous souhaitez réserver à votre serveur et gateway l'adresse de votre routeur (.254 pour une Freebox V5). Ensuite, côté *box, il doit être possible (en tout cas ça l'est sur une Freebox V5) de réserver une adresse IP donnée à une adresse MAC (adresse physique de l'interface réseau). Pour obtenir l'adresse MAC, vous pouvez passer par ifconfig eth0 par exemple, et noter l'adresse au format xx:xx:xx:xx:xx:xx derrière Hwaddr. Ensuite, pour une Freebox V5 il suffit de se rendre dans « configurer mon routeur Freebox » et « Baux DHCP permanents », et d'indiquer l'adresse IP que l'on veut faire correspondre à l'adresse MAC du serveur. Éteindre l'interface réseau par ifdown eth0, redémarrer la *box, puis remonter l'interface réseau par ifup eth0. Vous devriez être connecté avec l'adresse IP demandée (vérifier éventuellement avec ifconfig eth0).
Vous devriez maintenant pouvoir vous connecter à votre serveur en SSH avec la commande suivante : ssh pi@ip.de.votre.server -p xxxx où xxxx est le port que vous avez réglé sur le serveur SSH.
Installation du serveur web
Introduction
Le Raspberry Pi n'est pas un quad-core avec 12GB de RAM, il convient donc d'opter pour la légèreté. Pour le serveur HTTP, nginx fait très bien l'affaire. On y adjoindra seulement PHP et sqlite/mysql.
Prérequis
Vérification de l'état du système
Avant de se lancer dans l'installation, on s'assure que le système est bien à jour : aptitude update && aptitude full-upgrade.
Utilisateurs et groupes
Vérifier aussi que le groupe www-data existe et que l'utilisateur www-data en fait bien partie : groupadd www-data && usermod -a -G www-data www-data.
Paquets à (dés)installer
On peut ensuite commencer par virer tout ce qui se rapporte au serveur X, puisqu'on n'en aura pas l'usage :
aptitude purge xserver-xorg xserver-xorg-core xserver-xorg-input-all xserver-xorg-input-evdev xserver-xorg-input-synaptics xserver-xorg-video-fbdev xserver-common xpdf xinit x11-common x11-utils x11-xkb-utils xarchiver screen pcmanfm penguinspuzzle lxde-common lxappearance lxde-icon-theme lxinput lxmenu-data lxpanel lxpolkit lxrandr lxsession lxsession-edit lxshortcut lxtask lxterminal leafpad dillo galculator gnome-icon-theme gnome-themes-standard gnome-themes-standard-data gpicview hicolor-icon-theme
Après, un petit ménage des fichiers de configuration avec aptitude purge ~c, puis on installe localepurge pour faire de la place dans les fichier de locales : aptitude -R install localepurge && localepurge.
On installe ensuite les paquets utiles pour le serveur :
aptitude -R install htop iftop nginx sendmail openssl ssl-cert php5 php5-dev php5-gd php5-fpm php5-cli php5-sqlite php5-curl php5-common php5-cgi php5-mysql sqlite php-pear php-apc autoconf automake autotools-dev libapr1 libtool curl libcurl4-openssl-dev php-xml-parser mysql-client mysql-server mutt vsftpd
Paramétrage
nginx
Première étape importante : paramétrer le serveur HTTP, nginx. La configuration que j'utilise consiste à rediriger les requêtes HTTP (port 80) vers son pendant sécurisé HTTPS (port 443). Je n'ai d'ailleurs rien inventé, c'est la configuration recommandée par OwnCloud[2] :
cat > /etc/nginx/sites-available/default << _EOF_ server { listen 80; server_name x.x.x.x; rewrite ^ https://$server_name$request_uri? permanent; # enforce https } server { listen 443 ssl; server_name x.x.x.x; ssl_certificate /etc/nginx/cert.pem; ssl_certificate_key /etc/nginx/cert.key; root /var/www; index index.php index.html index.htm; client_max_body_size 1000M; # set maximum upload size # deny direct access location ~ ^/owncloud/(data|config|\.ht|db_structure\.xml|README) { deny all; } # default try order location / { try_files $uri $uri/ @webdav; } # WebDAV location @webdav { fastcgi_split_path_info ^(.+\.php)(/.*)$; fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param HTTPS on; include fastcgi_params; } # enable php location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param HTTPS on; include fastcgi_params; } } _EOF_
Où x.x.x.x est l'IP du serveur.
SSL
Comme la connexion au serveur va se faire par HTTPS, il nous faut une clé SSL. Pour ça, openssl req -new -x509 -days 365 -nodes -out /etc/nginx/cert.pem -keyout /etc/nginx/cert.key && chmod 600 /etc/nginx/cert.pem && chmod 600 /etc/nginx/cert.key.
PHP
Pour pouvoir envoyer de gros fichiers sur votre serveur via PHP (utile si comme moi vous hébergez un OwnCloud), modifiez les lignes upload_max_filesize et post_max_size de /etc/php5/fpm/php.ini pour les régler sur 1000M (1GB). Toujours si vous hébergez un OwnCloud, pour lui permettre de stocker ses fichiers temporaires, mkdir -p /srv/http/owncloud/data et décommenter la ligne upload_tmp_dir de /etc/php5/fpm/php.ini pour la passer à /srv/http/owncloud/data.
Sécurisation
sudo
Pour des raisons d'auto-discipline, bien que sudo soit supposé sécurisé je préfère ne pas l'utiliser sur un serveur. Pour s'en passer, il faut d'abord attribuer un mot de passe au compte root : sudo su && passwd. Puis supprimer le paquet sudo : aptitude purge sudo. Maintenant, pour s'identifier en tant que root, su - suivi du mot de passe.
MySQL
MySQL embarque un script de sécurisation automatique, que vous pouvez invoquer par mysql-secure-installation. Ce qui est fort conseillé d'ailleurs.
SSH
Le serveur SSH, si vous avez suivi, doit être déjà sécurisé à ce stade (voir Serveur web à la maison : raspberry pi:Configuration d'SSH).
fail2ban
Ce paragraphe provient quasi-intégralement de l'excellent article de lol sur la configuration de Fail2ban
Pour éviter que de mauvais garçons tentent de s'introduire chez vous pour piquer les photos de tante Martine, il est de bon ton d'installer fail2ban. Ce programme lit les fichiers logs des services installés sur le serveur, repère les échecs d'identification et les IPs y correspondant, les bloque avec une règle iptables et vous envoie un mail pour vous en avertir. Simple et efficace. Après aptitude -R install fail2ban, un peu de configuration s'impose. D'abord éditer le fichier /etc/fail2ban/jail.conf. Dans ce fichier, chercher la ligne qui commence par action = (attention, pas action_ =). Ce réglage vous permet de choisir quel type de rapport va vous envoyer fail2ban dans la boîte mail de root lors d'une tentative d'intrusion. Personnellement j'ai opté pour action =%(action_mwl)s qui envoie un rapport complet avec un whois de l'enquiquineur et les lignes de logs responsables du ban. Ensuite viennent plusieurs blocs type
[ssh] enabled = true port = ssh filter = sshd logpath = /var/log/auth.log maxretry = 6
Chaque bloc correspond à un service qui peut être protégé par fail2ban. Le jeu est donc de protéger ceux qui nous intéressent en passant la variable enabled correspondante à true. Dans notre cas, on active les blocs de surveillance ssh, ssh-ddos, apache, apache-noscript, apache-overflows et vsftpd. /!\ Attention : penser à changer le port SSH avec celui qu'on a choisi. /!\ Accessoirement on peut aussi ajouter les ports sftp dans le même bloc SSH en modifiant sa ligne port comme suit :
[ssh] enabled = true port = port_choisi,sftp filter = sshd logpath = /var/log/auth.log maxretry = 6
Comme si ça ne suffisait pas, on va ajouter deux règles perso. Pour ça, éditer le fichier /etc/fail2ban/jail.local pour y ajouter
[apache-admin] enabled = true port = http filter = apache-admin logpath = /var/log/apache*/error*.log maxretry = 6 [apache-404] enabled = true port = http filter = apache-404 logpath = /var/log/ispconfig/httpd/*/error* maxretry = 10
Auxquels il faut penser à adjoindre les filtres correspondants. Pour ça, créer dans le dossier /etc/fail2ban/filter.d/ les fichiers apache-admin.conf contenant
# Fail2Ban configuration file # # Author: Cyril Jaquier # # $Revision: 471 $ # [Definition] # Option: failregex # Notes.: regex to match the password failure messages in the logfile. The # host must be matched by a group named "host". The tag "<HOST>" can # be used for standard IP/hostname matching. # Values: TEXT # [client x.x.x.x] File does not exist: /home/www/admin/admin, failregex = [[]client <HOST>[]] File does not exist: .*admin|PMA|mysql # # Option: ignoreregex # Notes.: regex to ignore. If this regex matches, the line is ignored. # Values: TEXT # ignoreregex =
et apache-404.conf contenant
# Fail2Ban configuration file # # Author: Cyril Jaquier # # $Revision: 471 $ # [Definition] # Option: failregex # Notes.: regex to match the password failure messages in the logfile. The # host must be matched by a group named "host". The tag "<HOST>" can # be used for standard IP/hostname matching. # Values: TEXT # [client x.x.x.x] File does not exist: /home/www/admin/admin, failregex = [[]client <HOST>[]] File does not exist: .* # # Option: ignoreregex # Notes.: regex to ignore. If this regex matches, the line is ignored. # Values: TEXT # ignoreregex =
Après ça, service fail2ban restart et on y est !
denyhosts
Partiellement redondant avec fail2ban, denyhosts lit seulement les logs d'SSH et blackliste les plaisantins dans le fichier /etc/hosts.deny. Denyhosts nécessite beaucoup moins de configuration que fail2ban. Ici, on va juste s'assurer que les machines à partir desquelles vous vous connectez habituellement en SSH à votre serveur seront reconnues comme des amies et ne génèreront pas de rapport. Pour ça, éditer /etc/denyhosts.conf pour passer l'option SUSPICIOUS_LOGIN_REPORT_ALLOWED_HOSTS à NO. Ensuite, éditer le fichier /var/lib/denyhosts/allowed-hosts pour y entrer les IPs que vous souhaitez définir comme amies. Après un service denyhosts restart, c'est tout bon.
Rendre le serveur accessible depuis l'extérieur
Paramétrage de la *box
Pour le moment le serveur est accessible en interne. Pour le rendre accessible depuis l'extérieur, il suffit de rediriger le trafic entrant de certains ports de votre *box vers le serveur. En gros, quand la freebox sera interrogée sur le port 80 (HTTP), il faut lui faire savoir qu'elle doit rediriger cette interrogation vers le port 80 du serveur. Pour une freebox, les options de redirection se trouvent dans « Configurer mon routeur Freebox » et « Redirections / Baux DHCP ». Là on explique que le port externe 80 TCP doit être redirigé vers le port interne 80 à l'adresse IP interne de votre serveur. Et on refait la même chose pour les ports 443 (HTTPS), 21 (FTP), 3306 (MySQL) et le port SSH que vous avez configuré. Pensez aussi, côté serveur, à modifier /etc/nginx/sites-available/default pour y renseigner votre IP publique au lieu de votre IP interne. Vous pouvez l'obtenir en visitant DuckDuckGo [3] par exemple. Après redémarrage de votre *box, votre serveur sera normalement accessible depuis l'extérieur via l'IP (fixe, c'est préférable) de votre *box.
Nom de domaine
Je ne vous expliquerai pas comment configurer votre propre serveur DNS. En ce qui me concerne, je possédais déjà un nom de domaine chez OVH, et il suffit de se connecter à son interface pour rediriger le nom de domaine vers l'IP publique de votre *box. Rien de bien compliqué.
Usage
SSH
Se connecter en SSH : ssh pi@ip.de.votre.server -p xxxx, où xxxx est l'IP du serveur. Vous pouvez également ajouter une ligne ip.de.votre.server nom.du.server dans le fichier /etc/hosts, et vous connecter en SSH avec ssh pi@nom.du.server -p xxxx. Pour copier un fichier vers le serveur : scp fichier_local.ext pi@ip.de.votre.server:fichier_distant.ext. Inversement, pour copier un fichier depuis le serveur : scp pi@ip.de.votre.server:fichier_distant.ext fichier_local.ext.
FTP
Le client ftp fourni par défaut avec Debian est un peu caduque. Vous avez le choix, mais en ligne de commande ncftp m'a l'air vraiment bien. Avec interface graphique, j'utilise gftp. Dans les deux cas, le mieux est de vous connecter avec l'utilisateur www-data (et son mot de passe associé) pour vous retrouver directement dans le répertoire /var/www/, qui est le dossier auquel vous accédez quand vous interrogez votre serveur sur les ports HTTP ou HTTPS.
Sources
Tutoriaux
Je n'ai évidemment rien inventé, et voici en vrac les liens dans lesquels j'ai allègrement pioché pour écrire ce tutorial :
Penguintutor[4]
Jeremy Morgan[5]
RaspberryPioneer[6]
Instructables[7]
PetrockBlog[8]
Liens officiels
Raspberry Pi[9]
Kubii[10] ou RS[11] pour le matériel
TheMagPi[12] : un magazine dédié au Raspberry Pi
eLinux[13] : le wiki officiel