Sécurisation des communications dans une application Rails à trois niveaux à l’aide de tunnels SSH

introduction

Les applications Web sont souvent conçues avec trois niveaux distincts:

  • Le premier niveau est lepresentation layer, ce que voit l'utilisateur.

  • Vient ensuite lesapplication layer, qui fournissent lesbusiness logic de l'application.

  • Enfin, ledata layer stocke les données nécessaires à l'application.

Dans une applicationRuby on Rails, cela mappe de manière lâche vers un serveur Web pour la couche de présentation, un serveur Rails pour la couche application et une base de données pour la couche de données. Dans cette configuration, la couche d'application communique avec la couche de données pour extraire des données pour l'application, qui sont ensuite affichées à l'utilisateur par le biais de la couche de présentation.

Bien qu'il soit possible d'installer toutes ces applications sur un seul serveur, le fait de placer chaque couche sur son propre serveur facilite la mise à l'échelle de l'application. Par exemple, si le serveur Rails devenait un goulot d'étranglement, vous pourriez ajouter davantage de serveurs d'applications sans affecter les deux autres couches.

Dans ce didacticiel, vous allez déployer une application Rails dans une configuration à trois niveaux en installant un ensemble unique de logiciels sur trois serveurs distincts, en configurant chaque serveur et ses composants pour qu'ils communiquent et fonctionnent ensemble et en sécurisant les connexions entre eux avec des tunnels SSH. Pour la pile logicielle, vous utiliserezNginx comme serveur Web sur la couche de présentation,Puma comme serveur d'application Rails sur la couche application, etPostgreSQL comme base de données sur la couche de données .

Conditions préalables

Pour compléter ce didacticiel, vous devrez activer trois serveurs Ubuntu 16.04. Nommez cesweb-server,app-server etdatabase-server, et chacun doit avoir le réseau privé activé.

Chacun des trois serveurs doit avoir un utilisateur non root avec les privilègessudo ainsi qu'un pare-feu configuré pour autoriser les ocnnections SSH (que vous pouvez configurer en utilisant nosInitial Server Setup guide). Dans le contexte de ce tutoriel, l'utilisateursudo sur chaque serveur est nommésammy.

De plus, chacun des trois serveurs a ses propres exigences de configuration:

  • Sur lesweb-server:

  • Sur lesapp-server:

    • Installez Node.js en utilisant le PPA officiel, comme expliqué dansHow To Install Node.js on Ubuntu 16.04. Quelques fonctionnalités de Rails, telles que le pipeline d’actifs, dépendent d’un JavaScript Runtime et Node.js fournit cette fonctionnalité.

    • Installez le framework Ruby on Rails. Pour ce faire, suivez notre guide surHow to Install Ruby on Rails with rbenv on Ubuntu 16.04. Au fur et à mesure que vous suivez ce didacticiel, veillez à installer la dernière version de Ruby qui, au moment de la rédaction de cet article, est Ruby 2.5.1.

    • Installez PostgreSQL, comme indiqué dans la première section de notre tutorielHow To Use PostgreSQL with Your Ruby on Rails Application on Ubuntu 14.04. Cette section décrit également comment installerlibpq-dev, un autre package requis pour cette configuration à trois niveaux.

    • Déployez une application Rails à l'aide de Puma. Si vous n'avez pas d'application à déployer, suivez notre guide surHow To Deploy a Rails App with Puma and Nginx pour déployer un exemple d'application. Notez que dans la section «Installer le plug-in rbenv-vars» de ce prérequis, vous devez définir l'utilisateur et le mot de passe de la base de données pour refléter les valeurs que vous utilisez lorsque vous installez PostgreSQL sur lesdatabase-server. De plus, vous devez autoriser le port3000 à travers votre pare-feu pour que la section «Créer une base de données de production» fonctionne. Enfin, vous n'avez pas besoin de suivre les deux dernières étapes de ce didacticiel préalable, à savoir «Créer un script Puma Upstart» et «Installer et configurer Nginx».

  • Sur lesdatabase-server:

    • Installez et configurez le logiciel de base de données PostgreSQL. Suivez notre guide surHow To Install and Use PostgreSQL on Ubuntu 16.04 pour savoir comment procéder. En suivant ce didacticiel prérequis, créez un rôle PostgreSQL pour votre application Rails avec les autorisationssuperuser ainsi qu'une base de données portant le même nom que le rôle PostgreSQL. Tout au long de ce didacticiel, le rôle et la base de données PostgreSQL sont tous deux appeléssammy.

    • Définissez un mot de passe pour le rôle PostgreSQL nouvellement créé. Ignorez la première commande dans le "https://www.digitalocean.com/community/tutorials/how-to-deploy-a-rails-app-with-puma-and-nginx-on-ubuntu-14-04#create -production-database-user [Créer un utilisateur de la base de données de production] »du didacticiel Puma (que vous avez également utilisé pour configurer lesapp-server), et suivez les commandes restantes de cette section pour changer le mot de passe de l'utilisateur de la base de données . Notez que le nom du rôle PostgreSQL et le mot de passe que vous avez défini pour lesdatabase-server doivent être identiques à ceux que vous avez définis lors de l’installation PostgreSQL deapp-server.

[[step-1 -—- creation-a-user-for-the-ssh-tunnels]] == Étape 1 - Création d'un utilisateur pour les tunnels SSH

LesSSH tunnels sont des connexions chiffrées qui peuvent envoyer des données d'un port sur un serveur vers un port sur un autre serveur, donnant l'impression qu'un programme d'écoute sur le second serveur s'exécute sur le premier. Avoir un utilisateur dédié pour les tunnels SSH permet d'améliorer la sécurité de votre configuration: si un intrus accède à l'utilisateur desammyur l'un de vos serveurs, il ne pourra pas accéder aux autres serveurs des trois. configuration de niveau. De même, si un intrus devait accéder à l'utilisateur detunnel, il ne pourra ni modifier les fichiers dans le répertoire de l'application Rails ni utiliser la commandesudo.

Sur chaque serveur, créez un utilisateur supplémentaire nommétunnel. La seule fonction de l’utilisateur detunnel est de créer des tunnels SSH pour faciliter la communication entre les serveurs, donc, contrairement àsammy, ne donnez pas les privilèges àtunnelsudo. De plus, l'utilisateur detunnelne doit pas avoir accès en écriture au répertoire de l'application Rails. Exécutez la commande suivante sur chaque serveur pour ajouter l'utilisateurtunnel:

sudo adduser tunnel

Sur la machineweb-server, basculez vers l'utilisateurtunnel.

sudo su tunnel

En tant qu'utilisateurtunnel, générez une paire de clés SSH:

ssh-keygen

Enregistrez la clé à l'emplacement par défaut et ne créez pas de phrase de passe pour les clés, car cela pourrait compliquer l'authentification ultérieurement lorsque vous créez des tunnels SSH entre les serveurs.

Après avoir créé la paire de clés, revenez à l'utilisateursammy:

exit

Maintenant, passez auxapp-server et exécutez à nouveau les mêmes commandes:

sudo su tunnel
ssh-keygen
exit

Vous avez maintenant configuré tous les utilisateurs dont vous aurez besoin pour la suite du didacticiel. Net, vous apporterez quelques modifications au fichier/etc/hosts pour chaque utilisateurtunnel afin de rationaliser le processus de création des tunnels SSH.

[[step-2 -—- configuring-the-hosts-file]] == Étape 2 - Configuration du fichier Hosts

Tout au long de ce didacticiel, vous devez souvent vous référer aux adresses IP desapp-server ou desdatabase-server dans une commande. Plutôt que de devoir mémoriser et taper ces adresses IP à chaque fois, vous pouvez ajouter les adresses IP privées deapp-server etdatabase-server au fichier/etc/hosts de chaque serveur. Cela vous permettra d'utiliser leurs noms dans les commandes suivantes à la place de leurs adresses et facilitera le processus de configuration des tunnels SSH.

Veuillez noter que, pour simplifier les choses, ce didacticiel vous demande d’ajouter les adresses IP privées deapp-server etdatabase-server au fichier/etc/hosts sur chacun des trois serveurs. Bien qu’il ne soit techniquement pas nécessaire d’ajouter les adresses IP privées deapp-server oudatabase-server à leurs propres fichiershosts, cela ne posera aucun problème. La méthode décrite ici a été choisie simplement pour la rapidité et la commodité.

Tout d'abord, recherchez les adresses IP privées de vosapp-server etdatabase-server. Si vous utilisez des gouttelettes DigitalOcean, accédez à votre Panneau de configuration et cliquez sur le nom de ces gouttelettes. Sur l'une de leurs pages spécifiques à Droplet, les adresses IP publique et privée sont affichées en haut de la page.

Ensuite, sur chaque serveur, ouvrez le fichier/etc/hosts avec votre éditeur de texte préféré et ajoutez les lignes suivantes:

sudo nano /etc/hosts

/etc/hosts

. . .
app-server_private_ip app-server
database-server_private_ip database-server

En ajoutant ces lignes à ce fichier sur chaque serveur, vous pouvez utiliser les nomsapp-server etdatabase-server dans des commandes qui vous obligeraient généralement à utiliser les adresses IP de ces serveurs. Vous utiliserez cette fonctionnalité pour configurer les clés SSH afin que chacun de vos utilisateurstunnel puisse se connecter à vos autres serveurs.

[[step-3 -—- setting-up-ssh-logins]] == Étape 3 - Configuration des connexions SSH

Maintenant que vous avez un utilisateurtunnel et un fichier/etc/hosts mis à jour sur vos trois serveurs, vous êtes prêt à commencer à créer des connexions SSH entre eux.

Au cours de cette étape, considérez les trois niveaux comme une pyramide, avec lesdatabase-server en bas, lesapp-server au milieu et lesweb-server en haut. Lesapp-server doivent pouvoir se connecter auxdatabase-server afin d'accéder aux données nécessaires à l'application Rails, et lesweb-server doivent pouvoir se connecter auxapp-server donc il a quelque chose à présenter aux utilisateurs.

Ainsi, il vous suffit d'ajouter la clé publique SSH de chaque utilisateurtunnel au serveur «en dessous», ce qui signifie que vous devez ajouter la clé publique de l'utilisateurweb-servertunnel au serveurapp-server et ajoutez la clé publique de l'utilisateurapp-servertunnel auxdatabase-server. Cela vous permettra d’établir des tunnels SSH chiffrés entre les niveaux et d’empêcher les oreilles indiscrètes du réseau de lire le trafic qui les sépare.

Pour commencer ce processus, copiez la clé publique de l'utilisateurtunnel sur lesweb-server, située à/home/tunnel/.ssh/id_rsa.pub, dans le fichier/home/tunnel/.ssh/authorized_keys sur lesapp-server.

Sur lesweb-server, affichez la clé publique de l'utilisateurtunnel dans le terminal avec la commande suivante:

sudo cat /home/tunnel/.ssh/id_rsa.pub

Sélectionnez la sortie texte et copiez-la dans le presse-papier de votre système.

SSH dans lesapp-server dans une session de terminal distincte et basculer vers l'utilisateur du tunnel:

sudo su tunnel

Ajoutez la clé dans le presse-papiers de votre système au fichierauthorized_keys sur lesapp-server. Vous pouvez utiliser la commande suivante pour le faire en une seule étape. N'oubliez pas de remplacertunnel_ssh_publickey_copied_from_web_server par la clé publique dans le presse-papiers de votre système:

echo "tunnel_ssh_publickey_copied_from_web-server" >> /home/tunnel/.ssh/authorized_keys

Après cela, modifiez les autorisations sur le fichierauthorized_keys pour empêcher tout accès non autorisé à celui-ci:

chmod 600 /home/tunnel/.ssh/authorized_keys

Revenez ensuite à l'utilisateursammy:

exit

Ensuite, affichez la clé publique de l'utilisateurtunnel sur leapp-server - situé à/home/tunnel/.ssh/id_rsa.pub - et collez-la dans le fichier/home/tunnel/.ssh/authorized_keys sur ledatabase-server:

sudo cat /home/tunnel/.ssh/id_rsa.pub
sudo su tunnel

Étant donné que vous n’avez pas généré de paire de clés SSH sur lesdatabase-server, vous devrez créer le dossier/home/tunnel/.ssh et ajuster ses autorisations:

mkdir /home/tunnel/.ssh
chmod 700 /home/tunnel/.ssh

Ajoutez ensuite la clé publique deapp-server au fichierauthorized_keys et ajustez ses autorisations:

echo "tunnel_ssh_publickey_copied_from_app-server" >> /home/tunnel/.ssh/authorized_keys
chmod 600 /home/tunnel/.ssh/authorized_keys

Revenez ensuite à l'utilisateursammy:

exit

Ensuite, testez la première connexion en utilisant SSH pour vous connecter auxapp-server de votreweb-server en tant qu'utilisateurtunnel:

sudo su tunnel
ssh tunnel@app-server

La première fois que vous vous connectez duweb-server auapp-server, vous verrez un message vous demandant de confirmer que la machine à laquelle vous vous connectez est fiable. Tapez "yes" pour accepter l'authenticité desapp-server:

OutputThe authenticity of host '111.111.11.111 (111.111.11.111)' can't be established.
ECDSA key fingerprint is fd:fd:d4:f9:77:fe:73:84:e1:55:00:ad:d6:6d:22:fe.
Are you sure you want to continue connecting (yes/no)? yes

Vous verrez la bannière de bienvenue desapp-server et l'invite de commande montrera que vous êtes connecté auxapp-server. Cela confirme que la connexion SSH duweb-server auapp-server fonctionne correctement.

Quittez la connexion SSH vers leapp-server, puis quittez l’utilisateurtunnel pour revenir à l’utilisateursammy de votreweb-server:

exit
exit

Ensuite, suivez ces mêmes étapes pour tester la connexion SSH duapp-server audatabase-server:

sudo su tunnel
ssh tunnel@database-server

Acceptez également l'authenticité desdatabase-server. Lorsque vous verrez la bannière de bienvenue et l'invite de commande dudatabase-server, vous saurez que la connexion SSH duapp-server audatabase-server fonctionne comme prévu.

Quittez la connexion SSH vers lesdatabase-server, puis quittez l'utilisateurtunnel:

exit
exit

Les connexions SSH que vous avez configurées à l’étape constituent la base des tunnels SSH qui permettront des communications sécurisées entre vos trois niveaux de serveur. Cependant, dans leur forme actuelle, ces connexions sont susceptibles de s’effondrer et ne sont donc pas aussi fiables qu’elles pourraient l’être. En installant des logiciels supplémentaires et en configurant le tunnel pour qu'il fonctionne en tant que service, vous pouvez toutefois atténuer ces vulnérabilités.

[[step-4 -—- setting-up-a-persistent-ssh-tunnel-to-the-database-server]] == Étape 4 - Configuration d'un tunnel SSH persistant vers le serveur de base de données

Lors de la dernière étape, vous avez accédé à l'invite de commande sur un serveur distant à partir d'un serveur local. Un tunnel SSH vous permet de faire beaucoup plus que cela en mettant en tunnel le trafic des ports de l'hôte local aux ports de l'hôte distant. Ici, vous utiliserez un tunnel SSH pour crypter la connexion entre vosapp-server et lesdatabase-server.

Si vous avez suivi toutes les conditions préalables pour ce tutoriel, vous aurez installé PostgreSQL sur lesapp-server et lesdatabase-server. Pour éviter un conflit dans les numéros de port, vous devez configurer le tunnel SSH entre ces serveurs pour transférer les connexions du port5433 desapp-server au port5432 sur lesdatabase-server. Plus tard, vous reconfigurerez votre application Rails (hébergée sur vosapp-server) pour utiliser l'instance de PostgreSQL exécutée sur lesdatabase-server.

En commençant en tant qu'utilisateursammy sur leapp-server, passez à l'utilisateurtunnel que vous avez créé à l'étape 1:

sudo su tunnel

Exécutez la commandessh avec les indicateurs et options suivants pour créer le tunnel entre lesapp-server etdatabase-server:

ssh -f -N -L 5433:localhost:5432 tunnel@database-server
  • L'option-f envoiessh en arrière-plan. Cela vous permet d'exécuter de nouvelles commandes dans votre invite existante pendant que le tunnel continue de s'exécuter en arrière-plan.

  • L'option-N indique àssh de ne pas exécuter de commande à distance. Ceci est utilisé ici car vous ne voulez transférer que les ports.

  • L'option-L est suivie de la valeur de configuration5433:localhost:5432. Cela spécifie que le trafic provenant du port5433 du côté local (lesapp-server) est transmis au port5432 delocalhost sur le serveur distant (lesdatabase-server). Notez quelocalhost ici est du point de vue du serveur distant.

  • La dernière partie de la commande,tunnel@database-server, spécifie l'utilisateur et le serveur distant auxquels se connecter.

Après avoir établi le tunnel SSH, revenez à l'utilisateursammy:

exit

À ce stade, le tunnel est en cours d'exécution, mais rien ne le surveille pour s'assurer qu'il reste en place. Si le processus se bloque, le tunnel sera interrompu, l'application Rails ne sera plus en mesure de communiquer avec sa base de données et vous commencerez à voir des erreurs.

Supprimez le tunnel que vous avez créé pour l'instant, car nous allons créer une configuration plus fiable. Comme la connexion est en arrière-plan, vous devrez trouver son ID de processus pour la tuer. Étant donné que chaque tunnel est créé par l’utilisateurtunnel, vous pouvez trouver son ID de processus en répertoriant les processus en cours et en filtrant la sortie pour le mot-clé «tunnel»:

ps axu | grep tunnel

Cela retournera quelque chose comme la sortie ci-dessous:

Outputtunnel   21814  0.0  0.1  44920   692 ?        Ss   14:12   0:00 ssh -f -N -L 5433:localhost:5432 tunnel@database-server
sammy    21816  0.0  0.2  12916  1092 pts/0    S+   14:12   0:00 grep --color=auto tunnel

Arrêtez le processus en exécutant la commandekill suivie de son ID de processus:

sudo kill 21814

Pour maintenir une connexion SSH persistante entre le serveur d'applications et la base de données, installezautossh. autossh est un programme qui démarre et surveille une connexion SSH, et le redémarre si la connexion meurt ou cesse de passer du trafic:

sudo apt-get install autossh

systemd is the default init system on Ubuntu, ce qui signifie qu'il gère les processus après le démarrage du système. Vous pouvez utilisersystemd pour créer un service qui gérera et démarrera automatiquement votre tunnel SSH au redémarrage du serveur. Pour ce faire, créez un fichier appelédb-tunnel.service dans le répertoire/lib/systemd/system/, l'emplacement standard où les fichiers d'unité desystemd sont stockés:

sudo nano /lib/systemd/system/db-tunnel.service

Ajoutez le contenu suivant au nouveau fichier pour configurer un service poursystemd à gérer:

/lib/systemd/system/db-tunnel.service

[Unit]
Wants=network-online.target
After=network-online.target

[Service]
User=tunnel
WorkingDirectory=/home/tunnel
ExecStart=/bin/bash -lc 'autossh -N -L 5433:localhost:5432 tunnel@database-server'
Restart=always
StandardInput=null
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=%n
KillMode=process

[Install]
WantedBy=multi-user.target

La ligne clé ici estExecStart. Ceci spécifie le chemin d'accès complet à la commande et les arguments à exécuter pour démarrer le processus. Ici, il démarre un nouveau shellbash puis exécute le programmeautossh.

Enregistrez et fermez le fichier, puis rechargez la configuration desystemd pour vous assurer qu'elle récupère le nouveau fichier de service:

sudo systemctl daemon-reload

Activez le servicedb-tunnel pour que le tunnel vers lesdatabase-server démarre automatiquement à chaque démarrage du serveur:

sudo systemctl enable db-tunnel.service

Ensuite, démarrez le service:

sudo systemctl start db-tunnel.service

Exécutez à nouveau la commande suivante pour vérifier si le tunnel est actif:

ps axu | grep tunnel

Dans la sortie, vous verrez qu'il y a plus de processus en cours d'exécution cette fois carautossh surveille maintenant le tunnel:

Outputtunnel   25925  0.0  0.1   4376   704 ?        Ss   14:45   0:00 /usr/lib/autossh/autossh -N -L 5432:localhost:5432 tunnel@database-server
tunnel   25939  0.2  1.0  44920  5332 ?        S    14:45   0:00 /usr/bin/ssh -L 61371:127.0.0.1:61371 -R 61371:127.0.0.1:61372 -N -L 5432:localhost:5432 tunnel@database-server
sammy    25941  0.0  0.2  12916  1020 pts/0    S+   14:45   0:00 grep --color=auto tunnel

Maintenant que le tunnel est opérationnel, vous pouvez tester la connexion auxdatabase-server avecpsql pour vous assurer qu'il fonctionne correctement.

Démarrez le clientpsql et dites-lui de se connecter àlocalhost. Vous devez également spécifier le port5433 pour vous connecter via le tunnel SSH à l'instance PostgreSQL sur lesdatabase-server. Spécifiez le nom de la base de données que vous avez créé précédemment et entrez le mot de passe que vous avez créé pour l'utilisateur de la base de données lorsque vous y êtes invité:

psql -hlocalhost -p5433 sammy

Si vous voyez quelque chose comme la sortie suivante, la connexion à la base de données a été configurée correctement:

Outputpsql (9.5.10)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.

sammy=#

Pour fermer l'invite PostgreSQL, tapez\q puis appuyez surENTER.

Enfin, vous disposez d'un tunnel SSH persistant et fiable qui crypte le trafic entre vosapp-server etdatabase-server. Les fonctionnalités de sécurité du tunnel sont essentielles, car c'est via ce tunnel que l'application Rails sur vosapp-server communiquera avec l'instance PostgreSQL sur vosdatabase-server.

[[step-5 -—- configuring-rails-to-use-a-remote-database]] == Étape 5 - Configuration des rails pour utiliser une base de données distante

Maintenant que le tunnel duapp-server audatabase-server est configuré, vous pouvez l'utiliser comme canal sécurisé pour que votre application Rails se connecte via le tunnel à l'instance PostgreSQL sur ledatabase-server .

Ouvrez le fichier de configuration de la base de données de l’application:

nano /home/sammy/appname/config/database.yml

Mettez à jour la sectionproduction pour que le numéro de port soit spécifié en tant que variable d'environnement. Cela devrait maintenant ressembler à quelque chose comme ça:

/home/sammy/appname/config/database.yml

. . .
production:
  <<: *default
  host: localhost
  adapter: postgresql
  encoding: utf8
  database: appname_production
  pool: 5
  username: <%= ENV['APPNAME_DATABASE_USER'] %>
  password: <%= ENV['APPNAME_DATABASE_PASSWORD'] %>
  port: <%= ENV['APPNAME_DATABASE_PORT'] %>

Enregistrez et fermez ce fichier, puis ouvrez le fichier.rbenv-vars dans le répertoire de l'application et éditez les variables d'environnement:

nano /home/sammy/appname/.rbenv-vars

Si vous définissez un nom et un mot de passe différents pour le rôle PostgreSQL sur lesdatabase-server, remplacez-les maintenant (dans l'exemple ci-dessous, le rôle PostgreSQL est nommésammy). Ajoutez également une nouvelle ligne pour spécifier le port de la base de données. Après avoir apporté ces modifications, votre fichier.rbenv-vars devrait ressembler à ceci:

/home/sammy/appname/.rbenv-vars

SECRET_KEY_BASE=secret_key_base
APPNAME_DATABASE_USER=sammy
APPNAME_DATABASE_PASSWORD=database_password
APPNAME_DATABASE_PORT=5433

Enregistrez et fermez ce fichier lorsque vous avez terminé.

Étant donné que vous utilisez maintenant l'instance PostgreSQL sur lesdatabase-server au lieu de celle desapp-serverur lesquels vous avez déployé votre application Rails, vous devrez à nouveau configurer la base de données.

Sur lesapp-server, accédez au répertoire de votre application et exécutez la commanderake pour configurer la base de données:

[.note] #Note: Cette commande feranot migrer toutes les données de la base de données existante vers la nouvelle. Si vous avez déjà des données importantes sur votre base de données, vous devez les sauvegarder, puis les restaurer plus tard.
#

cd /home/sammy/appname
rake db:setup

Une fois cette commande terminée, votre application Rails commencera à communiquer avec l'instance PostgreSQL sur lesdatabase-server via un tunnel SSH chiffré. La prochaine chose à faire est de configurer Puma en tant que servicesystemd pour le rendre plus facile à gérer.

[[step-6 -—- configuration-et-démarrage-puma]] == Étape 6 - Configuration et démarrage de Puma

De la même manière que vous avez configuré le servicedb-tunnel à l'étape 4, vous configurerezsystemd pour exécuter Puma (le logiciel serveur que vous avez installé sur leapp-server dans le cadre des conditions préalables) en tant que service . L'exécution de Puma en tant que service lui permet de démarrer automatiquement au démarrage du serveur ou de redémarrer automatiquement en cas de panne, ce qui renforce la robustesse de votre déploiement.

Créez un nouveau fichier appelépuma.service dans le répertoire/lib/systemd/system/:

sudo nano /lib/systemd/system/puma.service

Ajoutez le contenu suivant, qui a été adapté dePuma’s systemd documentation, au nouveau fichier. Assurez-vous de mettre à jour les valeurs en surbrillance dans les directivesUser,WorkingDirectory etExecStart pour refléter votre propre configuration:

/lib/systemd/system/puma.service

[Unit]
Description=Puma HTTP Server
After=network.target

[Service]
# Foreground process (do not use --daemon in ExecStart or config.rb)
Type=simple

# Preferably configure a non-privileged user
User=sammy

# The path to the puma application root
# Also replace the "" place holders below with this path.
WorkingDirectory=/home/sammy/appname

# Helpful for debugging socket activation, etc.
# Environment=PUMA_DEBUG=1

Environment=RAILS_ENV=production

# The command to start Puma.
ExecStart=/home/sammy/.rbenv/bin/rbenv exec bundle exec puma -b tcp://127.0.0.1:9292

Restart=always

[Install]
WantedBy=multi-user.target

Enregistrez et fermez le fichier. Rechargez ensuitesystemd, activez le service Puma et démarrez Puma:

sudo systemctl daemon-reload
sudo systemctl enable puma.service
sudo systemctl start puma.service

Après cela, confirmez que Puma est en cours d’exécution en vérifiant le statut du service:

sudo systemctl status puma.service

S'il est en cours d'exécution, vous verrez une sortie semblable à celle-ci:

Outputpuma.service - Puma HTTP Server
   Loaded: loaded (/lib/systemd/system/puma.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2017-12-26 05:35:50 UTC; 1s ago
 Main PID: 15051 (bundle)
    Tasks: 2
   Memory: 31.4M
      CPU: 1.685s
   CGroup: /system.slice/puma.service
           └─15051 puma 3.11.0 (tcp://127.0.0.1:9292) [appname]

Dec 26 05:35:50 app systemd[1]: Stopped Puma HTTP Server.
Dec 26 05:35:50 app systemd[1]: Started Puma HTTP Server.
Dec 26 05:35:51 app rbenv[15051]: Puma starting in single mode...
Dec 26 05:35:51 app rbenv[15051]: * Version 3.11.0 (ruby 2.4.3-p205), codename: Love Song
Dec 26 05:35:51 app rbenv[15051]: * Min threads: 5, max threads: 5
Dec 26 05:35:51 app rbenv[15051]: * Environment: production

Ensuite, utilisezcurl pour accéder et imprimer le contenu de la page Web afin de vérifier qu'elle est correctement diffusée. La commande suivante indique àcurl de visiter le serveur Puma que vous venez de démarrer surapp-server sur le port9292:

curl localhost:9292/tasks

Si vous voyez quelque chose comme le code ci-dessous, cela confirme que Puma et la connexion à la base de données fonctionnent correctement:

Output...

Tasks

Title Note
...

Une fois que vous pouvez confirmer que votre application Rails est servie par Puma et est correctement configurée pour utiliser une instance PostgreSQL distante sur lesdatabase-server, vous pouvez passer à la configuration du tunnel SSH entre lesweb-server et le app-server.

[[step-7 -—- setting-up-and-persisting-the-ssh-tunnel-to-the-app-server]] == Étape 7 - Configuration et persistance du tunnel SSH sur le serveur d'applications

Maintenant que leapp-server est opérationnel, vous pouvez le connecter auweb-server. Comme pour le processus que vous avez suivi à l'étape 4, vous allez le faire en configurant un autre tunnel SSH. Ce tunnel permettra à Nginx sur lesweb-server de se connecter en toute sécurité via une connexion cryptée à Puma sur lesapp-server.

Commencez par installerautossh sur leweb-server:

sudo apt-get install autossh

Créez un nouveau fichier appeléapp-tunnel.service dans le répertoire/lib/systemd/system/:

sudo nano /lib/systemd/system/app-tunnel.service

Ajoutez le contenu suivant à ce fichier. Encore une fois, la ligne clé est celle qui commence parExecStart. Ici, cette ligne redirige le port9292 sur leweb-server vers le port9292 sur leapp-server où Puma écoute:

/lib/systemd/system/app-tunnel.service

[Unit]
StopWhenUnneeded=true
Wants=network-online.target
After=network-online.target

[Service]
User=tunnel
WorkingDirectory=/home/tunnel
ExecStart=/bin/bash -lc 'autossh -N -L 9292:localhost:9292 tunnel@app-server'
Restart=always
StandardInput=null
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=%n
KillMode=process

[Install]
WantedBy=multi-user.target

[.note] #Note: Le numéro de port dans la ligneExecStart est le même que celui configuré pour Puma à l'étape précédente.
#

Rechargezsystemd pour qu'il lit le nouveau fichier de service, puis activez et démarrez le serviceapp-tunnel:

sudo systemctl daemon-reload
sudo systemctl enable app-tunnel.service
sudo systemctl start app-tunnel.service

Vérifiez que le tunnel est en place:

ps axu | grep tunnel

Vous devriez voir quelque chose qui ressemble à la sortie ci-dessous:

Outputtunnel   19469  0.0  0.1   4376   752 ?        Ss   05:45   0:00 /usr/lib/autossh/autossh -N -L 9292:localhost:9292 tunnel@app-server
tunnel   19482  0.5  1.1  44920  5568 ?        S    05:45   0:00 /usr/bin/ssh -L 54907:127.0.0.1:54907 -R 54907:127.0.0.1:54908 -N -L 9292:localhost:9292 tunnel@app-server
sammy    19484  0.0  0.1  12916   932 pts/0    S+   05:45   0:00 grep --color=auto tunnel

Cette liste de processus filtrée montre queautossh est en cours d'exécution et qu'il a démarré un autre processusssh qui crée le tunnel chiffré réel entreweb-server etapp-server.

Votre deuxième tunnel est maintenant en place et crypte la communication entre vosweb-server etapp-server. Pour que votre application Rails à trois niveaux soit opérationnelle, il ne vous reste plus qu'à configurer Nginx pour qu'il transmette les demandes à Puma.

[[step-8 -—- configuring-nginx]] == Étape 8 - Configuration de Nginx

À ce stade, toutes les connexions et tunnels SSH requis ont été configurés et chacun de vos trois niveaux de serveur peut communiquer entre eux. La dernière pièce de ce casse-tête consiste à configurer Nginx pour qu'il envoie des demandes à Puma afin de rendre la configuration entièrement fonctionnelle.

Sur lesweb-server, créez un nouveau fichier de configuration Nginx à/etc/nginx/sites-available/appname:

sudo nano /etc/nginx/sites-available/appname

Ajoutez le contenu suivant dans le fichier. Ce fichier de configuration Nginx est similaire à celui que vous avez utilisé si vous avez suivi notre guide surHow To Deploy a Rails App with Puma and Nginx. La principale différence est l'emplacement de l'application en amont; au lieu d'utiliser le fichier socket local, cette configuration pointe Nginx vers le tunnel SSH écoutant sur le port9292:

/etc/nginx/sites-available/appname

upstream app {
    server 127.0.0.1:9292;
}

server {
    listen 80;
    server_name localhost;

    root /home/sammy/appname/public;

    try_files $uri/index.html $uri @app;

    location @app {
        proxy_pass http://app;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
    }

    error_page 500 502 503 504 /500.html;
    client_max_body_size 4G;
    keepalive_timeout 10;
}

Enregistrez et fermez ce fichier, puis activez le site et activez les modifications.

Tout d'abord, supprimez le site par défaut:

sudo rm /etc/nginx/sites-enabled/default

Accédez au répertoire Nginxsites-enabled:

cd /etc/nginx/sites-enabled

Créez unsymbolic link dans le répertoiresites-enabled dans le fichier que vous venez de créer dans le répertoiresites-available:

sudo ln -s /etc/nginx/sites-available/appname appname

Testez votre configuration Nginx pour les erreurs de syntaxe:

sudo nginx -t

Si des erreurs sont signalées, revenez en arrière et vérifiez votre fichier avant de continuer.

Lorsque vous êtes prêt, redémarrez Nginx pour qu’il lise votre nouvelle configuration:

sudo systemctl restart nginx

Si vous avez suivi le tutoriel Puma dans les prérequis, vous auriez installé Nginx et PostgreSQL sur lesapp-server. Tous les deux ont été remplacés par des instances distinctes s'exécutant sur les deux autres serveurs, ces programmes sont donc redondants. Par conséquent, vous devez supprimer ces packages desapp-server:

sudo apt remove nginx
sudo apt remove postgresql

Après avoir supprimé ces packages, veillez à mettre à jour vos règles de pare-feu pour empêcher tout trafic indésirable d’accéder à ces ports.

Votre application Rails est maintenant en production. Accédez à l'adresse IP publique de votreweb-server dans un navigateur Web pour le voir en action:

http://web-server_public_IP/tasks

Conclusion

En suivant ce tutoriel, vous avez déployé votre application Rails sur une architecture à trois niveaux et sécurisé les connexions de vosweb-server vers lesapp-server, et desapp-server vers ledatabase-server avec des tunnels SSH cryptés.

Avec les divers composants de votre application sur des serveurs distincts, vous pouvez choisir les spécifications optimales pour chaque serveur en fonction de la quantité de trafic que votre site reçoit. La première étape consiste à surveiller les ressources consommées par le serveur. Consultezour guide on CPU monitoring pour obtenir des instructions sur la façon de surveiller l'utilisation du processeur de vos serveurs. Si vous constatez que l'utilisation du processeur ou de la mémoire sur un niveau est très élevée, vous pouvez redimensionner le serveur sur ce niveau uniquement. Pour plus de conseils sur le choix d'une taille de serveur, consultez notre guide surChoosing the Right Droplet for Your Application.

Comme étape suivante immédiate, vous devez également sécuriser la connexion de vos utilisateurs auxweb-server en installant un certificat SSL sur lesweb-server. Consultez lesNginx Let’s Encrypt tutorial pour obtenir des instructions. De plus, si vous souhaitez en savoir plus sur l'utilisation des tunnels SSH, consultezthis guide.

Related