> For the complete documentation index, see [llms.txt](https://book.bsdcn.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://book.bsdcn.org/ask/flat/chapter-36-file-transfer-protocol-ftp/di-36.4-jie-vsftpd.md).

# 36.4 vsftpd

vsftpd (Very Secure FTP Daemon) is designed with security as its primary goal and is widely used in Linux systems. Testing has shown that FTP client access from Windows environments does not produce garbled text.

## Installing vsftpd

Install via pkg:

```sh
# pkg install vsftpd-ssl pam_pwdfile
```

Package descriptions:

| Name         | Description                                                                                                                               |
| ------------ | ----------------------------------------------------------------------------------------------------------------------------------------- |
| vsftpd-ssl   | vsftpd package with SSL support                                                                                                           |
| pam\_pwdfile | A PAM module that allows user authentication using a password file independent of system accounts (similar to the **/etc/passwd** format) |

> **Tip**
>
> On FreeBSD systems, the **/etc/passwd** file is used only for compatibility; actual authentication uses the corresponding database file.

Install via Ports:

```sh
# cd /usr/ports/ftp/vsftpd/ && make install clean
# cd /usr/ports/security/pam_pwdfile/ && make install clean
```

Observe the installation output:

```sh
[2/2] Installing vsftpd-ssl-3.0.5_2...
===> Creating groups
Using existing group 'ftp'
===> Creating users
Creating user 'ftp' with uid '14'
===> Creating homedir(s)
[2/2] Extracting vsftpd-ssl-3.0.5_2: 100%
```

vsftpd creates the user `ftp`. View the UID, GID, and group information for the ftp user:

```sh
# id ftp
uid=14(ftp) gid=14(ftp) groups=14(ftp)
```

## Creating Virtual Users

Add a new system user:

```sh
# adduser
Username: ftptest
Full name:
Uid (Leave empty for default):
Login group [ftptest]: ftp # Note this
Login group is ftp. Invite ftptest into other groups? []:
Login class [default]:
Shell (sh csh tcsh bash nologin) [sh]: nologin # Note this
Home directory [/home/ftptest]:
Home directory permissions (Leave empty for default):
Enable ZFS encryption? (yes/no) [no]:
Use password-based authentication? [yes]:
Use an empty password? (yes/no) [no]:
Use a random password? (yes/no) [no]:
Enter password: # Note this, set the password to z
Enter password again:
Lock out the account after creation? [no]:
Username    : ftptest
Password    : *****
Full Name   :
Uid         : 1003
ZFS dataset : zroot/home/ftptest
Class       :
Groups      : ftp
Home        : /home/ftptest
Home Mode   :
Shell       : /usr/sbin/nologin
Locked      : no
OK? (yes/no) [yes]:
adduser: INFO: Successfully created ZFS dataset (zroot/home/ftptest).
adduser: INFO: Successfully added (ftptest) to the user database.
Add another user? (yes/no) [no]:
Goodbye!
```

The following information has been created:

| Item     | Value     |
| -------- | --------- |
| Username | `ftptest` |
| Password | `z`       |
| Group    | `ftp`     |

## Configuring pam\_pwdfile

Create the PAM configuration file **/etc/pam.d/vsftpd**:

```ini
auth required /usr/local/lib/pam_pwdfile.so pwdfile /usr/local/etc/vsftpd_login.db   # Use PAM module pwdfile for user authentication
account required /usr/lib/pam_permit.so                                           # Use PAM module permit for account validation
```

Create the password database:

```sh
# echo "ftptest:$(openssl passwd -6)" >> /usr/local/etc/vsftpd_login.db
Password: # Enter password z
Verifying - Password: # Re-enter password z
```

The above command adds user `ftptest` to the vsftpd login database and sets the password to `z` (for testing purposes only, this password is not secure!).

To add new users later:

```sh
# echo "new_username:$(openssl passwd -6)" >> /usr/local/etc/vsftpd_login.db
Password: # Enter the new user's password
Verifying - Password: # Re-enter the new user's password
```

Here, `-6`: forces the use of the SHA-512-based Crypt hash algorithm.

## vsftpd Configuration File

The main configuration file for vsftpd is located at **/usr/local/etc/vsftpd.conf**, which can be modified directly; a backup template file is also provided at **/usr/local/etc/vsftpd.conf.sample**.

Modify the **/usr/local/etc/vsftpd.conf** file to the following content:

```ini
# /usr/local/etc/vsftpd.conf sample configuration file
#
# The default compiled settings are quite conservative. This sample file slightly relaxes some settings to make the FTP daemon more practical.
# See vsftpd.conf.5 for all default compiled settings.
#
# Note: This sample file is not an exhaustive list of vsftpd options.
# Please read the vsftpd.conf.5 manual page for a comprehensive understanding of vsftpd's capabilities.
#
# Disable anonymous FTP access
anonymous_enable=NO
#
# Allow local users to log in
local_enable=YES
#
# Enable FTP write operations
write_enable=YES
#
# The default umask for local users is 077. You may wish to change this to 022,
# if your users expect it. (Most other FTP daemons use 022 as the default umask)
# local_umask=022
#
# Uncomment this to allow anonymous FTP users to upload files. This only has an effect if the global write enable above is activated.
# Additionally, you will need to create a directory writable by the FTP user.
# anon_upload_enable=YES
#
# Uncomment this if you want anonymous FTP users to be able to create new directories.
# anon_mkdir_write_enable=YES
#
# Enable directory messages - give messages to remote users when they enter a directory.
dirmessage_enable=YES
#
# Enable upload/download logging.
xferlog_enable=YES
#
# Ensure that PORT transfer connections originate from port 20 (ftp-data).
connect_from_port_20=YES

local_root=/home/ftp
anon_root=/home/ftp
#
# If you want, you can arrange for uploaded anonymous files to be owned by a different user. Note! Using "root" for uploaded files is not recommended!
# chown_uploads=YES
# chown_username=whoever
#
# You may override where the log file goes if you like. The default is shown below.
# xferlog_file=/var/log/vsftpd.log
#
# If you want, you can have your log file in standard ftpd xferlog format.
# Note that the default location for this log file is /var/log/xferlog in this case.
# xferlog_std_format=YES
#
# Idle session timeout in seconds
idle_session_timeout=1800
#
# Data connection timeout in seconds
data_connection_timeout=1200
#
# It is recommended that you define a unique user on your system that the FTP server can use as a totally isolated and unprivileged user.
# nopriv_user=ftpsecure
#
# Enable this and the server will recognize asynchronous ABOR requests. Not recommended for security reasons (the code is non-trivial).
# Not enabling it, however, may confuse older FTP clients.
# async_abor_enable=YES
#
# By default the server will pretend to allow ASCII mode but in fact ignore the request.
# Turn on the below options to have the server actually do ASCII mangling on files when in ASCII mode.
# Beware that on some FTP servers, ASCII support allows a denial of service attack (DoS) via the command "SIZE /big/file" in ASCII mode. vsftpd predicted this attack and has always been safe, reporting the size of the raw file.
# ASCII mangling is a horrible feature of the protocol.
# ascii_upload_enable=YES
# ascii_download_enable=YES
#
# Custom login banner string
ftpd_banner=Welcome to blah FTP service.
#
# You may specify a file of disallowed anonymous email addresses. This may help to combat certain DoS attacks.
# deny_email_enable=YES
# (Default follows)
# banned_email_file=/etc/vsftpd.banned_emails
#
# Specify a list of users to chroot. If chroot_local_user is YES, then this list becomes a list of users to NOT chroot.
# (Warning! chroot can be very dangerous. If using chroot, ensure that the user does not have write permissions to the top-level directory of the chroot)
# chroot_local_user=NO means users in the chroot_list_file will be restricted to the directory specified by local_root
chroot_local_user=NO
chroot_list_enable=YES
# (Default follows)
chroot_list_file=/usr/local/etc/vsftpd.chroot_list
allow_writeable_chroot=YES
#
# Enable the "-R" recursive option for ls. The default is disabled to avoid excessive I/O load on large sites.
# ls_recurse_enable=YES
#
# When "listen" directive is enabled, vsftpd runs in standalone mode and listens on an IPv4 socket. This directive cannot be used in conjunction with the listen_ipv6 directive.
listen=YES
#
# This directive enables listening on an IPv6 socket. To listen on IPv4 and IPv6 sockets, you must run two vsftpd instances with two separate configuration files.
# Make sure one of the listen options is commented out!!
# listen_ipv6=YES

# Secure chroot jail directory path, this directory must be empty and not writable by FTP users
secure_chroot_dir=/usr/local/share/vsftpd/empty

# PID file path when running in the background; by default no PID file is created
# pid_file=/var/run/vsftpd.pid

background=YES

# Use local time
use_localtime=YES
```

For the official documentation, see [VSFTPD.CONF](https://security.appspot.com/vsftpd/vsftpd_conf.html). For a Chinese translation, refer to Jin Buguo's [vsftpd.conf Chinese version](https://www.jinbuguo.com/vsftpd/vsftpd.conf.html).

## The `vsftpd.chroot_list` File

Create and edit the **/usr/local/etc/vsftpd.chroot\_list** file, adding the user `ftptest` to it.

## Creating Paths

Create the FTP directory and set permissions:

```sh
# mkdir -p /home/ftp              # Create the FTP user's home directory
# chown -R ftp:ftp /home/ftp     # Set directory owner and group to ftp
# chmod -R 775 /home/ftp         # Set directory permissions to 775, allowing group users to read and write
```

## Service Management

After configuration is complete, start and manage the vsftpd service:

```sh
# service vsftpd enable    # Set vsftpd service to start on boot
# service vsftpd start     # Start the vsftpd service
# service vsftpd stop      # Stop the vsftpd service
# service vsftpd restart   # Restart the vsftpd service
```

Log in to FTP with the username `ftptest` and the password `z`.

vsftpd log files are located at **/var/log/vsftpd.log**.

## References

angeloma. How to set up vsftpd on FreeBSD 12?\[EB/OL]. (2020-02-13)\[2026-03-25]. <https://www.osradar.com/how-to-set-up-vsftpd-on-freebsd-12/>. Steps for installing and configuring vsftpd on FreeBSD.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://book.bsdcn.org/ask/flat/chapter-36-file-transfer-protocol-ftp/di-36.4-jie-vsftpd.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
