Another Home Page Blog - Vsftpdhttps://blog.anotherhomepage.org/2008-06-20T10:30:00+02:00Utilisateurs virtuels sous CentOS 5 avec base de données MySQL2008-06-20T10:30:00+02:002008-06-20T10:30:00+02:00Nils Ratuszniktag:blog.anotherhomepage.org,2008-06-20:/post/2008/06/20/Utilisateurs-virtuels-sous-CentOS-5-avec-base-de-donnees-MySQL/<p><code>convert\_to\_centos5\_fr.sh --url howtoforge.com</code></p>
<p>Depuis quelques temps j'essayais sans succès de faire des utilisateurs virtuels avec <a href="http://vsftpd.beasts.org/">Vsftpd</a>, mon logiciel de serveur ftp favori, sous CentOS 5. Alors oui, la db au format Berkeley, ça marche, mais je trouve ça casse-pieds à maintenir. Et puis pour changer …</p><p><code>convert\_to\_centos5\_fr.sh --url howtoforge.com</code></p>
<p>Depuis quelques temps j'essayais sans succès de faire des utilisateurs virtuels avec <a href="http://vsftpd.beasts.org/">Vsftpd</a>, mon logiciel de serveur ftp favori, sous CentOS 5. Alors oui, la db au format Berkeley, ça marche, mais je trouve ça casse-pieds à maintenir. Et puis pour changer le mot de passe, galère. J'avais vu qu'il était possible d'utiliser <a href="http://www-fr.mysql.com/">MySQL</a> comme base pour les utilisateurs et leurs mots de passe. Je me met en quête d'un how-to pour CentOS, sans succès. J'adapte donc <a href="http://www.howtoforge.com/vsftpd_mysql_debian_etch">ce how-to</a> de Howtoforge pour CentOS.</p>
<p>Commençons par l'installation des paquets qui vont bien. En supposant que vous ayez, comme moi, une CentOS 5 minimaliste mais à jour, ça se passe comme ceci :</p>
<div class="highlight"><pre><span></span><code><span class="n">root</span><span class="nv">@tristram</span><span class="err">:</span><span class="o">~</span><span class="w"> </span><span class="err">#</span><span class="w"> </span><span class="n">yum</span><span class="w"> </span><span class="o">-</span><span class="n">y</span><span class="w"> </span><span class="n">install</span><span class="w"> </span><span class="n">vsftpd</span><span class="w"> </span><span class="n">mysql</span><span class="o">-</span><span class="n">server</span><span class="w"></span>
</code></pre></div>
<p>Ensuite, soit on ajoute à ses dépôts le dépôt extras en mode testing (et là je vous encourage à faire très attention, et de n'activer que les noms des paquets nécessaires), soit on installe "à la main" le paquet <a href="http://pam-mysql.sourceforge.net/">pam-mysql</a>, qui permettra à vsftpd de dialoguer avec MySQL. Le RPM est disponible sur <a href="http://rpm.pbone.net/index.php3/stat/4/idpl/6192385/com/pam_mysql-0.7-0.5.rc1.el5.kb.2.i386.rpm.html">Pbone</a>.Moi j'ai fait :</p>
<div class="highlight"><pre><span></span><code><span class="n">root</span><span class="nv">@tristram</span><span class="err">:</span><span class="o">~</span><span class="w"> </span><span class="err">#</span><span class="w"> </span><span class="n">wget</span><span class="w"> </span><span class="nl">ftp</span><span class="p">:</span><span class="o">//</span><span class="n">ftp</span><span class="p">.</span><span class="n">pbone</span><span class="p">.</span><span class="n">net</span><span class="o">/</span><span class="n">mirror</span><span class="o">/</span><span class="n">centos</span><span class="p">.</span><span class="n">karan</span><span class="p">.</span><span class="n">org</span><span class="o">/</span><span class="n">el5</span><span class="o">/</span><span class="n">extras</span><span class="o">/</span><span class="n">testing</span><span class="o">/</span><span class="n">i386</span><span class="o">/</span><span class="n">RPMS</span><span class="o">/</span><span class="n">pam_mysql</span><span class="o">-</span><span class="mf">0.7</span><span class="o">-</span><span class="mf">0.5</span><span class="p">.</span><span class="n">rc1</span><span class="p">.</span><span class="n">el5</span><span class="p">.</span><span class="n">kb</span><span class="mf">.2</span><span class="p">.</span><span class="n">i386</span><span class="p">.</span><span class="n">rpm</span><span class="w"></span>
</code></pre></div>
<p>puis :</p>
<div class="highlight"><pre><span></span><code><span class="n">root</span><span class="nv">@tristram</span><span class="err">:</span><span class="o">~</span><span class="w"> </span><span class="err">#</span><span class="w"> </span><span class="n">rpm</span><span class="w"> </span><span class="o">-</span><span class="n">ivh</span><span class="w"> </span><span class="n">pam_mysql</span><span class="o">-</span><span class="mf">0.7</span><span class="o">-</span><span class="mf">0.5</span><span class="p">.</span><span class="n">rc1</span><span class="p">.</span><span class="n">el5</span><span class="p">.</span><span class="n">kb</span><span class="mf">.2</span><span class="p">.</span><span class="n">i386</span><span class="p">.</span><span class="n">rpm</span><span class="w"></span>
</code></pre></div>
<p>Une fois les logiciels qui vont bien installés, on peut avoir envie de gérer MySQL via phpMyAdmin, pour celà je vous renvoie à <a href="/post/2008/05/17/installation-de-phpmyadmin-sur-CentOS-5">un autre billet qui en parle</a>.</p>
<p>Commençons par MySQL, pour respecter l'ordre originel du howto. Une fois celui-ci installé, on configure le mot de passe de root :</p>
<div class="highlight"><pre><span></span><code><span class="n">root</span><span class="nv">@tristram</span><span class="err">:</span><span class="o">~</span><span class="w"> </span><span class="err">#</span><span class="w"> </span><span class="n">service</span><span class="w"> </span><span class="n">mysqld</span><span class="w"> </span><span class="k">start</span><span class="w"></span>
</code></pre></div>
<p>MySQL indique les commandes pour changer le mot de passe de root pour MySQL, en indiquant quel est le nom d'hôte MySQL de la machine (détail très important !)</p>
<div class="highlight"><pre><span></span><code><span class="n">root</span><span class="nv">@tristram</span><span class="err">:</span><span class="o">~</span><span class="w"> </span><span class="err">#</span><span class="w"> </span><span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="n">bin</span><span class="o">/</span><span class="n">mysqladmin</span><span class="w"> </span><span class="o">-</span><span class="n">u</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="n">password</span><span class="w"> </span><span class="s1">'changemoi'</span><span class="w"></span>
<span class="n">root</span><span class="nv">@tristram</span><span class="err">:</span><span class="o">~</span><span class="w"> </span><span class="err">#</span><span class="w"> </span><span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="n">bin</span><span class="o">/</span><span class="n">mysqladmin</span><span class="w"> </span><span class="o">-</span><span class="n">u</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="o">-</span><span class="n">h</span><span class="w"> </span><span class="n">tristram</span><span class="p">.</span><span class="n">anotherhomepage</span><span class="p">.</span><span class="n">loc</span><span class="w"> </span><span class="n">password</span><span class="w"> </span><span class="s1">'changemoi'</span><span class="w"></span>
</code></pre></div>
<p>(on voit donc que la machine servant à ce howto se nomme tristram.anotherhomepage.loc)Ensuite on se connecte à MySQL :</p>
<div class="highlight"><pre><span></span><code><span class="n">root</span><span class="nv">@tristram</span><span class="err">:</span><span class="o">~</span><span class="w"> </span><span class="err">#</span><span class="w"> </span><span class="n">mysql</span><span class="w"> </span><span class="o">-</span><span class="n">u</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="o">-</span><span class="n">p</span><span class="w"></span>
</code></pre></div>
<p>On crée la base de données et son utilisateur, <em>vsftpd</em> et mot de passe <em>ftpdpass</em> :</p>
<div class="highlight"><pre><span></span><code>mysql> CREATE DATABASE vsftpd;
mysql> GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP ON vsftpd.* TO 'vsftpd'@'localhost' IDENTIFIED BY 'ftpdpass';
mysql> GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP ON vsftpd.* TO 'vsftpd'@'localhost.localdomain' IDENTIFIED BY 'ftpdpass';
mysql> FLUSH PRIVILEGES;
</code></pre></div>
<p>Ensuite on créé le schéma (on est toujours dans le shell de MySQL) :</p>
<div class="highlight"><pre><span></span><code><span class="n">mysql</span><span class="o">></span><span class="w"> </span><span class="k">USE</span><span class="w"> </span><span class="n">vsftpd</span><span class="p">;</span><span class="w"></span>
<span class="n">mysql</span><span class="o">></span><span class="w"> </span><span class="k">CREATE</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n n-Quoted">`accounts`</span><span class="w"> </span><span class="p">(</span><span class="w"></span>
<span class="n n-Quoted">`id`</span><span class="w"> </span><span class="kt">INT</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="no">NULL</span><span class="w"> </span><span class="k">AUTO_INCREMENT</span><span class="w"> </span><span class="k">PRIMARY</span><span class="w"> </span><span class="k">KEY</span><span class="w"> </span><span class="p">,</span><span class="w"></span>
<span class="n n-Quoted">`username`</span><span class="w"> </span><span class="kt">VARCHAR</span><span class="p">(</span><span class="w"> </span><span class="mi">30</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="no">NULL</span><span class="w"> </span><span class="p">,</span><span class="w"></span>
<span class="n n-Quoted">`pass`</span><span class="w"> </span><span class="kt">VARCHAR</span><span class="p">(</span><span class="w"> </span><span class="mi">50</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="no">NULL</span><span class="w"> </span><span class="p">,</span><span class="w"></span>
<span class="k">UNIQUE</span><span class="w"> </span><span class="p">(</span><span class="w"></span>
<span class="n n-Quoted">`username`</span><span class="w"></span>
<span class="p">)</span><span class="w"></span>
<span class="p">)</span><span class="w"> </span><span class="k">ENGINE</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">MYISAM</span><span class="w"> </span><span class="p">;</span><span class="w"></span>
</code></pre></div>
<p>Et on quitte MySQL :</p>
<div class="highlight"><pre><span></span><code>mysql> quit;
</code></pre></div>
<p>On créée l'utilisateur virtuel pour accéder aux comptes ; sous CentOS 5, le groupe de l'utilisateur <em>nobody</em> est <em>nobody</em>, avec comme gid 99 (vu dans <em>/etc/groups</em>) :</p>
<div class="highlight"><pre><span></span><code><span class="n">root</span><span class="nv">@tristram</span><span class="err">:</span><span class="o">~</span><span class="w"> </span><span class="err">#</span><span class="w"> </span><span class="n">useradd</span><span class="w"> </span><span class="c1">--home /home/vsftpd --gid 99 -m --shell /sbin/nologin vsftpd</span>
</code></pre></div>
<p>On note aussi que pour empêcher un compte d'avoir un shell, on met plutôt <em>/sbin/nologin</em>.</p>
<p>Passons à Vsftpd. Sauvegardons la configuration par défaut et ajoutons la nôtre :</p>
<div class="highlight"><pre><span></span><code><span class="n">root</span><span class="nv">@tristram</span><span class="err">:</span><span class="o">~</span><span class="w"> </span><span class="err">#</span><span class="w"> </span><span class="n">cp</span><span class="w"> </span><span class="o">-</span><span class="n">p</span><span class="w"> </span><span class="o">/</span><span class="n">etc</span><span class="o">/</span><span class="n">vsftpd</span><span class="o">/</span><span class="n">vsftpd</span><span class="p">.</span><span class="n">conf</span><span class="w"> </span><span class="o">/</span><span class="n">etc</span><span class="o">/</span><span class="n">vsftpd</span><span class="o">/</span><span class="n">vsftpd</span><span class="p">.</span><span class="n">conf_orig</span><span class="w"></span>
<span class="n">root</span><span class="nv">@tristram</span><span class="err">:</span><span class="o">~</span><span class="w"> </span><span class="err">#</span><span class="w"> </span><span class="n">cat</span><span class="w"> </span><span class="o">/</span><span class="n">dev</span><span class="o">/</span><span class="k">null</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="o">/</span><span class="n">etc</span><span class="o">/</span><span class="n">vsftpd</span><span class="o">/</span><span class="n">vsftpd</span><span class="p">.</span><span class="n">conf</span><span class="w"></span>
<span class="n">root</span><span class="nv">@tristram</span><span class="err">:</span><span class="o">~</span><span class="w"> </span><span class="err">#</span><span class="w"> </span><span class="n">vi</span><span class="w"> </span><span class="o">/</span><span class="n">etc</span><span class="o">/</span><span class="n">vsftpd</span><span class="o">/</span><span class="n">vsftpd</span><span class="p">.</span><span class="n">conf</span><span class="w"></span>
</code></pre></div>
<p>Le fichier <em>vsftpd.conf</em> est le suivant ( les options sont expliquées en anglais <a href="http://vsftpd.beasts.org/vsftpd_conf.html">sur le site de vsftpd</a>) :</p>
<div class="highlight"><pre><span></span><code><span class="n">listen</span><span class="o">=</span><span class="n">YES</span><span class="w"></span>
<span class="n">anonymous_enable</span><span class="o">=</span><span class="n">NO</span><span class="w"></span>
<span class="n">local_enable</span><span class="o">=</span><span class="n">YES</span><span class="w"></span>
<span class="n">write_enable</span><span class="o">=</span><span class="n">YES</span><span class="w"></span>
<span class="n">local_umask</span><span class="o">=</span><span class="mi">022</span><span class="w"></span>
<span class="n">dirmessage_enable</span><span class="o">=</span><span class="n">YES</span><span class="w"></span>
<span class="n">xferlog_enable</span><span class="o">=</span><span class="n">YES</span><span class="w"></span>
<span class="n">connect_from_port_20</span><span class="o">=</span><span class="n">YES</span><span class="w"></span>
<span class="n">nopriv_user</span><span class="o">=</span><span class="n">vsftpd</span><span class="w"></span>
<span class="n">chroot_local_user</span><span class="o">=</span><span class="n">YES</span><span class="w"></span>
<span class="n">secure_chroot_dir</span><span class="o">=/</span><span class="k">var</span><span class="o">/</span><span class="n">run</span><span class="o">/</span><span class="n">vsftpd</span><span class="w"></span>
<span class="n">pam_service_name</span><span class="o">=</span><span class="n">vsftpd</span><span class="w"></span>
<span class="n">guest_enable</span><span class="o">=</span><span class="n">YES</span><span class="w"></span>
<span class="n">guest_username</span><span class="o">=</span><span class="n">vsftpd</span><span class="w"></span>
<span class="n">local_root</span><span class="o">=/</span><span class="n">home</span><span class="o">/</span><span class="n">vsftpd</span><span class="o">/$</span><span class="n">USER</span><span class="w"></span>
<span class="n">user_sub_token</span><span class="o">=$</span><span class="n">USER</span><span class="w"></span>
<span class="n">virtual_use_local_privs</span><span class="o">=</span><span class="n">YES</span><span class="w"></span>
<span class="n">user_config_dir</span><span class="o">=/</span><span class="n">etc</span><span class="o">/</span><span class="n">vsftpd</span><span class="o">/</span><span class="n">user_conf</span><span class="w"></span>
</code></pre></div>
<p>Une première différence avec celui de Howtoforge, je n'ai pas mis l'option <em>rsa_cert_file=/etc/ssl/certs/vsftpd.pem</em>, je verrai ça pour un autre billet. Une autre différence est l'endroit où je stocke les configurations personnalisées par utilisateur : comme il y a un répertoire <em>/etc/vsftpd</em>, j'ai créé un sous-répertoire <em>user_conf</em> :</p>
<div class="highlight"><pre><span></span><code><span class="n">root</span><span class="nv">@tristram</span><span class="err">:</span><span class="o">~</span><span class="w"> </span><span class="err">#</span><span class="w"> </span><span class="n">mkdir</span><span class="w"> </span><span class="o">/</span><span class="n">etc</span><span class="o">/</span><span class="n">vsftpd</span><span class="o">/</span><span class="n">user_conf</span><span class="w"></span>
</code></pre></div>
<p>Cette possibilité est bien entendue totalement optionnelle.</p>
<p>Il nous faut maintenant configurer pam, qui va permettre à vsftpd d'aller chercher les utilisateurs dans la base mysql plutôt que dans les utilisateurs système, stockés dans <em>/etc/passwd</em> et <em>/etc/shadow</em>. Comme avec Vsftpd, on sauvegarde l'ancien et on en crée un tout neuf :</p>
<div class="highlight"><pre><span></span><code><span class="n">root</span><span class="nv">@tristram</span><span class="err">:</span><span class="o">~</span><span class="w"> </span><span class="err">#</span><span class="w"> </span><span class="n">cp</span><span class="w"> </span><span class="o">-</span><span class="n">p</span><span class="w"> </span><span class="o">/</span><span class="n">etc</span><span class="o">/</span><span class="n">pam</span><span class="p">.</span><span class="n">d</span><span class="o">/</span><span class="n">vsftpd</span><span class="w"> </span><span class="o">/</span><span class="n">etc</span><span class="o">/</span><span class="n">pam</span><span class="p">.</span><span class="n">d</span><span class="o">/</span><span class="n">vsftpd_orig</span><span class="w"></span>
<span class="n">root</span><span class="nv">@tristram</span><span class="err">:</span><span class="o">~</span><span class="w"> </span><span class="err">#</span><span class="w"> </span><span class="n">cat</span><span class="w"> </span><span class="o">/</span><span class="n">dev</span><span class="o">/</span><span class="k">null</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="o">/</span><span class="n">etc</span><span class="o">/</span><span class="n">pam</span><span class="p">.</span><span class="n">d</span><span class="o">/</span><span class="n">vsftpd</span><span class="w"></span>
<span class="n">root</span><span class="nv">@tristram</span><span class="err">:</span><span class="o">~</span><span class="w"> </span><span class="err">#</span><span class="w"> </span><span class="n">vi</span><span class="w"> </span><span class="o">/</span><span class="n">etc</span><span class="o">/</span><span class="n">pam</span><span class="p">.</span><span class="n">d</span><span class="o">/</span><span class="n">vsftpd</span><span class="w"></span>
</code></pre></div>
<p>Le contenu de ce fichier est le suivant :</p>
<div class="highlight"><pre><span></span><code>auth required pam_mysql.so user=vsftpd passwd=ftpdpass host=localhost db=vsftpd table=accounts usercolumn=username passwdcolumn=pass crypt=3
account required pam_mysql.so user=vsftpd passwd=ftpdpass host=localhost db=vsftpd table=accounts usercolumn=username passwdcolumn=pass crypt=3
</code></pre></div>
<p>La différence avec la version howtoforge est que j'ai changé l'algorithme de hash du mot de passe. Au lieu d'utiliser la fonction PASSWORD(), je vais utiliser MD5(). Je reviendrai sur ce qui a motivé ce choix après. Pour le moment, relançons Vsftpd :</p>
<div class="highlight"><pre><span></span><code><span class="n">root</span><span class="nv">@tristram</span><span class="err">:</span><span class="o">~</span><span class="w"> </span><span class="err">#</span><span class="w"> </span><span class="n">service</span><span class="w"> </span><span class="n">vsftpd</span><span class="w"> </span><span class="n">restart</span><span class="w"></span>
</code></pre></div>
<p>Et maintenant, créons notre premier utilisateur dans MySQL :</p>
<div class="highlight"><pre><span></span><code><span class="n">root</span><span class="nv">@tristram</span><span class="err">:</span><span class="o">~</span><span class="w"> </span><span class="err">#</span><span class="w"> </span><span class="n">mysql</span><span class="w"> </span><span class="o">-</span><span class="n">u</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="o">-</span><span class="n">p</span><span class="w"></span>
</code></pre></div>
<p>Nous sommes dans le shell MySQL :</p>
<div class="highlight"><pre><span></span><code>mysql> USE vsftpd;
mysql> INSERT INTO accounts (username, pass) VALUES('testuser', MD5('secret'));
mysql> quit;
</code></pre></div>
<p>Le répertoire de l'utilisateur testuser est <em>/home/vsftpd/testuser</em>, mais Vsftpd ne peut pas le créer automatiquement pour nous, faisons-le à la main, en prenant soin qu'il appartient bien à vsftpd :</p>
<div class="highlight"><pre><span></span><code><span class="n">root</span><span class="nv">@tristram</span><span class="err">:</span><span class="o">~</span><span class="w"> </span><span class="err">#</span><span class="w"> </span><span class="n">mkdir</span><span class="w"> </span><span class="o">/</span><span class="n">home</span><span class="o">/</span><span class="n">vsftpd</span><span class="o">/</span><span class="n">testuser</span><span class="w"></span>
<span class="n">root</span><span class="nv">@tristram</span><span class="err">:</span><span class="o">~</span><span class="w"> </span><span class="err">#</span><span class="w"> </span><span class="n">chown</span><span class="w"> </span><span class="nl">vsftpd</span><span class="p">:</span><span class="n">nobody</span><span class="w"> </span><span class="o">/</span><span class="n">home</span><span class="o">/</span><span class="n">vsftpd</span><span class="o">/</span><span class="n">testuser</span><span class="w"></span>
</code></pre></div>
<p>Connectons-nous à notre serveur FTP en utilisant Filezilla sous Windows, Konqueror ou gFTP (ou bien en ligne de commande, ftp ou lftp) sous Linux/BSD, ou encore Cyberduck sous Mac OS X. Ca marche? Parfait :-)</p>
<p>Maintenant le pourquoi du comment que j'ai mis 3 au lieu de 2 et MD5 au lieu de PASSWORD : tout simplement parce que ça ne fonctionne pas sous CentOS 5. L'explication vient du fichier README de pam-mysql, dispo là : <em>/usr/share/doc/pam_mysql-0.7/README</em></p>
<blockquote>
<p>The method to encrypt the user's password:</p>
<p>0 (or "plain") = No encryption. Passwords stored in plaintext.HIGHLY DISCOURAGED.</p>
<p>1 (or "Y") = Use crypt(3) function.</p>
<p>2 (or "mysql") = Use MySQL PASSWORD() function. It is possiblethat the encryption function used by PAM-MySQLis different from that of the MySQL server, asPAM-MySQL uses the function defined in MySQL'sC-client API instead of using PASSWORD() SQL functionin the query.</p>
<p>3 (or "md5") = Use plain hex MD5.</p>
<p>4 (or "sha1") = Use plain hex SHA1.</p>
</blockquote>
<p>La fonction PASSWORD de MySQL et celle de pam-mysql ne renvoient donc pas le même hash de mot de passe. Dommage, hein? J'ai aussi essayé l'option 0, mais elle ne m'intéressait pas. Je n'ai pas encore essayé la fonction crypt ni la fonction sha1 pour vérifier si elles fonctionnent, mais il n'y a pas de raison ;)</p>
<p>Il ne reste à présent qu'à créer une page php ou un script shell qui permette de créer, modifier et effacer les utilisateurs.</p>
<h2>Commentaires</h2>
<h3>Le 25/01/2011 15:45 par jennifer</h3>
<p>Merci pour le tuto ca fonctionne nikel juste un petit oubli de votre part il faut créer le fichier vsftpd dans /var/run/ sinon il affiche un message d'erreur suite au chemin défini pour "secure_chroot_dir=/var/run/vsftpd" dans le fichier de configuration vsftpd.conf lors du lancement du ftp.</p>