Installation



À partir du moment où vous êtes connecté à votre instance, vous pouvez administrer votre serveur en SSH.

On va commencer par a mise à jour de la machine, ça ne fait jamais de mal.

apt update
apt upgrade

Hello world non sécurisé

On va juste vérifier que tout fonctionne bien en créant un premier serveur, non sécurisé, qui tournera sur le port 80 (HTTP) avec l'utilisateur root (à ne pas faire en vrai...).

apt install python3 python3-bottle
mkdir test
cd test
nano hello.py # ou vim hello.py

Rappels :

  • nano est un éditeur de texte en ligne de commande, très simple à utiliser. Il faut juste faire CTRL+X pour quitter et valider les modifications.
  • vim est un éditeur de texte en ligne de commande, plus puissant mais plus compliqué à utiliser. Il faut faire i pour entrer en mode insertion, puis ESC pour sortir du mode insertion et taper :wq pour enregistrer et quitter.

Dans hello.py, taper ou copier-coller le code suivant:

from bottle import route, run
@route('/')
def hello():
    return "Hello world !"
if __name__ == '__main__':
    run(host='0.0.0.0', port=80)

Puis on lance le serveur :

python3 hello.py

Vous pouvez alors tester en ouvrant un navigateur et en tapant l'adresse IP publique de votre instance. Vous devriez voir le message "Hello world !".

Hello world en ligne

Une fois le test terminé, vous pouvez arrêter le serveur en appuyant sur CTRL+C dans le terminal où il tourne, et supprimer le dossier test :

cd ..
rm -rf test

Hello world sécurisé

Un serveur HTTP ne doit pas tourner en root. Sauf que le protocole HTTP nécessite d'écouter sur le port 80, qui est un port privilégié.

Autre problème : nous avons une machine qui peut faire tourner plusieurs applications, mais une seule peut écouter sur le port 80.

Enfin, pour l'instant, notre application ne tourne pas en HTTPS, ce qui est un gros problème de sécurité.

Pour résoudre tous ces problèmes, on va utiliser un "vrai" serveur HTTP, qui va écouter sur le port 80, et rediriger les requêtes vers notre application, qui elle tournera sur un port non privilégié (au dessus de 1024, par exemple 8080), et sous un utilisateur non priviliégié (typiquement, un utilisateur différent pour chaque application : appli1, appli2, eleve1, ...).

Cette configuration est appelée "reverse proxy". Le serveur HTTP va simplement relayer les requètes vers notre application.

Reverse proxy

On va utiliser nginx, qui est un serveur HTTP très répandu et très performant. Il est aussi capable de faire du reverse proxy, c'est à dire de rediriger les requêtes vers une autre application qui tourne sur un autre port.

apt install nginx

On va aussi créer un utilisateur webapp qui va être l'utilisateur sous lequel va tourner notre application. Il n'aura pas de droits d'administration, donc il ne pourra pas faire de bêtises sur le serveur.

adduser webapp

Il faut maintenant créer un fichier de configuration pour nginx, qui va lui dire quoi faire. On va créer un fichier /etc/nginx/sites-available/webapp et y mettre la configuration suivante :

server {
    listen 80;
    server_name <adresse_ip_publique>;
    location / {
        proxy_pass http://localhost:8080;
        proxy_set_header Host $host;
    }
}

On crée ensuite un lien symbolique vers ce fichier dans le dossier /etc/nginx/sites-enabled/, qui est le dossier où nginx va chercher les fichiers de configuration actifs.

ln -s /etc/nginx/sites-available/webapp /etc/nginx/sites-enabled/webapp

et on redémarre nginx pour prendre en compte la nouvelle configuration :

systemctl restart nginx

Si vous allez voir dans votre navigateur à l'adresse IP publique de votre instance, vous devriez avoir une page d'erreur 502 Bad Gateway. C'est normal, car on n'a pas encore lancé notre application.

On va maintenant relancer notre application, mais cette fois-ci sous l'utilisateur webapp et sur le port 8080.

su webapp # On passe à l'utilisateur webap p
cd # On va dans le dossier de l'utilisateur webapp
mkdir test
cd test
nano hello.py

Puis on copie le code de tout à l'heure, mais en changeant le port et l'adresse IP d'écoute :

from bottle import route, run
@route('/')
def hello():
    return "Hello world !"
if __name__ == '__main__':
    run(host='localhost', port=8080)

Puis on lance le serveur :

python3 hello.py

Là, si vous allez sur l'adresse IP publique de votre instance, vous devriez voir le message "Hello world !".

Il ne manque plus que quelques "petites" choses :

  • un site avec un vrai nom de domaine (et pas une adresse IP publique)
  • un certificat SSL pour que le site soit en HTTPS
  • servir l'application avec gunicorn (ou uwsgi) pour qu'elle soit plus performante et qu'elle puisse tourner en arrière-plan.
  • un moyen de démarrer automatiquement l'application au démarrage du serveur (avec systemd par exemple)
  • et savoir comment déployer une nouvelle version de notre application ou la mettre à jour notre application sans devoir tout taper à la main dans un terminal.

Envoyer des fichier sur le serveur

Accès SSH

L'utilisateur webapp a été crée avec un login/mdp, mais les accès SSH par login/mdp sont désactivés par défaut sur les serveurs (pour des raisons de sécurité, l'authentification par clé SSH est plus sécurisée).

Il faut donc, pour pouvoir se connecter en SSH

  • soit ajouter une clef publique SSH à l'utilisateur webapp (ce qui est recommandé), dans le fichier ~/.ssh/authorized_keys (il faut créer le dossier .ssh et le fichier authorized_keys s'ils n'existent pas déjà).
  • soit modifier la configuration de SSH pour autoriser les connexions par login/mdp (ce qui n'est pas recommandé).

Pour ajouter une clef publique SSH à l'utilisateur webapp, il faut d'abord générer une clef SSH sur la machine depuis laquelle on va se connecter au serveur (vous pouvez utiliser la clef créée dans les étapes précédentes si c'est vous qui faites la manipulation, mais vous pouvez aussi donner un accès à vos élèves pour leur permettre d'envoyer leurs fichiers sur le serveur).

ssh-keygen
cat ~/.ssh/id_ed25519.pub # ou cat ~/.ssh/id_rsa.pub

Il faut ensuite copier le contenu de la clef publique (la ligne qui commence par ssh-ed25519 ou ssh-rsa) et la coller dans le fichier ~/.ssh/authorized_keys de l'utilisateur webapp sur le serveur.

su webapp
mkdir -p ~/.ssh
nano ~/.ssh/authorized_keys

Puis coller la clef publique dans le fichier authorized_keys et sauvegarder avec CTRL+X, Y, ENTRER. Il faut aussi donner les bons droits au dossier .ssh et au fichier authorized_keys :

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

Envoi de fichiers

Il est possible d'envoyer des fichiers ou des dossiers sur le serveur avec scp (secure copy).

# Pour un fichier
scp <fichier local> <utilisateur>@<adresse_ip_publique>:<fichier distant>
# Pour un dossier (le dossier distant sera écrasé si il existe déjà)
scp -r <dossier local> <utilisateur>@<adresse_ip_publique>:<dossier distant>

Par exemple, pour envoyer le dossier test sur le serveur :

scp -r test webapp@<adresse_ip_publique>:/home/webapp/test

Si vous êtes sous linux ou osx, vous pouvez aussi utiliser rsync, qui est plus rapide et plus efficace pour synchroniser des fichiers ou des dossiers entre deux machines.

rsync -avz <dossier local> <utilisateur>@<adresse_ip_publique>:<dossier distant>

Par exemple, pour envoyer le dossier test sur le serveur :

rsync -avz test webapp@<adresse_ip_publique>:/home/webapp/test

Vous pouvez aussi utiliser un client FTP/SFTP comme FileZilla ou WinSCP pour envoyer des fichiers sur le serveur.

Utiliser git pour déployer

Il est aussi possible d'utiliser git pour déployer une application sur un serveur : [local] -> [gitlab] -> [serveur]. CF formation forge.

En bref, il faut (en utilisant un gitlab, celui de la forge forge.apps.education.fr) :

  • créer / activer son compte sur gitlab

Sur votre machine locale :

  • associer votre clef SSH publique à votre compte gitlab (dans les paramètres de votre compte)
  • créer un projet gitlab (ou utiliser un projet existant)
  • utiliser les commandes fournies à la création du projet pour cloner le projet sur votre machine locale (ou ajouter git à un projet existant)
  • enregistrer vos modifications locales (commit) et les envoyer (push) sur le serveur gitlab

Sur votre serveur :

  • créer une clef SSH pour l'utilisateur qui est ou sera propriétaire du projet
  • ajouter cette clef SSH publique à votre compte gitlab (dans les paramètres de votre compte)
  • cloner le projet gitlab sur le serveur

A chaque modification, il suffira :

  • sur votre machine locale : d'enregistrer vos modifications (commit) et de les envoyer (push) sur le serveur gitlab
  • sur le serveur : de récupérer les modifications (pull) et de relancer l'application