Faire un site accessible uniquement en local

Faire un site accessible uniquement en local

Lors du hackathon j’ai mis en place un environnement de développement accessible uniquement sur le réseau local utilisé par les membres de mon équipe. Les techniques que j’ai utilisées pour construire cet environnement peuvent être reproduites ou adaptées pour divers besoins, par exemple pour se créer un environnement de développement chez soi, proposer un intranet en entreprise, ou mettre à disposition un logiciel web de gestion sans risquer qu’il soit disponible sur internet.

Je vous propose dans cet article de découvrir comment mettre en place cette solution et de mieux comprendre comment elle fonctionne.

 

Le matériel et le réseau de base

Pour réaliser cette solution, il nous faudra au minimum :

  • un routeur : il en a déjà sur la plupart des réseaux local, souvent intégré dans le modem. La plupart des routeurs (et à fortiori les modems-routeurs) proposent un serveur DHCP intégré, qui nous intéresse particulièrement pour cette config.
  • un serveur : tout d’abord pour héberger le site, mais également pour un serveur DNS local. Comme dans le cas du hackathon, se serveur peut être un petit Raspberry Pi qui suffira largement pour un petit site local. Le site, la base de données et le serveur DNS peuvent aussi être répartis sur 2 ou 3 serveurs différents. Pour cet exemple, le serveur sera sous système Raspbian, qui est une distribution Linux dérivée de Debian spécifique au RaspBerry Pi, mais le principe fonctionne quel que soit le système d’exploitation. Tout au long de cet article, je pars du principe que nous avons un accès SSH root sur le serveur.

Le routeur étant déjà en place et faisant office de passerelle pour tout le réseau, il suffit de brancher le serveur sur le réseau. Pour lui assigner une adresse IP, 2 possibilités :

  • soit il récupère une adresse IP grâce au DHCP, et il faut ensuite s’assurer que ce sera toujours cette IP qui lui sera attribuée. Cela se fait dans la configuration du serveur DHCP en attribuant un « bail fixe » à l’adresse mac du serveur.
  • soit on configure le serveur en IP fixe, en s’assurant que l’IP choisie est bien en dehors de la plage d’IP du serveur DHCP.

Le schéma du réseau peut donc être celui-ci (les adresses IP sont là pour illustrer l’exemple) :

 

La configuration

Pour l’instant, tous les ordinateurs du réseau utilisent le routeur comme passerelle vers internet. Le serveur DHCP leur a distribué les serveurs DNS du fournisseur d’accès à internet ou ceux qui lui ont été spécifiés. Le serveur est connecté au réseau et a accès à internet, mais il ne propose aucun service et personne ne l’utilise.

 

Un serveur DNS récursif avec zone locale

La première étape est d’installer un serveur DNS pour notre réseau local. Il existe 2 types de serveurs DNS :

  • les serveurs DNS maîtres (authoritative), qui sont la source d’information DNS pour un domaine donné. Ce sont eux qui détiennent la liste des enregistrements DNS et communiquent la ou les adresses IP correspondant à ce domaine ou sous-domaine à ceux qui le souhaitent.
  • les serveurs DNS récursifs (resolver), qui se chargent de trouver l’adresse IP correspondant à un nom de domaine quand on leur demande. Ils sont généralement restreints à certains utilisateurs pour éviter d’avoir un nombre trop important de requêtes à gérer et d’être vulnérable aux attaques. Les serveurs DNS fournis par les FAI sont de ce type par exemple, e ne sont accessibles qu’à leurs abonnés. Google fournit par contre des serveurs DNS ouverts à tous, aux adresses facile à retenir : 8.8.8.8 et 8.8.4.4 en IPv4, 2001:4860:4860::8888 et 2001:4860:4860::8844 en IPv6. Il faut cependant garder à l’esprit qu’en utilisant les services DNS Google, ou de n’importe quel autre fournisseur d’ailleurs, vous donnez à ce fournisseur la liste complète des sites et services que vous consultez en temps réel. Ce sont des informations personnelles sensibles qui peuvent être utilisées dans d’autres buts que la résolution DNS, il faut rester prudent sur la divulgation de ces informations sur Internet.

Ce que l’on souhaite faire ici, c’est de fournir un serveur DNS récursif aux utilisateurs du réseau, mais qui soit également serveur DNS maître pour notre domaine local, qui sera « monsite.nc » pour cet exemple. Le domaine n’a pas besoin d’être enregistré, d’exister réellement, ni même de correspondre à une extension existante : on peut choisir de servir « local.monentreprise » ou « intranet.local » ou bien encore « monsite.caledonie ». Faites-vous plaisir, c’est du local, vous faites ce que vous voulez !

Installation de Bind9

Bind est le serveur DNS le plus utilisé sur internet (de loin !). Il est robuste, efficace, fiable, et existe depuis presque autant de temps qu’internet lui même : c’est un standard. On va utiliser sa dernière version stable : bind9

apt install bind9

Rien de plus, c’est fait 🙂

Configuration en serveur DNS récursif

La configuration se trouve dans /etc/bind, et on va dire à Bind de se comporter en serveur récursif dans le fichier /etc/bind/named.conf.options :

options {
 directory "/var/cache/bind";

// If there is a firewall between you and nameservers you want
 // to talk to, you may need to fix the firewall to allow multiple
 // ports to talk. See http://www.kb.cert.org/vuls/id/800113

// If your ISP provided one or more IP addresses for stable 
 // nameservers, you probably want to use them as forwarders. 
 // Uncomment the following block, and insert the addresses replacing 
 // the all-0's placeholder.

// forwarders {
 // 0.0.0.0;
 // };

//========================================================================
 // If BIND logs error messages about the root key being expired,
 // you will need to update your keys. See https://www.isc.org/bind-keys
 //========================================================================
 dnssec-enable yes;
 dnssec-validation yes;

 auth-nxdomain no; # conform to RFC1035
 listen-on-v6 { any; };

 recursion yes; // c'est cette directive qui dit a Bind de se comporter en serveur récursif
 allow-query { monreseau; }; // et celle-ci restreint son accès (voir plus bas "acl monreseau")

 forwarders {
  // les serveurs DNS listés ici sont ceux à qui Bind ira demander les informations qu'ils ne connaît pas encore
  8.8.8.8; // indiquez ici les serveurs DNS que utilisés actuellement, ceux de votre FAI par exemple
  8.8.4.4; // ceux-ci sont les serveurs DNS publics de Google, qui fonctionnent aussi
 };
};


acl monreseau {
 192.168.1.0/24; // indiquez ici le réseau qui est autorisé à utiliser ce serveur DNS
 localhost;
 localnets;
};

Enregistrez la config, et relancez bind :

rndc reload

On peut maintenant tester que Bind répond de façon récursive avec le petit utilitaire « dig »:

$ dig @192.168.1.2 1012.nc
; <<>> DiG 9.10.3-P4-Ubuntu <<>> @192.168.1.2 1012.nc
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 62272
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;1012.nc. IN A

;; ANSWER SECTION:
1012.nc. 6015 IN A 202.87.129.41

;; Query time: 166 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Sun Dec 10 11:49:47 +11 2017
;; MSG SIZE rcvd: 52

C’est la présence de la réponse (« ANSWER SECTION ») qui nous indique que ca fonctionne. On aurait aussi pu avoir un réponse plus courte en indiquant l’option « +short » a dig :

$ dig @8.8.8.8 +short 1012.nc
202.87.129.41

On obtient bien une adresse IP, alors qu’il n’y aurait rien si ça ne fonctionnait pas.

Ajout d’une zone locale

Maintenant que le serveur répond aux requêtes, il faut lui indiquer qu’il est maître pour notre zone locale « monsite.nc ». Pour lui indiquer quelles zones il gère désormais, on va les spécifier dans le ficier /etc/bind/named.conf.local :

//
// Do any local configuration here
//

// Consider adding the 1918 zones here, if they are not used in your
// organization
//include "/etc/bind/zones.rfc1918";

zone "monsite.nc" {
 type master;
 file "/etc/bind/zones/db.monsite.nc"; # zone file path
};

zone "168.192.in-addr.arpa" {
 type master;
 file "/etc/bind/zones/db.168.192";
};

En plus de la zone « monsite.nc », on a ajouté une zone pour pouvoir indiquer les reverse DNS sur le réseau local. Les reverse DNS font l’inverse des DNS classiques :

  • les requêtes DNS classiques donnent la correspondance nom de domaine -> adresse IP
  • les reverse DNS donnent la correspondance adresse IP -> nom de domaine

Ce n’est pas indispensable, mais c’est plus propre.

On crée ensuite le dossier zones s’il n’existe pas :

mkdir /etc/bind/zones

et on va créer le fichier de zone /etc/bind/zones/db.monsite.nc :

$TTL 604800
@ IN SOA monsite.nc. admin.monsite.nc. (
 4 ; Serial
 604800 ; Refresh
 86400 ; Retry
 2419200 ; Expire
 604800 ) ; Negative Cache TTL
;
@   IN NS ns1.monsite.nc.
ns1 IN A 192.168.1.2 ; l'adresse de notre serveur DNS

@   IN A 192.168.1.2 ; l'adresse IP de notre futur serveur web, le même que le serveur DNS ici
www IN CNAME troc-oleti.nc.

Et pour la zone reverse :

$TTL 604800
@ IN SOA monsite.nc. admin.monsite.nc. (
 1 ; Serial
 604800 ; Refresh
 86400 ; Retry
 2419200 ; Expire
 604800 ) ; Negative Cache TTL
;
@ IN NS ns1.troc-oleti.nc.
2.1 IN PTR monsite.nc

On enregistre tout, et on relance bind :

rndc reload

Et voilà, la config DNS est terminée !

 

Distribution du serveur DNS par le serveur DHCP

Le serveur DNS est fonctionnel et configuré selon nos besoins, il ne reste plus qu’à l’utiliser. Plutôt que de le configurer à la main sur tous les appareils du réseau, on va le distribuer automatiquement grâce au DHCP. Suivant le modèle de votre routeur, la procédure sera différente, mais le principe reste le même :

  • on se connecte à l’interface d’administration du routeur (généralement http://192.168.1.1/)
  • on cherche la configuration du serveur DHCP
  • dans cette configuration, on va pouvoir indiquer les serveurs DNS qu’on souhaite distribuer. Par défaut, il est possible que le serveur DNS soit le routeur lui-même, ou bien que l’on récupère automatiquement les serveurs DNS du FAI pour les distribuer sur le réseau. Dans tous les cas, il faudra indiquer que le seul serveur DNS à distribuer en DHCP est celui de notre serveur à l’IP 192.168.1.2
  • on enregistre la configuration pour qu’elle soit bien appliquée

Les appareils sur le réseau n’auront pas immédiatement cette nouvelle configuration. Il faudra soit attendre le renouvellement du bail DHCP (le délai peut être variable suivant votre config), ou alors déconnecter puis reconnecter chaque appareil pour qu’il reprenne contact avec le serveur DHCP qui lui indiquera le nouveau serveur DNS.

Une fois que c’est fait, on dit avoir accès à internet comme avant sur chaque appareil, mais en plus, la zone locale « monsite.nc » doit exister ! On peut s’en assurer avec un dig :

dig +short 1012.nc
192.168.1.2

 

Installation du site web

L’étape suivant est d’installer le site web sur le serveur. Pour cet exemple, le site est sous WordPress, et a donc besoin d’un serveur web (Apache), de PHP et de MySQL (plus exactement MariaDB). Sous Debian (et donc Raspbian), Apache, PHP et MariaDB peuvent s’installer très simplement en une commande :

apt install phpmyadmin mariadb-server

En effet, cela fonctionne car le système de gestion des paquets sous Debian inclut un puissant système de dépendances. PHPMyAdmin (par ailleurs bien utile pour gérer les bases de données depuis une interface web) a les mêmes besoins que notre site web, le système de dépendance APT va donc installer et configurer tous les logiciels nécessaires et les faire fonctionner ensemble.

Une fois la commande exécutée jusqu’au bout (il faudra répondre à quelques questions de configuration simples), on peut d’ores et déjà vérifier que tout fonctionne en accédant à PHPMyAdmin à l’adresse :

http://192.168.1.2/phpmyadmin

Configuration de la base de données

Pour la suite, il va falloir créer un nouvel utilisateur dans MariaDB, avec une nouvelle base de données, qui sera utilisée par WordPress. Par défaut, il n’est pas possible de se connecter en root sans mot de passe avec PHPMyAdmin, on va donc le faire en ligne de commande :

Depuis un accès SSH, connexion à la base de données :

mysql -u root

Création de la base de données :

CREATE DATABASE mabase;

Création de l’utilisateur avec les droits en lecture et écriture sur la base :

GRANT ALL ON mabase.* TO monsite@localhost IDENTIFIED BY 'unsupermotdepasse';

On sort de la console MySQL (CTRL+D ou exit), et on teste le nouvel accès :

mysql -u monsite -punsupermotdepasse mabase

Si on peut se connecter, c’est que tout s’est bien passé ! Sinon un message d’erreur indiquera le problème.

 

Configuration du serveur web Apache

Apache est installé, il faut maintenant lui dire qu’il va devoir servir un nouveau site web. On va utiliser les VHOSTs pour pouvoir en héberger sur le même serveur. Pour créer un nouveau vhost, il faut écrire son fichier de configuration dans /etc/apache2/sites-available/monsite.conf :

<VirtualHost *:80>
 ServerAdmin contact@monsite.nc
 ServerName www.monsite.nc
 
 DocumentRoot /var/www/www.monsite.nc
 <Directory />
   Options FollowSymLinks
   AllowOverride None
 </Directory>
 <Directory /var/www/www.monsite.nc>
   Options Indexes FollowSymLinks MultiViews
   AllowOverride All
 </Directory>

ErrorLog /var/log/apache2/www.monsite.nc-error.log

 # Possible values include: debug, info, notice, warn, error, crit,
 # alert, emerg.
 LogLevel warn

CustomLog /var/log/apache2/www.monsite.nc-access.log combined

</VirtualHost>

Dans cet exemple, nous avons décidé que les fichiers se trouveraient dans /var/www/www.monsite.nc, mais on aurait très bien pu décider de les placer ailleurs, par exemple sur une partition séparée montée dans /srv. Pour qu’Apache puisse accepter cette configuration, il faut que le DocumentRoot existe, on va donc le créer et lui donner les droits appropriés pour qu’Apache puisse lire dedans :

mkdir /var/www/www.monsite.nc
chown www-data:www-data /var/www.monsite.nc

Si on avait voulu que l’url http://monsite.nc corresponde au même site que http://www.monsite.nc, on aurait pu ajouter « ServerAlias monsite.nc » juste en dessous du ServerName.

Si on souhaite héberger un 2ème site sur ce serveur, on peut tout à fait copier ce fichier en modifiant au minimum le ServerName et le DocumenRoot. Il est également utile de modifier les fichiers de logs pour séparer les stats de visite et mieux debugger en cas de problème ! Attention cependant à e que les DNS sit également configurés pour ce 2ème site.

Une fois créé, il faut activer la configuration :

a2ensite monsite.conf

puis indiquer à apache de recharger sa configuration :

service apache2 reload

L’hébergement est prêt !

Installation de WordPress

On a dit a apache que les fichiers se trouvaient dans /var/www/www.monsite.nc, c’est donc à cet endroit qu’on va devoir installer WordPress. Pour télécharger l’archive d’installation en ligne de commande (remplacer l’adresse avec celle de la dernière version de WordPress que vous trouverez ici, prenez l’archive tar.gz un peu moins volumineuse que l’archive zip) :

cd /tmp # placez-vous dans le répertoire /tmp du serveur
wget https://fr.wordpress.org/wordpress-4.9.1-fr_FR.tar.gz # téléchargement de l'archive WordPress
tar xvzf wordpress-4.9.1-fr_FR.tar.gz # extraction de l'archive, dans /tmp
mv wordpress/* /var/www/monsite.nc/. # on place les fichiers extraits là ou Apache les attend
chown -R www-data:www-data /var/www.monsite.nc/* # on donne les droits à Apache

Les fichiers sont prêts, on peut désormais se rendre à l’URL du futur site pour poursuivre l’installation :

http://www.monsite.nc

Il suffit ensuite de suivre la procédure proposée par WordPress. Il faudra lui donner :

  • l’adresse du serveur de base de données (« hôte ») : localhost ou 127.0.0.1 (port 3306) si elle se trouve sur le même serveur comme pour cet exemple
  • l’utilisateur de la base de données et le mot de passe créé juste avant : « monsite » et « unsupermotdepasse » pour cet exemple
  • le nom de la base de données créée : « mabase » pour cet exemple
  • on peut garder les valeurs par défaut pour le reste

Voilà, notre WordPress local est installé et fonctionnel ! Il se trouve à l’adresse prévue :

http://www.monsite.nc

et l’interface d’administration à cette adresse :

http://www.monsite.nc/wp-admin

Les identifiants pour se connecter sont ceux que l’on a donnés lors de la procédure web d’installation de WordPress.

Comme le serveur web n’est pas ouvert sur l’extérieur, et que le domaine n’existe que sur le réseau local, le site n’est accessible que sur ce réseau. De plus, il n’est pas vulnérable aux attaques directes sur Internet, les personnes hors du réseau ne peuvent même pas savoir qu’il existe !

 

Pour aller plus loin

Cette configuration couvre la base de la solution, il est bien entendu possible de la rendre plus robuste ou plus adaptée à vos besoins, avec par exemple :

  • l’ajout de HTTPS sur les services locaux
  • l’ajout d’un second serveur DNS pour mieux tolérer les pannes
  • d’autres services sur ce nom de domaine, sur le même serveur ou non

Si vous souhaitez de l’aide pour réaliser une configuration similaire ou pour d’autres solutions linux, n’hésitez pas à me contacter !