Il existe de nombreux articles qui traitent déjà du sujet, mais dans mon cas, je souhaitais partager mon propre retour d’expérience en détaillant le cheminement qui m’aura permis d’atteindre l’usage que j’en attendais.
Je garderai pour moi les motivations qui m’ont poussées à installer un serveur FTP (ça n’intéressera probablement personne 😅), d’autant plus que disposant d’un accès SSH, j’aurais très bien pu passer par SFTP !
Avant-propos
Nous partons du principe que nous disposons d’un site internet installé et opérationnel.
Les sources techniques sont hébergées sur un LAMP (dans mon cas un Debian Buster pour la partie liée au SE). Un compte linux est dédié à ce site, les sources techniques se trouvent donc dans son home, et en complément, comme il s’agit d’un serveur multi-site, le vhost de ce site utilise apache-itk.
A noter, comme il faut rendre à César ce qui appartient à César, voici l’article qui m’aura aidé à atteindre mon objectif. Il s’agit du wiki de la société Evolix avec qui j’ai déjà étais amené à travailler.
Voici quelques informations qui nous serviront pour la suite:
- Utilisateur : adrien
- Répertoire : /home/adrien/www
- UID : 1234 (id -u adrien)
- GID : 1234 (id -g adrien)
Installation & configuration
Nous commençons par installer proftpd :
apt update && apt install -y proftpd
Pour paramétrer l’ensemble, nous allons mettre en place notre propre fichier de configuration, en évitant de modifier le fichier original qui pourra potentiellement être écrasé au détour d’une mise à jour :
vim /etc/proftpd/conf.d/ftp.conf
Voici les règles à ajouter au fichier:
ServerName "__NOM_DU_SERVEUR__" # Le même que dans le fichier /etc/hosts UseIPv6 off # Passer à on si possible. MaxInstances 4 # A ajuster en fonction des connexions attendues MaxClients 2 # A ajuster en fonction des connexions attendues MaxClientsPerHost 2 # A ajuster en fonction des connexions attendues Umask 137 027 DefaultRoot ~ UseReverseDNS off IdentLookups off TimesGMT off RequireValidShell off UseFtpUsers off ServerIdent on "FTP Server Ready" AccessGrantMsg "Hello!" AllowStoreRestart on <Limit LOGIN> AllowUser adrien # Utilisateur autorisé à se connecter (un utilisateur par ligne) AllowGroup ftpusers # Groupe autorisé à se connecter DenyAll # Tous les autres utilisateurs ne peuvent pas se connecter </Limit>
Nous redémarrons le service pour prendre en compte ces nouveaux paramètres :
systemctl reload proftpd
N’hésitez pas à consulter la documentation officielle qui détaille l’ensemble des paramètres de configuration.
Nous notons la nécessité de créer un groupe (AllowGroup ftpusers). Ce dernier aura pour fonction d’autoriser uniquement les utilisateurs de ce groupe à se connecter en FTP. Une fois créé, nous aurons besoin d’ajouter notre utilisateur adrien au groupe ftpusers.
sudo groupadd ftpusers
sudo usermod -aG ftpusers adrien
A ce stade tout est prêt, nous pouvons utiliser login et mot passe du compte adrien pour réaliser une connexion FTP, mais ici plusieurs choses me dérangent :
- Nous utilisons login et mot de passe du compte adrien, et en FTP, les informations passent en clair. Problématique si le serveur dispose d’un serveur SSH, nous pourrions rapidement compromettre la sécurité du compte adrien
- L’accès n’est pas chrooté dans un répertoire précis, puisque nous arrivons directement dans le home de adrien, ce n’est pas l’idéal
Nous souhaiterions utiliser un autre login et un autre mot de passe, chrooté dans le répertoire de notre choix, qui hériterait des mêmes droits que adrien. Bonne nouvelle, c’est possible grâce aux utilisateurs virtuels !
Les utilisateurs virtuels
Les utilisateurs ne devraient pas pouvoir passer de commandes sur le serveur. Si la ligne « /bin/false » ne se trouve pas dans le fichier « /etc/shells », vous devrez l’ajouter :
Pour vérifier :
cat /etc/shells
Pour l’ajouter :
echo /bin/false >> /etc/shells
Ensuite nous allons ajouter à notre fichier de configuration, 2 nouvelles lignes :
AuthOrder mod_auth_file.c
AuthUserFile /etc/proftpd/vpasswd
Nous devrons recharger la configuration de proftpd pour que ces 2 nouvelles directives soient correctement prises en compte.
Ces lignes vont nous permettre d’associer un utilisateur virtuel à notre compte adrien. Pour cela, nous aurons besoin de connaitre son uid (id -u adrien : 1234) et son gid (id -g adrien : 1234) avant de lancer la commande ci-dessous:
sudo ftpasswd --file=/etc/proftpd/vpasswd --name=ftpadrien \
--home=/home/adrien/www --shell=/bin/false \
--uid=1234 --gid=1234 --passwd
C’est terminé !
En finalité, nous disposons d’un utilisateur FTP « ftpadrien » avec un mot de passe dédié à ce seul usage dont les droits « héritent » de adrien. Si je crée un fichier via FTP, je pourrai le modifier ou le supprimer en SSH, et inversement, nous ne rencontrerons donc aucun problème de droit !
Les connexions FTP sont chrootées dans le répertoire de notre site internet et non pas directement dans le home de adrien.
Mise en place du TLS
Notre serveur FTP fonctionne, maintenant, place au chiffrage des échanges !
Après avoir créé le répertoire de stockage, on lance la génération du certificat et de la clef auto-signée :
mkdir /etc/proftpd/ssl openssl req -x509 -newkey rsa:2048 \
-keyout /etc/proftpd/ssl/proftpd.key \
-out /etc/proftpd/ssl/proftpd.crt \
-nodes -days 365
Les fichiers ne doivent être lisibles que par root, on modifie les droits comme suit :
chmod 0640 /etc/proftpd/ssl/proftpd.key
chmod 0640 /etc/proftpd/ssl/proftpd.crt
Enfin, on ajoute cette nouvelle section à notre fichier de configuration avant de recharger proftpd :
<IfModule mod_tls.c> TLSEngine on TLSLog /var/log/proftpd/tls.log TLSProtocol SSLv23 TLSRSACertificateFile /etc/proftpd/ssl/proftpd.crt TLSRSACertificateKeyFile /etc/proftpd/ssl/proftpd.key TLSRequired on # Force l'utilisation du TLS, les connexions non sécurisées sont refusées TLSOptions NoSessionReuseRequired TLSRenegotiate required off </IfModule>
Pour aller plus loin
Histoire de verrouiller toujours un peu plus l’ensemble, nous pourrions changer le port par défaut et mettre en place du fail2ban pour bloquer les tentatives connexions en échecs, ce point-ci fera peut-être l’objet d’un nouvel article.