Using Pure-FTPd with LDAP

Documentation for version 1.0.17
Page 1 of 110
Index:
Main Documentation
1.
BLURB
2.
WHO'S USING IT?
3.
COMPILATION
4.
ADVANCED COMPILATION
5.
STANDALONE INSTALLATION
6.
SUPER-SERVER INSTALLATION
6.1. Usage with Inetd
6.2. Usage with Xinetd
6.3. Usage with TCPserver
6.4.
Usage with G2S
7.
OPTIONS
8.
SETTING UP AN ANONYMOUS FTP
9.
DISPLAYING BANNERS
10. DISPLAYING A COOKIE
11.
PER-USER CHROOT() RULES
12. RATIOS
13.
BANDWIDTH THROTTLING
14.
VIRTUAL SERVERS
15.
IPv6 SUPPORT
16.
LOGGING
17. WATCHING CURRENT SESSIONS
18. AFTER AN UPLOAD
19. LISTING DIRECTORIES
20. VIRTUAL QUOTAS
21. AUTHENTICATION
22.
DIRECTORY ALIASES
23.
PRIVILEGE SEPARATION
24. OPTIMIZING FOR HIGH LOAD
25. KNOWN ISSUES
26. DOWNLOADING PURE-FTPD
7
7
7
8
9
13
15
15
16
16
16
17
25
25
25
26
26
27
28
28
29
29
31
32
33
35
36
36
37
39
40
Notes for Debian users
41
Using Pure-FTPd with LDAP
1.
LDAP SUPPORT
2.
LDAP CONFIGURATION FILE
3.
THE LDAP SCHEMA
4.
EXTENDED LDAP SCHEMA (QUOTAS, THROTTLING, RATIOS)
5.
ANONYMOUS USERS
6.
ROOT USERS
43
43
43
45
46
46
47
Notes for MacOS X users
49
Page 2 of 110
Using Pure-FTPd with MySQL
1.
MYSQL SUPPORT
2.
MYSQL CONFIGURATION FILE
3.
TABLES STRUCTURES
4.
PER-USER SETTINGS
5.
TRANSACTIONS
6.
ANONYMOUS USERS
7.
ROOT USERS
51
51
52
53
54
54
54
55
Using Pure-FTPd with PostgreSQL
1.
PostgreSQL SUPPORT
2.
PGSQL CONFIGURATION FILE
3.
TABLES STRUCTURES
4.
PER-USER SETTINGS
5.
ANONYMOUS USERS
6.
ROOT USERS
57
57
58
59
60
60
61
How to add an SSL/TLS encryption layer
1.
SSL/TLS SUPPORT
2.
COMPILATION
3.
CERTIFICATES
4.
ACCEPTING TLS SESSIONS
5.
COMPATIBLE CLIENTS
Creating local indexed FTP-only accounts
63
63
63
64
66
67
69
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
VIRTUAL USERS
CREATING A NEW USER
CHANGING INFO
RESETTING ATTRIBUTES
DELETING USERS
CHANGING PASSWORDS
DISPLAYING INFO
COMMITING CHANGES
ENABLING VIRTUAL USERS
CONVERTING SYSTEM ACCOUNTS
ENVIRONNEMENT VARIABLES
69
70
71
71
71
71
72
73
73
74
74
How to write custom authentication handlers
1.
AUTHENTICATION MODULES
2.
EXAMPLE
75
75
77
Using a netfilter gateway
79
How the project was born
81
Contributors
83
Page 3 of 110
Greetings
1.
Forum and external contributors :
2.
Mailing list-members :
89
89
91
Windows port of Pure-FTPd
1.
WINDOWS PORT OF PURE-FTPD
2.
PURE-FTPD WIN32 REPOSITORY
3.
INSTALLATION
4.
RUNNING THE SERVER
5.
SERVER FILES
6.
ANONYMOUS FTP
7.
COMPILATION ENVIRONMENT
93
93
93
93
93
94
94
94
Frequently Asked Questions
1.
Users can delete root-owned files?
2.
Directories shared by multiple users.
3.
Restricting directory visibility.
4.
Shared directories and chroot.
5.
Tar and/or gzip on the fly
6.
How to restrict access to dot files ?
7.
Log files
8.
How to prevent your partitions to be filled
9.
Firewalling
10.
Unable to log in (unix authentication)
11.
Network filesystems.
12.
Solaris and chroot.
13. Upgrading.
14. OpenBSD, ISOS, EkkoBSD and MacOS X.
15. FTP over SSH.
16.
Virtual users: /etc/pureftpd.pdb .
17.
Giving access to dot-files.
18.
Initial banner.
19.
Internet Explorer doesn't show any login box.
20.
Internet Explorer doesn't want to log in. (Matthew Enger)
21.
Passwords and pure-pw scripting.
22.
Altlog and pure-uploadscript don't work.
23.
The server starts, but doesn't listen to any port?
24.
Double slash.
25.
Windows port.
26.
ftpwho as a non-root user.
27.
Changing bandwidth throttling on-the-fly.
28.
KERBEROS_V4 rejected as an authentication type.
29.
Wrong group ownership.
30.
Compilation with MySQL.
31.
"Sorry, I can't trust you".
32.
Customer-friendly configuration.
33.
Anonymous FTP with virtual users.
34.
A basic setup.
35.
Slow pure-ftpwho or slow login.
36.
Chrooted users can follow symlinks outside the chroot jail?
Page 4 of 110
95
95
95
95
96
96
96
97
97
98
98
98
99
99
99
100
101
101
101
101
101
102
102
102
102
103
103
103
103
104
104
104
104
105
105
106
106
37.
38.
39.
40.
41.
42.
43.
44.
How to start Pure-FTPd in background.
Windows command-line FTP client and 'ls'.
Global bandwidth limitation.
Linux, NTFS and Pure-FTPd.
Slowdowns and lags.
Firewalls and SSL/TLS.
TLS and error 00000000.
Files getting renamed automatically (submitted by C. Jon Larsen)
106
107
108
109
109
109
110
110
Page 5 of 110
Page 6 of 110
Main Documentation
1.
BLURB
Pure-FTPd is a fast, production-quality, standard-conformant FTP server, based upon Troll-FTPd.
The server has been designed to be secure in default configuration, it has no known vulnerability, it is really
trivial to set up and it is especially designed for modern kernels. It was successfully ported to Linux,
FreeBSD, NetBSD, OpenBSD, ISOS, EkkoBSD, BSDi, Solaris, Darwin, Tru64, Irix, AIX and HPUX.
Features include chroot()ed and/or virtual chroot()ed home directories, virtual domains, built-in 'ls', antiwarez system, configurable ports for passive downloads, FXP protocol, bandwidth throttling, ratios, LDAP /
MySQL / PostgreSQL-based authentication, fortune files, Apache-like log files, fast standalone mode, text /
HTML / XML real-time status report, virtual users, virtual quotas, privilege separation, SSL/TLS and more.
2.
WHO'S USING IT?
Many people new to Unix are running Pure-FTPd because they find it easy to install. But that software is
also used on embedded systems and highly loaded production servers, especially for hosting services. A list
of some companies successfully using it is available at http://www.pureftpd.org/users.shtml
Pure-FTPd was also part of a crack-a-machine challenge with other software, and that machine never got
compromised.
For large sites with centralized user management, Pure-FTPd provides flexible authentication schemes
including SQL and LDAP backends, plus the ability to easily write new custom handlers in any language.
Page 7 of 110
3.
COMPILATION
In its current form, Pure-FTPd uses some OS-specific system calls. And although some portability work has
been done in order to ease its port to other operating systems, only Linux FreeBSD, NetBSD, OpenBSD,
ISOS, EkkoBSD, BSDi, Darwin, Solaris, Tru64, Irix, AIX and HPUX are known to work, other operating
systems may need some tweaks. With Linux, any modern distribution should be ok.
An unofficial Windows port is available from http://www.pureftpd.org/windows
If you have Cdialog or Xdialog installed on your system, try the following command to build and install
Pure-FTPd:
make -f Makefile.gui
If you don't have Cdialog or if you prefer the conventional way, here it is:
./configure
make install-strip
Et voila! The software is now installed in /usr/local/sbin/pure-ftpd
To launch the server, just type the following command:
/usr/local/sbin/pure-ftpd &
If you installed a binary package (RPM, SLP, Debian), maybe use the following command instead:
/usr/sbin/pure-ftpd &
Your server is ready. Just type 'ftp localhost' to test it. If you want to automatically run the server when the
system boots, add the previous command to /etc/rc.d/rc.local or /etc/rc.d/boot.local . Don't forget the '&'
sign.
Note 1:
On Linux systems, you will notice that the server is always running as root. This is intentional and more
secure that servers who are changing their effective uid (and only effective uid, they still have root
privileges in fact, use ps -U to see what servers are really running as root) . We are using Linux kernelspecific tricks to drop privileges that "ps" can't show.
Note 2:
To compile under Irix, you have to issue this before typing ./configure:
export CC=cc
export CFLAGS=-I/usr/freeware/include
export LDFLAGS=-L/usr/freeware/lib32
To compile under Solaris 8, use GNU Make, not Solaris basic make. Then do:
export PATH=/usr/ccs/bin:$PATH
export MAKE=gmake
Note 3:
To deinstall Pure-FTPd (no, do you really want to do this?), use:
./configure
make uninstall
Page 8 of 110
4.
ADVANCED COMPILATION
The "./configure" script accepts some arguments you might want to add before the compilation:
/-------------------"--with-" switches
--------------------/
4.1.
--with-altlog: in addition to the syslog output, support logging into a specific file, in an alternative
format. Currently, the CLF, Stats and W3C formats are implemented. CLF (common log format) is
the basic format produced by Apache, WebFS, Roxen and most web servers. These log files only
record file transfers and they can feed web statistic software (Analog, Webalizer, etc.) to analyze
the load of your FTP server. The Stats format is a special output format, designed for log file analys
software. The W3C format is a standard format parsed by most commercial log analyzers (all
analyzers with support for IIS should deal with it) . Check the -O option later in this documentation
for additional info.
4.2.
--with-brokenrealpath: some Solaris versions have a broken realpath() implementation. If altlog
and/or pure-uploadscript doesn't seem to work properly on your system, try to recompile with this
switch.
4.3.
--with-certfile=<file>: the file with the SSL certificate (see README.TLS). The default is
/etc/ssl/private/pure-ftpd.pem .
4.4.
--with-cookie: display a fortune or a customized banner when an user logs in (see the '-F' option) .
4.5.
--with-diraliases: support directory aliases ("shortcuts" for the "cd" command) . Please read the
appropriate section about this (further in this manual) .
4.6.
--with-everything: build a big server with almost all features turned on:
altlog, cookies, throttling, ratios, ftpwho, upload script, virtual users (puredb), quotas, virtual hosts,
directory aliases and external authentication.
4.7.
--with-extauth: compiles support for external authentication modules. Please read
README.Authentication-Modules and the pure-authd(8) man page before enabling this feature.
Most users don't need it.
4.8.
--with-ftpwho: support for the 'pure-ftpwho' command. Enabling this feature needs some extra
memory. Better use it when the server is run in standalone mode. It can be way slower in inetd
mode.
Page 9 of 110
4.9.
--with-language=english
--with-language=german
--with-language=romanian
--with-language=french
--with-language=polish
--with-language=spanish
--with-language=danish
--with-language=Italian
--with-language=brazilian-portuguese
--with-language=slovak
--with-language=dutch
--with-language=korean
--with-language=swedish
--with-language=norwegian
--with-language=russian
--with-language=traditional-chinese
--with-language=simplified-chinese
--with-language=czech
Change the language of server messages. Default is english. If you want to contribute a translation,
please translate the 'src/messages_en.h' file and send it to [email protected].
4.10.
--with-largefile: support downloading of files larger than 2 gigabytes on 32-bit architectures.
Transfering so huge files through FTP is a strange idea. And your filesystem has to support it. Your
kernel and your libc as well. And of course, the FTP client has to be safe against large files, too.
And when this feature is enabled, downloads can be a bit slower (or more cpu-intensive) than
without it, due to a limitation of actual Linux kernels.
To summarize: don't enable this for fun, just if you are really planning to download files over 2
gigabytes.
4.11.
--with-ldap: use the native LDAP directory support. When this option is enabled, system accounts
can be bypassed. You need OpenLDAP to use that feature. If OpenLDAP is installed in a custom
location, you can use the --with-ldap=<directory> syntax. See the README.LDAP file for more
info about LDAP and Pure-FTPd.
4.12.
--with-minimal: to efficiently use features of modern FTP clients, Pure-FTPd implements the basics
of the FTP protocol, with many extensions (SITE IDLE, SITE CHMOD, MLSD, ...).
Using the --with-minimal directive, these extensions won't be compiled in. Also, there will be no
standalone server, no lookup for user/group names, no humor and no ASCII support. But the
executable file size will be smaller than in a default installation. You need at least GCC 3.3 to
compile with this option. Regular expressions are compiled in. If you still want to reduce the size,
use --without-globbing in conjunction with --with-minimal. If you are building an embedded
system, use this. In all other cases, to avoid complaints from customers (especially with Windows
clients), forget this.
4.13.
--with-mysql: use the native MySQL support for users database. When this option is enabled,
system accounts can be bypassed. MySQL client libraries should be installed to use that feature. If
MySQL is installed in a custom location, you can use the --with-mysql=<directory> syntax. See the
README.MySQL file for more info about MySQL and Pure-FTPd.
Page 10 of 110
4.14.
--with-nonroot: set up a server that doesn't need root privileges to be started. Any regular user can
run the server. It can be useful if you have a limited shell access to a non-dedicated hosting server.
But some features will be disabled and passwords can only be checked via LDAP, SQL or PureDB.
When virtual chroot is enabled, people will be restricted to the directory the server was started in.
This is an insecure mode, designed for setting up very temporary servers by regular (non-root)
users. Port 2121 will be listened by default in standalone mode. If you want to use the nonroot
mode, you must compile and *install* the software (./configure --prefix=... && make install-strip) .
/sbin, /bin and /man directories will be created in that prefix. But you must also add an /etc
directory (readable and writeable by the user pure-ftpd will run as).
4.15.
--with-pam: use pluggable authentification modules. Don't use this option if your login/passwd
pairs are always refused (but the real fix would be to fix your PAM configuration). You need to
create a /etc/pam.d/pure-ftpd file to properly use the PAM authentication. The 'pam' directory
contains an example of such a file.
4.16.
--with-paranoidmsg: favor paranoid messages over sysadmin-friendly messages. When this option
is enabled, login failures will show the same message to the user, regardless of the source of the
problem. Without this option, "Authentication failure" is displayed when this is a password
problem and "Sorry, I can't trust you" is displayed when the user has been banned by the sysadmin.
4.17.
--with-peruserlimits: enable per-user concurrency limits. Avoid this on very loaded servers.
4.18.
--with-pgsql: use the native Postgres support for users database. When this option is enabled,
system accounts can be bypassed. Postgres client libraries should be installed to use that feature. If
Postgres is installed in a custom location, you can use the --with-pgsql=<directory> syntax. See the
README.PGSQL file for more info about Postgres and Pure-FTPd.
4.19.
--with-probe-random-dev: Pure-FTPd uses /dev/arandom, /dev/urandom or /dev/random devices to
provide hardly-predicable random numbers. Presence of these devices are usually probed at
compile-time. If you want to compile a binary package on a host, then run it on another host, this
option will enable the probe at run-time. This is useless on Linux and BSD systems, but it can be
needed on Solaris and QNX.
4.20.
--with-puredb: support virtual users, ie. a local users database, independent of your system
accounts. Please read the README.Virtual-Users file for more info about virtual users.
4.21.
--with-quotas: enable virtual quotas. With virtual quotas, you can restrict the maximal number of
files an user can store in his account. You can also of course restrict the total size. See the "quotas"
section later in this document.
4.22.
--with-ratios: support upload/download ratios, to please w4r3z fr34k2.
4.23.
--with-sysquotas: support system quotas (not Pure-FTPd's virtual quotas).
Only enable this if you really plan to use system quotas.
4.24.
--with-throttling: support bandwidth throttling (see below).
4.25.
--with-uploadscript: since 0.98, Pure-FTPd has a nice feature regarding uploads. Any external
program or script can be automatically called after a successful upload. It needs another program
installed by the Pure-FTPd package, called 'pure-uploadscript'. Check the man page for more info
about this.
4.26.
--with-virtualchroot: usually, when an user is chrooted (-A and –a options), it's impossible to go out
of his home directory. Enabling that feature makes it possible: symbolic links are always followed,
even if they are pointing to directories not located in the user's home directory. This is very useful
for having shared directories (for instance, have a symbolic link to /var/incoming in every home
directory). This feature isn't enabled by default.
Page 11 of 110
4.27.
--with-virtualhosts: support virtual hosting. It means that you can have different anonymouns FTP
areas for each IP address. If your server has only one IP address, you don't need that feature. But if
you have multiple IP addresses and if you want a client that connects to IP xxx to get the content of
/etc/pure-ftpd/xxx/ instead of ~ftp/ , enable this option.
And read the the "VIRTUAL SERVERS" section at the end of this file.
4.28.
--with-welcomemsg: read 'welcome.msg' files for compatibility with some other FTP servers. This
is a security flaw (anonymous users may upload 'welcome.msg' files to add random banners) .
Pure-ftpd uses '.banner' files by default.
4.29.
--with-boring: display "professionnal-looking" messages.
4.30.
--with-privsep: enable privilege separation (see notes about this later).
/----------------------"--without-" switches
-----------------------/
4.31.
--without-ascii: does not support 7-bits transfers (ASCII) . If you have customers using Windows
clients to send scripts and HTML files, don't use this option or they will yell at you.
4.32.
--without-banner: don't display the initial banner. This is stupid security through obscurity.
4.33.
--without-capabilities: if the capabilities library (libcap) is found, Pure-FTPd will try to use it in
order to enhance security. This option overrides the test to ignore the library. Try this if capabilities
don't work properly on your system. libcap can be downloaded from
ftp://ftp.kernel.org/pub/linux/libs/security/linux-privs.
4.34.
--without-globbing: don't include the globbing code. It reduces the memory footprint but regular
expressions won't work any more (things like 'ls *.rpm').
Most people shouldn't use --without-globbing. Globbing is a nice feature.
4.35.
--without-humor: if you find what this option does without peeking at the source code, you're a
lucky guy!
4.36.
--without-inetd: if you will always be running Pure-FTPd in standalone-mode, enabling this flag
can save a few code bytes. Don't enable --without-inetd and --without-standalone, because it's
impossible to run a server without one of them. These options aren't enabled on binary distributions
of Pure-FTPd, so that both inetd-like and standalone mode are supported.
4.37.
--without-iplogging: don't log any IP address to protect confidentiality, especially for political
servers.
4.38.
--without-nonalnum: paranoid file name checking: only allow basic alphanumeric characters. Never
enable this switch blindly, or your customers will complain.
4.39.
--without-sendfile: on Linux, Solaris, HPUX and FreeBSD kernels, Pure-FTPd tries to reduce the
CPU/memory usage by using a special system call (sendfile) . It works very well with most
filesystems. However, this optimization is not implemented for all filesystems in current kernels.
Users reported that downloading files with Pure-FTPd failed with SMBFS (Samba) on FreeBSD
and TmpFS and NTFS on Linux (the error reported by the server is "broken pipe" or "Error during
write to data connection") . If you are planning to serve files from these filesystems, you have to
use the --without-sendfile switch to enable a workaround. It was also reported that PA-Risc Linux
systems need this flag.
Page 12 of 110
4.40.
--without-shadow: ignore the shadow passwords, even though they are auto-detected. Usually a bad
idea, unless you use PAM, LDAP or SQL. Pure-FTPd support expiration dates of shadow
passwords (both for accounts and passwords).
4.41.
--without-standalone: the FTP server can normally run in standalone-mode (without any superserver) . If you don't need that feature and if you want to save few code bytes, add this option. A
super-server like g2s, xinetd or tcpserver will be mandatory to run the service. But the standalone
mode is the recommended mode of operation.
4.42.
--without-usernames: never outputs user and group names in directory listings, only UIDs and
GIDs. It improves security and performances, but some people find this not user-friendly.
/-------------Other notes
--------------/
4.43.
Other traditional autoconf options are of course recognised, like "--prefix=" to change the
installation prefix, that defaults to "/usr/local/".
FYI, the binary RPM packages of Pure-FTPd are configured with the following command line:
./configure --with-everything --with-paranoidmsg --without-capabilities \
--with-virtualchroot
RPM packages are also compiled with --without-pam to enhance their portability.
5.
STANDALONE INSTALLATION
Unless you compiled the server with "--without-standalone", running the server is as easy as typing:
/usr/local/sbin/pure-ftpd &
In the following examples, we will assume that the 'pure-ftpd' file is located in /usr/local/sbin. This is the
default if you compiled the server from the source code tarball. But as I said earlier in this document, if you
installed a binary package (RPM, SLP, DEB, TGZ), the server maybe installed in /usr/sbin/. So just replace
'/usr/local/sbin/pure-ftpd' with '/usr/sbin/pure-ftpd'.
When the previous command is run, the server will listen for incoming connections on every interface, all IP
addresses and the standard FTP port (21) . If your system has IPv6 addresses, they should work as well.
Now, if you want to listen for an incoming connection on a non-standard port, just append '-S' and the port
number:
/usr/local/sbin/pure-ftpd -S 42
Service names are also allowed ('-S smtp' and the daemon will be accepting connections on the SMTP port
(25) . Very uncommon, but we should please everybody anyway, even disturbed minds).
Now, what if your system has many IP addresses and you want the FTP server to be reachable on only one
of these addresses, let's say 192.168.0.42?
Just use the following command line:
/usr/local/sbin/pure-ftpd -S 192.168.0.42,
The final comma is important, don't forget it. Actually, it's a shorthand for:
/usr/local/sbin/pure-ftpd -S 192.168.0.42,21
Page 13 of 110
If you prefer host names over IP addresses, it's your choice:
/usr/local/sbin/pure-ftpd -S ftp.rtchat.com,21
IPv6 addresses are of course supported.
With previous command lines, the server will run in the default configuration. Anonymous FTP logins will
be allowed if there's a system account called 'ftp' and every user of your system will be able to access the
FTP server using his regular login/password pair.
If you need to tweak that default configuration, other command-lines options can be added. For instance:
/usr/local/sbin/pure-ftpd -c 50 &
or
/usr/local/sbin/pure-ftpd -S ftp.rtchat.com,21 -c 50 &
And only 50 simultaneous connections will be allowed. To discover what options are available please jump
to the 'OPTIONS' chapter below. If the server runs perfectly for you in standalone mode, you don't need to
read the following chapter about super-servers. But read the options. '-m' and '-C' are recommended. '-D' is
also a good choice if you (or your customers) use broken clients. Please read on.
When you run 'ps auxw|grep pure-ftpd', the result looks like this:
root
root
root
15211 0.1 0.3 1276 452 ?
15212 0.1 0.5 1340 672 ?
15214 0.0 0.5 1340 672 ?
S 13:53 0:00 pure-ftpd [SERVER]
S 13:54 0:00 pure-ftpd [IDLE]
S 13:56 0:00 pure-ftpd [DOWNLOADING]
[SERVER] is the main server. If you kill this process, the server will exit after the next connection.
[IDLE] shows a client with no transfer activity.
[DOWNLOADING] shows a client downloading a file.
[UPLOADING] show a client uploading a file.
For easy scripting, the file '/var/run/pure-ftpd.pid' is created and it always contains the PID of the main
server process.
Page 14 of 110
6.
SUPER-SERVER INSTALLATION
Pure-FTPd can also run with the help of a super-server, like telnet, wu-ftp, finger or Qmail. Using a superserver is usually slower than the standalone mode. But if you love tcpwrappers or built-in filtering abilities
of your super-server, Pure-FTPd can cope with them.
Unix has tons of super-servers: Inetd (the most common one), TCPserver, G2S, Xinetd, Rlinetd, ... Only the
first three will be covered here, but integration with other super-servers should be painless.
6.1.
Usage with Inetd
Important: if security matters for you, forget inetd. In the default configuration, inetd will stop a
service after a high rate of connections to the same port. This creates an easy denial-of-service.
Also, inetd doesn't have any concurrency limit. Bad guys can fill up your memory and your
descriptor tables even if you are restricting the number of connections in pure-ftpd. Better use a
modern replacement for inetd, or run pure-ftpd in standalone mode.
Check that inetd is up:
ps auxw | grep inetd
root 3699 0.0 0.3 1072 492 ? S 15:47 0:00 inetd
Edit /etc/inetd.conf and look for a line like:
ftp stream tcp nowait root /usr/sbin/tcpd in.ftpd
The line may also end with "proftpd" or "wuftpd", but it should start with "ftp stream tcp".
Replace that line with the following one:
ftp stream tcp nowait root /usr/sbin/tcpd /usr/local/sbin/pure-ftpd
If /usr/sbin/tcpd is missing on your system, try the following line instead:
ftp stream tcp nowait root /usr/local/sbin/pure-ftpd pure-ftpd
Restart the inetd daemon:
killall -HUP inetd
If 'killall' is missing on your system, try this:
kill -HUP $(cat /var/run/inetd.pid)
Page 15 of 110
6.2.
Usage with Xinetd
Add the following entry to the /etc/xinetd.conf file:
service ftp
{
socket_type = stream
server = /usr/local/sbin/pure-ftpd
protocol = tcp
user = root
wait = no
disable = no
}
On Redhat systems, you can also put this in a /etc/xinetd.d/pure-ftpd file.
Then, restart the server:
killall -USR2 xinetd
6.3.
Usage with TCPserver
TCPServer is part of the ucspi-tcp package by Dan Bernstein. It's less bloated than inetd, less
D.O.S.-prone and has interesting filtering abilities. The simplest way of running Pure-FTPd with
TCPserver is thefollowing command:
tcpserver -DHRl0 0 21 /usr/local/bin/pure-ftpd &
You can add that line to your system local startup scripts (usually /etc/rc.d/boot.local or
/etc/rc.d/rc.local) . If it doesn't work, replace 'tcpserver' with its full path (eg.
'/usr/local/bin/tcpserver').
6.4.
Usage with G2S
Add the following lines to your /etc/jnetd.cf file (or whatever configuration file you choose for
G2S):
{
SERVICE ftp
DESCRIPTION "Pure-FTPd"
RUN /usr/local/sbin/pure-ftpd
}
Restart the 'jnetd' daemon and you're done.
Page 16 of 110
7.
OPTIONS
The previous steps should be enough to get a running FTP server. But you can add some command-line
arguments to change its behavior. These arguments have to be added after the pure-ftpd path in your superserver configuration.
For instance, you want to add the '-s' and '-a 42' flags. Here are what the configuration lines will look like in
your super-server:
- Inetd:
ftp stream tcp nowait root /usr/sbin/tcpd /usr/local/sbin/pure-ftpd -s -a42
or
ftp stream tcp nowait root /usr/local/sbin/pure-ftpd pure-ftpd -s -a42
If you use Inetd, don't put space between options and arguments. e.g. use -a42 instead of -a 42 . Inetd has
trouble dealing with a lot of options and with characters like ':' .
- Xinetd:
service ftp
{
socket_type = stream
server = /usr/local/sbin/pure-ftpd
server_args = -s -a 42
protocol = tcp
user = root
wait = no
disable = no
}
- TCPserver:
tcpserver -DHRl0 0 21 /usr/local/bin/pure-ftpd -s -a 42 &
- G2S:
{
SERVICE ftp
DESCRIPTION "Pure-FTPd"
RUN /usr/local/sbin/pure-ftpd -s -a 42
}
Users need a shell listed in /etc/shells to get restricted or unrestricted FTP access. Alternatively, you can
give them "ftp" as a shell. Users with a "ftp" shell will be able to login through FTP only: no telnet, no SSH.
And there's no need (and you shouldn't do so) for an "ftp" entry in /etc/shells.
Here are the recognised switches:
7.1.
'-0': when a file is uploaded and there is already a previous version of the file with the same name,
the old file will neither get removed nor truncated. Upload will take place in a temporary file and
once the upload is complete, the switch to the new version will be atomic. For instance, when a
large PHP script is being uploaded, the web server will still serve the old version and immediatly
switch to the new one as soon as the full file will have been transfered. This option is incompatible
with virtual quotas.
7.2.
'-1': log the PID of each session in syslog output.
7.3.
'-4': only listen to IPv4 connections. YOU HAVE TO ENABLE THIS ON OPENBSD, ISOS,
EKKOBSD AND MACOS X IF YOUR NETWORK IS NOT 100% IPV6! Even if you are starting
the server through a superserver like inetd.
Page 17 of 110
7.4.
'-a <gid>': Authenticated users will be granted access to their home directory and nothing else
(chroot) . This is especially useful for users without shell access, for instance, WWW-hosting
services shared by several customers. Only member of group number <gid> will have unrestricted
access to the whole filesystem. So add a "staff", "admin" or "ftpadmin" group and put your trusted
users in. <gid> is a NUMERIC group number, not a group name.
This feature is mainly designed for system users, not for virtual ones.
Note: 'root' (uid 0) always has full filesystem access.
If you want to chroot() everyone, but root, use the -A
7.5.
'-A': chroot() everyone, but root.
7.6.
'-b': Ignore parts of RFC standards in order to deal with some totally broken FTP clients, or broken
firewalls/NAT boxes.
7.7.
'-B': Have the standalone server start in background (daemonization).
7.8.
'-c <number of clients>': Allow a maximum of clients to be connected. For instance '-c 42' will
limit access to simultaneous 42 clients. There is a 50 client limit by default.
7.9.
'-C <max connection per ip>': Limit the number of simultanous connections coming from the same
IP address. This is yet another very effective way to prevent stupid denial of services and
bandwidth starvation by a single user. It works only when the server is launched in standalone
mode (if you use a super-server, it is supposed to do that).
If the server is launched with '-C 2', it doesn't mean that the total number of connections is limited
to 2. But the same client, coming from the same machine (or at least the same IP), can't have more
than two simultaneous connections. This feature needs some memory to track IP addresses, but it's
recommended to use it.
7.10.
'-d': Send various debugging messages to the syslog. Don't use this unless you really want to debug
Pure-FTPd. Passwords aren't logged. Duplicate '-d' to log responses, too.
7.11.
'-D': List files beginning with a dot ('.') even when the client doesn't append the '-a' option to the list
command. A workaround for badly configured FTP clients. If you are a purist, don't enable this. If
you provide hosting services and if you have lousy customers, enable this.
7.12.
'-e': Only allow anonymous users. Use this on a public FTP site with no remote FTP access to real
accounts.
7.13.
'-E': Only allow authenticated users. Anonymous logins are prohibited.
7.14.
'-f <facility>': Use that facility for syslog logging. It defaults to 'ftp' (or 'local2' if you got an
obsolete libc without that facility). Logging can be disabled with '-f none' .
7.15.
'-F <fortune file>': Display a fortune cookie on login. The sentence is a random extract from the
text file <fortune file>. This text file should be formatted like standard "fortune" files (fortunes are
separated by a '%' sign on a single line) . Pure-FTPd has to be compiled with support for cookies (-with-cookie). If you just want a simple banner displayed before the login prompt, add the name of
any text file here.
7.16.
'-g <pid file>': Change the location of the pid file when the server is run in standalone mode. The
default is /var/run/pure-ftpd.pid .
7.17.
'-G': Disallow renaming.
Page 18 of 110
7.18.
'-H': By default, fully-qualified host names are logged. To achieve this, DNS lookups are
mandatory. The '-H' flag avoids host names resolution. ("213.41.14.252" will be logged instead of
"www.toolinux.com") . It can significantly speed up connections and reduce bandwidth usage on
busy servers. Use it especially on public FTP sites. Also, please note that without -H, host names
are informative but shouldn't be trusted: no reverse mapping check is done to save DNS queries.
7.19.
'-i': Disallow upload for anonymous users, whatever directory permissions are. This option is
especially useful for virtual hosting, to avoid your users creating warez sites in their account.
7.20.
'-I <timeout>': Change the maximum idle time. The timeout is in minutes and defaults to 15
minutes. Modern FTP clients are trying to fool timeouts by sending fake commands at regular
interval. We disconnect these clients when they are idle for twice (because they are active anyway)
the normal timeout.
7.21.
'-j': If the home directory of a user doesn't exist, automatically create it. The newly created home
directory belongs to the user and permissions are set according to the current directory mask. Only
the home directory can be created (so /home/john/./public_html won't work, but /home/john will) .
To avoid local attacks, the parent directory should never belong to an untrusted user. Also note that
you must trust whoever manages the users databases, because with that feature, he'll be able to
create/chown directories anywhere on the server's filesystem.
7.22.
'-k <percentage>': Don't allow uploads if the partition is more than <percentage>% full. For
instance, "-k 95" will ensure your disks will never get filled more than 95% by FTP. No need for
the "percent" sign after the number.
7.23.
'-K': Allow users to resume and upload files, but *NOT* to delete or rename them. Directories can
be removed, but only if they are empty. However, overwriting existing files is still allowed (to
support upload resume) . If you want to disable this too, add -r (--autorename) .
7.24.
'-l <authentication>' or '-l <authentication>:<config file>': Adds a new rule to the authentication
chain. Please read the "Authentication" section, later in this README file. It's an important
section.
7.25.
'-L <max files>:<max depth>': To avoid stupid denial-of-service attacks (or just CPU hogs), PureFTPd never displays more than 2000 files in response to an 'ls' command. Also, a recursive 'ls' (-R)
never goes further than 5 subdirectories. You can increase/decrease those limits with the '-L' option.
7.26.
'-m <cpu load>': Don't allow anonymous download if the load is above <cpu load> . A very
efficient way to prevent overloading your server. Upload is still allowed, though.
7.27.
'-M': Allow anonymous users to create directories.
7.28.
'-n <max files>:<max size>': If the server has been compiled with support for virtual quotas,
enforce these quota settings for all users (except members of the 'trusted' group) . <max size> is in
Megabytes. See the "virtual quotas" section later in this document.
7.29.
'-N': NAT mode. Force ACTIVE mode. If your FTP server is behind a NAT box that doesn't
support applicative FTP proxying, or if you use port redirection without a transparent FTP proxy,
use this. Well... the previous sentence isn't very clear. Okay: if your network looks like this:
(FTP server)-------(NAT/masquerading gateway/router)------(Internet)
and if you want people coming from the internet to have access to your FTP server, please try
without this option first. If Netscape clients can connect without any problem, your NAT gateway
rulez. If Netscape doesn't display directory listings, your NAT gateway sucks. Use '-N' as a
workaround.
Page 19 of 110
7.30.
'-o': Write all uploaded files to '/var/run/pure-ftpd.upload.pipe' so that the 'pure-uploadscript'
program can run. Don't enable that option if you don't actually use 'pure-uploadscript'.
7.31.
'-O <format>:<log file>': Record all file transfers into a specific log file, in an alternative format.
Currently, three formats are supported: CLF (Apache-like), Stats and W3C.
If you add '-O clf:/var/log/pureftpd.log' to your starting options, Pure-FTPd will log transfers in
/var/log/pureftpd.log in a format similar to the Apache web server in default configuration.
If you use '-O stats:/var/log/pureftpd.log' to your starting options, Pure-FTPd will create log files in
a special format, designed for statistical reports. The Stats format is compact, more efficient and
more accurate that CLF and the old broken "xferlog" format.
The Stats format is:
<date> <session id> <user> <ip> <U or D> <size> <duration> <file>
<date> is a GMT timestamp (time()) and <session id> identifies the current session. <file> is
unquoted, but it's always the last element of a log line.
"U" means "Upload" and "D" means "Download".
Warning: the session id is only designed for statistics purposes. While it's always an unique string
in the real world, it's theoretically possible to have it non unique in very rare conditions. So don't
rely on it for critical missions.
A command called "pure-statsdecode" can be used to convert timestamps into human-readable
dates.
The W3C format is enabled with '-O w3c:/var/log/pureftpd.log' .
For security purposes, the path must be absolute (eg. /var/log/pureftpd.log, not ../log/pureftpd.log) .
If this log file is stored on a NFS volume, don't forget to start the lock manager (often called
"lockd" or "rpc.lockd").
7.32.
'-p <first port>:<last port>': Use only ports in the range <first port> to <last port> inclusive for
passive-mode downloads. This is especially useful if the server is behind a firewall without FTP
connection tracking. Use high ports (40000-50000 for instance), where no regular server should be
listening.
7.33.
'-P <ip address or host name>': Force the specified IP address in reply to a PASV/EPSV/SPSV
command. If the server is behind a masquerading (NAT) box that doesn't properly handle stateful
FTP masquerading, put the ip address of that box here. If you have a dynamic IP address, you can
put the public host name of your gateway, that will be resolved every time a new client will
connect.
7.34.
'-q <upload ratio>:<download ratio>': Enable ratios for anonymous users.
7.35.
'-Q <upload ratio>:<download ratio>': Enable ratios for everybody (anonymous and nonanonymous). Members of the root (0, something called 'wheel') have no ratio.
7.36.
'-r': Never overwrite existing files. Uploading a file whoose name already exists cause an automatic
rename. Files are called xyz, xyz.1, xyz.2, xyz.3, etc.
Tip: if you compile with 'make AUTORENAME_REVERSE_ORDER=1' , the naming convention
will be reversed. Files will be called xyz, 1.xyz, 2.xyz, 3.xyz, etc.
Page 20 of 110
7.37.
'-R': Disallow users (even non-anonymous ones) usage of the CHMOD command. On hosting
services, it may prevent newbies from making mistakes, like setting bad permissions on their home
directory. Only root can use CHMOD when -R is enabled.
7.38.
'-s': The "waReZ protection". Don't allow anonymous users to download files owned by "ftp"
(generally, files uploaded by other anonymous users). So that uploads have to be validated by a
system administrator (chown to another user) before being available for download.
7.39.
'-S [<ip address>,|<hostname>,] [<port>|<service name>]'. This option is only effective when the
server is launched as a standalone server. Connections are accepted on the specified IP and port.
IPv4 and IPv6 are supported. Numeric and fully-qualified host names are accepted. A service name
(see /etc/services) can be used instead of a numeric port number.
7.40.
'-T <bandwidth>' and '-t <bandwidth>': Enable bandwidth limitation (see below) . <bandwidth> is
specified in kilobytes/seconds. To set up separate upload/download bandwidth, the
[<upload>]:[<download>] syntax is supported.
7.41.
'-u <uid>': Don't allow uids below <uid> to log in. '-u 1' denies access to root (safe), '-u 100' denies
access to virtual accounts on most Linux distros.
7.42.
'-U <umask for files>:<umask for dirs>': Change the file creation mask. The default is 133:022. If
you want a new file uploaded by a user to only be readable by that user, use '-U 177:077'. If you
want uploaded files to be executable, use 022:022 (files will be readable -but not writable- by other
users) or 077:077 (files will only be executable and readable by their owner) . Please note that
Pure-FTPd support the SITE CHMOD extension, so a user can change the permissions of his own
files.
'-V <ip address>': Allow non-anonymous FTP access only on this specific local IP address. All
other IP addresses are only anonymous. With that option, you can have routed IPs for public access
and a local IP (like 10.x.x.x) for administration. You can also have a routable trusted IP protected
by firewall rules and only that IP can be used to login as a non-anonymous user.
7.43.
'-w': Support the FXP protocol only for authenticated users. FXP works with IPv4 and IPv6
addresses.
7.44.
'-W': Support the FXP protocol. FXP allows transfers between two remote servers without any file
data going to the client asking for the transfer.
However:
****************************************************************************
*FXP IS AN INSECURE PROTOCOL* (third-party hosts can steal the current connection) . In
Pure-FTPd, specific precautions have been taken to reduce FXP insertion attacks. But if your FTP
server serves private data:
NEVER ALLOW FXP ACCESS TO UNTRUSTED HOSTS. YOU CAN PLAY WITH IT ON AN
INTERNAL SERVER, BUT _DON'T_ GIVE FXP ACCESS TO ANONYMOUS INTERNET
USERS.
****************************************************************************
It's why FXP is disabled by default on Pure-FTPd unless you explicitely
enable it with '-W' or '-w'.
Page 21 of 110
7.45.
'-x': In normal operation mode, authenticated users can read/write files beginning with a dot ('.') .
Anonymous users can't, for security reasons (like changing banners or a forgotten .rhosts) . When 'x' is used, authenticated users can download dot-files, but not overwrite/create them, even if they
own them. That way, you can prevent hosted users from messing .qmail files. If you want to give
user access to a special dot-file, create a symbolic link to the dot-file with a file name that has no
dot in it and the client will be able to retrieve the file through that link.
7.46.
'-X': This flag is identical to the previous one (writing dot-files is prohibited), but in addition, users
can't even *read* files and directories beginning with a dot (like "cd .ssh").
****************************************************************************
When used in conjunction with "-a", members of the trusted group can bypass '-x'/'-X' restrictions.
****************************************************************************
7.47.
'-y <max user logins>:<max anonymous logins>': This option only works if the server has been
compiled with --with-peruserlimits. It restricts the number of concurrent sessions the same user can
have.
A null value ('0') means 'unlimited'.
Here's a concrete example:
/usr/local/sbin/pure-ftpd -y 3:20 -c 15 -C 5 –B
Here, we allow:
* A max total of 15 sessions.
* 5 connections max coming from the same IP address.
* 3 connections max with the same user name.
* 20 anonymous users max.
With such a setup, a single user can't easily fill all slots.
7.48.
'-Y 0': Disable the SSL/TLS encryption layer (default).
'-Y 1': Accept both standard and encrypted sessions.
'-Y 2': Refuse connections that aren't using SSL/TLS security mechanisms, including anonymous
sessions. The server must have been compiled with --with-tls and a valid certificate must be in
place to get this feature.
See the README.TLS file for more info about SSL/TLS.
7.49.
'-z': Allow anonymous users to read files and directories starting with a dot ('.').
7.50.
'-Z': Try to protect customers against common mistakes to avoid your technical support being busy
with stupid issues. Right now, the '-Z' switch prevents your users against making bad 'chmod'
commands, that would deny access to files/directories to themselves. The switch may turn on other
features in the future. If you are a hosting provider, turn this on.
If you prefer long options (GNU-style) over standard ones, the following aliases are available. You
can get this list at any time by typing 'pure-ftpd --help' .
Page 22 of 110
7.51.
switches sorted by ##standard switches## lexical order)
-0
-1
-4
-a
-A
-b
-B
-c
-C
-d
-D
-e
-E
-f
-F
-g
-G
-h
-H
-i
-I
-j
-k
-K
-l
-L
-m
-M
-N
-o
-O
-p
-P
-q
-Q
-r
-R
-s
-S
-t
-T
-u
-U
-V
-w
-W
-x
-X
-y
-Y
-z
-Z
--notruncate
--logpid
<file>
--ipv4only
--trustedgid
<gid>
--chrooteveryone
--brokenclientscompatibility
--daemonize
--maxclientsnumber
<number>
--maxclientsperip
<number>
--verboselog
--displaydotfiles
--anonymousonly
--noanonymous
--syslogfacility
<facility>
--fortunesfile
<file>
--pidfile
<path to pid file>
--norename
--help
--dontresolve
--anonymouscantupload
--maxidletime
<time (min)>
--createhomedir
--maxdiskusagepct
<percentage>
--keepallfiles
--login
<auth> or <auth>:<config file>
--limitrecursion
<number:number>
--maxload
<load>
--anonymouscancreatedirs
--natmode
--uploadscript
--altlog
<format>:<log file>
--passiveportrange
<minport:maxport>
--forcepassiveip
<ip address>
--anonymousratio
<upload ratio>:<download ratio>
--userratio
<upload ratio>:<download ratio>
--autorename
--nochmod
--antiwarez
--bind
<ip address,port>
--anonymousbandwidth <bandwidth (KB/s)>
--userbandwidth
<bandwidth (KB/s)> or [<up bw>]:[<down bw>]
--minuid
<uid>
--umask
<mask>
--trustedip
<ip address>
--allowuserfxp
--allowanonymousfxp
--prohibitdotfileswrite
--prohibitdotfilesread
--peruserlimits
<per user max>:<max anonymous sessions>
--tls
<0:no TLS | 1:TLS+cleartext | 2:enforce TLS>
--allowdotfiles
--customerproof
Page 23 of 110
7.52.
switches sorted by ##GNU-style long switches## lexical order
-W
-z
-w
-O
-t
-M
-i
-e
-q
-s
-r
-S
-b
-A
-j
-Z
-B
-D
-H
-P
-F
-h
-4
-K
-l
-1
-L
-c
-C
-k
-I
-m
-u
-N
-E
-R
-G
-0
-p
-y
-g
-X
-x
-f
-Y
-a
-V
-U
-o
-T
-Q
-d
Page 24 of 110
--allowanonymousfxp
--allowdotfiles
--allowuserfxp
--altlog
<format>:<log file>
--anonymousbandwidth <bandwidth (KB/s)>
--anonymouscancreatedirs
--anonymouscantupload
--anonymousonly
--anonymousratio
<upload ratio>:<download ratio>
--antiwarez
--autorename
--bind
<ip address,port>
--brokenclientscompatibility
--chrooteveryone
--createhomedir
--customerproof
--daemonize
--displaydotfiles
--dontresolve
--forcepassiveip
<ip address>
--fortunesfile
<file>
--help
--ipv4only
--keepallfiles
--login
<auth> or <auth>:<config file>
--logpid
<file>
--limitrecursion
<number:number>
--maxclientsnumber
<number>
--maxclientsperip
<number>
--maxdiskusagepct
<percentage>
--maxidletime
<time (min)>
--maxload
<load>
--minuid
<uid>
--natmode
--noanonymous
--nochmod
--norename
--notruncate
--passiveportrange
<minport:maxport>
--peruserlimits
<per user max>:<max anonymous sessions>
--pidfile
<path to pid file>
--prohibitdotfilesread
--prohibitdotfileswrite
--syslogfacility
<facility>
--tls
<0:no TLS | 1:TLS+cleartext | 2:enforce TLS>
--trustedgid
<gid>
--trustedip
<ip address>
--umask
<mask>
--uploadscript
--userbandwidth
<bandwidth (KB/s)> or [<up bw>]:[<down bw>]
--userratio
<upload ratio>:<download ratio>
--verboselog
8.
SETTING UP AN ANONYMOUS FTP
If a 'ftp' user exists and its home directory is reachable, Pure-FTPd will accept anonymous login, as 'ftp' or
'anonymous'. Files have to be located in the home FTP directory. There's no need for 'bin', 'lib', 'etc' and 'dev'
directories, nor any external program. Don't chown the public files to 'ftp', just writable directories
('incoming').
9.
DISPLAYING BANNERS
If a '.banner' file is located in the 'ftp' user home directory (or in the root directory of a virtual server, see
below), it will be printed when the client logs in. Put a nice ASCII-art logo with your name in that file.
This file shouldn't be larger than 4000 bytes, or it won't be displayed.
In each directory, you may also have a '.message' file. Its content will be printed when a client enters the
directory. Such a file can contain important information ("Don't download version 1.7, it's broken!").
10.
DISPLAYING A COOKIE
A funny random message can be displayed in the initial login banner. The random cookies are extracted
from a text file, in the standard "fortune" format. If you installed the "fortune" package, you should have a
directory (usually /usr/share/fortune) with binary files (xxxx.dat) and text files (without the .dat extension) .
To use Pure-FTPd cookies, just add the name of a text file to the '-F' option. For instance:
/usr/local/sbin/pure-ftpd -F /usr/share/fortune/zippy
If you want to have your own fortune files, just create a text file with the following structure.
Hello... this is the first fortune...
%
Welcome to the real world.
%
Follow the white rabbit.
%
Have fun...
Well... lotsa fun!
%
Yop is good for you.
Goddit? Fortunes are delimited by a '%' sign on a single line. But a fortune itself can be multi-line (see the
fourth example).
For security paranoia, the text file has to be readable by everybody (chmod 644 the file if necessary), or the
server will ignore it.
Of course, the fortune file can contain a single message.
Page 25 of 110
11.
PER-USER CHROOT() RULES
Apart from the "-a" flag, Pure-FTPd has another way to fine-tune chroot() rules. Let's take an /etc/passwd
entry:
mimi:x:501:100:Mimi:/home/mimi:/bin/zsh
Without any special rule, mimi will be able to log in and to retrieve any public-readable file in the
filesystem. Now, let's change a bit of its home directory:
mimi:x:501:100:Mimi:/home/mimi/./:/bin/zsh
So what? Mimi's home directory is still the same and common applications shouldn't notice any difference.
But Pure-FTPd understands "chroot() until /./". So when mimi next carries out a FTP log in, only the
/home/mimi directory will be reachable, not the whole filesystem. If you don't like the "-a" and its trusted
gid thing, this is a good way to only chroot() some users. Another trick is to add something after "/./":
mimi:x:501:100:Mimi:/home/mimi/./public_html:/bin/zsh
When Mimi will log in, two things will happen:
- chroot("/home/mimi") so that Mimi can't see anything but her home directory.
- chdir("public_html") so the session will start in the public_html directory.
"cd .." is still allowed, though.
That "url-style" handling is especially handy for FTP-only users (ie. without shell access).
If a user is chrooted with the /./ trick *and* belongs to the trusted group (-a) he *will* be chrooted, but he
will have no ratio and will be allowed to access dot files.
12.
RATIOS
If you want to force people to upload new files before being able to download other files, ratios are for you.
It's a very good way to get lotsa fresh stuff on a public FTP server and a must for warez traders. I don't like
that kind of business, but well... Pure-FTPd has to be designed to please everybody.
To enable ratios, just use the '-q' option, followed by the upload:download ratio:
-q 2:5
Means that an anonymous user has to upload at least 2 Mb of goodies to be able to download 5 Mb.
If ratios should apply to everyone (anon and non-anon), use the '-Q' option the same way.
Note:
'root' never has ratios.
Neither have users of the trusted group when '-Q' in used with the '-a' or '-A' option.
Page 26 of 110
13.
BANDWIDTH THROTTLING
Pure-FTPd has an interesting built-in feature: simple bandwidth throttling.
* You want to limit FTP throughput so that uploading and downloading files through that protocol can't fill
up your network bandwidth.
Compile Pure-FTPd with --with-throttling
Run it with the '-T' flag, followed by a number.
That number is the maximum bandwidth a user can use in a session,
in kilobytes/seconds.
* You want to allow less bandwidth to your anonymous users than your authenticated ones. So that during a
bandwidth starvation, real users can still upload/download properly.
Compile Pure-FTPd with --with-throttling
Run it with the '-t' flag, followed by a number.
Example:
/usr/local/sbin/pure-ftpd -t 64
And uploading/downloading files can't take more than 64 KB/sec whatever real bandwidth you have.
* It is possible to have different bandwidth limits for uploads and for downloads. '-t' and '-T' can indeed be
followed by two numbers delimited by a column (':') . The first number is the upload bandwidth and the next
one applies only to downloads. One of them can be left blank which means infinity.
Example 1: 256 KB/s for uploads, 64 KB/s for downloads
/usr/local/sbin/pure-ftpd -t 256:64
Example 2: 256 KB/s for uploads, no limit for downloads
/usr/local/sbin/pure-ftpd -t 256:
Example 3: no limit for uploads, 64 KB/s for downloads
/usr/local/sbin/pure-ftpd -t:64
With no column, the value applies to both, so '-t 64' is an alias for '-t 64:64'.
* When Pure-FTPd serves a session with restricted bandwidth, it decreases its process priority to 10. So, '-t
0' makes sense: during a CPU starvation, authenticated sessions may be more responsible than anonymous
ones. '-T 0' is quite useless, but it also works and it will always be nice to the server process.
* If you need advanced bandwidth management, have a look at your kernel Q.O.S. abilities.
Page 27 of 110
14.
VIRTUAL SERVERS
Using Virtual servers is a convenient way of hosting several FTP sites on the same computer. Let's say, you
got two customers. The former owns the 'c9x.org' domain name, while the latter owns the 'rtchat.com'
domain name. Both are hosted on the same computer, but they don't want to share the same files.
ftp://ftp.c9x.org/ should show different content than ftp://ftp.rtchat.com/
The FTP protocol doesn't allow name-based selection. So, if you want to host <N> different virtual FTP
servers on the same host and keep the standard port, you need <N> different IP addresses. Yes, Sir. Or use
HTTP.
Assign the needed IP adresses to your network adapter (with "ifconfig eth0:x ..." or "ip addr add dev eth0
a.b.c.d").
Now, create a /etc/pure-ftpd directory if it doesn't exist:
mkdir /etc/pure-ftpd
To add a virtual FTP server, you only need to create a symbolic link in /etc/pure-ftpd/ from the virtual host
IP to the directory that contains the file for that virtual host.
Example:
ln -s /home/customers/rtchat.com/ftp /etc/pure-ftpd/216.226.17.77
ln -s /home/customers/c9x.org/ftp /etc/pure-ftpd/212.73.209.252
Done! Put the C9X files in /home/customers/c9x.org/ftp/ and the RTChat files in
/home/customers/rtchat.com/ftp/.
With that feature, every account on the server can have its own public anonymous FTP area. If you are
providing hosting services, this is a nice feature for your customers.
* WARNING *: it also means that your customers can create "incoming" directories with 1777 permissions.
It can be nice, but it can also fill up your disk with warez. You can stop uploads for anonymous users with
the '-i' (or --anonymouscantupload) option.
By default, all IP addresses assigned to your server can be accessed by real or anonymous users. You can
restrict this with -e (only anonymous) or –E (only real).
A more flexible way is to use '-V <ip address>' to define a "trusted" IP address. When a client connects to
that trusted IP, anonymous and real logins are permitted. But on all other IP, only anonymous users are
permitted.
If you are a hosting service provider and if each customer has its own IP address, it may be a nice idea to
have a trusted IP you give to all your customers, so that they can manage the files in their account. That IP is
the same for all customers. You can easily restrict access to that IP with firewall rules if your customers
have static IP addresses. Use '-V <trusted ip>' and link /etc/pure-ftpd/<customer ip> to ~customer/ftp .
Every customer will have his own *anonymous only* FTP server and hackers will have to find the trusted
IP to get in.
15.
IPv6 SUPPORT
Pure-FTPd has full IPv6 support (native IPv6 addresses and 4-in-6 addresses). But use a super-server that
also understands the IPv6 protocol, like Rlinetd or Xinetd. Recent versions of Inetd should also be ok
(unverified). IPv6 is supported everywhere: logging, configuration switches, virtual hosts, protocol
(EPSV/EPRT support), name resolution...
Page 28 of 110
16.
LOGGING
Log messages are sent to the syslog daemon. You can disable logging with '-f none'.
If you want all FTP messages to be redirected to a file, say /var/log/ftp, add this line to your /etc/syslog.conf
file:
ftp.* /var/log/ftp
Then restart your syslogd daemon:
killall -HUP syslogd
You can also drop your old "syslogd" and "klogd" programs for Metalog, an efficient alternative:
http://metalog.sourceforge.net
Names of uploaded/downloaded files are logged with paths like this:
/home/ftp//pub/bla.jpg
The double-slash ('//') is the chroot limit.
17.
WATCHING CURRENT SESSIONS
Since 0.97.7, you can type 'pure-ftpwho' at any time to watch current active sessions.
If typing 'pure-ftpwho' answers 'Command not found', you have to add /usr/local/sbin in your PATH
environment variable.
The default output looks like this:
+------+---------+-------+------+-------------------------------------------+
| PID | Login |For/Spd| What |
File/IP
|
+------+---------+-------+------+-------------------------------------------+
| 2239 | jedi | 00:17 | D/L | XFree86-clients-4.0.3.tar.gz
|
| '' | '' | 41K/s| 33% | ->
nestea.funboard.de |
+------+---------+-------+------+-------------------------------------------+
| 2385 | ftp | 00:02 | IDLE |
|
| '' | '' |
|
| ->
gw2.crn.kjop.co.uk |
+------+---------+-------+------+-------------------------------------------+
'D/L' means that the client is downloading and 'U/L' means he's uploading some file whose name is shown
in the next column. '33%' is the real-time completion of the current operation. '41K/s' is the bandwidth used
by the client. You can track down who's starving your bandwidth with this.
The 'pureftp-who' command accepts interesting options:
17.1.
'-c': the program is called via a web server (CGI interface). Output is a full HTML page with the
initial content-type header. This option is automatically enabled if an environment variable called
GATEWAY_INTERFACE is found. This is the default if you can access the program from a CGIenabled web server (Apache, Roxen, Caudium, WN, ...) .
17.2.
'-h': show command-line options summary.
17.3.
'-n': don't resolve host names and only show IP addresses (faster).
Page 29 of 110
17.4.
'-s': output an easily parsable format for shell scripts (but not very userfriendly).
There's only one line per client, with only numeric data, delimited by a '|' character. It's not very
human-readable, but it's designed for easy parsing by shell scripts (cut/sed) . '|' characters in user
names or file names are quoted ('|' becomes '\|') .
Type 'pure-ftpwho -h' to check the format.
17.5.
'-w': output a complete HTML page (web mode).
17.6.
'-W': output an HTML page with no header and no footer. This is an embedded mode, suitable for
inline calls from CGI, SSI or PHP scripts.
17.7.
'-x': output well-formed XML data for post-processing. This is the most acurate mode. Time is in
seconds and file sizes are in bytes (in other output formats, sizes are in kbytes for easier readability)
.
17.8.
'-v': verbose output in text mode. Additional info includes the size of files being
downloaded/uploaded, the local IP or local host name and the connection port. This is especially
useful for virtual hosts. Here's a sample output of 'pure-ftpwho -v':
+------+---------+-------+------+-------------------------------------------+
| PID | Login |For/Spd| What | File/Remote IP/Size(Kb)/Local IP
+------+---------+-------+------+-------------------------------------------+
| 9086 | j
| 00:04 | DL | linux-2.4.4.tar.bz2
|
| '' | '' | 22K/s| 27% | ->
localhost |
| '' | '' |
|
| Total size: 20859 Transfered: 5632 |
| '' | '' |
|
| <localhost:21 |
+------+---------+-------+------+-------------------------------------------+
Page 30 of 110
|
18.
AFTER AN UPLOAD
After a successful upload, any external program or shell script can be spawned with the name of the newly
uploaded file as an argument. You can use that feature to automatically send a mail when a new file arrives.
Or you can pass it to a moderation system, an anti-virus, a MD5 signature generator or whatever you decide
can be done with a file.
To support this, the server has to be configured --with-uploadscript at compilation time. Then, the FTP
server has to be launched with the '-o' run-time option. Finally, you have to run another daemon called 'pureuploadscript' provided by this package.
IMPORTANT:
YOU MUST START PURE-FTPD _FIRST_ and _THEN_ START PURE-UPLOADSCRIPT.
THE REVERSE ORDER WON'T WORK.
For security purposes, the server never launches any external program. It's why there is a separate daemon,
that reads new uploads pushed into a named pipe by the server. Uploads are processed synchronously and
sequencially. It's why on loaded or untrusted servers, it might be a bad idea to use pure-uploadscript with
lenghty or cpu-intensive scripts.
The easiest way to run pure-uploadscript is 'pure-uploadscript -r <script>':
/usr/local/sbin/pure-uploadscript -r /bin/antivirus.sh
The absolute path of the newly uploaded file is passed as a first argument.
Some environment variables are also filled with interesting values:
- UPLOAD_SIZE : the size of the file, in bytes.
- UPLOAD_PERMS : the permissions, as an octal value.
- UPLOAD_UID : the uid of the owner.
- UPLOAD_GID : the group the file belongs to.
- UPLOAD_USER : the name of the owner.
- UPLOAD_GROUP : the group name the file belongs to.
- UPLOAD_VUSER : the full user name, or the virtual user name. (127 chars max)
There are also some options to "pure-uploadscript":
- '-u <uid>' and '-g <gid>' to switch the account pure-uploadscript will run as.
The script will be spawned with the same identity.
- '-B' to fork in background.
Please have a look at the man page ('man pure-uploadscript') for additional info.
Page 31 of 110
19.
LISTING DIRECTORIES
The built-in 'ls' supports all common options of a regular 'ls' command.
Here are the ones you should know for a better life with FTP:
- '-l': verbose listing, reporting dates, owners, perms and sizes.
- '-a': also lists files and directories beginning with a dot.
- '-F': adds a '/' after directory names.
- '-d': list the directory itself, not its content.
- '-R': recursive listing.
- '-S': sort by size.
- '-t': sort by date.
- '-r': reverse the sorting order.
If you aren't very familiar with Unix, log in to your FTP server and try these variants:
ls
ls –F
ls –l
ls –la
ls –lR
ls –Sl
ls –Slr
ls –tl
ls –tlr
Globbing is also supported. So if you are looking for a GNOME RPM in <I don't know the directory
name>/gnome-xxxxxxxx.rpm , you can find it that way:
ls */gnome*.rpm
Page 32 of 110
20.
VIRTUAL QUOTAS
With virtual quotas, you can restrict the maximum number of files and the total size of a user directory.
These quotas are "virtual" because they aren't handled at kernel-level, but by the FTP server itself. There are
some advantages over kernel quotas:
- Virtual quotas are specific to the FTP server.
You can have different system quotas to handle other files (eg. mail) on the same partition.
- You can have different virtual quotas for every user, even if they share the same system uid.
- Virtual quotas are working even on filesystems that don't support system quotas.
However, virtual quotas are slower and can't be as reliable as kernel quotas, so don't trust them ultimately,
they are probably races allowing to bypass them. Also the filesystem users directories are on must properly
support file locking.
Virtual quotas are implemented in Pure-FTPd as simple files called ".ftpquota", located in the home
directory of chrooted users. This file only contains two numbers: the current number of files for this user
and the total size of the directory (+ its subdirectories), in bytes. When a new file is uploaded, these numbers
grow. When a file is deleted, these numbers get smaller. Simple. Of course, when virtual quotas are enabled
for one user, that user must be 1) chrooted, 2) not allowed to write quota files, 3) not allowed to forbid
access to some directories to fool the counter.
Quotas can be enabled for all users for the -n (--quotas) option. This option is followed by the max number
of files and the max size (in Megabytes). Every user will have the same quota. Exception: members of the
trusted group, if -a is enabled.
You can also have different quotas for every user if you use PureDB or SQL databases. See the
"README.Virtual-Users" file for more info about PureDB databases.
So, if you want 1000 files max and 10 Mb max for all your customers, run the server like this:
/usr/local/sbin/pure-ftpd -n 1000:10
".ftpquota" files are created on demand when they are missing. However, when they are created, the server
assumes that the account was empty. If this is not the case, you must run the "pure-quotacheck" utility to
create an initial ".ftpquota" file.
"pure-quotacheck" is a tool that computes the size and the number of files in a directory and create a
".ftpquota" file with this info.
The syntax is:
pure-quotacheck -u username/uid -d home directory [-g group/gid]
For instance, if you want to summarize usage for the /home/ftpusers/john directory, whoose files are owned
by the "ftpusers" system account, just run:
pure-quotacheck -u ftpusers -d /home/ftpusers/john
You can run pure-quotacheck whenever you want, even when ".ftpquota" files are already there. This is
even a good idea to run this for all users in crontab, so that stored quotas are always exact, even if something
went wrong (server bug, filesystem corruption, savagely killed server, etc) .
With traditional quotas, when a hard limit is reached, it's impossible to write new data. It's nice for files that
are created fastly (operations on local filesystems) . But it's really frustrating when transfering files through
networks.
Page 33 of 110
Virtual quotas are working in a (somewhat strange) but handy way. When an user begins an upload, the
newly uploaded file can be as huge as his total quota. It means that if his quota is 10 Mb, he can upload a 10
Mb file, even if he already has 9 Mb of other files in his directory. The idea is that while he's uploading the
file, he can realize that his quota will be reached and he can move/compress/delete other files to save space
before the end of the upload. And only after completion of the upload, the quota is checked. If the quota is
still crunched, the newly uploaded file will be deleted.
Page 34 of 110
21.
AUTHENTICATION
Pure-FTPd supports multiple methods of authentication. To use a method, you must have it compiled in
(check the ./configure options) .
- To use Unix authentication (the traditional /etc/passwd file), add the following option when you run the
server:
-l unix
- To use PAM authentication, add this:
-l pam
- To use PureDB (virtual users), add this:
-l puredb:/path/to/puredb_database
(read README.Virtual-Users for more info about PureDB indexed files)
- To use LDAP directories, add this:
-l ldap:/path/to/ldap_config_file
(read README.LDAP for more info about LDAP directories)
- To use MySQL databases, add this:
-l mysql:/path/to/mysql_config_file
(read README.MySQL for more info about MySQL databases)
- To use Postgres databases, add this:
-l pgsql:/path/to/postgres_config_file
(read README.PGSQL for more info about Postgres databases)
- To use external authentication handlers (with pure-authd), use:
-l extauth:/path/to/authd/socket
(read README.Authentication-Modules for more info about external authentication)
Multiple authentication methods can be chained. For instance, you can run the server like this:
/usr/local/sbin/pure-ftpd -lldap:/etc/pureftpd-ldap.conf -lpuredb:/etc/pureftpd.pdb –lunix
Every method is tried in order. With the previous command line, an LDAP directory is probed first. If a user
isn't found in the directory, a PureDB database is scanned for the same user name. If that user is still not
found, /etc/passwd is scanned.
If the user is found in the LDAP directory, but the given password is wrong, further authentication methods
are skipped.
If you don't specify any -l option, PAM is assumed by default if the server is compiled with PAM support
and Unix is assumed by default otherwise.
Page 35 of 110
22.
DIRECTORY ALIASES
Directory aliases provides "shortcuts" for the "cd" command. For instance, if you define an alias called
"pictures" for "/usr/misc/pictures", when an user will type "cd pictures" and if no real "pictures" directory
exists, he will be automatically redirected to "/usr/misc/pictures". Unlike symbolic links, "cd pictures" will
work from any directory. Tildes are *not* expanded.
An user can get the list of available aliases with the following command:
SITE ALIAS
To support that feature, the server must be compiled with --with-diraliases passed to ./configure.
To define alias/directory pairs, you must create a file called /etc/pureftpd-dir-aliases,
whoose format is:
Alternating lines of alias and dir
(this enables embeded whitespace in dir and alias without quoting rules)
Optional blank lines
Optional lines beginning with '#' as comments
(no you can't put a '#' just anywhere)
Example:
pictures
/usr/misc/pictures
sources
/usr/src
# This is for the OpenBSD port tree
pureftpd-port
/usr/ports/net/pure-ftpd
23.
PRIVILEGE SEPARATION
When privilege separation is enabled, each session will spawn two processes :
a "privileged" process running as root, but that can only do very basic and trusted actions (binding a port and
remove the ftpwho scoreboard) and the "client" process. The "client" process definitely revokes all
privileges after authentication and chroot() and punctually communicates with the parent over a private
channel.
Privilege separation decreases performance of loaded servers, but it increases theorical security.
Some old broken operating systems may allow the ptrace() system call on processes that revoked privileges.
On these platforms, enabling privilege separation is a bad idea if untrusted users also have shell access. Use
the src/ptracetest program to check this. At least Solaris, ISOS, EkkoBSD, OpenBSD, FreeBSD and Linux
are known to be safe.
Page 36 of 110
24.
OPTIMIZING FOR HIGH LOAD
If you are going to use Pure-FTPd on a highly loaded server, here are some hints to get the best
performances:
- Compile with:
env CFLAGS="-O2 -fomit-frame-pointer -fgcse -Os" ./configure --with-minimal --without-inetd --without-pam
make install-strip
- Run it in standalone mode.
Don't use -C, don't enable pure-ftpwho nor pure-uploadscript (-o), nor per-user limits (-y).
- Increase your system max descriptors number and local port range.
On a Linux kernel, you can try:
echo 2000 > /proc/sys/fs/super-max
echo 60000 > /proc/sys/fs/file-max
ulimit -n 60000
echo 30000 65534 > /proc/sys/net/ipv4/ip_local_port_range
- On a Linux kernel, disable syncookies, ecn, timestamps and window scaling:
echo 0 > /proc/sys/net/ipv4/tcp_syncookies
echo 0 > /proc/sys/net/ipv4/tcp_ecn
echo 0 > /proc/sys/net/ipv4/tcp_timestamps
echo 0 > /proc/sys/net/ipv4/tcp_window_scaling
- Disable access time update on your mounted filesystems. On a Linux system, just add 'noatime,nodiratime'
for each mount point in your /etc/fstab file.
- Disable syslog output and DNS lookups. Run it with:
/usr/local/sbin/pure-ftpd -f none –H
For FreeBSD, DJ_Oggy recommends the following setting:
>>> QUOTE:
Drop into single user mode (do a shutdown now or boot -s) and enter
tunefs -n enable <filesystem>
i sugest / /usr /var
In /etc/fstab add ",noatime" to the options of all filesystems.
In /boot/loader.conf add the following:
hw.ata.wc="1"
kern.ipc.nmbclusters="60000"
Page 37 of 110
In /etc/sysctl.conf add the following:
vfs.vmiodirenable=1
kern.ipc.maxsockbuf=2097152
kern.ipc.somaxconn=8192
kern.ipc.maxsockets=16424
kern.maxfiles=65536
kern.maxfilesperproc=32768
net.inet.tcp.rfc1323=1
net.inet.tcp.delayed_ack=0
net.inet.tcp.sendspace=65535
net.inet.tcp.recvspace=65535
net.inet.udp.recvspace=65535
net.inet.udp.maxdgram=57344
net.local.stream.recvspace=65535
net.local.stream.sendspace=65535
give it two asprin, a reboot and call me in the morning!!!!!
<<< END OF QUOTE
Page 38 of 110
25.
KNOWN ISSUES
- On non-linux systems, '-c' only works in standalone mode.
- You should always avoid the use of spaces in login names: applications that are parsing log files often
choke on this.
- Incomplete transfers aren't logged in alternative formats.
- On Solaris (at least Solaris 8), the large files + virtualchroot combination doesn't compile (we need to use
struct stat64 in place of stat everywhere).
- On Solaris, to get chroot to work with pure-ftpd you need a dev directory in your new rootdir with these:
crw-rw-rwcrw-rw-rwcrw-rw-rwcrw-rw-rw-
1 root
1 root
1 root
1 root
other 11, 42 Dec 10 15:02 tcp
other 105, 1 Dec 10 15:02 ticotsord
other 11, 41 Dec 10 15:03 udp
other 13, 12 Dec 10 15:03 zero
else you get this
ftp> ls
425 Can't create the data socket: Bad file number.
If all your users are chrooted, you have to create these files in every home directory. Here's how:
mkdir dev
mknod dev/tcp c 11 42
chmod 0666 dev/tcp
mknod dev/udp c 11 41
mknod dev/zero c 13 12
mknod dev/ticotsord c 105 1
(Reported by Kenneth Stailey)
- Resuming ASCII transfers is refused. ASCII transfers are hell, because they are consuming CPU time both
at client and server sides. And they even consume *more* bandwidth than binary transfers. But they allow
Windows clients to upload scripts to Unix servers, stripping these nasty ^M signs. ASCII transfers are
implemented in Pure-FTPd. But they can't be resumed and this is intentional. To restart an ASCII transfer,
the file has to be read and analyzed byte by byte. It can be very long and by sending two trivial commands, a
client can completely kill a server (take a lot of CPU and disk resources) . And there's no workaround.
Another point is that while RFC describe a way to resume ASCII transfers, many clients and servers
implement them in another way. The result is that resumed ASCII transfers can lead to data corruption.
Some major servers didn't follow RFC, so some clients did the same mistake to support these servers, while
some other modern clients and servers are trying to fully conform to RFC. So when clients and servers are
speaking the same dialect, it works. When it's not the case, you get corrupted files. Messy, eh?
And what if a customer uploads a script to your server and thinks he can safely delete it from its hard disk?
If the remote file is corrupted, he will get really angry. It's why Pure-FTPd *refuses* to resume ASCII
transfers. If a customer tells you that he isn't able to upload/download a partially transfered ASCII file,
please tell him to remove the partial file and to retransfer it again.
This is a safe bet.
Page 39 of 110
26.
DOWNLOADING PURE-FTPD
Pure-FTPd home page is: http://www.pureftpd.org
Pure-FTPd mailing-lists: http://www.pureftpd.org/ml
You can also fetch the latest snapshots by CVS:
cvs -d:pserver:[email protected]:/cvsroot/pureftpd login
(hit return without entering any password)
cvs -z3 -d:pserver:[email protected]:/cvsroot/pureftpd co pureftpd
cd pureftpd
./autogen.sh
Alternatively you can peek at the "snapshots" directory of the FTP mirrors carrying the source tarball. It
contains experimental tarballs that are ready to compile.
FreeBSD port is available in: ports/ftp/pure-ftpd/
OpenBSD port is available in: ports/net/pure-ftpd/
NetBSD port is available in: pkgsrc/net/pureftpd/
Open Packages (C&W multiple-architectures OpenPKG standard packages) for Pure-FTPd are available
from http://www.openpkg.org/download.html. Pre-built Solaris binary packages are available from the same
location.
MacOS X packages are available from Fink: http://fink.sourceforge.net/pdb/package.php/pure-ftpd
Gentoo Linux emerging : emerge pure-ftpd
EkkoBSD ships it in the base install.
Latest releases and regular snapshots are always available from:
ftp://ftp.pureftpd.org/pub/pure-ftpd
(a link to a fast mirror)
ftp://ftp.fr.pureftpd.org/pub/pure-ftpd
(master, slow)
ftp://ftp2.fr.pureftpd.org/pub/mirrors/ftp.fr.pureftpd.org/pub/pure-ftpd (T-Online, fast)
(OAV / Cable&Wireless FR, fast)
ftp://ftp3.fr.pureftpd.org/pub/pure-ftpd
ftp://ftp.nl.pureftpd.org/pub/pure-ftpd
(WideXS NL, fast)
ftp://ftp.dk.pureftpd.org/mirrors/pure-ftpd
(Sunsite DK mirror, fast)
(Chinese mirror)
ftp://ftp.cn.pureftpd.org/pub/pureftpd/pure-ftpd
ftp://ftp.es.pureftpd.org/mirror/pureftpd/latest
(Spanish mirror, fast)
New mirrors are always welcome.
Korean RPM binary files are available from (thanks to Im Eunjea): http://kldp.org/~eunjea
QNX port is available from:
http://www.me.iitb.ac.in/~mritun
http://mritun.qnx.org.ru
http://www.qnxzone.com/~mritun
If you have question, suggestions or patches, feel free to post them to the mailing list. Newbies and silly
ideas are welcome.
Thank you, -Frank DENIS "Jedi/Sector One" [email protected].
* Please also read the CONTACT file
Page 40 of 110
Notes for Debian users
Thanks to Stefan Hornburg, there are now official and maintained packages for Pure-FTPd in Debian unstable,
available from your preferred repository.
Currently available packages are :
- pure-ftpd
- pure-ftpd-common
- pure-ftpd-ldap
- pure-ftpd-mysql
Have fun with apt-get and please report any bug in order to improve these packages.
These packages are also available from your favorite Pure-FTPd mirror in the "debian" directory.
Snapshots are usually available for testing from the following sources :
(woody) deb http://debian.cobolt.net/ pure-ftpd-test main
(sid) deb http://debian.cobolt.net/ pure-ftpd-sid main
Page 41 of 110
Page 42 of 110
Using Pure-FTPd with LDAP
If you never heard about LDAP before, *DON'T* enable LDAP support in Pure-FTPd. LDAP is useless if you
don't have to manage many shared accounts. But well... if you want to learn about LDAP anyway, here's a good
starting point: http://www.openldap.org
1.
LDAP SUPPORT
Since release 0.95, Pure-FTPd has a built-in support for LDAP directories.
When LDAP is enabled, all account info is fetched from a central LDAP directory.
To compile the server with LDAP support, you first have to build and install OpenLDAP. OpenLDAP is
freely available from http://www.openldap.org and binary packages are included in many major
distributions. But if you choose a binary form, don't forget to also install the development packages if they
are available separately.
Then, configure Pure-FTPd with --with-ldap and your favorite extra gadgets:
./configure --with-ldap --with-cookie --with-throttling --with-ratios
If your LDAP libraries are installed in a special path, you can specify it like this:
./configure --with-ldap=/usr/local/openldap
In this example, headers (ldap.h and lber.h files) will be searched in /usr/local/openldap/include, while
related libraries will be searched in /usr/local/openldap/lib.
Then, install the server as usual:
make install
2.
LDAP CONFIGURATION FILE
Before running the server, you have to create a configuration file. Why a configuration file instead of simple
command-line options? you may ask. Because for security reasons, you may want to hide how to connect to
your LDAP server. And as command-line options can be discovered by local users (with 'ps auxwww' for
instance), it's more secure to use a configuration file for sensitive data. Keep the file only readable by root
(chmod 600).
Here's a sample configuration file:
LDAPServer ldap.c9x.org
LDAPPort 389
LDAPBaseDN cn=Users,dc=c9x,dc=org
LDAPBindDN cn=Manager,dc=c9x,dc=org
LDAPBindPW r00tPaSsw0rD
LDAPDefaultUID 500
LDAPDefaultGID 100
Well... the keywords should be self-explanatory, but here we go for some details anyway:
- LDAPServer is the LDAP server name (hey!) . It defaults to 'localhost'.
- LDAPPort is the connecton port. It defaults to 389, the standard port.
- LDAPBaseDN is the search starting point for users accounts. Your tree must have posixAccount objects
under that node.
Page 43 of 110
- LDAPBindDN is the DN we should bind the server for simple authentication.
If you don't need authentication (ie. anonymous users can browse that part of the LDAP directory), just
remove that line.
- LDAPBindPW is the plaintext password to bind the previous DN. The configuration file should be only
readable by root if you are using LDAPBindDN/LDAPBindPW.
- LDAPDefaultUID and LDAPDefaultGID are default values for objects without any entry for them.
- LDAPFilter is the filter to use in order to find the object to authenticate against. The special sequence \L is
replaced with the login of the user.
The default filter is (&(objectClass=posixAccount)(uid=\L)) .
- LDAPHomeDir is the attribute to get the home directory ('homeDirectory' by default)
- LDAPVersion is the protocol version to use. Version 3 is recommended and needed with OpenLDAP
servers. It is the default.
In fact, the only mandatory keyword is LDAPBaseDN. Other keywords are optional and defaults are ok for
local testing.
Save the configuration file anywhere. Let's say /etc/pureftpd-ldap.conf .
Then, you have to run the pure-ftpd command with '-l ldap:' (it's an 'ell' not a 'one') followed by the path of
that configuration file. Here's an example with tcpserver:
tcpserver -DHRl0 0 21 /usr/local/bin/pure-ftpd -l ldap:/etc/pureftpd-ldap.conf &
You can mix different authentication methods. For instance, if you want to use system (/etc/passwd)
accounts when an account is not found in a LDAP directory,
use -l ldap:/etc/pureftpd-ldap.conf -l unix
Page 44 of 110
3.
THE LDAP SCHEMA
Pure-FTPd uses the standard 'posixAccount' class to locate accounts. With OpenLDAP, that class is defined
in the 'nis' schema.
FTP login names should match 'uid' attributes of 'posixAccount' instances. When an user logs in as 'joe', the
following filter is used to locate Joe's account:
(&(objectClass=posixAccount)(uid=joe))
Here's a sample entry in LDIF format:
dn: cn=Joe,dc=rtchat,dc=com
objectClass: posixAccount
cn: Joe
uid: joe
uidNumber: 500
gidNumber: 100
homeDirectory: /home/joe
userPassword: {crypt}wl6AOU6KgWUz6
'userPassword' is the hashed password, with the system 'crypt' function, MD5, SHA, SMD5 or SSHA
digests. Modern LDAP clients should handle all, anyway (or get GQ from http://biot.com/gq/) .
SSHA is believed to be the most secure one-way hashing method, but it's also the slowest and it can be timeconsuming if you're accepting a lot of users.
Please note that a login ('uid' field) can only contains common characters:
A...Z, a...z, 0...9, -, ., _, space and ' . For security purposes, other characters are forbidden.
If you don't want to use posixAccount objects, you can edit src/log_ldap.h to customize attribute names.
Page 45 of 110
4.
EXTENDED LDAP SCHEMA (QUOTAS, THROTTLING, RATIOS)
To enable quotas, download/upload rate throttling and/or download/upload ratios, an extended LDAP
schema is needed. This modified schema also allows you to completely enable and disable users' FTP
access by simply changing the "FTPStatus" field in their LDAP entry.
Simply copy the included pureftpd.schema file to your OpenLDAP schema directory
(/usr/local/etc/openldap/schema in this example) and add the appropriate line to your slapd.conf, like so:
include
/usr/local/etc/openldap/pureftpd.schema
This schema defines a new objectClass, PureFTPdUser, which contains the *OPTIONAL* status, quota,
throttling and ratio fields as in the example below:
dn: uid=Ichiro,dc=gmo,dc=jp
objectClass: PureFTPdUser
objectClass: posixAccount
cn: Ichiro
uid: Ichiro
uidNumber: 888
gidNumber: 888
homeDirectory: /home/ichiro
userPassword: {crypt}$1$w58NLo5z$NHhr6GzSPw0qxaxs3PAaK/
FTPStatus: enabled
FTPQuotaFiles: 50
FTPQuotaMBytes: 10
FTPDownloadBandwidth: 50
FTPUploadBandwidth: 50
FTPDownloadRatio: 5
FTPUploadRatio: 1
The example is mostly self-explanatory. FTPQuotaMBytes is the quota size in megabytes.
FTPDownloadBandwidth and FTPUploadBandwidth are in KB/sec.
FTPStatus should be either "enabled" or "disabled". If the FTPStatus field exists and is set to anything
except "enabled", the user will not be permitted to log in. If the FTPStatus field does not exist, the user
*WILL* be allowed to log in as normal, to allow LDAP users without the PureFTPdUser objectClass.
There are also optional FTPuid and FTPgid attributes. If present, they will override uidNumber and
gidNumber values, so that you can have different uid/gid mapping for FTP and for other services.
Please note that all of the FTP* LDAP fields are optional for the PureFTPdUser objectClass. You can have a
user with just FTPQuotaFiles and FTPQuotaMBytes set, for example, if you only wish to enforce a quota,
but not throttle the user's bandwidth or enforce ratios.
Of course, you must make sure to enable the features you wish to use at compile time (--with-quotas, --withthrottling, --with-ratios) .
5.
ANONYMOUS USERS
If you want to accept anonymous users on your FTP server, you don't need to have any 'ftp' user in the
LDAP directory. But you need to have a system 'ftp' account on the FTP server.
Page 46 of 110
6.
ROOT USERS
If an LDAP user entry has a root (0) uidNumber and/or gidNumber, Pure-FTPd will refuse to log him in.
Without this preventive restriction, if your LDAP server ever gets compromised, the attacker could also
easily compromise the FTP server.
-Frank DENIS [email protected]
-Ben Gertzfield [email protected]
Page 47 of 110
Page 48 of 110
Notes for MacOS X users
To get Pure-FTPd authenticate against system users on MacOS X (at least since version 10.3) you need to use
PAM. In order to make PAM work you currently have to:
$ cd /usr/include
$ ln -s pam security
Then configure and build.
$ ./configure --with-pam <your other favorite options like --with-everything>
$ make install-strip
Create a /etc/xinetd.d/ftp file similar to this one:
service ftp
{
disable = no
socket_type = stream
wait = no
user = root
server = /usr/local/sbin/pure-ftpd
server_args = -A -E –lpam
groups = yes
flags = REUSE
}
Create a /etc/pam.d/pure-ftpd file:
# pure-ftpd: auth account password session
auth required pam_nologin.so
auth sufficient pam_securityserver.so
auth sufficient pam_unix.so
auth required pam_deny.so
account required pam_permit.so
password required pam_deny.so
session required pam_uwtmp.so
Restart xinetd:
$ kill -HUP $(cat /var/run/xinetd.pid)
Page 49 of 110
Page 50 of 110
Using Pure-FTPd with MySQL
If you never heard about MySQL before, *DON'T* enable MySQL support in Pure-FTPd. MySQL is useless if
you don't have to manage many shared accounts. But well... if you want to learn about MySQL anyway, here's a
good starting point: http://www.mysql.com
1.
MYSQL SUPPORT
Since release 0.99.1, Pure-FTPd has a built-in support for MySQL databases.
When MySQL is enabled, all account info is fetched from a central MySQL database.
To compile the server with MySQL support, you first have to build and install the MySQL client libraries.
MySQL is freely available from http://www.mysql.com and binary packages are included in many major
distributions. But if you choose a binary form, don't forget to also install the development packages if they
are available separately.
Then, configure Pure-FTPd with --with-mysql and your favorite extra gadgets:
./configure --with-mysql --with-cookie --with-throttling --with-ratios
If your MySQL libraries are installed in a special path, you can specify it like this:
./configure --with-mysql=/opt/mysql
In this example, headers (like mysql.h) will be searched in /opt/mysql/include and /opt/mysql/include/mysql,
while related libraries will be searched in /opt/mysql/lib and /opt/mysql/lib/mysql .
Then, install the server as usual:
make install
Page 51 of 110
2.
MYSQL CONFIGURATION FILE
Before running the server, you have to create a configuration file. Why a configuration file instead of simple
command-line options? you may ask. Because for security reasons, you may want to hide how to connect to
your MySQL server. And as command-line options can be discovered by local users (with 'ps auxwww' for
instance), it's more secure to use a configuration file for sensitive data. Keep it readable only by root (chmod
600) .
Here's a sample configuration file:
#MYSQLServer
#MYSQLPort
MYSQLSocket
MYSQLUser
MYSQLPassword
MYSQLDatabase
MYSQLCrypt
MYSQLGetPW
MYSQLGetUID
MYSQLGetGID
MYSQLGetDir
localhost
3306
/tmp/mysql.sock
root
rootpw
pureftpd
cleartext
SELECT Password FROM users WHERE User="\L"
SELECT Uid FROM users WHERE User="\L"
SELECT Gid FROM users WHERE User="\L"
SELECT Dir FROM users WHERE User="\L"
Have a look at the sample pureftpd-mysql.conf configuration file for explanations of every keyword.
Save the configuration file anywhere. Let's say /etc/pureftpd-mysql.conf .
Then, you have to run the pure-ftpd command with '-l mysql:' (it's an 'ell' not a 'one') followed by the path of
that configuration file. Here's an example with tcpserver:
tcpserver -DHRl0 0 21 /usr/local/bin/pure-ftpd -l mysql:/etc/pureftpd-mysql.conf &
You can mix different authentication methods. For instance, if you want to use system (/etc/passwd)
accounts when an account is not found in a MySQL database, use -l mysql:/etc/pureftpd-mysql.conf -l unix
Page 52 of 110
3.
TABLES STRUCTURES
Pure-FTPd is very flexible and users can be stored in any way in SQL tables.
You just have to have fields with the following info:
- The user's login.
- The user's password, in plaintext, MD5, crypt()ed or MySQL's password() format. Pure-FTPd also accepts
the "any" value for the MySQLCrypt field. With "any", all hashing functions (not plaintext) are tried.
* RECOMMENDATION: On Solaris systems and on very old C libraries, use MySQL MD5 hashing. On
all other systems, better use crypt(), which adds a salt. Avoid password() whoose hash function is rather
weak.
- The system uid to map the user to. This can be a numeric id or an user name, looked up at run-time.
- The system gid (numeric or not) .
- The home directory.
Here's a dump of a simple table to handle this:
CREATE TABLE users (
User varchar(16) NOT NULL default '',
Password varchar(64) NOT NULL default '',
Uid int(11) NOT NULL default '-1',
Gid int(11) NOT NULL default '-1',
Dir varchar(128) NOT NULL default '',
PRIMARY KEY (User)
);
Uid and Gid can be char() instead of int() if you want to use names instead of values.
Then, in the pureftpd-mysql.conf configuration file, you have to provide SQL templates to fetch the needed
info.
Let's take the previous example:
MYSQLGetPW SELECT Password FROM users WHERE User="\L"
MYSQLGetUID SELECT Uid FROM users WHERE User="\L"
MYSQLGetGID SELECT Gid FROM users WHERE User="\L"
MYSQLGetDir SELECT Dir FROM users WHERE User="\L"
For each query:
\L is replaced by the login of an user trying to authenticate.
\I is replaced by the IP address the client connected to.
\P is replaced by the port number the client connected to.
\R is replaced by the remote IP address the client connected from.
\D is replaced by the remote IPv4 address, as a long decimal number.
You can mix all of these to store info in various tables. For instance, with \I, you can have a different table
for every domain, so that joe@domain1 won't be the same account than joe@domain2 . And with \R, you
can restrict one account to one specific address.
Please note that a login can only contains common characters:
A...Z, a...z, 0...9, -, ., _, space, :, @ and ' . For security purposes, other characters are forbidden.
You can also remove uid and gid fields in your tables and use default values instead (thus saving useless
lookups) . Two directives are useful to serve that purpose: MYSQLDefaultUID and MYSQLDefaultGID.
Page 53 of 110
Obvious example:
MYSQLDefaultUID 1000
MYSQLDefaultGID 1000
Using these directives overrides MYSQLGetUID and MYSQLGetGID.
4.
PER-USER SETTINGS
Individual settings can be set for every user, using optional queries.
- MySQLGetQTAFS is the maximal number of files an user can store in his home directory.
Example:
MySQLGetQTAFS SELECT QuotaFiles FROM users WHERE User="\L"
- MySQLGetQTASZ is the maximal disk usage, in Megabytes.
Example:
MySQLGetQTASZ SELECT QuotaSize FROM users WHERE User="\L"
- MySQLGetRatioUL and MySQLGetRatioDL are optional ratios.
Example:
MySQLGetRatioUL SELECT ULRatio FROM users WHERE User="\L"
MySQLGetRatioDL SELECT DLRatio FROM users WHERE User="\L"
- MySQLGetBandwidthUL and MySQLGetBandwidthDL are optional upload and download bandwidth
restrictions. Returned values should be in KB/s.
Example:
MySQLGetBandwidthUL SELECT ULBandwidth FROM users WHERE User="\L"
MySQLGetBandwidthDL SELECT DLBandwidth FROM users WHERE User="\L"
- MySQLForceTildeExpansion is yet another optional feature, to enable "~" expansion in paths. 0 disables it
(default), 1 enables it. Only enable this if real (system) users and virtual (MySQL) users match. In all other
cases, don't enable it blindly.
5.
TRANSACTIONS
If you upgraded your tables to transaction-enabled tables, you can configure Pure-FTPd to take advantage of
transactions. That way, you can be sure that all info parsed by the server is complete even if you're updating
it at the same time.
To enable transactions, add this line:
MySQLTransactions On
Don't enable transactions on tables that still are in ISAM or MyISAM formats. Transactions are only
working with newer backends (Gemini, InnoDB, BerkeleyDB...) and in recent MySQL versions.
6.
ANONYMOUS USERS
If you want to accept anonymous users on your FTP server, you don't need to have any 'ftp' user in the
MySQL directory. But you need to have a system 'ftp' account on the FTP server.
Page 54 of 110
7.
ROOT USERS
If a MySQL user entry has a root (0) uid and/or gid, Pure-FTPd will refuse to log him in.
Without this preventive restriction, if your MySQL server ever gets compromised, the attacker could also
easily compromise the FTP server.
Security barriers are also implemented to avoid bad implications if wrong data types (eg. binary blobs
instead of plain text) are fetched with SQL queries.
-Frank DENIS [email protected]
Page 55 of 110
Page 56 of 110
Using Pure-FTPd with PostgreSQL
1.
PostgreSQL SUPPORT
When PostgreSQL is enabled, all account info is fetched from a central Potgres database.
To compile the server with PostgreSQL support, you first have to build and install the PostgreSQL client
libraries. PostgreSQL is freely available from http://www.postgresql.org and binary packages are included
in many major distributions. But if you choose a binary form, don't forget to also install the development
packages if they are available separately.
Then, configure Pure-FTPd with --with-pgsql and your favorite extra gadgets:
./configure --with-pgsql --with-cookie --with-throttling --with-ratios
If your PostgreSQL libraries are installed in a special path, you can specify it like this:
./configure --with-pgsql=/opt/pgsql
In this example, headers (like pgsql.h) will be searched in /opt/pgsql/include and /opt/pgsql/include/pgsql,
while related libraries will be searched in /opt/pgsql/lib and /opt/pgsql/lib/pgsql .
Then, install the server as usual:
make install
Page 57 of 110
2.
PGSQL CONFIGURATION FILE
Before running the server, you have to create a configuration file. Why a configuration file instead of simple
command-line options? you may ask. Because for security reasons, you may want to hide how to connect to
your PostgreSQL server. And as command-line options can be discovered by local users (with 'ps auxwww'
for instance), it's more secure to use a configuration file for sensitive data. Keep it readable only by root
(chmod 600) .
Here's a sample configuration file:
PGSQLServer
PGSQLPort
PGSQLUser
PGSQLPassword
PGSQLDatabase
PGSQLCrypt
PGSQLGetPW
PGSQLGetUID
PGSQLGetGID
PGSQLGetDir
localhost
5432
root
rootpw
pureftpd
cleartext
SELECT "Password" FROM "users" WHERE "User"='\L'
SELECT "Uid" FROM "users" WHERE "User"='\L'
SELECT "Gid" FROM "users" WHERE "User"='\L'
SELECT "Dir" FROM "users" WHERE "User"='\L'
Have a look at the sample pureftpd-pgsql.conf configuration file for explanations of every keyword.
Save the configuration file anywhere. Let's say /etc/pureftpd-pgsql.conf .
Then, you have to run the pure-ftpd command with '-l pgsql:' (it's an 'ell' not a 'one') followed by the path of
that configuration file. Here's an example with tcpserver:
tcpserver -DHRl0 0 21 /usr/local/bin/pure-ftpd -l pgsql:/etc/pureftpd-pgsql.conf &
You can mix different authentication methods. For instance, if you want to use system (/etc/passwd)
accounts when an account is not found in a PostgreSQL database,
use -l pgsql:/etc/pureftpd-pgsql.conf -l unix
Page 58 of 110
3.
TABLES STRUCTURES
Pure-FTPd is very flexible and users can be stored in any way in SQL tables.
You just have to have fields with the following info:
- The user's login.
- The user's password, in plaintext, crypt()ed format or MD5. Pure-FTPd also accepts the "any" value for the
PGSQLCrypt field. With "any", all hashing functions (not plaintext) are tried.
- The system uid to map the user to. This can be a numeric id or an user name, looked up at run-time.
- The system gid (numeric or not) .
- The home directory.
Here's a dump of a simple table to handle this:
CREATE TABLE "users" (
"User" varchar(16) NOT NULL default '',
"Password" varchar(64) NOT NULL default '',
"Uid" int(11) NOT NULL default '-1',
"Gid" int(11) NOT NULL default '-1',
"Dir" varchar(128) NOT NULL default '',
PRIMARY KEY ("User")
);
Uid and Gid can be char() instead of int() if you want to use names instead of values.
Then, in the pureftpd-pgsql.conf configuration file, you have to provide SQL templates to fetch the needed
info.
Let's take the previous example:
PGSQLGetPW
PGSQLGetUID
PGSQLGetGID
PGSQLGetDir
SELECT "Password" FROM "users" WHERE "User"='\L'
SELECT "Uid" FROM "users" WHERE "User"='\L'
SELECT "Gid" FROM "users" WHERE "User"='\L'
SELECT "Dir" FROM "users" WHERE "User"='\L'
For each query:
\L is replaced by the login of an user trying to authenticate.
\I is replaced by the IP address the client connected to.
\P is replaced by the port number the client connected to.
\R is replaced by the remote IP address the client connected from.
\D is replaced by the remote IPv4 address, as a long decimal number.
You can mix all of these to store info in various tables. For instance, with \I, you can have a different table
for every domain, so that joe@domain1 won't be the same account than joe@domain2 . And with \R, you
can restrict one account to one specific address.
Please note that a login can only contains common characters:
A...Z, a...z,0...9, -, ., _, space, :, @ and and ' .
For security purposes, other characters are forbidden.
You can also remove uid and gid fields in your tables and use default values instead (thus saving useless
lookups) . Two directives are useful to serve that purpose: PGSQLDefaultUID and PGSQLDefaultGID.
Page 59 of 110
Obvious example:
PGSQLDefaultUID 1000
PGSQLDefaultGID 1000
Using these directives overrides PGSQLGetUID and PGSQLGetGID.
4.
PER-USER SETTINGS
Individual settings can be set for every user, using optional queries.
- PGSQLGetQTAFS is the maximal number of files an user can store in his home directory.
Example:
PGSQLGetQTAFS SELECT "QuotaFiles" FROM "users" WHERE "User"='\L'
- PGSQLGetQTASZ is the maximal disk usage, in Megabytes.
Example:
PGSQLGetQTASZ SELECT "QuotaSize" FROM "users" WHERE "User"='\L'
- PGSQLGetRatioUL and PGSQLGetRatioDL are optional ratios.
Example:
PGSQLGetRatioUL SELECT "ULRatio" FROM "users" WHERE "User"='\L'
PGSQLGetRatioDL SELECT "DLRatio" FROM "users" WHERE "User"='\L'
- PGSQLGetBandwidthUL and PGSQLGetBandwidthDL are optional upload and download bandwidth
restrictions. Returned values should be in KB/s.
Example:
PGSQLGetBandwidthUL SELECT "ULBandwidth" FROM "users" WHERE "User"='\L'
PGSQLGetBandwidthDL SELECT "DLBandwidth" FROM "users" WHERE "User"='\L'
5.
ANONYMOUS USERS
If you want to accept anonymous users on your FTP server, you don't need to have any 'ftp' user in the
PGSQL directory. But you need to have a system 'ftp' account on the FTP server.
Page 60 of 110
6.
ROOT USERS
If a PGSQL user entry has a root (0) uid and/or gid, Pure-FTPd will refuse to log him in.
Without this preventive restriction, if your PGSQL server ever gets compromised, the attacker could also
easily compromise the FTP server.
Security barriers are also implemented to avoid bad implications if wrong data types (eg. binary blobs
instead of plain text) are fetched with SQL queries.
Hint:
PostgreSQL supports views and it's common practice to define a new DB user, e.g., ftpd and a view of the
'real' user database with just the bits that the server needs. E.g., if you have virtual domains you could use:
create view vftpd as select u.vuser, u.domain, u.passwd, d.uid, d.gid,
'/virtual/' || u.domain || '/' || u.vuser || '/./' as homedir
from vusers as u, vdomains as d where u.domain = v.domain;
grant select on vftpd to ftpd;
The definition of homedir shows how views can be used to enforce a canonical form for home directories nothing short of defining this view will allow a user to drop the chroot from their home directory.
Page 61 of 110
Page 62 of 110
How to add an SSL/TLS encryption layer
1.
SSL/TLS SUPPORT
Starting with version 1.0.16, Pure-FTPd has experimental support for encryption of the control channel
using SSL/TLS security mechanisms.
When this extra security layer is enabled, login and passwords are no more sent cleartext. Neither are other
commands sent by your client nor replies made by the server.
However, the data channel is not affected by SSL/TLS. This combination brings no significant decrease of
performance and the FXP protocol keeps working even when mixing SSL/TLS-enabled and non SSL/TLSenabled servers.
2.
COMPILATION
To support SSL/TLS, the OpenSSL library must already be installed on your system. This is a common
requirement so your operating system probably already ships with it.
Pure-FTPd also has to be configured with the --with-tls switch before compilation :
./configure --with-tls ...
make install-strip
If something goes wrong, try to bring your OpenSSL library up-to-date.
Using at least version 0.9.6 is strongly advised, not only for full compatibility with Pure-FTPd, but also
because there are known vulnerabilities in previous versions of the library.
If your system does not have a working randomness device like /dev/srandom, /dev/arandom or
/dev/random, please have a look at the OpenSSL FAQ in order to properly seed the PRNG for your
operating system.
Page 63 of 110
3.
CERTIFICATES
To use SSL/TLS, you must provide a file called /etc/ssl/private/pure-ftpd.pem with a private key for your
host and the related certificate.
The location can be changed at compile-time with the --with-certfile option passed to ./configure.
A certificate is similar to an identity card. You fill a form with a set of personal info, then you have some
trusted third-party bash an official stamp onto it to confirm its validity.
If you already have an SSL certificate for another service on the same host (commonly for HTTPS), you can
use it as well with Pure-FTPd and other SSL-enabled services.
If you don't have any certificate, you have to get one. Make a Google search for "SSL certificates" to find
authorities that will sell you certificates with valid "official" signatures.
Once you have a valid and stamped certificate, clients will usually be able to connect to your host with no
further question.
You can also avoid these third-party authorities and put your own stamp. You will get a so called "selfsigned certificate".
With a self-signed certificate, only you can tell whether the certificate is valid or not. If bad dudes are able
to take on your server (ex: man-in-the middle attacks), clients won't notice. Also some client software will
ask the user whether he's willing to accept your certificate.
On the other hand, self-signed certificates are free and ready to serve.
To summarize : if you are an ISP, buy a certificate or lousy customers will call your support before clicking
on "accept this certificate". If you are paranoid, if a man-in-the-middle attack would be a disaster for your
business and if you don't trust the hops between clients and servers, buy a certificate. Or better, use ssh. In
all other cases, a self-certificate is probably good enough.
To create a self-signed certificate, you can use the following commands :
mkdir -p /etc/ssl/private
openssl req -x509 -nodes -newkey rsa:1024 -keyout
/etc/ssl/private/pure-ftpd.pem \
-out /etc/ssl/private/pure-ftpd.pem
chmod 600 /etc/ssl/private/*.pem
In this example, 1024 is the number of bits used for authentication. In some countries, using or exporting
keys whoose size is more than 512 bits is prohibited. Take care of this. There's no need to use huge keys
either. A key of 1024 bits is considered extremely secure. And to be fair, even a 512 bits key is extremely
long to brute-force with standard hardware.
Here's what the /etc/ssl/private/pure-ftpd.pem should look like :
Page 64 of 110
-----BEGIN RSA PRIVATE KEY----MIICXQIBAAKBgQC+KU+laUdHceXk4ZWSH5nFJPd/TJjpZVuVgZ5FuS2/mkof8kOV
AoGBAIh2MNetAx+8FpP3ZlRkJP8alhleKGVk/SH+0EuMpZ3XtNXUDrf5QU96FLlf
rx0bLVWBq6mahgWTPVi25W9FFaQa83dLuizUcncCsF5sjbibXyT+f+r5KdcSi4Qv
YgI4fCvpDje5mSUj6zKESho+3fAfo9nt1XU+iHT/bPdDOCfBAkEA5JX5QVdoRTmr
h+NN7wjayTCJBxEe+Q8RSccF/NnnShKIpY8CqKOOhWCKRZ1dWYXPM7u55wyrkpNf
FgOGJl/TMJqfdLvWD70S2aG1EQ3La+KF1joT2oWQE6M6QLhdMh9ReKQqKoECQQCG
lGU5qG0TrQJBANT3od0sX87IXI1lQ7LTqAk+jcLCmLi5RK6mY6i1fklyjKj5Ym8i
qKyUVqMfdCyeLIotZFlJ2y3jSa+c0uLu+qNLYFhv0YsLxlxB4Dft4UmzIdFzudbn
jBjrk71j3uxNK8huKNgGNCOOJhFaM6dBMQQJBrRQTFkWO5YXIu5RKF/AhQIDAQAB
r1UtzLiXtS0dn4IElkGBqE+7DXmZxDRzuzkCQDHkCeMZEMkLLUUbd4cUh6why8af
rA20klIHrlYwp9+2nve82MzGY0Q2Shovo1KUJik1AvYGCNYBh1p+r9asyGqum/P5
QTNPO1GXEb9ErUMQtDqpAkA0XlRHrYWZ+qFByBvsLgJY4L151DblcQ0xuC9qrn67
SwWH5WI9d0CffE30Ab1VpDnzKRn1ncBfvh3GIdLBgtjy
-----END RSA PRIVATE KEY---------BEGIN CERTIFICATE----MIICoDCCAgmgAwIBAgIBADANBgkqhkiG9w0BAQQFADBFMQswCQYDVQQGEwJBVTET
MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ
dHkgTHRkMB4XDTAzMDcyMDEzMzQyOFoXDTAzMDgxOTEzMzQyOFowRTELMAkGA1UE
wNr5m+Tnh4ad8OzT/XycKl4HJA0wbQYDVR0jBGYwZIAUwNr5m+Tnz4ad8OzT/Xyc
BhMCQVUxEzARBgNVBAgTXlNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdp
ZGdpdHMgUHR5IEx0ZDCBnzANBgkqhkig9w0BAQEFAAOBjQAwgYkCgYEAvilPpWlH
R3Hl5OGVkh+ZxST3f0yY6WVblYGeRbktv5pKH/JDlaislFajH3QsniyKLWRZSdst
40mvnNLi7vqjS2BYb9GLC8ZcQeA37eFJsyHRc7nW54wY65O9Y97sTSvIbijYBjQj
jiYRWjOnQTEECQa0UExZFjuWFyLuUShfwIUCAwEAAaOBnRCBnDAdBgNVHQ4EFgQU
/zANBgkqhkiG9w0BAQQFAAOBgQAD6Wv8wvy+cbNdhrH/3kdsCX6BzP63xrI81XHO
Kl4HJA2hSaRHMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEw
HwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGSCAQAwDAYDVR0TBAUwAwEB
rCDQ6/tnrrLfjhjMGPWt1NZ1EG6KvMa4Qt9Jd2GnKRn5aOFqiVl1efB7XOeK9XeN
kTjc03V3gg1ls+UMGxaUsFJsD5Y5PpETeWQz1NQW4DK5k7Sr/2+6eEmfXk8YTvKR
QZ2/xw==
-----END CERTIFICATE----Note: theorically, a client should always connect using a valid, verifiable certificate. In the real world this is
rarely the case. Most clients just use invalid certificates. It's why Pure-FTPd doesn't require client
certificates to be valid, but if you absolutely need this feature and you know what you are doing, define the
REQUIRE_VALID_CLIENT_CERTIFICATE macro before compiling the server.
If you changed the installation prefix when pure-ftpd was compiled, the certificate must be in the <prefix
sysconf dir>/ssl/private/pure-ftpd.pem file.
Page 65 of 110
4.
ACCEPTING TLS SESSIONS
Once the certificate has been installed, you need to start a TLS-enabled pure-ftpd daemon
with the -Y (or --tls=) switch. Example :
/usr/local/sbin/pure-ftpd --tls=1 &
- With "--tls=0", support for SSL/TLS is disabled. This is the default.
- With "--tls=1", clients can connect either the traditional way or through an SSL/TLS layer.
- With "--tls=2", cleartext sessions are refused and only SSL/TLS compatible clients are accepted.
When SSL/TLS has been successfully negociated for a connection, you'll see something similar to this in
log files :
<<
SSL/TLS: Enabled TLSv1/SSLv3 with DES-CBC3-SHA, 168 secret bits cipher
>>
A cipher using traditional algorithms with a 40 bits key is weak but exportable to almost any country. This is
the minimum size accepted by the server, else a "Cipher too weak" error message will be logged and
reported to the client.
Page 66 of 110
5.
COMPATIBLE CLIENTS
Pure-FTPd was reported to be fully compatible with the following clients with the SSL/TLS encryption
layer turned on :
* CoreFTP Lite (Windows)
URL: http://www.coreftp.com
SSL/TLS perfectly works when "AUTH TLS" is enabled. CoreFTP Lite has some neat features like IPv6
support, remote file searching, .htaccess editing, queueing, bandwidth control, etc.
CoreFTP Lite is free both for personnal and business use, but people who want to register in order to get the
enhanced (non-"lite") version and commercial support can get a special discount for Pure-FTPd users,
through this secret link :
http://www.2checkout.com/cgi-bin/ccbuyers/purchase.2c?sid=62821&product_id=9&quantity=1
* SmartFTP (Windows)
URL: http://www.smartftp.com
An excellent client with IPv6 support, port range limitation and other useful features (!= bloat) . And it's free
for personal, educational and non-commercial use. And it detects Pure-FTPd :)
SSL/TLS perfectly works when the "FTP over SSL (explicit)" protocol is selected and when the data
connection mode (Tools->Settings->SSL) is set to "clear data connection" while the AUTH mode (also in
Tools->Settings->SSL) is set to "TLS".
* IglooFTP Pro (Windows, Linux)
URL: http://www.iglooftp.com
SSL/TLS is automatically detected and works when Preferences->Security->Encrypt is set to "Commands
[if possible], Transfers [if possible]".
* FlashFXP (Windows)
URL: http://www.flashfxp.com
SSL/TLS works. In the "Quick connect" dialog box, pick the "SSL" tab and :
- enable Auth TLS
- disable Secure File Listing
- disable Secure File Transfers
* SDI FTP (Windows)
URL: http://www.sdisw.com
SSL/TLS works. In the "Connection" tab, just pick "SSL Support: TLSv1".
* LFTP (Unix, MacOS X)
URL: http://lftp.yar.ru
SSL/TLS is automatically detected and works out of the box.
* FTPTLS (OpenBSD, possibly other Unices as well)
URL: http://www-user.tu-chemnitz.de/~grmo/ftptls
Port: http://www-user.tu-chemnitz.de/~grmo/ftptls/port/ftptls-port.tar.gz
This is the OpenBSD's default FTP client with TLS support merged in. It perfectly works with Pure-FTPd
with no special tuning.
Page 67 of 110
* Glub Tech Secure FTP Client (at least Unix, MacOS X and Windows)
URL: http://secureftp.glub.com
SSL/TLS is automatically detected and works out of the box.
* Transmit (MacOS X)
http://www.panic.com/transmit/index.html
SSL/TLS was reported to properly work with Pure-FTPd.
The following clients are _not_ compatible with Pure-FTPd's TLS :
* WS_FTP Pro 8
Only the old authentication scheme (AUTH SSL) seems to be implemented, the recommended one (AUTH
TLS) is missing.
Workaround: none.
* FTP Voyager 9
No support for AUTH TLS.
Page 68 of 110
Creating local indexed FTP-only accounts
1.
VIRTUAL USERS
Since release 0.99.2, Pure-FTPd supports virtual users.
Virtual users is a simple mechanism to store a list of users, with their password, name, uid, directory, etc. It's
just like /etc/passwd. But it's not /etc/passwd. It's a different file, only for FTP.
It means that you can easily create FTP-only accounts without messing up your system accounts.
Additionnaly, virtual users files can store individual quotas, ratios, bandwidth, etc. System accounts can't do
this.
Thousands of virtual users can share the same system user, as long as they all are chrooted and they have
their own home directory.
So a good thing to do before using virtual users is to create a system user for this. Of course, you can use
any existing account like "nobody" (but not root), but it's better to have a dedicated account.
Let's create an "ftpgroup" group and an "ftpuser" user.
Linux/OpenBSD/NetBSD/Solaris/HPUX/a lot of other Unix-like systems:
groupadd ftpgroup
useradd -g ftpgroup -d /dev/null -s /etc ftpuser
FreeBSD:
pw groupadd ftpgroup
pw useradd ftpuser -g ftpgroup -d /dev/null -s /etc
Then, all maintenance of virtual users can be made with the "pure-pw" command. You can also edit the files
by hand if you want.
Files storing virtual users have one line per user. These lines have the following syntax:
<account>:<password>:<uid>:<gid>:<gecos>:<home directory>:<upload bandwidth>:
<download bandwidth>:<upload ratio>:<download ratio>:<max number of connections>:
<files quota>:<size quota>:<authorized local IPs>:<refused local IPs>:
<authorized client IPs>:<refused client IPs>:<time restrictions>
Fields can be left empty (exceptions: account, password, uid, gid, home directory) .
Passwords are compatible with the hashing function used in /etc/passwd or /etc/master.passwd . They are
crypto hashed with blowfish, md5, multiple-des and simple des, in this order, according to what your system
has support fort.
Page 69 of 110
2.
CREATING A NEW USER
To add a new user, use the following syntax:
pure-pw useradd <login> [-f <passwd file>] -u <uid> [-g <gid>]
-D/-d <home directory> [-c <gecos>]
[-t <download bandwidth>] [-T <upload bandwidth>]
[-n <max number of files>] [-N <max Mbytes>]
[-q <upload ratio>] [-Q <download ratio>
[-r <allow client host>[/<mask>][,<allow client host>[/<mask>]]...]
[-R <deny client host>[/<mask>][,<deny client host>[/<mask>]]...]
[-i <allow local host>[/<mask>][,<allow client host>[/<mask>]]...]
[-I <deny local host>[/<mask>][,<deny local host>[/<mask>]]...]
[-y <max number of concurrent sessions>]
[-z <hhmm>-<hhmm>] [-m]
Let's create "joe", whoose home directory will be /home/ftpusers/joe . The system account associated with
"joe" is "ftpusers".
pure-pw useradd joe -u ftpuser -d /home/ftpusers/joe
Joe's password is asked twice.
With -d, joe will be chrooted.
If you want to give joe access to the whole filesystem, use -D instead of -d.
You don't need to create /home/ftpusers/joe if you run pure-ftpd with the -j (--createhome) switch. With that
switch, home directories will automatically be created when users will log in for the first time.
The "-z" option allow an user to connect only during a range of day time. For instance, with -z 0900-1800,
joe will only be able to connect from 9 am to 18 pm. Warning: an user that connected during authorized
hours can finish his session after these authorized hours.
-r and -R are handy to restrict where the user can connect from. They can be followed by a simple IP/mask
pair (-r 192.168.1.0/24),
multiple pairs separated by a coma (-r 192.168.1.0/24,10.1.0.0/16,127.0.0.1/32),
single IPs (-r 192.168.1.4,10.1.1.5), host names (-r bla.bla.net,yopcitron.com),
or anycombination of those.
-y is to restrict the number of concurrent sessions an user can have at the same time. '' or 0 mean unlimited.
Avoid this feature on very loaded servers. Use per-ip limits instead.
Ok, "joe" has been created. By default, the list of virtual users is stored in the /etc/pureftpd.passwd file (you
can of course change this with –f <file>) .
Let's have a look at its content:
joe:$1$LX/3.F60$bYdYwsQOYIaWq.Ko.hfI3.:500:101::/home/ftpusers/joe/./:::::::::::::
Passwords are hashed with the best one-way hash function your system supports.
Hashes are tried in this order: Blowfish, MD5, multiple DES, simple DES.
Page 70 of 110
3.
CHANGING INFO
Once virtual users have been created, you can edit their info. For instance you can add bandwidth throttling,
change quotas, add their full name, update ratio, etc.
The "pure-pw usermod" command works just like "pure-pw useradd" except that it modifies an existing
account instead of creating a new one.
For instance, we will add a quota to Joe. Joe should be limited to 1000 files and 10 Megabytes.
pure-pw usermod joe -n 1000 -N 10
Let's have a look at /etc/pureftpd.passwd:
joe:$1$LX/3.F60$bYdYwsQOYIaWq.Ko.hfI3.:500:101::/home/ftpusers/joe/./::::::1000:10485760::::::
As you can see, the size quota is stored in bytes in the file.
4.
RESETTING ATTRIBUTES
To disable file quotas, use pure-pw usermod <user> -n ''
To disable size quotas, use pure-pw usermod <user> -N ''
To disable ratios, use pure-pw usermod <user> -q '' -Q ''
To disable download bandwidth throttling, use pure-pw usermod <user> -t ''
To disable upload bandwidth throttling, use pure-pw usermod <user> -T ''
To disable IP filtering, use pure-pw usermod <user> <-i,-I,-r or -R> ''
To disable time restrictions, use pure-pw usermod <user> -z ''
To disable the number of concurrent sessions, use pure-pw usermod <user> -y ''
5.
DELETING USERS
We won't delete Joe at this time. Joe is a fine guy :) But FYI, deleting an user is as simple as running "purepw userdel", whoose syntax is:
pure-pw userdel <login> [-f <passwd file>] [-m]
Deleting Joe would be:
pure-pw userdel joe
The content of his home directory is kept. Delete it by hand if you want.
6.
CHANGING PASSWORDS
To change the password of an user, use "pure-pw passwd":
pure-pw passwd <login> [-f <passwd file>] [-m]
Page 71 of 110
7.
DISPLAYING INFO
To review info about one user, reading the /etc/pureftpd.passwd file is ok, but it's not really human-friendly.
It's why you can use "pure-pw show", whoose syntax is:
pure-pw show
<login> [-f <passwd file>]
Let's try with joe:
pure-pw show joe
Login
: joe
Password
: $1$LX/3.F60$bYdYwsQOYIaWq.Ko.hfI3.
UID
: 500 (ftpuser)
GID
: 101 (ftpgroup)
Directory
: /home/ftpusers/joe/./
Full name
:
Download bandwidth : 0 Kb (unlimited)
Upload bandwidth : 0 Kb (unlimited)
Max files
: 1000 (enabled)
Max size
: 10 Mb (enabled)
Ratio
: 0:0 (unlimited:unlimited)
Allowed local IPs :
Denied local IPs :
Allowed client IPs : 192.168.0.0/16
Denied client IPs : 192.168.1.1,blah.verybadhost.com
Time restrictions : 0900-1800 (enabled)
Max sim sessions : 0 (unlimited)
"/./" at the end of a home directory means that this user will be chrooted.
Page 72 of 110
8.
COMMITING CHANGES
IMPORTANT:
You can add, modify and delete users with the previous commands, or by editing /etc/pureftpd.passwd by
hand. But the FTP server won't consider the changes you make to that file, until you commit them.
Commiting changes really means that a new file is created from /etc/pureftpd.passwd (or whatever file name
you choose) . That new file is a PureDB file. It contains exactly the same info than the other file. But in that
file, accounts are sorted and indexed for faster access, even with thousands of accounts. PureDB files are
binary files, don't try to view them or your terminal will beep like hell.
Let's create a PureDB file from /etc/pureftpd.passwd. The indexed file will be called /etc/pureftpd.pdb (as
always, choose whatever name you like):
pure-pw mkdb
this reads /etc/pureftpd.passwd and creates /etc/pureftpd.pdb by default, but to read another file, add the pdb
file, optionnaly followed by -f <passwd file>
For instance:
pure-pw mkdb /etc/accounts/myaccounts.pdb -f /etc/accounts/myaccounts.txt
All modifications you made to the virtual users database will be committed atomatically: all new accounts
will be activated at the same time and all deleted users won't be able to log in as soon as you'll have hit the
Return key.
There's no need to restart the pure-ftpd server to commit changes.
You can also change something to the text passwords file (add users, change password, delete users, etc) and
automatically run "pure-pw mkdb /etc/pureftpd.pdb" afterwards. To do so, just use the –m switch:
pure-pw passwd joe –m
This command will change Joe's password in pureftpd.passwd *and* commit the change to
/etc/pureftpd.pwd .
9.
ENABLING VIRTUAL USERS
Of course, to use virtual users, you have to enable their support in the FTP server itself. At compile-time,
this is done by giving --with-puredb to ./configure (--with-everything also enables it and binary packages
have it compiled in) .
Then, add this switch to your usual pure-ftpd switches:
-l puredb:/path/to/puredb_file
If long options are enabled, you can also use --login instead of -l .
Let's run the server with automatic creation of home directories and puredb authentication:
/usr/local/sbin/pure-ftpd -j -lpuredb:/etc/pureftpd.pdb &
Try to 'ftp localhost' and log in as joe.
Page 73 of 110
10.
CONVERTING SYSTEM ACCOUNTS
You can convert all system (/etc/passwd) accounts to virtual FTP users,
with the "pure-pwconvert" tool.
Just run it:
pure-pwconvert >> /etc/pureftpd.passwd
If you do it as a non-privileged user, passwords won't be filled in. If you do it as root, everything will be
copied, even hashed passwords.
Copying system accounts to FTP accounts makes sense, because that way, users can use different passwords
for FTP and for Telnet access.
11.
ENVIRONNEMENT VARIABLES
If defined, a PURE_PASSWDFILE environment variable can set the default path to the pureftpd.passwd
file. Without this variable, it defaults to /etc/pureftpd.passwd .
If defined, a PURE_DBFILE environment variable can set the default path to the pureftpd.pdb file. Without
this variable, it defaults to /etc/pureftpd.pdb .
Page 74 of 110
How to write custom authentication handlers
1.
AUTHENTICATION MODULES
Since release 1.0.8, anyone can add new custom authentication methods to Pure-FTPd without recompiling
anything, using "authentication modules".
To enable it, you must ./configure with --with-extauth, or --with-everything. Linux binary packages have it
enabled by default.
Here's how they are working:
1) A client connects to the FTP server and issues a login/password pair.
2) The FTP server connects to a local separate daemon, called 'pure-authd'.
Data transmitted to that daemon is: user's login, user's password, the IP address that
user connected to, the local port that user connected to and the user's remote IP address.
3) pure-authd spawns an authentication program. It can be anything, including a shell
script. The program is given the collected info (login, password, IP addresses, etc)
as environment variables.
4) The authentication program replies (to the standard output) with the user's home
directory, quota, ratio, bandwidth and if authentication was successful or not.
5) pure-authd relays this info to pure-ftpd.
This method is a bit slower than built-in authentication methods. But it's very flexible as anyone can easily
write his own authentication programs. And they can run non-root, chrooted, with limited capabilities, etc.
Communication between pure-ftpd and pure-authd is done through a local Unix socket. It's recommended to
put that socket in a directory where non-trusted users have no write access to.
Authentication programs can read the following environment variables to get info about the user trying to
authenticate:
AUTHD_ACCOUNT
AUTHD_PASSWORD
AUTHD_LOCAL_IP
AUTHD_LOCAL_PORT
AUTHD_REMOTE_IP
They are self-explanatory. Previous global environment variables aren't cleared when the script is called.
The content of these variables is _not_ quoted. If you are using shell scripts to process them, don't forget the
quotes.
The program must respond on the standard output with lines like:
auth_ok:1
uid:42
gid:21
dir:/home/j
end
Note the final 'end' keyword. It's mandatory.
Page 75 of 110
Here's the list of recognized tokens ('xxx' has of course to be filled):
* auth_ok:xxx
If xxx is 0, the user was not found (the next authentication method passed to pure\-ftpd will be tried) . If xxx
is \-1, the user was found, but there was a fatal authentication error: user is root, password is wrong, account
has expired, etc (next authentication methods will not be tried) . If xxx is 1, the user was found and
successfully authenticated.
* uid:xxx
The system uid to be assigned to that user. Must be > 0.
* gid:xxx
The primary system gid. Must be > 0.
* dir:xxx
The absolute path to the home directory. Can contain /./ for a chroot jail.
*slow_tilde_expansion:xxx (optional, default is 1)
When the command 'cd ~user' is issued, it's handy to go to that user's home directory, as expected in a shell
environment. But fetching account info can be an expensive operation for non-system accounts. If xxx is 0,
'cd ~user' will expand to the system user home directory. If xxx is 1, 'cd ~user' won't expand. You should
use 1 in most cases with external authentication, when your FTP users don't match system users. You can
also set xxx to 1 if you're using slow nss_* system authentication modules.
* throttling_bandwidth_ul:xxx (optional)
The allocated bandwidth for uploads, in bytes per second.
* throttling_bandwidth_dl:xxx (optional)
The allocated bandwidth for downloads, in bytes per second.
*user_quota_size:xxx (optional)
The maximal total size for this account, in bytes.
* user_quota_files:xxx (optional)
The maximal number of files for this account.
* ratio_upload:xxx and radio_download:xxx (optional)
The user must match a ratio_upload:ratio_download ratio.
* per_user_max:xxx (optional)
The maximal authorized number of concurrent sessions.
Page 76 of 110
2.
EXAMPLE
Here's a very basic example. Our sample authentication program will only accept user 'john' with any
password and return a fixed home directory and uid/gid.
#! /bin/sh
if test "$AUTHD_ACCOUNT" = "john"; then
echo 'auth_ok:1'
echo 'uid:69'
echo 'gid:42'
echo 'dir:/tmp'
echo 'end'
else
echo 'auth_ok:0'
fi
Let's say we save this file as /usr/bin/ftp-auth-handler
Now, we have to run pure-authd and pure-ftpd, to connect them through a local socket and to tell pure-ftpd
to use our external authentication module:
pure-authd -s /var/run/ftpd.sock -r /usr/bin/ftp-auth-handler &
pure-ftpd -lextauth:/var/run/ftpd.sock &
That's all. Now, we can only log in as 'john', as all FTP authentication is done by the shell script.
Page 77 of 110
Page 78 of 110
Using a netfilter gateway
*** IF YOU ARE RUNNING A RECENT LINUX KERNEL (2.4.3ac14, 2.4.4 and ***
*** later) FOR FIREWALL/MASQUERADING , YOU DON'T NEED TO READ THIS ***
*** DOCUMENT. ALSO, BSD SYSTEMS RUNNING IPFILTER AREN'T CONCERNED. ***
Linux kernel 2.4 has a nice built-in NAT/firewalling code called Netfilter. This new code supports connection
tracking ('stateful firewall') and is easily extensible.
But the FTP protocol itself has always been a nightmare for firewalls designers. Because the protocol isn't
complex, but... well... strange! So that it requires a special handler (especially for the 'passive mode') .
Linux kernel earlier than 2.4.4 (or 2.4.3ac14) have a partial support of the FTP protocol.
If you are trying to firewall or masquerade a Pure-FTPd server, passive connections won't work with some
modern clients like lftp. Commands like 'ls' will freeze your client and finally close the connection.
This is *NOT* a bug in Pure-FTPd, but a problem in Netfilter. Old versions of Netfilter only know a very
limited subset of the FTP protocol. They don't know about EPSV and EPRT commands, implemented in modern
FTP clients and servers. These commands superscede PASV and PORT and are IPv6 capable.
Pure-FTPd is not the only server that doesn't work with older Netfilter code. *ALL* recent BSD servers (current
OpenBSD, FreeBSD, NetBSD) are also affected. Of course you have to use a EPSV/EPRT aware client to
trigger the bug. SuSE Linux comes with NetBSD 'ftp' client that supports these commands.
Also, old linux kernels have a serious security flaw in their FTP connection tracking code. Basically, an external
user can open any filtered port if the FTP connection tracking code is enabled.
So, if you are using Linux firewalls/masquerading boxes, please upgrade their kernel as soon as possible, to the
latest 2.4 release. Even 2.4.4 kernels are rather old and they also have known bugs and vulnerabilities.
It's why upgrading is definitely something to do. And EPSV/EPRT will work.
Page 79 of 110
Page 80 of 110
How the project was born
Troll-FTPd is a nice FTP server coded by Arnt Gulbrandsen from Troll Tech. Despite his lack of popularity, it
has always been a very good project, coded with the following requirements in mind :
- No useless bloat,
- No external command calls (source of most security flaws)
- RFC standards conformance,
- Easy to set up,
- User friendly,
- Secure.
The official repository for this piece of software is ftp://ftp.troll.no/freebies/ftpd.
People who tried Troll-FTPd usually kept it and used it in production servers for years without any problem.
Alternatively, WU-FTPd, ProFTPd, BeroFTPd and many others have had serious security and reliability issues,
and system administrators had to always watch for patches and new releases to ensure a good nights sleep.
Troll-FTPd was often considered for inclusion in secure distributions, but the project was't actively maintained.
Release 1.25 is dated 03/1999 and has been made with help from Janos Farkas, [email protected], August
Fullford and Ximenes Zalteca. Troll-FTPd 1.26 was released two years after, just to fix minor bugs. Arnt said
that there won't be any other release unless he ever moves to IPv6.
This is why I started to collect various unofficial patches over the internet, merged them (and it wasn't painless),
added my own ones, cleaned up the code, audited it, repackaged it, rewrote the documentation... and the PureFTPd project was born.
The first released version of Pure-FTPd was labeled 0.90 because I wanted some margin before 1.00, just to add
missing features that prevent people from moving from other FTP servers. Also the documentation was in need
for a full update before version 1.00 . It was based on Troll-FTPd 1.25, and changes from 1.26 were backported.
Troll-FTPd 1.26 and earlier are vulnerable to a local root exploit (Troll-FTPd 1.27 was released later to fix it) .
Pure-FTPd is not vulnerable to this, and it has never been. The fix was already applied to the first version of
Pure-FTPd before the flaw was discovered and fixed in Troll-FTPd.
Thanks to Arnt for his excellent job. The Pure-FTPd project would never have been started without it.
-Frank DENIS "Jedi/Sector One" [email protected]
Page 81 of 110
Page 82 of 110
Contributors
Credits for Troll-FTPd are going to the following dudes.
* Original Troll-FTPd authors :
Arnt Gulbrandsen [email protected]
Troll Tech AS http://www.troll.no/
* Original Troll-FTPd contributors :
Janos Farkas [email protected]
August Fullford
Ximenes Zalteca
Patrick Michael Kane [email protected]
Credits for Pure-FTPd are going to the following ones.
* Michal Moskal [email protected]
* Arkadiusz Miskiewicz <[email protected]> :
IPv6 support.
Polish translation.
* Michael K. Johnson [email protected]
* Kelley Lingerfelt <[email protected]> :
PAM support.
* Sebastian Andersson <[email protected]> :
ASCII transfers.
sendfile() usage.
Capability drop.
* Andreas Westin <[email protected]> :
FXP support.
ftpwho design and reference implementation.
* The OpenBSD team (http://www.openbsd.org/)
The NetBSD team (http://www.netbsd.org/)
The Regents of the University of California :
Most of the glob() function, getopt_long() and realpath() replacements.
* The sh-utils team (ftp://alpha.gnu.org/gnu/fetish/)
getloadavg.c derivative.
* Jason Lunz <[email protected]> :
Daemonization (-B).
Get rid of -D in favor of <config.h> (thanks to Arkadiusz, too).
Fix XML output.
Official ninja warrior.
First Debian package maintainer.
Page 83 of 110
* Mathias Gumz [email protected]
German translation.
* Claudiu Costin [email protected]
Romanian translation.
KcmPureftpd author.
* Ping [email protected]
French translation.
* Paul Lasarev [email protected]
Initial Debian packages.
* Jean-Mathieux Schaffhauser [email protected]
Web page logo.
GTK configuration interface.
* Emmanuel Hocdet [email protected]
Nice bug fixes (config file parsers, replycmd) and suggestions.
* Peter Pentchev [email protected]
Integration to the FreeBSD port collection and FreeBSD improvements.
build.sh improvements.
* Luis Llorente Campo [email protected]
Spanish translation.
* Sami Koskinen [email protected]
Open a session when using PAM.
* Matthias Andree [email protected]
-1 option.
A lot of code cleanups and robustness fixes.
Documentation cleanups.
Solaris < 8 portI
Fixed Solaris large file support.
* Trilucid (http://www.trilucid.com/)
Web design of pureftpd.org .
* Isak Lyberth [email protected]
Danish translation.
Page 84 of 110
* Bernhard Weisshuhn [email protected]
Spec file fixes.
Fixes to the german translation.
* Steve Reid [email protected]
Original SHA1 implementation.
* RSA Data Security, Inc. (http://www.rsa.com/)
Original MD5 implementation.
* Dmitry Lebkov
MD5/SHA1 LDAP authentication.
* Sami Farin [email protected]
A lot of code cleanups.
* Johan Huisman [email protected]
* Jan van Veen [email protected]
Dutch translation.
* Thorsten Kukuk [email protected]
LFS fixes.
RPM fixes.
* Stefano F. <[email protected]> :
* Alex Dupre <[email protected]> :
Italian translation.
* Roger Constantin Demetrescu [email protected]
Brazilian Portugese translation.
* Freeman <[email protected]> :
"Powered by Pure-FTPd" web button.
* Robert Varga <[email protected]> :
Slovak translation.
* James Metcalf <[email protected]> :
Complete review of the english doc.
* Im Eunjea <[email protected]> :
Korean translation.
Page 85 of 110
* Philip Gladstone <[email protected]> :
PureDB speedups.
* Kenneth Stailey <[email protected]> :
Support for load average checks on Solaris.
Directory aliases.
HPUX support.
sendfile() support on HPUX and Solaris.
* Brad Smith <[email protected]> :
Maintainer of the OpenBSD port.
* Cindy Marasco <[email protected]> :
PostgreSQL support.
* Ulrik Sartipy <[email protected]> :
Swedish translation.
* Nicolas Doye :
Support for MD5 hashed passwords in MySQL.
* Thomas Briggs <[email protected]> :
Implementation of the W3C logfile format.
Helped with Tru64 portability.
* Stanton Gallegos
MacOS X maintainer (see http://fink.sourceforge.net/) .
* Florin Andrei <[email protected]>
Chan Wilson [email protected]
Implemented load average check on Irix systems.
* Bjoern Metzdorf [email protected]
Merged MD5/any hash functions for passwords in the PgSQL backend.
* Ben Gertzfield [email protected]
Implemented the extended LDAP schema to support quotas, throttling and ratios.
* Akhilesch Mritunjai [email protected]
Maintainer of the QNX port.
* Dawid Szymanski [email protected]
Maintainer of the NetBSD port.
Page 86 of 110
* Kurt Inge Smådal / EasyISP.org [email protected]
Norwegian translation.
* Gabriele Vinci [email protected]
Official logo artwork.
* Andrey Ulanov [email protected]
Russian translation.
* Fygul Hether [email protected]
Traditional and simplified Chinese translations.
* Jeffrey Lim [email protected]
A lot of excellent documentation improvements.
* Ying-Chieh Liao [email protected]
FreeBSD fixes for pure-mrtginfo.
* Johannes Erdfelt [email protected]
Fix error when deleting files with an absolute directory when quotas are enabled.
RPM spec file improvements.
* Martin Sarfy [email protected]
Czech translation.
* Clive Goodhead [email protected]
Implement MYSQLDefaultGID and MYSQLDefaultUID.
* Aristoteles Pagaltzis [email protected]
pure-config.pl rewrite.
* Stefan Hornburg [email protected]
Debian maintainer.
* Mehmet Cokcevik [email protected]
Turkish translation.
* Frank DENIS aka Jedi/Sector One <[email protected]> :
Pure-FTPd project initiator and maintainer.
Almost everything else :)
Original license :
Copyright 1995-2000 Trolltech AS. Copyright 2001-2002 Arnt Gulbrandsen.
Use, modification and distribution is allowed without limitation, warranty, or liability of any kind.
Page 87 of 110
Page 88 of 110
Greetings
A big *THANK YOU* to all Pure-FTPd users that reported bugs, made interesting suggestions, asked relevant
questions and contributed to help us build that tiny piece of free software. If you don't see your name in the
following list, I'm awfully sorry. It's difficult to keep it up to date. But as you are reading this, you must be a
very nice guy.
1.
Forum and external contributors :
* William Kern(el panic) (thanks for your wish list)
* Sven Goldt (sorry, no plans for gtar on the fly)
* Ryan Laginski (suggested for -P feature)
* JKadilak (reported a Flash FXP feature, good for the FAQ)
* Nicolas (for all his questions)
* Guenter Bittner (suggested the umask option and reported that LeechFTP didn't parse properly the SIZE return)
* Jeff Skubick (reported that netfilter lacked EPSV/EPRT support)
* Alex Black
* Aaron Stephanic
* Florent Rushuru
* Youssef El Fathi
* Steven Radack
* M.Robbins (reported OpenLDAP 1.x compilation problem)
* Marc Dukes (xinetd configuration)
* Juergen Nagel (reported that it didn't work with old libc)
* Marcus Danielsson <[email protected]> (reported USER null deref).
* Daniel Elsaesser (suggested the -E flag and reported an AbsoluteFTP bug)
* Jobush (thanks for your suggestions)
* Simon Lyngshede (--bind thing, good for the FAQ)
* Cyberic (-k suggestion)
* Mason lee (asked for SQL support)
* Aluminiumcan (investigation of Cisco 675 NAT)
* Jason Piterak (reported the 0.97.1 passive bug)
* Martin Gerardi (proposed user-domain ACL)
* Jean-Francois Cousi (stress-testing pureftpd on production servers)
* Patrick <[email protected]> (testing the FreeBSD port)
* Gunnar Isaksson
* Shea Martin (reported the -U failure and suggested '.banner' for everyone)
* Olivier Tharan <[email protected]> (pointed out that Xinetd needs -USR2 not -HUP) .
* Jean-Philippe Le Hénaff (suggested the welcome.msg compatibility and reported ftpwho bandwidth problems).
* Erik (Cirvam, <[email protected]>) for his very nice help on the Solaris port.
* François SIMOND.
* Brian B (MrBubbs) for reporting that long-options weren't implemented on BSD systems.
* Jim Jones (suggested -f none) .
* Kelton.
* Nicklas Uvelöv.
* Alec Lanari.
* Martin Hedenfalk (reported a bug related to listing of symbolic links to directories).
* Thomas Maschutznig.
* Paul Hansen (Windward) - tracked down the syslog-in-clientfd bug and reported various logging-related issues.
* Olivier Soell.
* Peter Green (Peyote) - thanks for your bug reports and your posts.
* Dannej.
* Juan Carlos Perez.
* Matthew Hartman.
* Terry Davis - A very nice guy. He helped to fix ASCII upload issues.
* Brandon Covert - Thanks for reporting the pure-ftpwho parsing bug.
* Sacha Hoehne.
* Johan Schuld.
* Wouter de Jong [email protected]
Page 89 of 110
* Keith Vance - Thanks a lot for the Mac testing.
* Sami Farin - Thanks for reporting the bad fd CORKing in error()
* David Vincelli - Reported OpenBSD issues.
* Adrian Zurek - Suggested LDAP improvements.
* Oliver Soell <[email protected]> - RPM fixes.
* Bernhard Weisshuhn - Reported that RNTO should work with existing targets.
Corrected the german translation for grammatical/spelling errors.
* Leszek Reimus - Suggested that /./ mix with -a to get chrooted useres with no ratio.
* Trilucid ( http://www.trilucid.com ) - Web design of pureftpd.org
* Rafa Michalski - Reported broken throtting under FreeBSD.
* Juergen Henge-Ernst - Reported broken process names on Linux.
* Joe Silva (aka j03y) - Suggested adding "shadow" into PAM rules.
* John Hart - Fixed access to remote MySQL servers.
* Christian Janssen - Suggested the --createhomedir switch.
* Lan Yufeng - Reported a --createhome bug.
* Jeff Moe - Suggested --without-iplogging.
* Thomas Ericsson - Reported documentation glitches.
* Juan Pablo Gimenez - Improved the RPM package.
* Tomonori Kamitaki - Helped pure-ftpd to work on Playstation 2.
* Daniel Tschan - Thanks for reporting bugs with uploads and ReiserFS.
* Marc Jauvin - Reported an incompatibility with old MySQL versions and implemented quotas in the MySQL backend.
* Robin Ericsson - Implemented support for MySQL password() function.
* Robert Wierzbicki - Reported a typo in README.Virtual-Users.
* Ben Weir - Reported and straced a bug in pure-pw.
* Eric <[email protected]> - Reported a quota bug.
* Eric Larsson - Reported a ftpwho bug.
* Gareth Woolrdige - Fixed compilation on Corel Netwinder devices.
* Mariusz Pekala <[email protected]> - Fixed typo-errors in the polish translation.
* Paul <[email protected]> - Provided SSH access to sort out a bug with a specific glibc version.
* Benoit Massard - Suggested that dot-files should be given access even when virtual quotas are enabled.
* Jan Pavlik - Reported that .ftpquota was counted in pure-quotacheck.
* Ben Gertzfield (che_fox) - Fixed Solaris compilation and LDAP SSL dependencies.
* Pierre <[email protected]> - Reported a compilation bug with extauth.
* Mark Reidel <[email protected]> - Reported that users couldn't revert perms on a directory after they
removed read/execute access rights.
* Jose Pedro Oliveira <[email protected]> - Spec file fixes.
* Francis Little aka dj_oggy <[email protected]> - For his valuable help on Sourceforge
forums, his testing of snapshot and his helpful advices.
Thanks a lot, dude.
* iTooo <[email protected]> , for reporting a nasty typo in throttling code.
* Martin Hedenfalk (mhe) - Reported that MLST shouldn't accept any option nor multiple file names.
* Ying-Chieh Liao <[email protected]> for the FreeBSD port updates and for reporting that
simplified and traditional chinese settings were swapped in 1.0.12 .
* Kyle Herbert (http://www.firstnetimpressions.com/) for reporting a typo in the example configuration file.
* Anthony DeRobertis - Fixed the on-demand creation of home directories.
* Maharaja - Reported a typo in the README file.
* Darth Vader (freddyke) - Suggested to have consistent max user lengths.
* Axel Apitz <[email protected]> - Support for Solaris shadow/NIS.
* Yann Bizeul (projects.tynsoe.org) - Reported a Panther specific issue with getnameinfo().
Thanks a lot for providing a temporary account on a Panther machine in order to implement a workaround.
Page 90 of 110
2.
Mailing list-members :
* [email protected] (thanks for your opinion on config files and your help for CVS repositories)
* [email protected]
* [email protected] (romanian translator and great tester)
* [email protected]
* [email protected] (german translator and very nice guy)
* [email protected]
* [email protected]
* [email protected]
* [email protected]
* [email protected]
* [email protected] (thanks for helping users on the ML)
* [email protected] (who asked the rights questions for a FAQ)
* [email protected]
* [email protected] (and everyone from the PLD Linux Distribution : http://www.pld-linux.org/)
* [email protected] (who reported that accents were filtered)
* [email protected]
* [email protected]
* [email protected] (an hosting service company, moving from proftpd to pureftpd)
* [email protected]
* [email protected]
* [email protected]
* [email protected]
* [email protected] (very, very nice guy, helped the debian packaging)
* [email protected]
* [email protected]
* [email protected]
* [email protected]
* [email protected]
* [email protected]
* [email protected]
* [email protected]
* [email protected] (for your patch and your code help proposal)
* [email protected] (for reporting the bug in space parsing and suggesting webalizer patch/ftpwho/ftpcount)
* [email protected]
* [email protected]
* [email protected]
* [email protected]
* [email protected]
* [email protected] (reported the syslog bug)
* [email protected]
* [email protected]
* [email protected]
* [email protected] (suggested authenticating users on virtual hosts)
* [email protected] (thanks for reporting the --without-usernames stuff in 0.98.5pre2)
* [email protected] (very nice guy)
* [email protected]
* [email protected] (who reported how to have MSIE open an authentication dialog when
anonymous users were denied) .
* Olle <[email protected]> - reported log format error when working with webalizer
* Florin Andrei <[email protected]> - SGI Irix fixes.
* Marc Thoben <[email protected]> - SuSE init script.
* Jeffrey Koetsier <[email protected]> - Fixed MySQL documentation typo.
* Stephan Wentz <[email protected]> - Helped to solve a bad interaction with Macromedia Homesite.
* Joshua Rodman <[email protected]> - did a major rewrite of pure-config.py for reliability and maintainability.
* Michael Glad <[email protected]> - Submitted a patch to accept long .message files even on Irix.
* Gareth Blades <[email protected]> - Provided a fix for SMC Barricade routers.
* Shiroiwa Noboru <[email protected]> - Reported a bad interaction with FTP Explorer.
* Ben <[email protected]> - RPM improvements to build with SQL or LDAP.
Page 91 of 110
* Philip Mak <[email protected]> - Suggested that pure-quotacheck should be runnable as a non-root user.
* Adam Kruszewski (Fantomik) and Wojtek "elluin" Kaniewski
Pointed out an ugly fucking stupid huge bug (initgroups() called after chroot()).
* TJ Saunders <[email protected]> - Reported that Proftpd and Proftpd-modquota were different packages.
* Kittiwat Manosuthi <[email protected]> - Help with Virtuozzo.
* Henrik Edlund <[email protected]> - Suggested documentation fixes
(quoting field names) in PostgreSQL templates.
* Joerg Pulz <[email protected]> - Pointed out that upload-pipe locking didn't work with daemonization.
* John Sullivan <[email protected]> - Helped to spot a zeno effect with pure-uploadscript
in 1.0.15 snapshots when the server was started in inetd mode.
* Aaron D. Marasco <[email protected]> - Noticed an obsolete comment in pure-ftpd.conf .
* Paul F. William" <[email protected]> - Reported that Pure-FTPd compiled and worked fine on an
IBM RS/6000 system running AIX 5.2 using the Visual Age C++ Ver 6.0 compiler.
* Marshall Pierce <[email protected]> - For his tests on MacOS X.
* Shantanu <[email protected]> - For his valuable exercices in order to hands solid like steel,
ready to type billions of source code :)
* JG <[email protected]> - Reported a breakage of pure-ftpwho in version 1.0.16.
* C. Jon Larsen <[email protected]> - Wrote a nice part of the FAQ about the STOU command.
In the memory of all people dead on September 11 2001, in Manhattan and in Pennsylvania, due to braindamaged people thinking they can live in a better world by killing their fellow men.
Page 92 of 110
Windows port of Pure-FTPd
1.
WINDOWS PORT OF PURE-FTPD
Before all: Pure-FTPd was designed on Unix and for Unix. The Windows port has been done because some
people are forced to work on Win32 by their pointy hairy boss. For these people, Apache is a nice
alternative to IIS. But when it comes to FTP servers, most of them are designed for warez trading rather than
being secure. And closed-source doesn't help.
So a Windows port of Pure-FTPd makes sense. As long as Cygwin32 is able to compile and run this piece of
software without any change to the source code, Win32 binaries will be provided. But don't expect any
Windows-specific change or optimization. Also, a great part of the server security relies on Cygwin's
libraries emulation functions. So Pure-FTPd on Win32 should be considered experimental and unsupported.
And some features may just not work.
On the good side, initial testing showed that the server was immune to common attacks other Windows FTP
daemons were vulnerable to (directory traversals, device opening, etc) .
2.
PURE-FTPD WIN32 REPOSITORY
Info and download links about Pure-FTPd on Win32 platforms are available from:
http://www.pureftpd.org/windows
3.
INSTALLATION
Copy the executable files (*.EXE) in a suitable directory. Also copy CYGWIN1.DLL in that directory.
Create a C:\CYGWIN directory (you can leave it empty, but the directory should be there) .
4.
RUNNING THE SERVER
PURE-FTPD.EXE works like Unix's /usr/local/sbin/pure-ftpd program and all command-line switches apply
as well.
A noticeable difference, though, is that users can't be stored in /etc/passwd (or equivalent files) . All users
have the same UID/GID. So better chroot everyone.
Users must be in a puredb database. PURE-PW.EXE can be used to create virtual users. It you use it in the
default configuration, you have to create C:\CYGWIN\etc and C:\etc .
Ray Jachrist says that Pure-FTPd can run as a service using Firedaemon:
http://www.firedaemon.com
Page 93 of 110
5.
SERVER FILES
All files managed by Pure-FTPd have their path relative to C:\CYGWIN .
It means that starting the server with:
pure-ftpd -lpuredb:/etc/pureftpd.pdb
Will read:
C:\CYGWIN\etc\pureftpd.pdb
It also applies to log files and users directories.
6.
ANONYMOUS FTP
Files for anonymous FTP must be stored in a directory called:
C:\CYGWIN\FTP
(of course you can use the -e switch to disable anonymous FTP) .
Alternatively, you can have a WIN32_ANON_DIR environment variable to define the directory for public
files.
Virtual hosting is supported as well. Files must be in:
C:\CYGWIN\PURE-FTPD\<ip>\
If you don't want anonymous users to upload files, use the -i switch.
7.
COMPILATION ENVIRONMENT
The Win32 version of Pure-FTPd has been configured with the following command-line, using the Cygnus
Win32 environment:
env CFLAGS="-O2 -march=pentium -pipe" LDFLAGS="-static -s" \
./configure --with-everything --with-brokenrealpath \
--without-shadow --with-nonroot --with-tls \
--with-probe-random-dev --without-ascii
All these switches (except --with-everything and --with-tls) are highly recommended to compile Pure-FTPd
on Windows.
Needed packages are: base, gcc (+ dependencies), make and the crypt library. All of these can be installed
with the standard Cygwin32 installer (http://www.cygwin.com) .
Page 94 of 110
Frequently Asked Questions
1.
Users can delete root-owned files?
I have a directory owned by 'john', but I've put some files owned by 'root' (or another user) in it. However, I
noticed that John can delete these files!
Yes, this is the standard Unix behavior: the owner of a directory can do whatever he likes to do in his
directory, regardless of who owns the file in it. If you want to have immutable files, check for such a feature
in your operating system.
For instance, on Linux and ext2/ext3 filesystems, "chattr +i <file>" does the trick. On BSD systems, try
"chflags schg <file>".
2.
Directories shared by multiple users.
I have a "public" directory. All users can download and upload files from/to this directory. Permissions are
777 on it. But user 'john' can delete files owned by user 'joe'. How to prevent this?
Put the sticky bit on that directory: chmod 1777 public. That way, the directory remains public (read/write),
but people can only delete files they own.
3.
Restricting directory visibility.
I want that people only see their home directory and their own files. I don't want them to look at my systems
files.
This feature is called "chroot". You can enable this by running pure-ftpd with the "-A" switch to do this with
ALL your users (but root) .
You can alternatively use "-a <gid>" to have a "trusted group". Everyone will be caged, EXCEPT members
of that group.
Don't use -a <gid> and -A together.
Another way is to selectively choose what users you want to chroot. This can be done with the /./ trick (see
the README file about this) or with virtual users.
Page 95 of 110
4.
Shared directories and chroot.
I have a directory, say /var/incoming, that I want to be shared by every user. But I want my users to be
chrooted. So /var/incoming should be visible in 'joe' and 'john' accounts, but those are chrooted. So, how to
have the content of /var/incoming visible in these accounts?
Making a symbolic link won't work, because when you are chrooted, it means that everything outside a base
directory (your user's home directory) won't be reachable, even though a symbolic link.
But all modern operating systems can mount local directories to several locations. To have an exact
duplicate of your /var/incoming directory available in /home/john/incoming and /home/joe/incoming, use
one of these commands:
* Linux : mount --bind /var/incoming /home/john/incoming
* Solaris : mount -F lofs /var/incoming /home/john/incoming
* BSD
: mount_null /var/incoming /home/john/incoming
Warning: FreeBSD's mount_null is broken and causes kernel crashes with all FreeBSD systems prior to
release 4.4 .
Another alternative is to compile Pure-FTPd with --with-virtualchroot as a ./configure option. With virtual
chroot, symbolic links pointing outside a chroot jail *are* followed.
Binary packages are compiled with this feature turned on.
5.
Tar and/or gzip on the fly
Is it possible to use a command like "get directory.tar" as with Wu-FTPd ? (Sven Goldt)
Unfortunately, no. Server-side gzip/tar creation is not a present nor a planned feature. It has been
responsible of severe security flaws in Wu-ftpd and BSD ftpd, it can take a lot of server resource (denial-ofservice) and it's a pain to set up (chrooted environment => need to add /etc /lib /bin directories, /dev on some
platforms, etc) .
6.
How to restrict access to dot files ?
Is there an option to prevent people from accessing "." files/dirs (such as .bash_history, .profile, .ssh ...)
EVEN if they are owned by the user ? (William Kern)
Yes. '-x' (--prohibitdotfileswrite) denies write/delete/chmod/rename of dot-files, even if they are owned by
the user. They can be listed, though, because security through obscurity is dumb and software shouldn't lie
to you. But users can't change the content of these files.
Alternatively, you can use '-X' (--prohibitdotfilesread) to also prevent users from READING these files and
going into directories that begin with "." .
Page 96 of 110
7.
Log files
Where does logging info go ? How to redirect it to a specific file ? How to suppress logging ?
Log messages are sent to the syslog daemon. The syslog daemon is often called syslogd or syslog-ng. He's
in charge of dispatching logging events from various programs to log files, according to a "facility"
(category) and a "priority" (urgency: debug, info, warning, error, critical...) .
Pure-FTPd logging messages are send with the "ftp" facility by default (or "local2" on some older systems
without the "ftp" facility) . Unless you told the syslogd to redirect messages with the "ftp" facility to a
specific file, the messages will be merged into /var/adm/messages, /var/log/messages, /var/adm/syslog or
/var/log/syslog.
Check /etc/syslogd.conf. You should have a line like:
*.*;mail.none;news.none -/var/log/messages
just add ftp.none:
*.*;ftp.none;mail.none.news.none -/var/log/messages
And if you want FTP info go in a specific file, just add:
ftp.* /var/log/ftp
and all FTP messages will go in /var/log/ftp . And only there.
The facility can be changed if you add the -f <facility> option to pure-ftpd (or --facility=<facility>)
To completely disable logging, use -f none (or --facility=none) . If you don't read your log files, it's
recommended: it will improve performance and reduce disk I/O.
8.
How to prevent your partitions to be filled
Is it possible to forbid new uploads when the disk is almost full ? (Cyberic)
Use the "-k" (--maxdiskusagepct) flag. If you add -k 95 , no new upload can occur if your partition if more
than 95% full.
Page 97 of 110
9.
Firewalling
My FTP server is behind a firewall. What ports should I open?
First, you have to open port 21 TO the FTP server. You also have to allow connections FROM (not to) ports
<= 20 (of the FTP server) to everywhere. That's enough to handle the "active" mode. But that's not enough
to handle all types of clients. Most clients will use another mode to transmit data called 'passive' mode. It's a
bit more secure than 'active' mode, but you need to open more ports on your firewall to have it work.
So, open some ports TO the FTP server. These ports should be > 1023. It's recommended to use at least
twice the max number of clients you are expecting. So, if you accept 200 concurrent sessions, opening ports
50000 to 50400 is ok.
Then, run pure-ftpd with the '-p' switch followed by the range configured in your firewall. Example:
/usr/local/sbin/pure-ftpd -p 50000:50400 &
Unlike some popular belief, the MORE opened ports you have for passive FTP, the MORE your FTP server
will be secure, because the LESS you are vulnerable to data hijacking.
If your firewall also does network translation (NAT), you have to enable port forwarding for all passive
ports.
On the client side, if a client if behind a firewall, that firewall must understand the FTP protocol. On Linux
firewalls (iptables), just load the ip_conntrack_ftp and ip_nat_ftp modules. On OpenBSD, ISOS and
EkkoBSD firewalls (PF), redirect all traffic to port 21, to ftp-proxy.
10.
Unable to log in (unix authentication)
I'm using simple Unix authentication. No PAM, no puredb, no MySQL, no LDAP. Anonymous FTP works,
but I can't log in as any other user. It keeps saying "authentication failed".
To log in, the shell assigned to your users must be listed in the /etc/shells file. The exact path should be
there, even for fake shells like /etc or /bin/true.
Also double check that you have a carriage return after the last line in /etc/shells.
11.
Network filesystems.
I have a strange problem on Linux or FreeBSD. Uploading a file works fine, but downloading a file only
create 0-byte files. On the server, these files are on NFS/Novell shares/Appletalk
shares/Coda/Intermezzo/SMB volumes.
By default, pure-ftpd uses zero-copy networking in order to increase throughput and reduce the CPU load.
But zero-copy doesn't work with all filesystems, especially network filesystems.
You have to disable zero-copy if you want to serve files from a network FS or from a TMPFS virtual disk.
To disable zero-copy, recompile pure-ftpd with ./configure --without-sendfile
Page 98 of 110
12.
Solaris and chroot.
When I ftp to my Solaris server, I get this as an answer to 'ls':
"425 Can't create the data socket: Bad file number."
On Solaris, to get chroot to work with pure-ftpd you need a dev directory in your new rootdir with these:
crw-rw-rw- 1 root other 11, 42 Dec 10 15:02 tcp
crw-rw-rw- 1 root other 105, 1 Dec 10 15:02 ticotsord
crw-rw-rw- 1 root other 11, 41 Dec 10 15:03 udp
crw-rw-rw- 1 root other 13, 12 Dec 10 15:03 zero
(Reported by Kenneth Stailey)
13.
Upgrading.
Can anyone explain how to update Pureftpd (from source), without having to change all my settings etc.
(Simon H)
1) get the source code and unpack it.
2) ./configure it with your favorite options
3) make
4) rm -f /usr/local/sbin/pure-ftpd
5) make install-strip
6) if you run pure-ftpd from inetd,tcpserver,xinetd, etc: nothing left to do. You have it upgraded.
7) if you run it standalone, stop the server:
kill $(cat /var/run/pure-ftpd.pid)
then launch it again:
/usr/local/sbin/pure-ftpd &
14.
OpenBSD, ISOS, EkkoBSD and MacOS X.
I'm trying to run Pure-FTPd on OpenBSD. The daemon is running, but I can't connect: nobody answers on
port 21.
Intentionally, OpenBSD refuses to listen for IPv4 and IPv6 connections on a single socket. By defaut, PureFTPd will only listen to IPv6 connections on OpenBSD. The same thing applies to recent releases of ISOS,
EkkoBSD and MacOS X.
To listen to IPv4 addresses, you must run pure-ftpd with the '-4' switch:
/usr/local/sbin/pure-ftpd -4 &
Page 99 of 110
15.
FTP over SSH.
How to run Pure-FTPd over SSH? I want to encrypt all connection data (including passwords) .
FTP-over-SSH is a nice alternative over FTP-over-SSL (impossible to securely firewall) and SFTP (which is
slower, but only uses one port) .
Customers using Windows can use FTP-over-SSH with the excellent Van Dyke's SecureFX client
(http://www.vandyke.com) . It doesn't require any special knowledge: just tell your customer to check "FTPover-SSH2" in the "Protocol" listbox when creating an account for your FTP server.
On the server side, here's how to manage FTP-over-SSH accounts:
1) Add /usr/bin/false to your /etc/shells file (on some systems, it's /bin/false) .
2) To create a FTP-over-SSH account, create a system account with /dev/null as a home directory and
/usr/bin/false as a shell. You don't need a dedicated uid: the same uid can be reused for every FTP-over-SSH
account.
3) Create a virtual user account for that user (either with PureDB, SQL or LDAP) . Give that virtual user a
real home directory and only allow connections coming from 127.0.0.1 (all FTP-over-SSH sessions will
come from localhost, due to SSH tunneling) .
People with no home directory (/dev/null) and no valid shell (/usr/bin/false) won't be able to get a shell nor
to run any command on your server. But they will be granted FTP-over-SSH sessions.
Here are examples (Linux/OpenBSD/ISOS/EkkoBSD commands, translate them if necessary) .
1) Creating a regular FTP account:
pure-pw useradd customer1 -m -d /home/customer1 -u ftpuser
2) Creating a FTP-over-SSH account (non-encrypted sessions are denied):
useradd -u ftpuser -g ftpgroup -d /dev/null -s /usr/bin/false customer2
pure-pw useradd customer2 -m -d /home/customer2 -u ftpuser -r 127.0.0.1/32
3) Creating an account who can use regular (unencrypted) FTP from the internal network (192.168.1.x), but
who must use FTP-over-SSH when coming from an external network (internet):
useradd -u ftpuser -g ftpgroup -d /dev/null -s /usr/bin/false customer3
pure-pw useradd customer3 -m -d /home/customer3 -u ftpuser -r 127.0.0.1/32,192.168.1.0/24
Page 100 of 110
16.
Virtual users: /etc/pureftpd.pdb .
I made changes to /etc/pureftpd.passwd but the server doesn't understand them: I can't access any account I
just created.
The server never reads /etc/pureftpd.passwd directly. Instead, it reads /etc/pureftpd.pdb
(or whatever file name you gave after -lpuredb:...) .
This file is a copy of /etc/pureftpd.passwd, but in a binary format, optimized for fast lookups.
After having made a manual change to /etc/pureftpd.passwd, you must rebuild /etc/pureftpd.pdb with the
following commands:
pure-pw mkdb
If you add/delete/modify user accounts with pure-pw useradd/usermod/userdel/ passwd, don't forget the '-m'
option to automatically rebuild /etc/pureftpd.pdb and not only update /etc/pureftpd.passwd .
17.
Giving access to dot-files.
I don't want my users to read files beginning with a dot. Except one file I'd like to give 'John' read (and
maybe write) access to.
Create a symbolic link in John's account, pointing to the dot-file. Example:
ln -s .bashrc bashrc
John will be able to access ".bashrc" through the symbolic link, "bashrc".
18.
Initial banner.
How do I display a customized message before the login prompt?
Compile with --with-cookie and run the server with -F <file name> . In that file, put a nice customized
banner message.
19.
Internet Explorer doesn't show any login box.
IE does a very strange trick to detect whether an FTP server does accept anonymous connections or not.
Basically, it connects to the server and logs in as 'anonymous'. But if you say 'no' at this point, it drops the
connections with an error. You have to say 'ok, anonymous users are allowed' and then, when a dummy
password ('IE@') is sent, you say 'ah ehm... finally... no... anonymous users aren't allowed' . Silly. To play
that game, you must run pure-ftpd with the -E (non-anonymous server) and –b (compatibility with broken
clients) flags. Then, the magic popup will show up. But please note that IE (and browsers at large) are
usually bad FTP clients.
20.
Internet Explorer doesn't want to log in. (Matthew Enger)
Check that the max number of connections (either per user or per IP) is at least 2. IE needs two connections
to connect to an FTP server.
Page 101 of 110
21.
Passwords and pure-pw scripting.
I would like to create virtual users with a shell-script. if i us pure-pw useradd ..... it always asks for the new
password. is there any command-line option which tells pure-pw the password (like useradd ftp-user ftppassword -m) ? (at1ce) .
Giving cleartext (and badly one-way hashed) passwords through command-line switches is a bad idea.
Because users could issue a simple 'ps' command and discover these passwords.
One way to enter a password (not from the keyboard) is to put the password twice in a temporary file, then
redirect that file to stdin. Example:
pure-pw useradd john -d /tmp/john -u ftpuser -m < ~/tmp/passfile
And in ~/tmp/passfile, have something like:
john's password
john's password
If you really need to avoid a temporary file and if nobody but you can log on the machine, you can always
do this:
(echo blahblah; echo blahblah) | pure-pw useradd john -d /tmp/john -u ftpuser
22.
Altlog and pure-uploadscript don't work.
pure-uploadscript doesn't run anything. Alternative logging methods (CLF, stats, W3C...) create a logfile,
but it always stays empty.
Maybe your operating system has a buggy realpath() implementation. Some old Solaris and Linux versions
are known to have such a bug. Try to recompile pure-ftpd, but run ./configure with the --withbrokenrealpath switch first.
23.
The server starts, but doesn't listen to any port?
The server is properly running, I see it in the process list, but any try to connect to the configured port (or
port 21 by default) fails. The socket isn't even open.
Check two things :
- If you are running a BSD system and you want to listen to IPv4 addresses, check that the "-4" switch
("IPV4Only" in config file) is enabled.
- If you upload script are enabled ("-o", or "CallUploadScript"), make sure that the pure-uploadscript is
started. Or the FTP server will actually wait until pure-uploadscript is actually ready to process new uploads.
If you don't need the uploadscript facility, remove "-o".
24.
Double slash.
Why do I see double slashes in log files? For instance, the path of a downloaded file looks like
/home/john//pictures/zok.jpg .
'//' is a symbol for the limit of the chroot jail. In that example, it means that John is caged in /home/john/ .
Page 102 of 110
25.
Windows port.
Does Pure-FTPd run on Windows?
Yes, there's a port available from http://www.pureftpd.org/windows But the server is developped on Unix
and the Win32 version should be considered experimental and unsupported.
26.
ftpwho as a non-root user.
How do I give access to the 'pure-ftpwho' command to non-root users?
The 'pure-ftpwho' command is restricted to root by default, because users probably shouldn't be given the
ability to spy what other users are doing on the same host. However, it's safe to put the setuid bit on that
command, in order to have it work as any user:
chmod 4711 /usr/local/sbin/pure-ftpwho
27.
Changing bandwidth throttling on-the-fly.
Is it possible to change the bandwidth allocated to an user during a transfer, so that the change takes place
immediately?
Unfortunately, no. Or at least not at pure-ftpd level. Doing so would need to re-read user's parameters all the
time and it would be horribly slow. Other mechanisms would work, like signals to interrupt transfers, reread parameters, then resume. But it would introduce a lot of complexity to the code.
If you're using a modern operating system like OpenBSD, ISOS, EkkoBSD or Linux, your kernel already
includes a fair TCP/IP traffic shaper. And because it works at kernel-level, you can easily change the
bandwidth allowed to IPs or services on-the-fly. Have a look at pf.conf(5) OpenBSD, ISOS and EkkoBSD,
and at tc (or read the Linux networking HOWTO) on Linux.
Also see the 'Global bandwidth limitation' section later in this document.
28.
KERBEROS_V4 rejected as an authentication type.
It works and I can log in, but I recieve these strange error messages at log in, even in a non-chrooted
environment:
220 FTP server ready.
502 Security extensions not implemented
502 Security extensions not implemented
KERBEROS_V4 rejected as an authentication type
Why and what do they mean?
This is a Linux-specific instllation issue. It means that your command-line FTP client isn't a normal one, but
a Kerberos FTP client. You probably installed RPMs for Kerberos, although you don't use it. These
messages are harmless as Kerberos clients will fallback to normal FTP (after these errors), but you just have
to deinstall Kerberos on your client host to have 'ftp' work without these messages.
Page 103 of 110
29.
Wrong group ownership.
I have an user called 'john' whoose group is 'johngroup'. When John uploads a file, that one belongs to 'john',
but to another group like 'wheel' (whoose John isn't a member of). What's wrong?
This is a BSD standard behavior (verified on OpenBSD, ISOS, EkkoBSD and FreeBSD): when a new file is
created, the group is inherited from the parent directory. On other systems (like GNU/Linux), files are
owned by the primary group of the user, unless the directory has the setgid bit set.
If you want new files uploaded in John's directory to belong to group 'johngroup', have that directory (and
probably also subdirectories) belong to 'johngroup':
chgrp -R johngroup /home/john
30.
Compilation with MySQL.
I can't compile with MySQL. ./configure says that MySQL libraries aren't properly installed.
The libmysqlclient.so file should be in a path known by your dynamic linker.
For instance, on a GNU/Linux system, add the path to libmysqlclient.so file (only the path, not the file itself)
to /etc/ld.so.conf . Then, run 'ldconfig' .
31.
"Sorry, I can't trust you".
When an user tries to log in, he gets "Sorry, I can't trust you". But his login/password pair is right. What
wrong?
That message can means two things:
- The user has a shell that isn't listed in /etc/shells. You must add it, even if it's a fake shell like /bin/false .
Also make sure that you have a carriage return after the last entry in /etc/shells.
- You are using the -u <uid> option to deny access to users whoose uid is below <uid> . But the user you are
trying to log in as, has an uid in the forbidden range.
32.
Customer-friendly configuration.
What switches do you recommend to start the server, for an hosting service?
Here's a good start:
--chrooteveryone \
--maxclientsperip=5 \
--displaydotfiles \
--noanonymous \
--minuid=100 \
--umask=022:022 \
--limitrecursion=10000:3 \
--customerproof
Page 104 of 110
33.
Anonymous FTP with virtual users.
I successfully created a virtual user called 'ftp' or 'anonymous', but anonymous FTP doesn't work.
Pure-FTPd never fetch any info from the virtual users backends (puredb, MySQL, LDAP, etc) for
anonymous sessions. There are three reasons not to do so: - Speed: do we need to query a database just to
get the anonymous user's home directory? We don't need to retrieve any password for anonymous sessions.
- Consistency: with the virtual hosting mechanism.
To run an anonymous FTP server you must have a *system* account called 'ftp'. Don't give it any valid
shell, just a home directory. That home directory is the anonymous area.
34.
A basic setup.
I'm trying to set up a ftp server just for me and my family so we can get and upload files when on the road.
How can I make two users, say Jane and Joe, who share the directory /home/ftp and /home/ftp/incoming. In
/home/ftp they only have read privs. and in /home/ftp/incoming they have read and write privs.
Add a group for all FTP users (not mandatory, but more secure):
groupadd ftpgroup
Add an uid for all FTP users (idem, not mandatory, but better):
useradd -g ftpgroup -d /dev/null -s /etc ftpuser
Now, let's create /home/ftp and /home/ftp/incoming:
mkdir -p /home/ftp/incoming
chown -R root:ftpgroup /home/ftp/incoming
chmod -R 755 /home/ftp
chmod -R 1775 /home/ftp/incoming
Let's add Jane:
pure-pw useradd jane -m -u ftpuser -d /home/ftp
Let's add Joe:
pure-pw useradd joe -m -u ftpuser -d /home/ftp
Let's start the FTP server:
/usr/local/sbin/pure-ftpd -lpuredb:/etc/pureftpd.pdb -H –B
Everything should be ok now.
For more info about how to create new users, change passwords, etc.:
http://www.pureftpd.org/README.Virtual-Users
Page 105 of 110
35.
Slow pure-ftpwho or slow login.
Sometimes, pure-ftpwho is slow to show the result. And sometimes, when an user logs in, the session stucks
a bit before he can get a directory listing.
This is probably caused by a slow DNS resolver. In order to display full host names, pure-ftpd has indeed to
make DNS queries that can be slow if you link is slow, or if the client link is slow.
You can speed up pure-ftpwho and pure-ftpd with the -H switch. Names won't be resolved, you will see IP
addresses instead.
36.
Chrooted users can follow symlinks outside the chroot jail?
People can create symbolic links to '/' and escape their home directory!
There are two chroot implementations in pure-ftpd:
- The traditional one, based upon your kernel chroot() system call. This is the default. With that one,
symbolic links can only point inside the chroot jail, or they won't be followed.
- The 'virtual chroot' implementation. With that feature, users *can* follow all symbolic links, even when
they don't point inside the jail. This is very handy to set up directories shared by multiple users. Binary
packages are compiled with virtual chroot by default.
To enable the virtual chroot feature when you are compiling the server, use the --with-virtualchroot with
./configure . If you want a restricted chroot, don't include --with-virtualchroot.
Please note that the FTP server will never let people create new symbolic links. Symbolic links have to be
already there to be followed. Or if your users can create symbolic links through Perl or PHP scripts, your
hosting platform is really badly configured. People can install any web file browser, they don't need FTP to
look at your system files. Recompile PHP without POSIX functions and run all Perl scripts chrooted.
37.
How to start Pure-FTPd in background.
I start 'pure-ftpd' from an X terminal and the server properly answers. However, as soon as I close the
terminal, the server stops.
This is a shell dependent issue. Your shell is configured to close all background jobs when leaving. You can
change your shell options (probably with a 'set' directive) or detach background jobs with the 'disown'
keyword. Alternatively, you can just start pure-ftpd with the -B switch in order to have it detach at startup
time:
/usr/local/sbin/pure-ftpd –B
Page 106 of 110
38.
Windows command-line FTP client and 'ls'.
With the command-line Windows FTP client, 'ls -la' doesn't return any file.
The 'ls' command of an FTP client has nothing to do with the 'ls' command started from an Unix shell.
With the command-line Windows client, typing 'ls' really sends the FTP command 'NLST'. So when you
type 'ls -la', it doesn't mean 'verbosely list all files'. According to RFCs, it means 'list the file called -la' . So
you get what you asked for. If no file is called '-la', you get nothing.
If you want to play with regular expressions and switches, you should type 'dir' (which is translated to
'LIST') instead. 'dir -la' is ok.
This is a bit illogical and that brain damage is specific to Microsoft's command-line FTP client.
If you really want 'ls' to parse options, you can start pure-ftpd with the -b (broken) switch.
Page 107 of 110
39.
Global bandwidth limitation.
How do I limit the *total* bandwidth for FTP?
Pure-FTPd can limit bandwidth usage of every session. But limiting the total bandwidth is intentionally not
implemented, because most operating systems already have very efficient algorithms to handle bandwidth
throttling.
Here's an example with Linux.
1) Have a look at /proc/sys/net/ipv4/ip_local_port_range. You will see two numbers: this is the interval of
local ports your Linux kernel will use for regular outgoing connections. The FTP ports you have to reserve
for passive FTP must *not* be in this range. So if:
"cat /proc/sys/net/ipv4/ip_local_port_range"
returns "32768-61000", you can reserve ports 10000 to 20000 for your FTP server, but not 30000 to 40000.
(alternatively, you can change the local port range) .
2) Change the first lines and save the following script:
---------------------------- Cut here ---------------------------#! /bin/sh
# Simple bandwidth limiter - [email protected]
# Change this to your link bandwidth
# (for cable modem, DSL links, etc. put the maximal bandwidth you can
# get, not the speed of a local Ethernet link)
REAL_BW='10Mbit'
# Change this to the bandwidth you want to allocate to FTP.
# We're talking about megabits, not megabytes, so 80Kbit is
# 10 Kilobytes/s
FTP_BW='80Kbit'
# Change this to your physical network device (or 'ppp0')
NIC='eth0'
# Change this to the ports you assigned for passive FTP
FTP_PORT_LOW="10000"
FTP_PORT_HIGH="20000"
tc qdisc add dev "$NIC" root handle 1: cbq bandwidth "$REAL_BW" avpkt 1000
tc class add dev "$NIC" parent 1: classid 1:1 cbq bandwidth "$REAL_BW" \
rate "$REAL_BW" maxburst 5 avpkt 1000
tc class add dev "$NIC" parent 1:1 classid 1:10 cbq \
bandwidth "$REAL_BW" rate "$FTP_BW" maxburst 5 avpkt 1000 bounded
tc qdisc add dev "$NIC" parent 1:10 sfq quantum 1514b
tc filter add dev "$NIC" parent 1: protocol ip handle 1 fw flowid 1:10
iptables -t mangle -A OUTPUT -p tcp --sport 20:21 -j MARK --set-mark 1
iptables -t mangle -A OUTPUT -p tcp \
--sport "$FTP_PORT_LOW":"$FTP_PORT_HIGH" -j MARK --set-mark 1
---------------------------- Cut here ----------------------------
Page 108 of 110
3) Make sure that you have the 'tc' command installed. If your Linux distro doesn't ship 'ip' and 'tc'
commands, it really sucks and you must install a package called 'iproute2' to get them.
4) Start Pure-FTPd with the passive port range you assigned:
/usr/local/sbin/pure-ftpd -p 10000:20000 –HBA
5) Run the script you created in step 2. It it doesn't work, check that QOS support was compiled in your
Linux kernel.
6) Enjoy :)
40.
Linux, NTFS and Pure-FTPd.
On Linux, I can't transfer files from an NTFS partition.
Keep in mind that the NTFS filesystem is still an experimental beast in Linux. Some basic operations are not
implemented yet. Fortunately, a big effort is being made and Linux 2.5 has a new NTFS implementation that
fully works with Pure-FTPd (try ./configure --without-sendfile, though) . And it is more reliable and really
faster than the old one. And even more fortunately, the new NTFS implementation has been backported to
recent 2.4.x kernels. Have a look at http://linux-ntfs.sf.net/ .
41.
Slowdowns and lags.
Some users complains that transfering large files doesn't work. Transfers are starting as expected, with a
decent rate. But then, the speed dramatically decreases, there are some serious lags and they often must
disconnect (or the client force them to do it, after a timeout) . The server is behind a firewall that filters
incoming ICMP, but let FTP ports in.
Don't, don't, don't filter ICMP. At least not blindly without understanding what you are filtering. ICMP is
part of the TCP/IP specifications. Filtering it can have nasty side effects with no real win. If you even filter
ICMP types 3 and 4, your firewall is definitely broken and this is probably why you have such troubles with
transfers of large files.
Please read these documents about ICMP filtering :
http://www.phildev.net/mss/index.html
http://alive.znep.com/~marcs/mtu
http://www.freelabs.com/~whitis/isp_mistakes.html
42.
Firewalls and SSL/TLS.
My client is behind a stateful firewall doing applicative filtering (like IPTables with ip_conntrack_ftp or
ip_nat_ftp) . Connections to an SSL/TLS enabled server does't work. Authentication works, but I'm unable
to download files nor list directories.
First, try to force your client to use the passive mode. In active mode, the server has to connect to the client
(or the NAT gateway) on a dynamic port that is negociated on the connection socket. But when SSL/TLS is
used, that connection socket is encrypted, therefore no man-in-the middle can see what ports will be used to
transfer data, including the firewall. There are some proposals to work around this problem, but neither
popular clients nor common firewalls are aware of these tricks. Therefore, use the passive mode or switch to
SSH.
Page 109 of 110
43.
TLS and error 00000000.
My TLS-enabled client doesn't work. It outputs something like :
"SSL connect: error:00000000:lib(0):func(0):reason(0)". What does it mean?
This error is not very explicit. You get it from some Unix clients like LFTP. It actually means that there is a
firewall or a NAT box between a TLS-enabled server and a TLS-enabled client, but that firewall is unable to
handle encrypted FTP sessions. Unfortunately, there's no simple workaround against this. Try to switch your
client to active mode and use 1:1 NAT, but SSL/TLS, firewalls and FTP don't mix very well.
44.
Files getting renamed automatically (submitted by C. Jon Larsen)
Sometimes when files get uploaded they are getting renamed to something like
"pureftpd.3f3300d2.33.0001". What is causing this ?
The ftp client that is being used to upload the files is using the STOU (Store Unique) FTP command instead
of the STOR FTP command. If you check the ftp logfile you should see something like this in the logs:
([email protected]) [DEBUG] Command [stou] [file_name_from_the_client.ext]
/var/ftp/ftpcustomer/pureftpd.3f3300d2.33.0001 uploaded (218168 bytes, 127.79KB/sec)
The STOU command tells the ftp client to begin the transmission of the file to the remote site; the remote
filename picked by the ftp server will be unique within in the current directory that the ftp client is using.
The response from the server will include the filename.
The ftp client has an option like "create unique files" or "upload file with a temporary name" enabled. You
should have the ftp user uncheck this option.
Trying to disable the STOU command on the server side is not a good idea or solution as some ftp clients
will use STOU to upload a file with the temporary, unique name, and then rename the file once the upload is
complete.
This helps prevent failed uploads from leaving partial files around.
Page 110 of 110