Paranoid Penguin - Secure Anonymous FTP with vsftpd

To keep your FTP site secure, stick to anonymous access only and run an FTP dæmon with minimal complexity.
Standalone Dæmon vs. inetd/xinetd

Before configuring vsftpd itself, you must decide whether to run it as a standalone dæmon or by way of a super-server, inetd or xinetd. In previous versions of vsftpd, its developer recommended using it with xinetd due to xinetd's logging and access-control features. However, vsftpd versions 1.2 and later have native support for most of those features. For this reason, Evans now recommends that vsftpd be run as a standalone dæmon. In addition, a performance cost is associated with using inetd or xinetd. The cost isn't warranted if your system is to be a dedicated FTP server or if you anticipate FTP comprising a significant percentage of your system's activity.

I'm going to take the liberty of using standalone dæmon examples for the remainder of this article. vsftpd's included documentation amply describes how to use vsftpd with inetd and xinetd; see the example configurations included in vsftpd's EXAMPLE directory.

Interestingly, the vsftpd package that comes with SuSE 9 is preconfigured to run from xinetd, while Debian 3.0's runs from inetd. This is especially logical in the latter case, because Debian 3.0 comes with an older version of vsftpd (1.0.0), but SuSE 9.0 uses vsftpd 1.2. The vsftpd RPMs that come with Fedora and Red Hat install vsftpd as a standalone dæmon. At any rate, there are two steps to converting vsftpd from inet/xinetd startup to standalone startup.

First, as I mentioned in the Getting and Installing vsftpd section, you must make sure you've got an enabled startup script for vsftpd in /etc/init.d. The Fedora Core 1 and SuSE 9.0 packages both provide and install one; in SuSE's case it's present but disabled by default, in favor of xinetd. If you used Debian 3.0's vsftpd package or installed vsftpd from source, however, you need to create your own startup script. You also must create the corresponding links in the directories for the runlevels at which you want vsftpd to run, such as rc3.d and rc5.d. The last step is easy to do automatically with chkconfig or update-rc.d.

Second, you need either to disable vsftpd's xinetd file, by setting disable = yes in the file /etc/xinetd.d/vsftpd or to comment out vsftpd's line in /etc/inetd.conf. Alternatively, you can disable inetd or xinetd altogether, if vsftpd was the only important thing it was starting.

Arguably, it's irresponsible of me to recommend that you enable an application's startup script before you've fine-tuned that application's security. In my opinion, enabling is one thing; you're fine so long as you follow through and lock down the service before actually starting it or rebooting your system.

Third, you need to make sure that in /etc/vsftpd.conf the parameter listen is set to YES. This brings us to vsftpd configuration proper.

Configuring vsftpd for Anonymous FTP

Actually, you may not need to do anything more to configure vsftpd for secure anonymous FTP. Its default configuration settings permit only anonymous FTP. What's more, no write commands of any kind are enabled by default, and in recent versions of vsftpd, the dæmon chroots itself to the directory /usr/share/empty whenever possible. This is one of the things I love about vsftpd. It actually takes more work to loosen its security than it does to tighten it down.

Assuming your distribution hasn't altered this default behavior, all you need to do now is populate your anonymous FTP user account's home directory with FTP content for people to download. On Debian 3.0, SuSE 9.0 and Fedora Core 1, the anonymous FTP user is ftp by default, with a home directory of /srv/ftp for Debian and SuSE and /var/ftp in the case of Fedora. If you installed vsftpd from source, the anonymous FTP directory is whatever home directory you assigned to the anonymous FTP user account you created. Pay special attention to ownership and permissions when populating your FTP directories. Defaults may or may not be appropriate, but at least do a quick ls -al now and then to see for yourself.

Even though default settings suffice for many users, let's take a closer look at the vsftpd.conf parameters most relevant to anonymous FTP. By default, this file resides in /etc, but on Red Hat and Fedora systems it resides in /etc/vsftpd/. Listing 1 shows a sample vsftpd.conf file.

In practice, you'd never use a vsftpd.conf file exactly like Listing 1. All parameters in it are, in fact, set to their default values. Rather, this listing is meant as a quick reference. Let's discuss its parameters in turn.

  • listen: tells vsftpd to run as a dæmon rather than as a per-connection process invoked as needed by inetd or xinetd. Default value is NO.

  • listen_address: specifies on which local IP address vsftpd should listen for connections. The default is "" (null), signifying all local IP addresses. If you want to run multiple virtual FTP servers, you need to set this parameter in each virtual server's configuration file (see the next section, Virtual Servers).

  • anonymous_enable: this parameter, whose default is YES, determines whether vsftpd accepts anonymous logins. If set to YES or not set at all, vsftpd accepts connections from the users anonymous and ftp (the two are equivalent) without requiring a real password.

  • ftp_username: the name of the user account used for anonymous logins, that is, FTP logins as anonymous and ftp. This account must exist in /etc/passwd and should have a valid home directory that is not owned by the user account; the default is ftp.

  • anon_root: the directory vsftpd should chroot into for anonymous logins. This defaults to the home directory of the anonymous ftp user account (see ftp_username), but you can use this parameter to set a different anonymous FTP root. Either way, this directory should not be owned by the anonymous ftp user.

  • write_enable: unless this parameter is set to YES, no user may upload any files under any circumstances, regardless of other settings in vsftpd.conf. Its default value is NO.

  • anon_upload_enable: if this parameter and write_enable are both set to YES, anonymous users are permitted to upload files into directories on which the anonymous user account has write permission.

  • anon_mkdir_write_enable: if this parameter and write_enable are both set to YES, anonymous users are permitted to create new directories within directories on which the anonymous user account has write permission.

  • anon_other_write_enable: if this parameter and write_enable are both set to YES, anonymous users are permitted to delete and rename directories within directories on which the anonymous user account has write permission.

  • anon_world_readable_only: if set to YES, this parameter forbids anonymous users from downloading any non-world-readable file. Most useful if anonymous users are able to upload files you don't want other anonymous users to download.

  • anon_max_rate: specifies the maximum data transfer rate, in bytes per second, that anonymous users can use. The default value is 0, which means unlimited.

  • idle_session_timeout: the maximum amount of time, in seconds, allowed to transpire between FTP commands until a session is closed forcibly by the server. Default value is 300, but if you're worried about denial-of-service attacks, you may want to set this lower.

  • ascii_download_enable: if set to YES, this allows users to perform ASCII-mode downloads, as opposed to binary-mode. The default is NO because ASCII-mode is seldom if ever necessary, and it's much less efficient, so much so as to represent a potential vector for denial-of-service attacks.

  • ascii_upload_enable: ASCII-mode uploads, on the other hand, are sometimes necessary for such things as scripts. This parameter's default value is, nonetheless, NO.

  • connect_from_port_20: in active-mode FTP sessions, whenever a user downloads anything, including directory listings, the server initiates a new connection back to the client, conventionally originating from the server's TCP port 20. By default, however, vsftpd originates such connections from a higher, non-privileged port, in order to avoid having to run as root. To change this default behavior, in case your FTP users connect from behind proxies or firewalls that don't expect such behavior, set this parameter to YES.

  • port_enable: set this to NO to disable PORT commands, which effectively disables active-mode FTP altogether. Default is YES.

  • hide_ids: if set to YES, replaces the owner and group fields in all directory listing output to ftp and ftp, respectively. Personally, I think this can be a useful bit of obscurity when used on public FTP servers, but the default is NO.

  • log_ftp_protocol: if set to YES, turns on per-command logging, FTP protocol commands, that is, triggered by but distinct from FTP user-space commands. Invaluable for troubleshooting.

  • syslog_enable: normally vsftpd writes log messages to /var/log/vsftpd.log. Setting this parameter to YES (its default is NO) sends those messages instead to the system's syslog service, using the FTPD facility.

  • max_per_ip: specifies the maximum number of concurrent connections permitted from a single source IP address. Limiting this may seem like a good idea—the default is 0, which means unlimited—but doing so has a disproportionate effect on users connecting from behind NAT/SPAT firewalls, which cause multiple users to appear to originate from the same source IP address.

  • cmds_allowed: specifies a comma-separated list of allowed FTP commands; default value is "" (null), which means unlimited. Only FTP protocol-level commands may be specified, not the commands commonly accepted by FTP client software packages. For example, to allow clients only to list files, change working directories and download files, you'd use cmds_allowed=USER,LIST,NLST,CWD,RETR,PORT,QUIT. The Web site is a useful reference for these commands.

  • local_root: this specifies an empty, root-owned directory to which vsftpd chroots itself any time it doesn't need access to other parts of the filesystem. Default value is /usr/share/empty.

  • nopriv_user: specifies the non-privileged user vsftpd runs as whenever possible. vsftpd obviously needs to be root when doing things like binding to TCP port 21. It demotes itself as soon as it can, however, in order to lessen the chance of a buffer-overflow vulnerability or other process-hijacking event leading to root compromise.

  • ftpd_banner: banner message to display when FTP clients attempt to connect. Default message is hard-coded into vsftpd; in v1.2.0, it's simply (vsFTPd 1.2.0). Alternatively, you can use the parameter banner_file to specify a text file containing your banner message.

The vsftpd.conf(5) man page explains these and many other parameters you can use. Believe it or not, I've only scratched the surface here.



Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Setting up ftp site

Anonymous's picture


I would like to setup a site where people can just click the installer that they want to download the automatically the prompt asking to open or save the file will appear.(no need for any username or email address) The installers are located in a linux server. I have already installed vsftpd the problem is I don't know how to configure my ftp to this setup.

chown based on user

Dustin's picture

Is it possible to have uploaded files have ownership set to the name of the user that uploaded them? For example, if user 'user1' uploads a file, the owner should be 'user1' instead of 'ftp' (the default). Additionally, if 'user2' logs in (and is placed in a different root directory - which I have working fine), the owner of files should be 'user2'. Is this easily possible (and within one vsftpd.conf)? Thank you.


ehsan's picture

i want to anynom users can visit /myftp folder and download some files.

then i want to users lik u1,u2,u3 can login to ftp
and can upload,change files in /myftp sub folders.

u1 should have access to /myftp/folder1
u2 should have access to /myftp/folder1 and /myftp/folder2
u3 should have access to /myftp/ all folders
anonym should not access to /myftp/folder3 !

is it possible?


Problems when starting vsftpd daemon on redhat 4

T. Hoang's picture

1. Very good and detailed article about secure ftp
2. Problems:
When I tried to start "vsftpd &" on Redhat 4, I got the following error:
"./vsftpd: error while loading shared libraries: cannot open shared object file: No such file or directory"

On my server, I only have "/lib/". Please help.

T. Hoang


Anonymous's picture

Thanks Mick ,
It is a very nice article. I think it will help many in configuring
vsftpd in the correct way.
My query is regarding how to configure the server so that my server
support privileged ports. I have enabled the option


but still I am getting the error.

"" Your ftp bounce server doesn't allow privileged ports, skipping

Please clarify me what options I have to enable so that my server
supports privileged port...

With thanks in advance.....

vsftpd: does not run standalone, must be started from inetd

Anonymous's picture

please help me rectify this problem

quota per viretual user

Anonymous's picture

Is there a way to set quota for virtual user?

disk quotas for anmonymous ftp users

Anonymous's picture

Yes you can, but with a separate package not related to vsftpd but to Linux. Check Red Hat for info. It is similar for all Linux versions.
It is not difficult but a bit laborious for the first setup. After that it's transparent.

IP Based access permission using vsftpd

UDIT's picture

hi i have established a vsftp server on my fedora core 3 m/c. now i want to have restriction on the ips that access my server. How could i set permission and access rights based on the ips of the systems.

setup iptables to control

Anonymous's picture

setup iptables to control who can access particular ip and ftp port. The rest can be done through config file, since every virtual ftp server has its own config file.

IP Based access permission using vsftpd

sam chester's picture

I've the same problem. How can we set permission and access rights based on the ip of systems?? Help plz.

anon_umask, I think!

pcoleman's picture

I have everything working fine except when anonymous writes a file it always gets the permissions 600. No matter what I do to the anon_umask it stays the same. Does anyone have any idea how to change this and make it upload a file with different permissions?



anon_umask, I think!

Anonymous's picture

I have the same problem. Did you ever get an answer to this?

exactly same problem, still

Anonymous's picture

exactly same problem, still no answer

Name Based Vhost ?

Rakotomandimby Mihamina's picture

How about name based virtual host please? Is it possible?

500 OOPS: Could not bind listening IPv4 socket

Anonymous's picture

i am using Fedora Core 3 and installed VSFTPD, but when i try to check my FTP server i always get 500 OOPS: Could not bind listening IPv4 socket. I have followed the steps to setup VSFTPD but still i got this error, What could be my problem?

Check your vsftpd.conf file.

Dan's picture

Check your vsftpd.conf file. If the command "listen=YES" is not commented out, then comment it out. For some reason, the example file seems to enable it by default. When enabled, it can only run in the "stand-alone" mode, not from xinetd.

Re:500 OOPS: Could not bind listening IPv4 socket

Anonymous's picture

I just stopped the inetd service, and the started the indivdual VSFTPD service, and it worked fine for me


Re:500 OOPS: Could not bind listening IPv4 socket

Deepak Naik's picture

Sorry, the xinetd service I stopped, not the inetd service

Might be the firewall!

Laurin's picture

I had the same problem. Dont know why, the ipconfig-firewall closed port 20 & 21 to the inner systen. (SUSE 9.2 prof) Guard from inner system (or how it is called like in English) is NOT activated.

Solution: Do NOT open the ports 20 & 21 in the experts-firewall-settings. Does not work.
You have to type there "ftp" - and make your vsftpd listen to your inner system only (if you want it to), using listen_at=(IP) in standalone-mode.

Happy computing — Laurin.

hi Modify the /etc/vsftpd/vs

Anonymous's picture

Modify the /etc/vsftpd/vsftpd.conf
Rem the line #Listen=YES
Restart xinetd
#services xinetd restart

works for me on fedora core 3

OOPS error

Mika's picture

worked with OpenSuSE 10.1 aswell.

Thanks a lot!

This worked for me as well.

Dlogan's picture

This worked for me as well. Centos 4.0.

500 OOPS: vsftpd: refusing to run with writable anonymous root

Markus Merz's picture

500 OOPS: vsftpd: refusing to run with writable anonymous root

This very common error appears when the FTP root directory is writable.

I found the simple solution in an Oracle manual

To avoid this error:
500 OOPS: vsftpd: refusing to run with writable anonymous root

# chmod u-w /srv/ftp
# mkdir /srv/ftp/pub
# chown ftp:ftp /srv/ftp/pub

The first line takes care of the root directory being not writable.
The second line creates a directory.
The third line changes the owner to the user and group ftp.

The ftp root directory MUST NOT be owned by ftp for security reasons (it should be root:root).

I just had to find out about this solution yesterday 15.2.05 - so I hope it helps somebody else.

best regards


Thank you for the tip

MarbolanGos's picture

It is an old tip you gave but it saved me, I was trying to find the solution sincze a month when someone pointed me that topic.

Thanks !

anonymous user still cannot upload files

peter's picture

Dear markus,
I followed your steps as
# chmod u-w /srv/ftp
# mkdir /srv/ftp/pub
# chown ftp:ftp /srv/ftp/pub

Just changed srv to var. It does not work for me. I cannot figure out
what "chown ftp:ftp /srv/ftp/pub" means.

I believe my vsftpd.conf is ok.

chown changes owner to usr

Anonymous's picture

chown changes owner to usr ftp, group frp for the file /srv/ftp/pub. Anyway, man chown would have answered your question straight.

Exactly why is this in an

Strykar's picture

Exactly why is this in an Oracle handbook.
You saved me many hours of grief Markus, thanks a ton.

500 OOPS: vsftpd: refusing to run with writable anonymous root

Stan Omoregie's picture

Thanks Markus for the tip. It saved my day...

Anonymous FTP Write permissions with vsftpd

KC's picture

500 OOPS: vsftpd: refusing to run with writable anonymous root.

My FTP root was not readable, so vsftpd would start, but I couldn't get it to allow anonymous uploads, no matter what I did. I looked for hours for the answer! Why is it not spelled out a little more clearly in the docs?? Why do you have to look at an Oracle Manual to find an obvious VSFTPD config issue??

Markus, you have HUGE props in my book for putting that info down...too bad it took a few hours of goolge, change config, get frustrated, repeat before I came across this post.

I think I'll drop by and relay this info. Thanks again.

More anonymous FTP uploading problems

Stu Hill's picture

Gah! I am also trying to get anonymous to be able to write. I have got this working on one fedora8 box, but on another fedora8 I cannot get it to allow me to write, the clues on the non-working machine are :

yum list|grep vsftpd
vsftpd.i386 2.0.5-19.fc8 installed
system-config-vsftpd.noarch 0.5.1-1.fc8 updates-newkey
vsftpd.i386 2.0.5-21.fc8 updates-newkey

vsftpd.conf contains (copied from the working machine) ::

ls -l /var
drwxr-xr-x 3 root root 4096 2009-09-26 21:12 ftp

ls -l /var/ftp
drwxr-xr-x 2 ftp ftp 4096 2009-09-26 21:12 pub

grep ftp /etc/passwd
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin

FTP allows me to login and cd into pub but then i am unable to create a directory !!!

What else can i check for, as like i said it is working on one machine but not another...

Anonymous FTP Write permissions with vsftpd

Nico's picture


And what if you want to have the FTP root filesystem writable by the anonymous user in order to have file uploads processed by automation from another system that connects as anonymous ?

If someone knows...


anonymous ftp

Anonymous's picture

set in vsftp.conf

giving the pub write access

that just takes you back to

fluxdude's picture

that just takes you back to the beginning of having a root that is writeable by anonymous...

make the root some dir and then create a pub dir inside that and chown that pub directory to the ftp user.

Anonymous must then ftp, cd to pub and then upload.