May the source be with you, but remember the KISS principle ;-)
Contents Bulletin Scripting in shell and Perl Network troubleshooting History Humor

Pure-ftpd Daemon


FTP Protocol Recommended Links Pure-FTPd on Suse Pure-ftpd configuration Troubleshooting of ftp connections FAQ

TCP Wrappers

NetDrive Mirroring Tools FTP Security FTP over weak links FTP by mail Web publishing
Ftp Filesystems wu-ftpd ProFTPD vsftp Xinetd Humor Etc

Pure-ftpd is used as a default ftpd daemon on Suse. It has several interesting features not found in other ftpd daemons:

On Suse pure-ftpd is typically used with xinetd. In this case it is sysadmin responsibility to specify all command switches, as configuration file is not read by the daemon. The file /etc/xinetd.d/pure-ftpd file is installed when RPM is installed and by default the service is disabled: 

service ftp 
{ socket_type = stream
  server = /usr/sbin/pure-ftpd 
  protocol = tcp
  user = root
  wait = no
  disable = no
Note: The startup file for standalone running of the daemon /etc/init.d/pure-ftpd is also installed and can be used instead of xinetd invocation method.

So /etc/xinetd.d/pure-ftpd should be either modified to invoke

/usr/sbin/pure-config-args /etc/pure-ftpd/pure-ftpd.conf
to generate parameters from config file or deleted as the /etc/init.d/pure-ftpd script provides for automatic generation of parameters from the config file, which resembles a standard Unix daemons behavior.

Actually this parameter generation can be adapted to xinetd  via additional script that modifies 

Pure-ftpd configuration

See Pure-FTPd installation and configuration for configuration of this daemon in Suse.

Unlike many daemons, Pure-FTPd doesn't read any configuration file. Instead, it uses command-line options. That makes is less convenient for usage with the xinetd as you need to remember to modify options in /etc/xinetd.d/pure-ftpd file.  At the same time it is not complied with TCP wrapper so for Internet facing servers it is not recommended to use it as a standalone service launched from /etc/init.d/, unless firewall is enabled

Unlike many daemons, Pure-FTPd doesn't read any configuration file. Instead, it uses command-line options. That makes is less convenient for usage with the xinetd as you need to remember to modify options in /etc/xinetd.d/pure-ftpd file. 

At the same time it is not complied with TCP wrapper so for Internat facing servers it is not recommended to use it as a standalone service launched from /etc/init.d/, unless firewall is enabled

For instance, the '-H' flag is designed to speed up highly loaded servers, by avoiding DNS lookups. To enable this, just add it to the server name:

/usr/sbin/pure-ftpd -H
alternative long options are also supported. here's an equivalent of the previous command: e>
/usr/sbin/pure-ftpd --dontresolve
Traditional configuration file can be used only as a prototype for generating relevant command options that need to be passed to pure-ftpd daemon:
PURE_FTPD_PARAMS=`/usr/sbin/pure-config-args /etc/pure-ftpd/pure-ftpd.conf` 


Why 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>" .

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.

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.

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:

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.

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-of-service) and
it's a pain to set up (chrooted environment => need to add /etc /lib /bin directories, /dev on some platforms, etc) .

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 "." .

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; -/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.

How to prevent your partitions to be filled

-> Is it possible to forbid new uploads when the disk is almost full ?

Use the "-k" (--maxdiskusagepct) flag. If you add -k 95 , no new upload can
occur if your partition if more than 95% full.


-> 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: 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
FreeBSD 5 firewalls (PF), redirect all traffic to port 21, to ftp-proxy.

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

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

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)


-> 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 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/
then launch it again:
local/sbin/pure-ftpd &

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 al

	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 ( . It doesn't require any special
knowledge: just tell your customer to check "FTP-over-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 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 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 (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 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 bin/false customer2
pure-pw useradd customer2 -m -d /home/customer2 -u ftpuser -r

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 bin/false customer3
pure-pw useradd customer3 -m -d /home/customer3 -u ftpuser \

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 .

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".

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.

Internet Explorer.

-> 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

-> 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.

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
ftp-password -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

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 --with-brokenrealpath
switch first.

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".

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/ .

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 local/sbin/pure-ftpwho

Changing bandwidth throttling on-the-fly.

-> Is it possible to change the bandwidth allocated to a 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, re-read
parameters, then resume. But it would introduce a lot of complexity to the

If you're using a modern operating system like OpenBSD, ISOS 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 FreeBSD 5,
and at tc (or read the Linux networking HOWTO) on Linux.
Also see the 'Global bandwidth limitation' section later in this document.

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.

Wrong group ownership.

-> I have a 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, DragonflyBSD 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

Compilation with MySQL.

-> I can't compile with MySQL. ./configure says that MySQL libraries aren't
properly installed.

The file should be in a path known by your dynamic linker.
For instance, on a GNU/Linux system, add the path to file
(only the path, not the file itself) to /etc/ . Then, run
'ldconfig' .

"Sorry, I can't trust you".

-> When a 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.

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 \

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
- 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.

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/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.:

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.

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.

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/sbin/pure-ftpd -B

* 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.

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 - <j at>

# 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)

# Change this to the bandwidth you want to allocate to FTP.
# We're talking about megabits, not megabytes, so 80Kbit is
# 10 Kilobytes/s

# Change this to your physical network device (or 'ppp0')

# Change this to the ports you assigned for passive FTP

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 ----------------------------

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/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 :)

Also have a look at : and

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 .

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 :

Also some hardware routers don't properly handle window scaling. Try
to turn it off, for instance on Linux:
sysctl -w net.ipv4.tcp_window_scaling=0
sysctl -w net.ipv4.tcp_bic=0

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.

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.

Slow TLS operations.

-> When clients connect with TLS encryption, listing directories and
downloading files are slow operations. Nothing happens after a command is
sent, things only start moving after a 5 secondes delay.

Check the host name of your certificate. It should be a fully-qualified host
name and if possible, it shouldn't be a CNAME entry.

Also check your DNS cache servers.

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:

(user@a.b.c.d) [DEBUG] Command [stou] [file_name_from_the_client.ext]
/var/ftp/ftpcustomer/pureftpd.3f3300d2.33.0001 uploaded (218168 bytes,

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.

Top Visited
Past week
Past month


Old News ;-)

[Jul 20, 2013]  Getting passive FTP connections to work through a firewall properly CPanel Server Tweaks Your online

Setting up the FTP Server (Pure-FTPD):

There are two different config files your server may use. If you are using CPanel, then most likely it is located here:


If you are unable to find that file, or if your FTP Server is setup to read a conf file, then most likely it is located here:


Using: /etc/sysconfig/pure-ftpd

Look for a line containing: -p or --passiveportrange

Now just check that the port range listed is correct. Remember, port ranges listed here have a ':' character between the numbers, while APF has a '_' character.

Ie. (if the port range is 35000 to 36000 and appears as 35000_36000 in the APF config file then it should look like this)

--passiveportrange 35000:36000
-p 35000:36000

If you do not find it, then go to the end of the file, and add:
followed by the port range you had in the APF firewall config file, except replace the '_' character with a ':'.

So if the port range is 35000 to 36000 and appears as 35000_36000 in the APF config file, then you want to add 35000:36000.

Ie. (port range from 35000 to 36000)
--passiveportrange 35000:36000

When done, save the file and restart your FTP server.

/etc/init.d/pure-ftpd restart

Using: /etc/pure-ftpd.conf

Look for a line containing: PassivePortRange


# Port range for passive connections replies. - for firewalling.

#PassivePortRange          30000 40000
If there is a leading '#' character, remove it.

If the port range is incorrect, change it. The port range here has an actual space between the numbers, not a '_' character.

Ie. (previous example becomes this)
# Port range for passive connections replies. - for firewalling.

PassivePortRange          35000 36000

Now save the file and restart your FTP server.

/etc/init.d/pure-ftpd restart

[Jul 20, 2013]  FTP Filezilla connection timed out - cPanel Forums

FTP Filezilla connection timed out

I can connect use filezilla, it accepts user name and password. i then tries to list the directory and times out.

I have included a print out of what filezilla is doing.

Please help, many thanks in advance

Status: Resolving address of
Status: Connecting to
Status: Connection established, waiting for welcome message...
Response: 220---------- Welcome to Pure-FTPd [TLS] ----------
Response: 220-You are user number 8 of 50 allowed.
Response: 220-Local time is now 19:49. Server port: 21.
Response: 220-This is a private system - No anonymous login
Response: 220-IPv6 connections are also welcome on this server.
Response: 220 You will be disconnected after 15 minutes of inactivity.
Command: USER
Response: 331 User OK. Password required
Command: PASS ********
Response: 230-User has group access to: cha49382
Response: 230 OK. Current restricted directory is /
Command: SYST
Response: 215 UNIX Type: L8
Command: FEAT
Response: 211-Extensions supported:
Response: EPRT
Response: IDLE
Response: MDTM
Response: SIZE
Response: MLST type*;size*;sizd*;modify*;UNIX.mode*;UNIX.uid*;UNIX.gid*;unique*;
Response: MLSD
Response: ESTP
Response: PASV
Response: EPSV
Response: SPSV
Response: ESTA
Response: AUTH TLS
Response: PBSZ
Response: PROT
Response: 211 End.
Status: Connected
Status: Retrieving directory listing...
Command: PWD
Response: 257 "/" is your current location
Command: TYPE I
Response: 200 TYPE is now 8-bit binary
Command: PASV
Response: 227 Entering Passive Mode (116,0,23,213,120,167)
Command: LIST
Error: Connection timed out
Error: Failed to retrieve directory listing

Reply With Quote Reply With Quote .


08-06-2008, 05:08 PM #2

viraj viraj is offline Member viraj's Avatar -------------------------------------------------------------------------------- Join Date:Sep 2006Location:IndiaPosts:209 cPanel/WHM Access Level: DataCenter Provider


Do you have any firewall active on the server ? Try switching it off, also try increasing the port range in the firewall just in case it's causing the problem..

Regards, Viraj


Phone:0253-2342932|Mobile:+91-9860900069 Support/Billing/Sales:24x7x365 |

Reply With Quote Reply With Quote .


08-06-2008, 06:56 PM #3

RobertNikic RobertNikic is offline Member -------------------------------------------------------------------------------- Join Date:Jun 2008Location:Tampa BayPosts:31

If you do have a firewall installed into your server, i would suggust checking the settings or disabling it (test mode) to see if this is whats causing the FTP to timeout.

If the firewall is not an issue, I would suggest monitoring your FTP service or perhaps restarting it.

If you have any further questions, feel free to contact me.


It seems passive ports are not opened at the server firewall. Please contact the server support team for opening the ports or you can try the ftp in the active mode.


As your logs clearly shows that after entering Passive Mode connection timed out

================ Response: 227 Entering Passive Mode (116,0,23,213,120,167) Command: LIST Error: Connection timed out Error: Failed to retrieve directory listing ================

If you have your own server then open passive port range in FTP configuration file as well as in firewall if you have any or if you are not having server access then contact your hosting provider and ask them to open passive ports.

[Jul 20, 2013] FTP drops connection on ls command - Support - SmartFTP Forums

Failed connection log below: Initiated from Username home pc with passive mode enabled.

Connecting to 12/2/2005 11:40:20 PM 220 (vsFTPd 1.2.1) USER username

331 Please specify the password. PASS **** 230-Username - 230- 230-This is your home directory. 230-I will set you up a web server shortly. 230- 230- 230- 230- 230- 230- 230 Login successful. FEAT

211-Features: MDTM REST STREAM SIZE 211 End PWD

257 "/home/username" TYPE A

200 Switching to ASCII mode. CWD /home/username

250 Directory successfully changed. PASV

227 Entering Passive Mode (64,6,42,21,244,144) ERROR 10060 Data Socket: The current connection has timeout. TYPE A

200 Switching to ASCII mode. CWD /home/username

250 Directory successfully changed. PASV

227 Entering Passive Mode (64,6,42,21,216,118) ERROR 10060 Data Socket: The current connection has timeout.


If you have read this far in these log files, thank you very much and God bless you.


Posted 09 December 2005 - 04:28 PM

There are two options:

1) You connect in active mode. This requires you to configure some port forwarding: Go to Tools -> Settings, Connection. Choose to limit the port range to e.g. 6000 - 7000, and forward that port range via NAT to your PC in your router / firewall / DSL-modem. Alternatively, you could try to limit the port range and enable UPNP (in the checkbox below) if your router supports UPNP.

2) You connect in passive mode. This requires the server administrator to make some changes to his firewall / router. For vsFTPd, he needs to adjust the pasv_min_port / pasv_max_port values in vsftpd.conf and forward these ports through his firewall to the server.


Posted 10 December 2005 - 02:51 AM

thanks very much for reply and information eyebex. This is exactly the type specific information I've been looking for. Appreciate your taking time to answer.

I am wondering why it is that another pc on the same subnet as mine has no problems accessing the ftp site giving me problems without doing port forwarding?

thanks again,


[Jul 20, 2013]  How to Configure Windows Firewall for a Passive Mode FTP Server

Configure an inbound firewall rule to allow inbound FTP connections to only the ports on which FTP is listening
  1. Open an Administrator command-prompt. Click Start, click All Programs, click Accessories, right-click Command Prompt, and then click Run as Administrator.
  2. Run the following command:


    netsh advfirewall firewall add rule name=”FTP Service” action=allow service=ftpsvc protocol=TCP dir=in
  3. Finally, disable stateful FTP filtering so that the firewall does not block any FTP traffic.


    netsh advfirewall set global StatefulFTP disable

[Jul 20, 2013]  ftp connection error 550 Data channel timed out The Official Microsoft IIS Forums

[Jul 20, 2013]  HP Communities - FTP problem - invalid argument getpeername - Enterprise Business Community

well, since your ftpd is not running with some exotic switches, the only question is how many firewalls do you have between this client and this server and who is in charge of those firewalls.

The error you are getting getpeername:Invalid argument, implies that the socket connection ftpd is expecting to find is getting closed immediately, even before this getpeername call gets executed. I do not think that your server is doing it. The only other option is to look for the restrictions in the firewall.

Are you able to successfully establish ftp sessions from other clients to this server or is it the response to ftp request coming from anywhere ?

try ftp'ing from a neighboring node while watching the syslog. By neighboring node, I am implying something like this :

	ftp server ip : 
	ftp client ip : 192.168.100.x  	
where netmask is, i.e., on the same subnet so that we should not worry about any cross network routing hence eliminating firewall blockage possibilities.

also you can change your ftp line in your inetd.conf file to something like this:

ftp stream tcp nowait root /usr/lbin/ftpd ftpd -Llu 111

for more extensive logging. Then

inetd -k
inetd -l

then try the ftp while on a separate window, running

tail -f /var/adm/syslog/syslog.log

UNIX because I majored in cryptology...

[Feb 24, 2013] PROFTPD vs VSFTPD

May 15, 2010 | Web Hosting Talk


Web Hosting Evangelist Join Date: Mar 2009
Posts: 519


PROFTPD vs VSFTPD which one would you choose and why I've been vsftpd on my personal servers before but is there any advantage in using proftpd?

TheServerExperts, Web Hosting Master

From those two i would go with ProFTPd.

But we recommend Pure-FTPd -

Pure-ftpd is the default cPanel ftp of choice, it use to be proftpd :-)



* Allows use of .ftpaccess files for per-directory access controls.
* Supports TCPwrappers based access controls.
* Highly configurable.


* Uses more memory
* Recommended only when additional configuration flexibility is required.



* Faster login time.
* Uses less memory.
* Allows virtual access on any IP address.
* Better security model.
* Allows virtual user quotas.
* More compatible with software RAID systems.


* Fails PCI Compliance testing on FreeBSD systems.

Patrick, Stairway To Hosting

VSFTPD is the clear winner between the two, unless of course you're talking about using it alongside cPanel in which case just stick with PureFTPD for compatibility reasons. (VSFTPD is very lightweight compared to ProFTPD and probably has a better security track record...)


[Jun 14, 2011] Strange pure-ftp problem

This is a problem connected with the fact that the user is not a member of trusted groups and as such is chorooted.
October 26. 2010 | HowtoForge  


Everything looks like it's working fine, I look in the System Log and it shows;

Oct 26 15:30:11 web pure-ftpd: (?@xx.xx.xx.xx) [INFO] New connection from xx.xx.xx.xx
Oct 26 15:30:11 web pure-ftpd: (?@xx.xx.xx.xx) [INFO] testclient-test is now logged in

Unfortunately in the ftp client it says;

220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------
220-You are user number 1 of 50 allowed.
220-Local time is now 15:00. Server port: 21.
220-This is a private system - No anonymous login
220-IPv6 connections are also welcome on this server.
220 You will be disconnected after 15 minutes of inactivity.
USER testclient-test
331 User testclient-test OK. Password required
PASS (password not shown)
230-User testclient-test has group access to: client1 sshusers
230 OK. Current restricted directory is /
211-Extensions supported:
MLST type*;size*;sizd*;modify*;UNIX.mode*;UNIX.uid*;UNI X.gid*;unique*;
211 End.
550 Access is denied.
257 "/" is your current location
200 TYPE is now ASCII
227 Entering Passive Mode (172,16,5,3,248,79)
550 Access is denied.
: //

Recommended Links


FAIR USE NOTICE This site contains copyrighted material the use of which has not always been specifically authorized by the copyright owner. We are making such material available in our efforts to advance understanding of environmental, political, human rights, economic, democracy, scientific, and social justice issues, etc. We believe this constitutes a 'fair use' of any such copyrighted material as provided for in section 107 of the US Copyright Law. In accordance with Title 17 U.S.C. Section 107, the material on this site is distributed without profit exclusivly for research and educational purposes.   If you wish to use copyrighted material from this site for purposes of your own that go beyond 'fair use', you must obtain permission from the copyright owner. 

ABUSE: IPs or network segments from which we detect a stream of probes might be blocked for no less then 90 days. Multiple types of probes increase this period.  


Groupthink : Two Party System as Polyarchy : Corruption of Regulators : Bureaucracies : Understanding Micromanagers and Control Freaks : Toxic Managers :   Harvard Mafia : Diplomatic Communication : Surviving a Bad Performance Review : Insufficient Retirement Funds as Immanent Problem of Neoliberal Regime : PseudoScience : Who Rules America : Neoliberalism  : The Iron Law of Oligarchy : Libertarian Philosophy


War and Peace : Skeptical Finance : John Kenneth Galbraith :Talleyrand : Oscar Wilde : Otto Von Bismarck : Keynes : George Carlin : Skeptics : Propaganda  : SE quotes : Language Design and Programming Quotes : Random IT-related quotesSomerset Maugham : Marcus Aurelius : Kurt Vonnegut : Eric Hoffer : Winston Churchill : Napoleon Bonaparte : Ambrose BierceBernard Shaw : Mark Twain Quotes


Vol 25, No.12 (December, 2013) Rational Fools vs. Efficient Crooks The efficient markets hypothesis : Political Skeptic Bulletin, 2013 : Unemployment Bulletin, 2010 :  Vol 23, No.10 (October, 2011) An observation about corporate security departments : Slightly Skeptical Euromaydan Chronicles, June 2014 : Greenspan legacy bulletin, 2008 : Vol 25, No.10 (October, 2013) Cryptolocker Trojan (Win32/Crilock.A) : Vol 25, No.08 (August, 2013) Cloud providers as intelligence collection hubs : Financial Humor Bulletin, 2010 : Inequality Bulletin, 2009 : Financial Humor Bulletin, 2008 : Copyleft Problems Bulletin, 2004 : Financial Humor Bulletin, 2011 : Energy Bulletin, 2010 : Malware Protection Bulletin, 2010 : Vol 26, No.1 (January, 2013) Object-Oriented Cult : Political Skeptic Bulletin, 2011 : Vol 23, No.11 (November, 2011) Softpanorama classification of sysadmin horror stories : Vol 25, No.05 (May, 2013) Corporate bullshit as a communication method  : Vol 25, No.06 (June, 2013) A Note on the Relationship of Brooks Law and Conway Law


Fifty glorious years (1950-2000): the triumph of the US computer engineering : Donald Knuth : TAoCP and its Influence of Computer Science : Richard Stallman : Linus Torvalds  : Larry Wall  : John K. Ousterhout : CTSS : Multix OS Unix History : Unix shell history : VI editor : History of pipes concept : Solaris : MS DOSProgramming Languages History : PL/1 : Simula 67 : C : History of GCC developmentScripting Languages : Perl history   : OS History : Mail : DNS : SSH : CPU Instruction Sets : SPARC systems 1987-2006 : Norton Commander : Norton Utilities : Norton Ghost : Frontpage history : Malware Defense History : GNU Screen : OSS early history

Classic books:

The Peter Principle : Parkinson Law : 1984 : The Mythical Man-MonthHow to Solve It by George Polya : The Art of Computer Programming : The Elements of Programming Style : The Unix Hater’s Handbook : The Jargon file : The True Believer : Programming Pearls : The Good Soldier Svejk : The Power Elite

Most popular humor pages:

Manifest of the Softpanorama IT Slacker Society : Ten Commandments of the IT Slackers Society : Computer Humor Collection : BSD Logo Story : The Cuckoo's Egg : IT Slang : C++ Humor : ARE YOU A BBS ADDICT? : The Perl Purity Test : Object oriented programmers of all nations : Financial Humor : Financial Humor Bulletin, 2008 : Financial Humor Bulletin, 2010 : The Most Comprehensive Collection of Editor-related Humor : Programming Language Humor : Goldman Sachs related humor : Greenspan humor : C Humor : Scripting Humor : Real Programmers Humor : Web Humor : GPL-related Humor : OFM Humor : Politically Incorrect Humor : IDS Humor : "Linux Sucks" Humor : Russian Musical Humor : Best Russian Programmer Humor : Microsoft plans to buy Catholic Church : Richard Stallman Related Humor : Admin Humor : Perl-related Humor : Linus Torvalds Related humor : PseudoScience Related Humor : Networking Humor : Shell Humor : Financial Humor Bulletin, 2011 : Financial Humor Bulletin, 2012 : Financial Humor Bulletin, 2013 : Java Humor : Software Engineering Humor : Sun Solaris Related Humor : Education Humor : IBM Humor : Assembler-related Humor : VIM Humor : Computer Viruses Humor : Bright tomorrow is rescheduled to a day after tomorrow : Classic Computer Humor

The Last but not Least

Copyright © 1996-2016 by Dr. Nikolai Bezroukov. was created as a service to the UN Sustainable Development Networking Programme (SDNP) in the author free time. This document is an industrial compilation designed and created exclusively for educational use and is distributed under the Softpanorama Content License.

The site uses AdSense so you need to be aware of Google privacy policy. You you do not want to be tracked by Google please disable Javascript for this site. This site is perfectly usable without Javascript.

Original materials copyright belong to respective owners. Quotes are made for educational purposes only in compliance with the fair use doctrine.

FAIR USE NOTICE This site contains copyrighted material the use of which has not always been specifically authorized by the copyright owner. We are making such material available to advance understanding of computer science, IT technology, economic, scientific, and social issues. We believe this constitutes a 'fair use' of any such copyrighted material as provided by section 107 of the US Copyright Law according to which such material can be distributed without profit exclusively for research and educational purposes.

This is a Spartan WHYFF (We Help You For Free) site written by people for whom English is not a native language. Grammar and spelling errors should be expected. The site contain some broken links as it develops like a living tree...

You can use PayPal to make a contribution, supporting development of this site and speed up access. In case is down you can use the at


The statements, views and opinions presented on this web page are those of the author (or referenced source) and are not endorsed by, nor do they necessarily reflect, the opinions of the author present and former employers, SDNP or any other organization the author may be associated with. We do not warrant the correctness of the information provided or its fitness for any purpose.

Last modified: February, 19, 2014