Comment configurer une infrastructure d'application Web sécurisée avec les pare-feu cloud DigitalOcean

De Get Docs
Aller à :navigation, rechercher

Introduction

Les pare-feu Cloud DigitalOcean fournissent un service de pare-feu puissant au niveau du réseau, laissant vos serveurs libres de faire leur travail de servir vos applications et de stocker vos données. Dans ce didacticiel, nous allons adapter une configuration Wordpress et MySQL à deux serveurs pour utiliser Cloud Firewalls et démontrer certains des avantages que ce service peut offrir. Si vous souhaitez plus d'informations sur ce service de pare-feu avant de commencer, veuillez lire notre tutoriel Introduction aux pare-feu cloud DigitalOcean.

Conditions préalables

Avant de commencer ce didacticiel, vous devez avoir créé l'infrastructure décrite dans Comment configurer une base de données distante pour optimiser les performances du site avec MySQL sur Ubuntu 16.04. Cela vous laissera avec deux serveurs, un serveur Web Nginx avec PHP et WordPress installés, et un serveur MySQL autonome. Tout au long de ce didacticiel, nous appellerons ces serveurs respectivement frontend-01 et database-01.

Situation actuelle de notre pare-feu

À l'heure actuelle, nos deux serveurs ont des pare-feu configurés à l'aide de l'utilitaire ufw. ufw est un wrapper facile à utiliser autour du moteur de pare-feu iptables de Linux. Connectez-vous maintenant aux deux serveurs et vérifions l'état de nos pare-feux :

Tout d'abord, sur le serveur Web, frontend-01 :

sudo ufw status verbose
OutputStatus: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip

To                         Action      From
--                         ------      ----
22/tcp (OpenSSH)           ALLOW IN    Anywhere
80,443/tcp (Nginx Full)    ALLOW IN    Anywhere
22/tcp (OpenSSH (v6))      ALLOW IN    Anywhere (v6)
80,443/tcp (Nginx Full (v6)) ALLOW IN    Anywhere (v6)

Dans la sortie, après Default:, on nous montre que le pare-feu refuse, par défaut, toutes les connexions entrantes et autorise toutes les connexions sortantes. De plus, nous avons quatre règles qui autorisent les connexions TCP IPv4 et IPv6 entrantes (ALLOW IN) aux ports 22 (SSH), 80 (HTTP) et 443 (HTTPS).

Faisons la même chose sur le serveur de base de données, database-01 :

sudo ufw status verbose
OutputStatus: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip

To                         Action      From
--                         ------      ----
22/tcp (OpenSSH)           ALLOW IN    Anywhere
3306                       ALLOW IN    Anywhere
22/tcp (OpenSSH (v6))      ALLOW IN    Anywhere (v6)
3306 (v6)                  ALLOW IN    Anywhere (v6)

Cette sortie est similaire, sauf que nous avons remplacé les deux ports Nginx par le port 3306, qui est le port MySQL standard. Maintenant que nous connaissons notre configuration actuelle, planifions notre remplacement.

Notre plan de pare-feu cloud

Bien que nous puissions simplement créer deux pare-feu cloud, un adapté à chaque serveur spécifique, et en appliquer un à frontend-01 et l'autre à database-01, nous allons prendre un peu plus approche flexible de la façon dont nous organisons nos règles.

Tout d'abord, nous voulons nous préparer à un avenir où nous devrons peut-être ajouter un troisième type de service à ce système (peut-être un serveur de cache). Nous allons donc diviser nos règles de pare-feu en fonction des rôles, et non par serveur physique. Nous pouvons appliquer plusieurs Cloud Firewalls à chaque Droplet, ce n'est donc pas un problème de rendre ces pare-feu fins et modulaires.

Remarque : Si vous souhaitez une exploration plus approfondie des meilleures pratiques concernant la structuration de vos pare-feu cloud, veuillez lire Comment organiser les pare-feu cloud DigitalOcean.


Si nous décomposons un peu les choses, nous remarquons que nos deux serveurs ont en fait plusieurs fonctions. Il y a la fonction principale de servir des pages Web ou des informations de base de données, et il y a aussi une fonction de gestion fournie par le service SSH. Il serait judicieux pour nous de créer un pare-feu gestion, un pare-feu frontend et un pare-feu base de données.

Pour gérer le scénario futur où nous adaptons nos services Web ou de base de données à plusieurs hôtes, nous utiliserons la fonction de marquage de DigitalOcean pour organiser nos Droplets par rôle. Les balises sont de simples étiquettes que nous pouvons appliquer aux gouttelettes pour les catégoriser et adresser des groupes entiers de serveurs à la fois. Le service Cloud Firewall peut appliquer des règles de pare-feu à tous les droplets d'une balise, ce qui facilite le provisionnement de nouveaux droplets avec les règles de pare-feu correctes déjà en place.

Un bonus supplémentaire - et quelque chose qui serait difficile à faire de manière dynamique en utilisant ufw - est que les pare-feu cloud peuvent restreindre l'accès entrant en fonction des balises. Ainsi, par exemple, nos serveurs database doivent uniquement être accessibles depuis nos serveurs frontend. La configuration actuelle ufw a la base de données ouverte à tous sur le réseau. Nous allons verrouiller cela uniquement sur nos gouttelettes étiquetées avec frontend.

Résumons les trois pare-feux que nous devons mettre en place, en langage clair :

  • Gestion : autorise le trafic entrant vers le port TCP 22 à partir de n'importe quel hôte
  • Frontend : autorise le trafic entrant vers les ports TCP 80 et 443 à partir de n'importe quel hôte
  • Base de données : autorise le trafic entrant vers le port TCP 3306 uniquement à partir des serveurs balisés frontend

Nous n'allons pas du tout restreindre le trafic sortant dans ce didacticiel. Ce n'est pas une mauvaise idée, mais il faut s'assurer de ne pas casser les mécanismes de mise à jour automatique et d'autres fonctionnalités critiques du système d'exploitation sous-jacent.

Maintenant que nous avons un plan pour nos nouveaux pare-feux, commençons.

Étape 1 - Marquage de nos serveurs

Tout d'abord, nous allons étiqueter nos Droplets par rôle, en préparation de nos règles de pare-feu. Accédez au panneau de configuration DigitalOcean. La vue par défaut est une liste de vos Droplets. Cliquez sur le bouton Plus à droite de votre droplet frontend-01, et sélectionnez Ajouter des balises :

Une zone de texte apparaîtra dans laquelle vous pourrez saisir des balises pour cette gouttelette. Entrez frontend et cliquez sur le bouton Ajouter des balises :

Faites de même pour votre serveur de base de données, en lui donnant une balise database. Les balises apparaîtront dans votre liste Droplet :

Lors de la création de futurs droplets, vous pouvez appliquer ces balises lors du processus de provisionnement initial. Les Droplets hériteront alors automatiquement des règles de pare-feu correspondantes.

Nous établirons ces règles à l'étape suivante.

Étape 2 - Création de pare-feu cloud

Nous allons maintenant mettre en place nos Cloud Firewalls. Nous allons commencer par le pare-feu frontend, suivi de la base de données, puis de la gestion. Cette commande ne devrait entraîner aucune interruption de service pour les visiteurs de votre site Web, mais nous perdrons temporairement la possibilité d'établir de nouvelles connexions SSH. Cela n'affectera pas les connexions déjà établies.

Le service Firewalls est disponible dans la section Networking du panneau de configuration DigitalOcean. Une fois là-bas, cliquez sur l'onglet Pare-feu, puis cliquez sur le bouton Créer un pare-feu pour commencer.

Création du pare-feu frontal

Sur la page Créer un pare-feu, nous devons remplir un Nom, configurer nos Règles de trafic entrant et sélectionner les droplets auxquels appliquer le pare-feu. Nous laisserons la section Outbound Rules telle quelle.

Nous créons d'abord le pare-feu frontend, alors mettez frontend-fw dans le champ Name.

Remarque : Nous ajouterons -fw à la fin de nos noms de pare-feu pour les lever de l'ambiguïté. Bien que l'interface du Panneau de configuration utilise des icônes pour différencier les types de ressources, cela peut prêter à confusion si vous utilisez la ligne de commande ou l'API et que vous avez plusieurs éléments frontend, par exemple.


Ensuite, nous devons supprimer la règle SSH par défaut de la section Inbound Rules'. Nous allons casser cette règle dans le pare-feu de gestion ' pour plus de flexibilité. Utilisez le lien Supprimer sur le côté droit de la page pour supprimer la règle SSH maintenant.

Ensuite, cliquez sur le menu déroulant Nouvelle règle et sélectionnez HTTP. Cela remplira automatiquement le protocole (TCP) et le port (80) corrects et autorisera par défaut le trafic de toutes les adresses IPv4 et IPv6. C'est ce que nous voulons.

Si vous avez activé HTTPS, répétez le processus ci-dessus pour créer une deuxième règle, en sélectionnant HTTPS cette fois. Votre section Inbound Rules se terminera ainsi :

Enfin, dans le champ Apply to Droplets, commencez à taper frontend puis sélectionnez la balise frontend lorsqu'elle est auto-suggérée.

Cliquez sur le bouton Créer un pare-feu. Le nouveau pare-feu sera créé et appliqué à n'importe quel droplet avec la balise frontend. Vous serez redirigé vers une page récapitulative du pare-feu mise à jour indiquant votre nouveau pare-feu :

Nous allons maintenant créer le pare-feu database.

Création du pare-feu de base de données

Sur la page Pare-feu, cliquez à nouveau sur Créer un pare-feu. Le processus sera essentiellement le même que pour notre pare-feu frontend.

Tapez database-fw dans le champ Name.

Dans Inbound Rules, supprimez la règle SSH par défaut. Ensuite, créez une nouvelle règle à l'aide de la liste déroulante, en sélectionnant MySQL. Une règle MySQL par défaut sera créée permettant l'accès au port 3306 à partir de toutes les IP. Supprimez All IPv4 et All IPv6 du champ Sources. Nous voulons que seuls nos serveurs frontaux puissent accéder à la base de données. Commencez à taper frontend dans la case Sources, et sélectionnez la balise frontend lorsqu'elle est suggérée automatiquement. Désormais, toute gouttelette avec cette balise appliquée sera autorisée à accéder au serveur de base de données. Toutes les autres IP sont bloquées.

Laissez les Règles de trafic sortant telles quelles. Sous Apply to Droplets, appliquez ce pare-feu à la balise database, puis cliquez sur Create Firewall. Une fois de plus, vous serez renvoyé à la page de résumé du pare-feu :

Notez que les deux pare-feu montrent qu'ils sont appliqués à un droplet chacun. Si vous chargez votre site Web, il devrait toujours se charger correctement. Maintenant, réactivons la gestion via SSH.

Création du pare-feu de gestion

Cliquez une dernière fois sur Créer un pare-feu. Ajoutez management-fw au champ Nom.

La règle SSH par défaut est tout ce dont nous avons besoin pour ce pare-feu. Cela permettra à n'importe quelle adresse IP de se connecter au port 22.

Vous pouvez également remplacer le champ Sources de la règle SSH par une adresse IP spécifique à partir de laquelle vous vous connecterez. Par exemple, si votre bureau a une adresse IP statique et que vous souhaitez limiter l'accès SSH aux seules connexions du bureau, placez cette adresse IP dans Sources, en remplaçant All IPv4 et Tous IPv6. Si jamais votre adresse IP change à l'avenir, vous n'aurez qu'à mettre à jour cette seule règle pour restaurer l'accès de gestion, un autre avantage de planifier à l'avance et de rendre nos règles modulaires.

Sous Apply to Droplets, ajoutez les balises frontend et database, puis cliquez sur Create Firewall. Jetons un coup d'œil à notre résumé final du pare-feu :

À ce stade, notre pare-feu cloud devrait être entièrement fonctionnel, mais nous avons également toujours les pare-feu basés sur l'hôte ufw actifs. Désactivons-les, puis testons nos connexions.

Étape 3 - Suppression des pare-feu hôtes

Nous devons désactiver le pare-feu ufw sur les deux hôtes. Tout d'abord, sur frontend-01 :

sudo ufw disable
OutputFirewall stopped and disabled on system startup

Puis sur database-01 :

sudo ufw disable
OutputFirewall stopped and disabled on system startup

Cela arrête le pare-feu actuel, vide toutes les règles et empêche la réactivation des règles au démarrage.

À ce stade, toute notre connectivité devrait être restaurée. Essayez de créer une nouvelle session SSH sur l'un de vos serveurs. Chargez ensuite votre site Web pour vérifier que le serveur Web se connecte toujours à la base de données et renvoie les pages Web au navigateur.

Le fait de pouvoir se connecter à tous nos services ne prouve pas qu'un pare-feu fonctionne. Faisons un peu plus de tests pour vérifier que nos pare-feux sont bien en place.

Étape 4 — Tester nos pare-feu

Pour tester nos pare-feu, nous allons nous connecter à un troisième serveur et utiliser un utilitaire appelé nmap pour analyser nos serveurs Web et de base de données. nmap est un analyseur de ports qui analyse nos hôtes et nous indique quels ports sont ouverts, fermés ou filtrés.

Connectez-vous à un autre serveur Ubuntu 16.04 situé dans la même région que vos serveurs frontend-01 et database-01. Installez ensuite nmap :

sudo apt-get update
sudo apt-get install nmap

Ensuite, utilisez nmap pour analyser l'adresse IP publique du serveur Web :

nmap -Pn frontend-01_public_ip
OutputStarting Nmap 7.01 ( https://nmap.org ) at 2017-06-05 17:08 UTC
Nmap scan report for 203.0.113.11
Host is up (0.0022s latency).
Not shown: 997 filtered ports
PORT    STATE SERVICE
22/tcp  open  ssh
80/tcp  open  http
443/tcp open  https

Nmap done: 1 IP address (1 host up) scanned in 4.54 seconds

Notez la sortie sur filtered ports. Si le pare-feu ne fonctionnait pas, ceux-ci s'afficheraient comme closed ports. Filtered signifie que nmap ne peut même pas se connecter pour déterminer si le port est ouvert ou fermé.

Notez également que nous voyons que nos ports SSH, HTTP et HTTPS sont ouverts, comme prévu.

Ensuite, nous allons scanner le serveur de base de données. Assurez-vous d'utiliser l'adresse IP privée du Droplet si vous l'avez configuré de cette façon, car c'est ce que la base de données MySQL écoutera :

nmap -Pn database-01_private_ip
OutputStarting Nmap 7.01 ( https://nmap.org ) at 2017-06-05 17:21 UTC
Nmap scan report for 198.51.100.20
Host is up (0.0024s latency).
Not shown: 999 filtered ports
PORT   STATE SERVICE
22/tcp open  ssh

Nmap done: 1 IP address (1 host up) scanned in 8.17 seconds

On voit que la plupart des ports sont filtrés, comme avant. Cependant, nous ne voyons que le port SSH comme ouvert, sans port MySQL disponible. Rappelez-vous que nous avons limité l'accès à la base de données aux seuls serveurs marqués avec frontend. Revenez au panneau de configuration DigitalOcean et ajoutez la balise frontend au serveur à partir duquel vous utilisez nmap. Puis relancez la commande :

nmap -Pn database-01_private_ip
OutputStarting Nmap 7.01 ( https://nmap.org ) at 2017-06-05 17:22 UTC
Nmap scan report for 198.51.100.20
Host is up (0.0033s latency).
Not shown: 998 filtered ports
PORT     STATE SERVICE
22/tcp   open  ssh
3306/tcp open  mysql

Nmap done: 1 IP address (1 host up) scanned in 4.46 seconds

Le port MySQL apparaît maintenant comme ouvert. Nous avons vérifié que nos deux serveurs sont désormais protégés par nos règles Cloud Firewall. Vous pouvez maintenant restaurer les paramètres de pare-feu d'origine de ce serveur de test en revenant au Panneau de configuration et en supprimant la balise frontend du Droplet.

Conclusion

Dans ce didacticiel, nous avons remplacé une configuration de pare-feu ufw par une configuration de pare-feu cloud flexible et puissante basée sur le réseau. Pour plus d'informations sur l'utilisation de Cloud Firewalls via doctl ou l'API DigitalOcean, veuillez consulter les articles suivants :