Authentification vsftpd par base de données MariaDB
Architecture du laboratoire
| Rôle | Système | Adresse IP |
|---|---|---|
| Serveur FTP | Centos7 | 192.168.119.131 |
| Serveur de bases de données | Centos7_mini2 | 192.168.119.147 |
| Poste client | Ubuntu22 | 192.168.119.149 |
Démarche de mise en place
Étape 1 : Installation et préparation de MariaDB
Sur le serveur dédié à la base de données, installer le paquet MariaDB puis activer le service au démarrage :
yum -y install mariadb-server
systemctl enable --now mariadb.service
Étape 2 : Création de la structure de données pour l'authentification FTP
Se connecter à MariaDB pour préparer la base et la table des utilisateurs virtuels :
MariaDB [(none)]> CREATE DATABASE ftp_auth;
MariaDB [(none)]> USE ftp_auth;
MariaDB [ftp_auth]> CREATE TABLE accounts (
-> uid INT AUTO_INCREMENT PRIMARY KEY,
-> login VARCHAR(50) BINARY NOT NULL,
-> passhash VARCHAR(48) BINARY NOT NULL
-> );
MariaDB [ftp_auth]> INSERT INTO accounts(login, passhash) VALUES('util_a', PASSWORD('MotDePasse1'));
MariaDB [ftp_auth]> INSERT INTO accounts(login, passhash) VALUES('util_b', PASSWORD('MotDePasse1'));
Accorder les droits en lecture seule à un compte applicatif dédié :
MariaDB [ftp_auth]> GRANT SELECT ON ftp_auth.* TO 'ftp_app'@'192.168.119.%' IDENTIFIED BY 'MotDePasse1';
MariaDB [ftp_auth]> FLUSH PRIVILEGES;
Étape 3 : Compilation du module PAM pour MySQL
Sur le serveur FTP, installer les dépendances puis compiler pam_mysql :
yum -y install vsftpd gcc gcc-c++ make mariadb-devel pam-devel
tar xf pam_mysql-0.7RC1.tar.gz
cd pam_mysql-0.7RC1/
./configure --with-pam-mods-dir=/lib64/security
make && make install
Vérifier la présence du module compilé :
ls -la /lib64/security/pam_mysql.so
Étape 4 : Configuration du module PAM
Créer un fichier PAM spécifique à vsftpd avec les paramètres de connexion à la base :
cat > /etc/pam.d/vsftpd.mariadb <<'EOF'
auth required pam_mysql.so user=ftp_app passwd=MotDePasse1 host=192.168.119.147 db=ftp_auth table=accounts usercolumn=login passwdcolumn=passhash crypt=2
account required pam_mysql.so user=ftp_app passwd=MotDePasse1 host=192.168.119.147 db=ftp_auth table=accounts usercolumn=login passwdcolumn=passhash crypt=2
EOF
Étape 5 : Création de l'espace FTP et activation des utilisateurs invités
Définir un compte système sans shell pour porter les utilisateurs virtuels, puis préparer l'arborescence d'accueil :
useradd -s /sbin/nologin -d /srv/ftp_root -r ftp_virtual
mkdir -p /srv/ftp_root/depot
setfacl -m u:ftp_virtual:rwx /srv/ftp_root/depot/
Modifier la configuration de vsftpd :
cat >> /etc/vsftpd/vsftpd.conf <<'EOF'
guest_enable=YES
guest_username=ftp_virtual
pam_service_name=vsftpd.mariadb
EOF
systemctl enable --now vsftpd
Étape 6 : Définition de droits différenciés par utilisateur
Activer le répertoire de configuration par utilisateur :
echo "user_config_dir=/etc/vsftpd/per_user" >> /etc/vsftpd/vsftpd.conf
mkdir /etc/vsftpd/per_user
Configurer les permissions pour l'utilisateur util_a :
cat > /etc/vsftpd/per_user/util_a <<'EOF'
anon_upload_enable=YES
anon_mkdir_write_enable=YES
anon_other_write_enable=YES
local_root=/srv/ftp_util_a
EOF
mkdir -p /srv/ftp_util_a/{envoi,reception}
chown ftp_virtual:ftp_virtual /srv/ftp_util_a/envoi/
systemctl restart vsftpd
Étape 7 : Validation
Depuis le poste client, tester la connexion avec util_a :
ftp 192.168.119.131
# Connexion avec util_a / MotDePasse1
ftp> cd envoi
ftp> put fichier_test.txt
ftp> ls
Puis avec util_b qui accède au répertoire par défaut du compte ftp_virtual :
ftp 192.168.119.131
# Connexion avec util_b / MotDePasse1
ftp> ls
Partage Samba du répertoire /www
Environnement
| Rôle | Système | Adresse IP |
|---|---|---|
| Serveur Samba | Centos8-mini | 192.168.119.148 |
| Client | Centos7 | 192.168.119.142 |
Procédure
Installation des composants
# Sur le serveur
yum -y install samba
systemctl enable --now smb
# Sur le client
yum -y install samba-client
Création d'un utilisateur Samba
useradd partage1
smbpasswd -a partage1
# Saisir le mot de passe souhaité
pdbedit -L # Vérifier l'enregistrement
Préparation du répertoire partagé
mkdir /www
chmod 777 /www
echo "fichier initial" > /www/readme.txt
Définition du partage
Éditer /etc/samba/smb.conf et ajouter la section suivante :
[docs_www]
path = /www
writeable = yes
systemctl restart smb
Vérification depuis le client
smbclient //192.168.119.148/docs_www -U partage1%m0tDeP@sse
smb: \> ls
smb: \> put document.txt
smb: \> ls
Synchronisation en temps réel avec rsync et inotify
Environnement
| Rôle | Système | Adresse IP |
|---|---|---|
| Source de données | Centos8-mini | 192.168.119.148 |
| Serveur de sauvegarde | Rocky8-mini | 192.168.119.128 |
Procédure
Installation des outils
# Sur le serveur source
yum -y install inotify-tools
# Sur le serveur de sauvegarde
yum -y install rsync rsync-daemon
systemctl enable --now rsyncd
Configuration du démon rsync
cat > /etc/rsyncd.conf <<'EOF'
uid = root
gid = root
max connections = 0
ignore errors
exclude = lost+found/
log file = /var/log/rsyncd.log
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsyncd.lock
reverse lookup = no
[replique]
path = /www
read only = no
auth users = syncuser
secrets file = /etc/rsync.secret
EOF
echo "syncuser:m0tDeP@sse" > /etc/rsync.secret
chmod 600 /etc/rsync.secret
systemctl restart rsyncd
mkdir /www
setfacl -m u:nobody:rwx /www/
Test de transfert manuel
# Sur le serveur source
echo "syncuser" > /etc/rsync.secret
chmod 600 /etc/rsync.secret
rsync --password-file=/etc/rsync.secret /etc/sysctl.conf rsync://syncuser@192.168.119.128/replique
Script de synchronisation automatique via inotify
#!/bin/bash
SOURCE_DIR='/www/'
REMOTE_DEST='syncuser@192.168.119.128::replique'
SECRET_FILE='/etc/rsync.secret'
rpm -q rsync &>/dev/null || yum -y install rsync
inotifywait -mrq \
--exclude=".*\.swp" \
--timefmt '%Y-%m-%d %H:%M:%S' \
--format '%T %w %f' \
-e create,delete,moved_to,close_write,attrib \
"${SOURCE_DIR}" | while read HEURE HORAIRE CHEMIN NOM; do
CHEMIN_COMPLET="${CHEMIN}${NOM}"
rsync -az --delete \
--password-file="${SECRET_FILE}" \
"${SOURCE_DIR}" "${REMOTE_DEST}" \
&& echo "${HORAIRE} ${HEURE} : ${CHEMIN_COMPLET} synchronisé" >> /var/log/sync_changes.log
done
Lancer le script en arrière-plan :
bash /opt/scripts/sync_inotify.sh &
Algorithmes de répartition de charge LVS
Algorithmes statiques
Ces algorithmes répartissent les requêtes sans tenir compte de la charge réelle des serveurs back-end.
RR (Round Robin)
Répartition cyclique : chaque serveur reçoit les requêtes à tour de rôle de manière séquentielle.
WRR (Weighted Round Robin)
Comme RR, mais chaque serveur possède un coefficient de pondération. Un serveur avec un poids élevé traite proportionnellement plus de requêtes.
SH (Source Hashing)
Le hachage de l'adresse source garantit qu'un même client est toujours dirigé vers le même serveur, assurant la persistance de session. Ce mécanisme pose toutefois problème lorsque de nombreux utilisateurs partagent une même IP publique : tout le trafic converge vers un seul serveur.
DH (Destination Hashing)
Le hachage de l'adresse destination oriente systématiquement les requêtes vers un serveur spécifique. Utile dans les architectures de cache web, où une même ressource est toujours servie par le même nœud.
Algorithmes dynamiques
Ces algorithmes intègrent l'état de charge des serveurs dans la décision de répartition. Le serveur présentant la plus faible valeur de surcharge (overhead) est sélectionné.
LC (Least Connections)
Adapté aux applications maintenant des connexions longues.
Overhead = connexions_actives × 256 + connexions_inactives
WLC (Weighted Least Connections)
Algorithme par défaut de LVS, très répandu en production.
Overhead = (connexions_actives × 256 + connexions_inactives) / poids
SED (Shortest Expected Delay)
Priorise les serveurs à fort poids lors de la connexion initiale. Seules les connexions actives sont comptabilisées.
Overhead = (connexions_actives + 1) × 256 / poids
NQ (Never Queue)
Lors du premier cycle, chaque serveur reçoit une requête sans file d'attente. Ensuite, l'algorithme SED prend le relais.
LBLC (Locality-Based Least Connections)
Variante dynamique de DH adaptée au proxy inverse et au cache web. La destination est choisie en fonction de la charge locale.
LBLCR (Locality-Based Least Connections with Replication)
Étend LBLC en répliquant les données du cache vers les serveurs les moins sollicités, corrigeant les déséquilibres de charge.
Nouveautés depuis le noyau 4.15
FO (Weighted Fail Over)
Parcourt la liste des serveurs et sélectionne celui ayant le poids le plus élevé parmi ceux non surchargés (drapeau IP_VS_DEST_F_OVERLOAD). Algorithme statique.
OVF (Overflow-Connection)
Algorithm dynamique basé sur les connexions actives et le poids. Les nouvelles connexions sont dirigées vers le serveur de plus fort poids jusqu'à ce que ses connexions actives dépassent sa valeur de poids, puis vers le suivant.
Critères d'éligibilité d'un serveur réel :
- Drapeau
IP_VS_DEST_F_OVERLOADnon positionné - Nombre de connexions actives inférieur au poids attribué
- Poids non nul
Déploiement LVS en mode DR inter-réseaux
Schéma de l'architecture
L'architecture comprend un client distant (réseau 192.168.225.0/24), un routeur reliant les deux sous-réseaux, un répartiteur LVS et deux serveurs réels dans le réseau 192.168.119.0/24. L'adresse VIP (172.16.0.100) est configurée sur les interfaces loopback du LVS et des serveurs réels.
Détail des machines
| Machine | Interface | Adresse | Passerelle |
|---|---|---|---|
| Client (Ubuntu20) | eth0 | 192.168.225.135/24 | 192.168.225.10 |
| Routeur (Rocky8) | ens33 | 192.168.119.10/24 | — |
| ens33:1 | 172.16.0.10/24 | — | |
| ens37 | 192.168.225.10/24 | — | |
| LVS (Rocky8) | lo:1 | 172.16.0.100/32 | — |
| ens33 | 192.168.119.146/24 | 192.168.119.10 | |
| RS1 (Rocky8) | lo:1 | 172.16.0.100/32 | — |
| ens33 | 192.168.119.128/24 | 192.168.119.10 | |
| RS2 (Rocky8) | lo:1 | 172.16.0.100/32 | — |
| ens33 | 192.168.119.138/24 | 192.168.119.10 |
Configuration du routeur
Activer le routage IP pour relier les deux sous-réseaux :
echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf
sysctl -p
Préparation des serveurs réels
Installer Apache sur chaque serveur réel et y déposer une page d'identification :
# Sur RS1
yum -y install httpd
echo "SR1 192.168.119.128" > /var/www/html/index.html
systemctl enable --now httpd
# Sur RS2
yum -y install httpd
echo "SR2 192.168.119.138" > /var/www/html/index.html
systemctl enable --now httpd
Configuration du répartiteur LVS
yum -y install ipvsadm
# Définir le service virtuel sur la VIP avec l'algorithme RR
ipvsadm -A -t 172.16.0.100:80 -s rr
# Ajouter les serveurs réels en mode routage direct (-g)
ipvsadm -a -t 172.16.0.100:80 -r 192.168.119.128:80 -g
ipvsadm -a -t 172.16.0.100:80 -r 192.168.119.138:80 -g
Vérifier la table de répartition :
ipvsadm -Ln
# IP Virtual Server version 1.2.1 (size=4096)
# Prot LocalAddress:Port Scheduler Flags
# -> RemoteAddress:Port Forward Weight ActiveConn InActConn
# TCP 172.16.0.100:80 rr
# -> 192.168.119.128:80 Route 1 0 0
# -> 192.168.119.138:80 Route 1 0 0
Validation depuis le client
curl 172.16.0.100
# SR2 192.168.119.138
curl 172.16.0.100
# SR1 192.168.119.128
curl 172.16.0.100
# SR2 192.168.119.138
curl 172.16.0.100
# SR1 192.168.119.128
Les réponses alternent bien entre les deux serveurs réels, confirmant le fonctionnement correct de la répartition cyclique.