Serveur Proftpd et log en fifo

Dans cet article nous allons voir comment mettre en place un serveur FTP Proftpd.

la première partie concerne l’installation et le paramétrage du serveur, puis dans une seconde partie la mise en place des logs dans une fifo.

L’intérêt de mettre les logs en fifo est de pouvoir traiter au fil de l’eau les événements du serveur FTP pour pouvoir faire sa propre journalisation ou faire traiter dans une application personnelle certaine information des accès au serveur.

Pour ma part ce projet est venu d’une simple idée : j’avais un serveur web pour un produit qui gère la réception d’événement, et un serveur FTP (filezilla serveur) qui permettait de faire le téléchargement du firmware de mes produits. Il n’y avait aucun corrélation coté serveur entre les 2 serveurs et si je ne venais pas lire et inspecter les logs de filezilla (sous windows, beurk ^^ ) je ne savais pas en temps réelles si les produits avait effectivement fait leur mise a jour.

Je voulais également avoir une application légère qui me permettait d’avoir une visualisation (un superviseur en quelque sortes) des produits encours de mise a jour, ce qui était effectué et les erreurs.

Pour le serveur web pas de souci, mais pour le serveur FTP, filezilla sous windows ne permet pas de traiter facilement les informations.

Donc je me suis orienté sur un serveur Proftp sous linux (coooool ^^) pour plusieurs raisons :

  • stabilité linux reconnu
  • sécurité
  • logs plus facile a traiter en fifo (nous verrons en détail cela plus loin)

donc je vais vous faire part de mon expérience. Voyons d’abord comment mettre en place un serveur proftpd

Installation Proftpd

je me base sur un Ubuntu 12.04

pour l’installation dans un terminal :

sudo apt-get install proftpd-basics

lors de l’installation, choisissez :

  • soit le démarrage par inet (démarrage automatique par le système au boot)
  • soit le mode indépendant, donc manuel

dans un premier temps choisissons « indépendant »

Paramétrage

Pour le paramétrage, éditez le fichier /etc/proftpd/proftpd.conf

insérer :

DefaultRoot ~ ftpusers
<Limit ALL>
DenyGroup !ftpusers
</Limit>

Modifiez :

ServerName « Ftp Maj »
PassivePort 49152 65534
DefaultRoot ~ ftpusers

Créons une groupe de users pour les autorisations FTP dans un terminal tapez :

sudo addgroup ftpusers

Créons un utilisateur et son répertoire :

adduser test –ingroup ftpusers –shell /bin/bash –home /home/test/

Lors de la création il vous sera demander de rentrer un mot de passe. choisissez celui que vous voulez.
Votre serveur est maintenant prêt à être exécuté :

sudo /etc/init.d/proftpd start

Activation des FIFOs pour les logs

Proftpd enregistre les logs standard dans des fichiers situés au chemin spécifié dans le fichier proftpd.conf. Pour connaître l’emplacement et le nom des fichiers, localiser dans le fichier de conf les directives suivantes :

TransferLog /var/log/proftpd/xferlog
SystemLog /var/log/proftpd/proftpd.log

Ces fichiers sont les logs par défaut et ne peuvent pas servir de fifo.
Pour mettre en place des fifos, il faut utiliser les directives ExtendedLog avec le LogFormat. voyons comment paramétrer proftpd pour cela.
Dans le fichier proftpd.conf, ajouter :

LogFormat auth « %t %a %u (%U) \ »%r\ » %s %S »
LogFormat write « %t %a %u (%U) \ »%r\ » %f %s %S %b »
LogFormat all « %t %a %u (%U) \ »%r\ » %f %s %S %b »
ExtendedLog /var/log/proftpd_log_auth.fifo AUTH auth
ExtendedLog /var/log/proftpd_log_access.fifo WRITE,READ write
ExtendedLog /var/log/proftpd_log_all.fifo ALL all

ExtendedLog permet de définir l’emplacement et le fichier de log (qui peut etre une fifo), puis la list des commandes FTP qu’on veut loggué et ensuite un nom de profil de log. exemple :

ExtendedLog /var/log/proftpd_log_access.fifo WRITE,READ write

ici on logguera dans /var/log/proftpd_log_access.fifo toutes les commandes de lecture et d’écriture en FTP et ce profil sera nommé « write ».
Ensuite il faut définir le format du log qui sera inscrit dans le fichier de log :

LogFormat write « %t %a %u (%U) \ »%r\ » %f %s %S %b »

LogFormat permet de définir les champs de données et leur ordre, afin d’avoir un format identique et voulu a chaque log, ce qui rend plus facile l’analyse ensuite par un programme spécifique.

Reportez vous à la documentation officiel de proftpd pour avoir plus d’information sur le format et les champs possibles.

Maintenant que le fichier de configuration est paramétré, il faut créer physiquement les fifos ; dans un terminal :

sudo mkfifo /var/log/proftpd_log_auth.fifo
sudo mkfifo /var/log/proftpd_log_access.fifo
sudo mkfifo /var/log/proftpd_log_all.fifo

Il est préférable de ne pas créer les fifos dans le repertoire de log de proftpd, car vous serez dans l’obligation de lancer votre « cat » ou votre logiciel en mode root avec un sudo. C’est pour ca que j’ai mis les logs dans le repertoire /var/log et ensuite que je les ai nommés proftpd_log_xxxx.fifo, afin de bien les identifier quand même.

si vous faites un « ls -al » de /var/log/proftpd, vous verrez 3 nouvelles fifos créées avec un « p »devant les permissions, ce qui indique que ce sont des fifos (pipe in english ! ).
maintenant si vous lancer proftpd, les log étendus seront envoyez dans les fifos.
pour voir une fifo :

sudo cat /var/log/proftpd_log_all.fifo

le « cat » est bloquant et ne sortira pas jusqu’au CTRL+C ou un autre « cat » dans un autre terminal.
Laissez le terminal avec « cat  » actif et lancer par exemple filezilla en connexion sur votre serveur FTP. Vous devriez voir apparaître dans le terminal du « cat » les logs des commandes FTP que vous exécutez via filezilla.
Ça y est nos fifos sont actives. Voyons rapidement un code en C pour récupérer le contenu de la fifo

Gestion des lectures de FIFOs en C

On peut considerer les fifos comme des fichiers qu’on peut lire ou écrire. Donc en C il est facile d’ouvrir un fichier et de lire le contenu.

voici le code suivant : (adapté de StackOverFlow)

#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
        int fifo, c=0;
        char buf[200];

        char fifo_name[] = "/var/log/proftpd_log_all.fifo";
        fifo= open(fifo_name, O_RDONLY|O_NONBLOCK);

        // receive messages
        while (1)
        {
            if (read(fifo, &buf, sizeof(char)*200) > 0)
            {
                printf("%s \n", buf);
                c=0;
            }
            usleep(100000);
            c++;
            if (c>20)
                break;
        }

        printf("exit");
        close(fifo);

    return 0;
}

Ici, on ouvre le fichier /var/log/proftpd_log_all.fifo en mode lecture seule.
Ensuite on scrute avec la fonction read() si il y a eu une lecture effective possible dans la fifo et on affiche le contenu de la lecture.
Le reste du code est là pour sortir du programme apres 20 lecture de fifo.

Voila le principe.
J’ai utilisé cette technique pour loggué sur un superviseur l’etat du transfert FTP en fonction de la connexion de mes produits.

En esperant que ce tuto vous sera egalement utile.