594 lines
16 KiB
Markdown
594 lines
16 KiB
Markdown
---
|
||
categories: web
|
||
title: Howto ProFTPD
|
||
...
|
||
|
||
* Documentation : <http://www.proftpd.org/docs/>
|
||
|
||
[ProFTPD](http://www.proftpd.org/) est un serveur [FTP](https://fr.wikipedia.org/wiki/File_Transfer_Protocol) libre.
|
||
|
||
Il est particulièrement configurable grâce à des modules. Il permet notamment de facilement restreindre un compte dans un répertoire donné ("_chroot_") ou d'utiliser les protocoles FTPS (FTP over SSL/TLS) et SFTP/SCP (FTP over SSH).
|
||
|
||
|
||
## Installation
|
||
|
||
~~~{bash}
|
||
# apt install proftpd
|
||
|
||
# proftpd -v
|
||
ProFTPD Version 1.3.5b
|
||
|
||
# systemctl status proftpd
|
||
● proftpd.service - LSB: Starts ProFTPD daemon
|
||
Loaded: loaded (/etc/init.d/proftpd; generated; vendor preset: enabled)
|
||
Docs: man:systemd-sysv-generator(8)
|
||
Process: 28249 ExecStop=/etc/init.d/proftpd stop (code=exited, status=0/SUCCESS)
|
||
Process: 22916 ExecReload=/etc/init.d/proftpd reload (code=exited, status=0/SUCCESS)
|
||
Process: 28259 ExecStart=/etc/init.d/proftpd start (code=exited, status=0/SUCCESS)
|
||
Tasks: 1 (limit: 4915)
|
||
CGroup: /system.slice/proftpd.service
|
||
└─28267 proftpd: (accepting connections)
|
||
~~~
|
||
|
||
|
||
## Configuration
|
||
|
||
### Configuration simple
|
||
|
||
Le fichier de configuration principal est `/etc/proftpd/proftpd.conf`.
|
||
|
||
Vous pouvez aussi ajouter des fichiers `.conf` pour customiser la configuration dans `/etc/proftpd/conf.d`, qui sont inclus à la fin de `/etc/proftpd/proftpd.conf` et permettent d'écraser les directives générales.
|
||
|
||
Voici les directives que nous conseillons de changer :
|
||
|
||
~~~
|
||
ServerName "Foo FTP Server"
|
||
PassivePorts 60000 61000
|
||
MaxInstances 50
|
||
MaxClients 40
|
||
MaxClientsPerHost 20
|
||
Umask 137 027
|
||
UseReverseDNS off
|
||
IdentLookups off
|
||
TimesGMT off
|
||
DefaultRoot ~
|
||
RequireValidShell off
|
||
UseFtpUsers off
|
||
ServerIdent on "FTP Server Ready"
|
||
AccessGrantMsg "Hey, bienvenue %u sur le serveur FTP example.com !"
|
||
# Allow RESUME (REST command)
|
||
AllowStoreRestart on
|
||
|
||
<Limit LOGIN>
|
||
AllowUser $ftp_user
|
||
AllowGroup $ftp_group
|
||
DenyAll
|
||
</Limit>
|
||
~~~
|
||
|
||
Dans cette configuration, un utilisateur doit être dans le groupe `$ftp_group` (à créer) pour utiliser le FTP.
|
||
|
||
Si l'IPv6 n'est pas fonctionnel sur votre serveur :
|
||
|
||
~~~
|
||
UseIPv6 off
|
||
~~~
|
||
|
||
|
||
### Configuration dans différents VirtualHost
|
||
|
||
D'une manière similaire à [Apache](HowtoApache), on peut isoler des configurations FTP dans différents VirtualHost.
|
||
|
||
Cela permet notamment de faire écouter ProFTPD sur 2 ports différents en même temps.
|
||
|
||
Ainsi, on peut mettre en place à la fois un FTP classique et un SFTP.
|
||
|
||
Par exemple, on laisse la configuration par défaut écouter sur le port 21, et on fait écouter un VirtualHost sur le port 8887.
|
||
|
||
Note : La balise `VirtualHost` accepte les adresses IP et les noms de domaine.
|
||
|
||
Voici un exemple de configuration classique qui écoute sur un port différent dans un VirtualHost :
|
||
|
||
~~~
|
||
# vim /etc/proftpd/conf.d/my_vhost.conf
|
||
|
||
<VirtualHost 192.168.1.8>
|
||
|
||
ServerName "FTP Server"
|
||
ServerIdent on "FTP Server Ready"
|
||
AccessGrantMsg "Hey, bienvenue %u sur le serveur FTP !"
|
||
|
||
SFTPEngine on
|
||
Port 8887
|
||
DefaultRoot ~
|
||
PassivePorts 60000 61000
|
||
UseReverseDNS off
|
||
IdentLookups off
|
||
TimesGMT off
|
||
|
||
# Local permissions
|
||
DefaultRoot ~
|
||
Umask 137 027
|
||
RequireValidShell off
|
||
UseFtpUsers off
|
||
|
||
# Allow RESUME (REST command)
|
||
AllowStoreRestart on
|
||
|
||
</VirtualHost>
|
||
~~~
|
||
|
||
Si l'on veut faire écouter deux VirtualHost sur deux IPs différentes (publique ou LAN), mais sur le même port, il faut utiliser ces options avant la directive `<VirtualHost>` :
|
||
|
||
~~~
|
||
Port 0
|
||
SocketBindTight on
|
||
~~~
|
||
|
||
Cela va forcer à utiliser l'IP configurée dans la directive `<VirtualHost>` avec le port indiqué dans celui-ci. Exemple avec une configuration SFTP :
|
||
|
||
~~~
|
||
Port 0
|
||
SocketBindTight on
|
||
|
||
<VirtualHost 192.168.199.27>
|
||
|
||
<IfModule mod_sftp.c>
|
||
SFTPEngine on
|
||
Port 22
|
||
DefaultRoot ~
|
||
RequireValidShell off
|
||
|
||
AuthUserFile /etc/proftpd/vpasswd
|
||
</IfModule>
|
||
|
||
</VirtualHost>
|
||
~~~
|
||
|
||
Les VirtualHosts ont de nombreuses autres fonctionnalités, comme les Alias par exemple.
|
||
|
||
Voir la documentation : <http://www.proftpd.org/docs/howto/Vhost.html>.
|
||
|
||
|
||
## Gestion des utilisateurs
|
||
|
||
ProFTPD permet l'authentification via les comptes Unix, un fichier de configuration simple, PAM, une base de données SQL, LDAP.
|
||
|
||
Les comptes ont les mêmes attributs qu'un compte Unix : username, password, uid, gid, gecos, homedir, shell.
|
||
|
||
Lorsqu'un compte FTP utilise un UID et un GID non définis dans `/etc/passwd`, il est dit "virtuel".
|
||
|
||
On détaille ici l'utilisation de comptes définis dans un fichier `/etc/proftpd/vpasswd`.
|
||
|
||
Il faut ajouter dans `/etc/proftpd/proftpd.conf` :
|
||
|
||
~~~
|
||
AuthOrder mod_auth_file.c
|
||
AuthUserFile /etc/proftpd/vpasswd
|
||
~~~
|
||
|
||
**Attention :** Le fichier `/etc/proftpd/vpasswd` doit avoir les droits en 600, sinon ProFTPD refuse de se lancer.
|
||
|
||
La gestion des comptes se fait ensuite via le script Perl `ftpasswd` inclu avec ProFTPD.
|
||
|
||
Documentation :
|
||
|
||
* <http://www.proftpd.org/docs/howto/Authentication.html>
|
||
* <http://www.proftpd.org/docs/howto/VirtualUsers.html>
|
||
|
||
|
||
### Ajouter un compte
|
||
|
||
#### Dans un répertoire existant, appartenant déjà à un utilisateur Unix
|
||
|
||
Dans ce cas, les `$ftp_uid` et `$ftp_gid` doivent être ceux du compte Unix propriétaire du répertoire :
|
||
|
||
~~~{bash}
|
||
# ftp_home=... # répertoire racine du compte FTP
|
||
# ftp_uid=$(stat -c '%u' $ftp_home) # UID du compte FTP
|
||
# ftp_gid=$(stat -c '%g' $ftp_home) # GID du compte FTP
|
||
|
||
# ftp_user=... # nom du futur utilisateur FTP
|
||
# apg -n 1 -m 12 # génération du mot de passe
|
||
# ftpasswd --file=/etc/proftpd/vpasswd --name=$ftp_user --home=$ftp_home --shell=/bin/false --uid=$ftp_uid --gid=$ftp_gid --passwd
|
||
~~~
|
||
|
||
|
||
#### Avec un nouveau répertoire racine, dédié à l'utilisateur FTP
|
||
|
||
Dans ce cas, on choisit des `$ftp_uid` et `$ftp_gid` qui ne sont pas utilisés dans `/etc/passwd`.
|
||
|
||
Pour lister les UID et GID déjà utilisés : `cut -d: -f1,3,4 /etc/passwd`
|
||
|
||
Puis, on crée le répertoire racine, possédé par les numéros `$ftp_uid` et `$ftp_gid` de l'utilisateur FTP.
|
||
|
||
Attention : **ne pas utiliser le nom du compte FTP dans `chown`** (Unix ne le reconnaît pas car le compte FTP n'est pas dans `/etc/passwd`).
|
||
|
||
~~~{bash}
|
||
# ftp_home=... # répertoire racine du compte FTP
|
||
# ftp_uid=... # UID du compte FTP
|
||
# ftp_gid=... # GID du compte FTP
|
||
# mkdir $ftp_home
|
||
# chown $ftp_uid:$ftp_gid -R $ftp_home
|
||
|
||
# ftp_user=... # nom du futur utilisateur FTP
|
||
# apg -n 1 -m 12 # génération du mot de passe
|
||
# ftpasswd --passwd --file=/etc/proftpd/vpasswd --name=$ftp_user --home=$ftp_home --shell=/bin/false --uid=$ftp_uid --gid=$ftp_gid
|
||
~~~
|
||
|
||
|
||
### Changer le mot de passe
|
||
|
||
Pour changer le mot de passe d'un compte :
|
||
|
||
~~~{bash}
|
||
# ftp_user=... # nom du compte FTP
|
||
# apg -n 1 -m 12 # génération du mot de passe
|
||
# ftpasswd --passwd --file /etc/proftpd/vpasswd --name=$ftp_user --change-password
|
||
~~~
|
||
|
||
|
||
### Supprimer un compte
|
||
|
||
Pour supprimer un compte :
|
||
|
||
~~~{bash}
|
||
# ftp_user=... # nom du compte FTP à supprimer
|
||
# ftpasswd --passwd --file=/etc/proftpd/vpasswd --name=$ftp_user --delete-user
|
||
~~~
|
||
|
||
|
||
### Directive `Limit`
|
||
|
||
Documentation : <http://www.proftpd.org/docs/howto/Limit.html>
|
||
|
||
La directive `Limit` permet d'autoriser ou empêcher l'exécution de commande FTP bas niveau.
|
||
|
||
**Attention :** C'est puissant et dangereux, car on pourrait croire que l'on empêche la lecture d'un fichier, mais il faut avoir en tête qu'il existe plusieurs commandes FTP pour faire cela. Il existe des groupes de commandes : LOGIN, DIRS, READ, WRITE et enfin ALL (tout sauf LOGIN).
|
||
|
||
Voici un exemple d'utilisation pour empêcher toutes opérations sauf dans un répertoire :
|
||
|
||
~~~
|
||
<Directory *>
|
||
<Limit ALL>
|
||
DenyAll
|
||
</Limit>
|
||
</Directory>
|
||
|
||
<Directory $path>
|
||
<Limit ALL>
|
||
AllowAll
|
||
</Limit>
|
||
</Directory>
|
||
~~~
|
||
|
||
Ou encore autoriser **uniquement** le dépôt de fichiers dans un répertoire :
|
||
|
||
~~~
|
||
<Directory $path>
|
||
<Limit ALL>
|
||
DenyAll
|
||
</Limit>
|
||
<Limit CDUP CWD XCWD XCUP PWD STOR STOU>
|
||
AllowAll
|
||
</Limit>
|
||
</Directory>
|
||
~~~
|
||
|
||
Pour avoir un utilisateur en lecture seule, confiné dans son `$ftp_home` :
|
||
|
||
~~~
|
||
<Directory ~$ftp_user>
|
||
<Limit CWD PWD DIRS READ>
|
||
AllowUser $ftp_user
|
||
</Limit>
|
||
|
||
<Limit ALL>
|
||
DenyUser $ftp_user
|
||
</Limit>
|
||
</Directory>
|
||
~~~
|
||
|
||
Pour blacklister les connexions depuis une IP ou un hôte, mais en autorisant seulement certains comptes :
|
||
|
||
~~~
|
||
<Limit LOGIN>
|
||
Deny from $IP
|
||
AllowUser $ftp_user1
|
||
AllowUser $ftp_user2
|
||
</Limit>
|
||
~~~
|
||
|
||
Cette configuration refuse toutes les connexions au serveur depuis l'IP $IP, mais accepte les connexions aux utilisateur $ftp_user1 et $ftp_user2, à l'exception de tous les autres utilisateurs.
|
||
|
||
**Attention :** Dans ce dernier cas, s'il y a plusieurs blocs / directives LOGIN dans la configuration ou le VirtualHost, il faut autoriser les utilisateurs dans toutes ces directives, sinon l'accès sera refusé tout le temps.
|
||
|
||
|
||
## Divers
|
||
|
||
Pour limiter les uploads de fichiers de taille supérieure à 50 Mo :
|
||
|
||
~~~
|
||
MaxStoreFileSize 50 Mb
|
||
~~~
|
||
|
||
Forcer les droits 640 en fichier et 750 en répertoire avec l'umask:
|
||
|
||
~~~
|
||
<Directory $ftp_home>
|
||
Umask 0137 0027
|
||
|
||
<Limit SITE_CHMOD>
|
||
DenyAll
|
||
</Limit>
|
||
</Directory>
|
||
~~~
|
||
|
||
|
||
## Quota
|
||
|
||
Pour activer les quotas spécifiquement à ProFTPD avec gestion via fichiers :
|
||
|
||
~~~{bash}
|
||
# cd /etc/proftpd
|
||
# ftpquota --create-table --type=limit
|
||
# ftpquota --create-table --type=tally
|
||
~~~
|
||
|
||
Puis ajouter dans la configuration :
|
||
|
||
~~~
|
||
<IfModule mod_quotatab.c>
|
||
QuotaEngine on
|
||
QuotaLimitTable file:/etc/proftpd/ftpquota.limittab
|
||
QuotaTallyTable file:/etc/proftpd/ftpquota.tallytab
|
||
</IfModule>
|
||
~~~
|
||
|
||
On peut ensuite positionner des quotas, par exemple pour limiter les données uploadées à 200 Go :
|
||
|
||
~~~{bash}
|
||
# ftpquota --add-record --type=limit --bytes-upload=200 --units=Gb --name=foo --quota-type=user
|
||
~~~
|
||
|
||
Imaginons que vous positionnez le quota alors que l'utilisateur a déjà 170 Go, vous devez mettre à jour son compteur :
|
||
|
||
~~~{bash}
|
||
# ftpquota --update-record --type=tally --bytes-upload=170 --units=Gb --name=foo --quota-type=user
|
||
~~~
|
||
|
||
On peut lister les données de quota sur le serveur ainsi :
|
||
|
||
~~~{bash}
|
||
# ftpquota --show-records --type=tally
|
||
-------------------------------------------
|
||
Name: foo
|
||
Quota Type: User
|
||
Uploaded bytes: 182536110080.00
|
||
Downloaded bytes: 0.00
|
||
Transferred bytes: 0.00
|
||
Uploaded files: 0
|
||
Downloaded files: 0
|
||
Transferred files: 0
|
||
|
||
# ftpquota --show-records --type=limit
|
||
-------------------------------------------
|
||
Name: foo
|
||
Quota Type: User
|
||
Per Session: False
|
||
Limit Type: Hard
|
||
Uploaded bytes: 214748364800.00
|
||
Downloaded bytes: unlimited
|
||
Transferred bytes: unlimited
|
||
Uploaded files: unlimited
|
||
Downloaded files: unlimited
|
||
Transferred files: unlimited
|
||
~~~
|
||
|
||
Via FTP, vous pourrez voir les données de quota ainsi :
|
||
|
||
~~~{bash}
|
||
ftp> quote SITE QUOTA
|
||
200-Quota pour la session actuelle [courant / limite]:
|
||
200-Nom: foo
|
||
200-Type quota: Utilisateur
|
||
200-Par session : Faux
|
||
200-Type de limite : matérielle
|
||
200- bytes: 182536110080.00/193273528320.00 envoyés
|
||
200- bytes: unlimited reçus
|
||
200- bytes: unlimited téléchargés
|
||
200- files: unlimited envoyés
|
||
200- files: unlimited reçus
|
||
200- files: unlimited téléchargés
|
||
200 Veuillez contacter ftpmaster@example.com si ces données sont inexactes
|
||
~~~
|
||
|
||
Enfin, on peut réinitialiser un compteur (tous les jours par exemple) :
|
||
|
||
~~~{bash}
|
||
# ftpquota --update-record --type=tally --name=foo --quota-type=user
|
||
~~~
|
||
|
||
Ou même effacer toutes les données de quota d'un utilisateur :
|
||
|
||
~~~{bash}
|
||
# ftpquota --delete-record --type=limit --name=foo --quota-type=user
|
||
# ftpquota --delete-record --type=tally --name=foo --quota-type=user
|
||
~~~
|
||
|
||
|
||
## FTPS (FTP over SSL/TLS)
|
||
|
||
On peut activer SSL/TLS en créant un fichier `/etc/proftpd/tls.conf` contenant les directives suivantes :
|
||
|
||
~~~{bash}
|
||
# vim /etc/proftpd/tls.conf
|
||
TLSEngine on
|
||
TLSLog /var/log/proftpd/tls.log
|
||
TLSProtocol SSLv23
|
||
TLSRSACertificateFile /etc/proftpd/ssl/proftpd.crt
|
||
TLSCACertificateFile /etc/proftpd/ssl/proftpd.ca.crt
|
||
TLSRSACertificateKeyFile /etc/proftpd/ssl/proftpd.key
|
||
~~~
|
||
|
||
Vérifiez que les certificats et la clé privé existent bien.
|
||
|
||
Il faut vérifier que le fichier est bien chargé par la configuration principale `/etc/proftpd/proftpd.conf` :
|
||
|
||
~~~{bash}
|
||
# vim /etc/proftpd/proftpd.conf
|
||
Include /etc/proftpd/tls.conf
|
||
~~~
|
||
|
||
Testez la configuration et rechargez la configuration :
|
||
|
||
~~~{bash}
|
||
# proftpd -t && systemctl reload proftpd.service
|
||
~~~
|
||
|
||
Testez la connexion :
|
||
|
||
~~~{bash}
|
||
# host=... # IP ou domaine
|
||
# lftp $host
|
||
lftp host:~> set ftp:ssl-force true
|
||
lftp host:~> login $ftp_user
|
||
Mot de passe :
|
||
lftp $ftp_user@host:~> ls
|
||
~~~
|
||
|
||
Si l'on peut lire le contenu du répertoire, alors la connexion est fonctionnelle.
|
||
|
||
|
||
## SFTP (FTP over SSH)
|
||
|
||
On peut configurer SFTP avec les directives suivantes :
|
||
|
||
~~~
|
||
LoadModule mod_tls.c
|
||
|
||
<IfModule mod_sftp.c>
|
||
SFTPEngine on
|
||
Port 2222
|
||
DefaultRoot ~
|
||
|
||
SFTPLog /var/log/proftpd/sftp.log
|
||
|
||
SFTPAuthMethods password publickey
|
||
# ProFTPD doesn't support ed25519 yet
|
||
#SFTPHostKey /etc/ssh/ssh_host_ed25519_key
|
||
SFTPHostKey /etc/ssh/ssh_host_ecdsa_key
|
||
SFTPHostKey /etc/ssh/ssh_host_rsa_key
|
||
|
||
SFTPAuthorizedUserKeys file:/etc/sftp/authorized_keys/%u
|
||
|
||
SFTPCompression delayed
|
||
|
||
</IfModule>
|
||
~~~
|
||
|
||
Généralement, on souhaite conserver un service FTP "classique" en parallèle. On met donc cette configuration dans un VirtualHost, pour pouvoir écouter sur un deuxième port.
|
||
|
||
Par exemple :
|
||
|
||
~~~
|
||
$ vim /etc/proftpd/conf.d/sftp.conf
|
||
|
||
LoadModule mod_tls.c
|
||
|
||
<VirtualHost 0.0.0.0>
|
||
<IfModule mod_sftp.c>
|
||
|
||
SFTPEngine on
|
||
Port 2222
|
||
DefaultRoot ~
|
||
|
||
SFTPLog /var/log/proftpd/sftp.log
|
||
|
||
SFTPAuthMethods password publickey
|
||
# ProFTPD doesn't support ed25519 yet
|
||
#SFTPHostKey /etc/ssh/ssh_host_ed25519_key
|
||
SFTPHostKey /etc/ssh/ssh_host_ecdsa_key
|
||
SFTPHostKey /etc/ssh/ssh_host_rsa_key
|
||
|
||
SFTPAuthorizedUserKeys file:/etc/proftpd/sftp.passwd.keys/%u
|
||
AuthOrder mod_auth_file.c
|
||
AuthUserFile /etc/proftpd/vpasswd
|
||
|
||
RequireValidShell off
|
||
|
||
</IfModule>
|
||
</VirtualHost>
|
||
~~~
|
||
|
||
Les clés SSH doivent être au format de compatibilité défini dans la RFC 4716, qui n'est pas le format par défaut de SSH.
|
||
|
||
Pour créer les clés privées compatibles côté serveur :
|
||
|
||
~~~{bash}
|
||
# ssh-keygen -f /etc/ssh/ssh_host_rsa_key -t rsa -N '' -m PEM
|
||
# ssh-keygen -f /etc/ssh/ssh_host_ecdsa_key -t ecdsa -N '' -m PEM
|
||
~~~
|
||
|
||
Testez la configuration et rechargez la configuration :
|
||
|
||
~~~{bash}
|
||
# proftpd -t && systemctl reload proftpd.service
|
||
~~~
|
||
|
||
Testez la connexion via un mot de passe :
|
||
|
||
~~~{bash}
|
||
# host=... # IP ou domaine
|
||
# lftp $host
|
||
lftp host:~> set ftp:ssl-force true
|
||
lftp host:~> login $ftp_user
|
||
Mot de passe :
|
||
lftp $ftp_user@host:~> ls
|
||
~~~
|
||
|
||
Si l'on peut lire le contenu du répertoire, alors la connexion est fonctionnelle.
|
||
|
||
|
||
### Authentification par clé SSH
|
||
|
||
On peut gérer des clés SSH avec la directive [SFTPAuthorizedUserKeys](http://www.proftpd.org/docs/contrib/mod_sftp.html#SFTPAuthorizedUserKeys) :
|
||
|
||
~~~
|
||
SFTPAuthorizedUserKeys file:/etc/proftpd/sftp.authorized_keys/%u
|
||
~~~
|
||
|
||
Attention, la clé publique à mettre dans le fichier doit être au format RFC4716, on peut convertir une clé ainsi :
|
||
|
||
|
||
~~~{bash}
|
||
$ ssh-keygen -e -f ~/.ssh/id_rsa.pub
|
||
~~~
|
||
|
||
Il faut ajuster les droits :
|
||
|
||
~~~
|
||
# chmod 700 /etc/proftpd/sftp.authorized_keys/
|
||
# chmod 600 /etc/proftpd/sftp.authorized_keys/foo
|
||
~~~
|
||
|
||
|
||
## Logs
|
||
|
||
[fichier xferlog](http://www.castaglia.org/proftpd/doc/xferlog.html)
|
||
|
||
|
||
## Troubleshooting
|
||
|
||
### Problème d'envoi de fichier avec erreur `open for write: permission denied`
|
||
|
||
L'erreur est provoquée lorsque l'on veut écraser un fichier existant, il faut rajouter la directive `AllowOverwrite on` dans le la configuration de ProFTPD ou du VirtualHost concerné.
|
||
|
||
On la positionne dans une balise `<Directory>` comme ceci :
|
||
|
||
~~~
|
||
<Directory /home/*>
|
||
AllowOverwrite on
|
||
</Directory>
|
||
~~~
|