<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Marcus Povey &#187; proftp</title>
	<atom:link href="http://www.marcus-povey.co.uk/tag/proftp/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.marcus-povey.co.uk</link>
	<description>Making the world a better place, one byte at a time...</description>
	<lastBuildDate>Mon, 06 Feb 2012 19:13:58 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.1</generator>
	<atom:link rel='hub' href='http://www.marcus-povey.co.uk/?pushpress=hub'/>
		<item>
		<title>How to set up ProFTP, MySQL and Virtual Users</title>
		<link>http://www.marcus-povey.co.uk/2010/06/15/proftp-mysql-virtual-users-howto/</link>
		<comments>http://www.marcus-povey.co.uk/2010/06/15/proftp-mysql-virtual-users-howto/#comments</comments>
		<pubDate>Tue, 15 Jun 2010 10:59:45 +0000</pubDate>
		<dc:creator>Marcus Povey</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[ftp]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[proftp]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[virtual users]]></category>

		<guid isPermaLink="false">http://www.marcus-povey.co.uk/?p=551</guid>
		<description><![CDATA[ProFTP is a configurable FTP server available on most *nix platforms. I recently had the need to get this working and authenticating off a PHP maintained MySQL backend, and this post is primarily to aid my own memory should I ever have to do it again. Installing ProFTP In order to use MySQL as a [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.proftp.org"><img src="http://www.marcus-povey.co.uk/wp-content/proftpd.png" alt="" width="150" align="right" />ProFTP</a> is a configurable FTP server available on most *nix platforms.</p>
<p>I recently had the need to get this working and authenticating off a PHP maintained MySQL backend, and this post is primarily to aid my own memory should I ever have to do it again.</p>
<p><strong>Installing ProFTP</strong></p>
<p>In order to use MySQL as a back end you need to install some packages. If you&#8217;re using a <a href="http://www.debian.org">Debian</a> based distro like <a href="http://www.ubuntu.com">Ubuntu</a>, this is easy:</p>
<blockquote><p><code>apt-get install mysql-server proftpd proftpd-mod-mysql</code></p></blockquote>
<p><strong>The database schema</strong></p>
<p>Next, you need to install the database schema to store your users and passwords.</p>
<blockquote><p><code>CREATE TABLE IF NOT EXISTS users (<br />
userid varchar(30) NOT NULL default '',<br />
passwd <strong>varchar(128)</strong> NOT NULL default '',<br />
uid int(11) default NULL,<br />
gid int(11) default NULL,<br />
homedir varchar(255) default NULL,<br />
shell varchar(255) default NULL,<br />
UNIQUE KEY uid (uid),<br />
UNIQUE KEY userid (userid)<br />
) TYPE=MyISAM;</code></p>
<p><code>CREATE TABLE IF NOT EXISTS groups (<br />
groupname varchar(30) NOT NULL default '',<br />
gid int(11) NOT NULL default '0',<br />
members varchar(255) default NULL<br />
) TYPE=MyISAM;</code></p></blockquote>
<p>One important thing to note here &#8211; that caused me a fair amount of hair pulling when I tried to use encrypted passwords &#8211; is that the password field shown in many howtos on the internet is much too short. This causes the hashed password to be quietly truncated by MySQL when saved.</p>
<p>This results in a somewhat misleading &#8220;<strong>No such user found</strong>&#8221; error to appear in the logs when using encrypted passwords.</p>
<p>To end all argument I&#8217;ve allowed passwords up to 128 chars, but this field could probably be a good deal shorter.</p>
<p>The user table looks much like /etc/passwd and is largely self explanatory. The <strong>uid</strong> &amp; <strong>gid</strong> fields correspond to a system user in most cases, but since we&#8217;re using virtual users they can largely be ignored. <strong>Homedir </strong>points to a location which will serve as the user&#8217;s default directory. <strong>Shell</strong> is largely unused and can be set to <strong>/bin/false</strong> or similar.</p>
<p><strong>Configuring ProFTP</strong></p>
<p>Next, you need to make some changes to the ProFTP configuration files stored in /etc/proftpd. While doing this it is handy to run proftp in debug mode from the console:</p>
<blockquote><p><code>proftpd -nd6</code></p></blockquote>
<p><strong><em>proftpd.conf</em></strong></p>
<ol>
<li>Make sure the AuthOrder line looks like:<br />
<blockquote><p><code>AuthOrder mod_sql.c</code></p></blockquote>
</li>
<li>Ensure that the following line is uncommented:<br />
<blockquote><p><code>Include /etc/proftpd/sql.conf</code></p></blockquote>
</li>
<li>For belts and braces I&#8217;ve included the following at the end, although I&#8217;m not entirely sure it&#8217;s strictly required:<br />
<blockquote><p><code>&lt;IfModule mod_auth_pam.c&gt;<br />
AuthPAM off<br />
&lt;/IfModule&gt;<br />
</code></p></blockquote>
</li>
<li>Our users don&#8217;t need a valid shell, so:<br />
<blockquote><p><code>RequireValidShell off</code></p></blockquote>
</li>
</ol>
<p><em><strong>modules.conf</strong></em></p>
<ol>
<li>Make sure the following lines are uncommented:<br />
<blockquote><p><code>LoadModule mod_sql.c<br />
LoadModule mod_sql_mysql.c</code></p></blockquote>
</li>
</ol>
<p><strong><em>sql.conf</em></strong></p>
<ol>
<li>Set your SQL backend and ensure that authentication is turned on:<br />
<blockquote><p><code>SQLBackend mysql<br />
SQLEngine on<br />
SQLAuthenticate on</code></p></blockquote>
</li>
<li>Tell proftp how passwords are stored. You have a number of options here, but since I was using mysql&#8217;s PASSWORD function, I&#8217;ll defer to the backend.<br />
<blockquote><p><code>SQLAuthTypes backend</code></p></blockquote>
</li>
<li>Tell proftp how to connect to your database by providing the required connection details, ensure that the user has full access to these tables.<br />
<blockquote><p><code>SQLConnectInfo <em>database</em>@<em>host</em> <em>user</em> <em>password</em></code></p></blockquote>
</li>
<li>Define your table structure in the format <em>tablename</em> <em>fields&#8230;.</em><br />
<blockquote><p><code>SQLUserInfo users userid passwd uid gid homedir shell<br />
SQLGroupInfo groups groupname gid members</code></p></blockquote>
</li>
</ol>
<p><strong>Adding users</strong></p>
<p>I manage users from within a <a href="http://php.net">PHP</a> web application that I&#8217;m developing, but in a nutshell adding FTP users from this point is a simple insert statement looking something like:</p>
<blockquote><p><code>mysql_query("REPLACE INTO users<br />
(userid, passwd, uid, gid, homedir, shell)<br />
VALUES<br />
('$userid', PASSWORD('$password'), $uid, $gid, '$homedir', '$shell')");</code></p></blockquote>
<p>Have fun!</p>
<div class="wsbuttons">
	<div class="shareblob facebook">
		<div class="fb-like" data-href="http://www.marcus-povey.co.uk/2010/06/15/proftp-mysql-virtual-users-howto/" data-send="false" data-layout="box_count" data-width="60" data-show-faces="false" data-colorscheme="light"></div>
	</div>

	<div class="shareblob google">
		<div class="g-plusone" data-size="tall" data-href="http://www.marcus-povey.co.uk/2010/06/15/proftp-mysql-virtual-users-howto/"></div>
	</div>

	<div class="shareblob twitter">
		<div class="twitter">
			<a href="https://twitter.com/share?url=http%3A%2F%2Fwww.marcus-povey.co.uk%2F2010%2F06%2F15%2Fproftp-mysql-virtual-users-howto%2F&count=vertical" class="twitter-share-button" data-lang="en">Tweet</a>
			<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
		</div>
	</div>

</div>
	]]></content:encoded>
			<wfw:commentRss>http://www.marcus-povey.co.uk/2010/06/15/proftp-mysql-virtual-users-howto/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
	</channel>
</rss>

