https://hub.docker.com/r/stilliard/pure-ftpd
Docker Pure-ftpd Server
https://hub.docker.com/r/stilliard/pure-ftpd/
Check out our basic example workflow & our slightly more advanced workflow with tls & an auto created user.
Pull down latest version with docker:
docker pull stilliard/pure-ftpd:hardened
Often needing to run as sudo
, e.g. sudo docker pull stilliard/pure-ftpd
If you want to make changes, my advice is to either change the run command when running it or extend this image to make any changes rather than forking the project.
This is because rebuilding the entire docker image via a fork can be very slow as it rebuilds the entire pure-ftpd package from source.
To change the command run on start you could use the command:
option if using docker-compose
, or with docker run
directly you could use:
docker run --rm -d --name ftpd_server -p 21:21 -p 30000-30009:30000-30009 stilliard/pure-ftpd:hardened bash /run.sh -c 30 -C 10 -l puredb:/etc/pure-ftpd/pureftpd.pdb -E -j -R -P localhost -p 30000:30059
To extend it you can create a new project with a DOCKERFILE
like so:
FROM stilliard/pure-ftpd
# e.g. you could change the defult command run:
CMD /run.sh -c 30 -C 10 -l puredb:/etc/pure-ftpd/pureftpd.pdb -E -j -R -P $PUBLICHOST -p 30000:30059
Then you can build your own image, docker build --rm -t my-pure-ftp .
, where my-pure-ftp is the name you want to build as
Starting it
docker run -d --name ftpd_server -p 21:21 -p 30000-30009:30000-30009 -e "PUBLICHOST=localhost" stilliard/pure-ftpd:hardened
Or for your own image, replace stilliard/pure-ftpd with the name you built it with, e.g. my-pure-ftp
You can also pass ADDED_FLAGS as an env variable to add additional options such as --tls to the pure-ftpd command.
e.g. -e "ADDED_FLAGS=--tls=2"
Operating it
docker exec -it ftpd_server /bin/bash
Setting runtime FTP user
To create a user on the ftp container, use the following environment variables: FTP_USER_NAME
, FTP_USER_PASS
and FTP_USER_HOME
.
FTP_USER_HOME
is the root directory of the new user.
Example usage:
docker run -e FTP_USER_NAME=bob -e FTP_USER_PASS=12345 -e FTP_USER_HOME=/home/bob stilliard/pure-ftpd
If you wish to set the UID
& GID
of the FTP user, use the FTP_USER_UID
& FTP_USER_GID
environment variables.
Using different passive ports
To use passive ports in a different range (eg: 10000-10009
), use the following setup:
docker run -e FTP_PASSIVE_PORTS=10000:10009 --expose=10000-10009 -p 21:21 -p 10000-10009:10000-10009
You may need the --expose=
option, because default passive ports exposed are 30000
to 30009
.
Example usage once inside
Create an ftp user: e.g. bob with chroot access only to /home/ftpusers/bob
pure-pw useradd bob -f /etc/pure-ftpd/passwd/pureftpd.passwd -m -u ftpuser -d /home/ftpusers/bob
No restart should be needed.
If you have any trouble with volume permissions due to the uid or gid of the created user you can change the -u flag for the uid you would like to use and/or specify -g with the group id as well. For more information see issue #35.
More info on usage here: https://download.pureftpd.org/pure-ftpd/doc/README.Virtual-Users
Test your connection
From the host machine:
ftp -p localhost 21
Docker compose
Docker compose can help you simplify the orchestration of your containers.
We have a simple example of the docker compose.
& here's a more detailed example using wordpress with ftp using this image.
Max clients
By default we set 5 max clients at once, but you can increase this by using the following environment variable FTP_MAX_CLIENTS
, e.g. to FTP_MAX_CLIENTS=50
and then also increasing the number of public ports opened from FTP_PASSIVE_PORTS=30000:30009
FTP_PASSIVE_PORTS=30000:30099
. You'll also want to open those ports when running docker run. In addition you can specify the maximum connections per ip by setting the environment variable FTP_MAX_CONNECTIONS
. By default the value is 5.
All Pure-ftpd flags available:
https://linux.die.net/man/8/pure-ftpd
Logs
To get verbose logs add the following to your docker run
command:
-e "ADDED_FLAGS=-d -d"
Then if you exec into the container you could watch over the log with tail -f /var/log/messages
Want a transfer log file? add the following to your docker run
command:
-e "ADDED_FLAGS=-O w3c:/var/log/pure-ftpd/transfer.log"
Tags available for different versions
Latest versions
latest
- latest working versionjessie-latest
- latest but will always remain on debian jessiehardened
- latest + more secure/hardened defaults
Previous version before tags were introduced
wheezy-1.0.36
- incase you want to roll back to before we started using debian jessie
Specific pure-ftpd versions
jessie-1.x.x
- jessie + specific versions, e.g. jessie-1.0.36hardened-1.x.x
- hardened + specific versions
Check the tags on github for available versions, feel free to submit issues and/or pull requests for newer versions
Usage of specific tags: sudo docker pull stilliard/pure-ftpd:hardened-1.0.36
An arm64 build is also available here: https://hub.docker.com/r/zhabba/pure-ftpd-arm64 - Thanks @zhabba
Our default pure-ftpd options explained
/usr/sbin/pure-ftpd # path to pure-ftpd executable
-c 5 # --maxclientsnumber (no more than 5 people at once)
-C 5 # --maxclientsperip (no more than 5 requests from the same ip)
-l puredb:/etc/pure-ftpd/pureftpd.pdb # --login (login file for virtual users)
-E # --noanonymous (only real users)
-j # --createhomedir (auto create home directory if it doesnt already exist)
-R # --nochmod (prevent usage of the CHMOD command)
-P $PUBLICHOST # IP/Host setting for PASV support, passed in your the PUBLICHOST env var
-p 30000:30009 # PASV port range (10 ports for 5 max clients)
-tls 1 # Enables optional TLS support
For more information please see man pure-ftpd
, or visit: https://www.pureftpd.org/
Why so many ports opened?
This is for PASV support, please see: #5 PASV not fun :)
Docker Volumes
There are a few spots onto which you can mount a docker volume to configure the server and persist uploaded data. It's recommended to use them in production.
/home/ftpusers/
The ftp's data volume (by convention)./etc/pure-ftpd/passwd
A directory containing the singlepureftps.passwd
file which contains the user database (i.e., all virtual users, their passwords and their home directories). This is read on startup of the container and updated by thepure-pw useradd -f /etc/pure- ftpd/passwd/pureftpd.passwd ...
command./etc/ssl/private/
A directory containing a singlepure-ftpd.pem
file with the server's SSL certificates for TLS support. Optional TLS is automatically enabled when the container finds this file on startup.
Keep user database in a volume
You may want to keep your user database through the successive image builds. It is possible with Docker volumes.
Create a named volume:
docker volume create --name my-db-volume
Specify it when running the container:
docker run -d --name ftpd_server -p 21:21 -p 30000-30009:30000-30009 -e "PUBLICHOST=localhost" -v my-db-volume:/etc/pure-ftpd/passwd stilliard/pure-ftpd:hardened
When an user is added, you need to use the password file which is in the volume:
pure-pw useradd bob -f /etc/pure-ftpd/passwd/pureftpd.passwd -m -u ftpuser -d /home/ftpusers/bob
(Thanks to the -m option, you don't need to call pure-pw mkdb with this syntax).
Changing a password
e.g. to change the password for user "bob":
pure-pw passwd bob -f /etc/pure-ftpd/passwd/pureftpd.passwd -m
Development (via git clone)
# Clone the repo
git clone https://github.com/stilliard/docker-pure-ftpd.git
cd docker-pure-ftpd
# Build the image
make build
# Run container in background:
make run
# enter a bash shell inside the container:
make enter
# test that it's all working with
make test
TLS
If you want to enable tls (for ftps connections), you need to have a valid certificate. You can get one from one of the certificate authorities that you'll find when googling this topic. The certificate (containing private key and certificate) needs to be at:
/etc/ssl/private/pure-ftpd.pem
Use docker volumes to get the certificate there at runtime. The container will automatically enable optional TLS when it detect the file at this location.
You can also self-sign a certificate, which is certainly the easiest way to start out. Self signed certificates come with certain drawbacks, but it might be better to have a self signed one than none at all.
Here's how to create a self-signed certificate from within the container:
mkdir -p /etc/ssl/private
openssl dhparam -out /etc/ssl/private/pure-ftpd-dhparams.pem 2048
openssl req -x509 -nodes -newkey rsa:2048 -sha256 -keyout \
/etc/ssl/private/pure-ftpd.pem \
-out /etc/ssl/private/pure-ftpd.pem
chmod 600 /etc/ssl/private/*.pem
Automatic TLS certificate generation
If ADDED_FLAGS
contains --tls
and file /etc/ssl/private/pure-ftpd.pem
does not exists it is possible to generate self-signed certificate if TLS_CN
, TLS_ORG
and TLS_C
are set.
Keep in mind that if no volume is set for /etc/ssl/private/
directory generated certificates won't be persisted and new ones will be generated on each start.
You can also pass -e "TLS_USE_DSAPRAM=true"
for faster generated certificates though this option is not recommended for production.
Credits
Thanks for the help on stackoverflow with this! https://stackoverflow.com/questions/23930167/installing-pure-ftpd-in-docker-debian-wheezy-error-421
Also thanks to all the awesome contributors that have made this project amazing!https://github.com/stilliard/docker-pure-ftpd/graphs/contributors
================================
vsftp的权限组合配置很强大,但是对于一般人来说比较复杂,老牛从头就开始用vsftp,到现在很多年了
虽然知道其他几种ftp,但这么多年都没安装来试试,今天在一台VPS上需要用到ftp,就顺便换换pure-ftpd试试
安装
修改配置文件pure-ftpd.conf
# #
# Configuration file for pure-ftpd wrappers #
# #
############################################################
# If you want to run Pure-FTPd with this configuration
# instead of command-line options, please run the
# following command :
#
# /usr/sbin/pure-config.pl /etc/pure-ftpd/pure-ftpd.conf
#
# Please don't forget to have a look at documentation at
# http://www.pureftpd.org/documentation.shtml for a complete list of
# options.
# Cage in every user in his home directory
#限制所有用户只能访问主目录
ChrootEveryone yes
# If the previous option is set to "no", members of the following group
# won't be caged. Others will be. If you don't want chroot()ing anyone,
# just comment out ChrootEveryone and TrustedGID.
#信任组ID,不用设置,注释掉
# TrustedGID 100
# Turn on compatibility hacks for broken clients
#是否断开非兼容的客户端,设置no时,兼容ie等比较非正规化的ftp客户端
BrokenClientsCompatibility no
# Maximum number of simultaneous users
#最大连接的客户端数量
MaxClientsNumber 10
# Fork in background
#是否以守护(doemon)进程运行,设置yes
Daemonize yes
# Maximum number of sim clients with the same IP address
#单个IP最大连接数
MaxClientsPerIP 8
# If you want to log all client commands, set this to "yes".
# This directive can be duplicated to also log server responses.
#是否记录所有用户的ftp连接命令
VerboseLog no
# List dot-files even when the client doesn't send "-a".
#客户端未发出-a命令时,是否列出隐藏文件(dot-files)?
DisplayDotFiles yes
# Don't allow authenticated users - have a public anonymous FTP only.
#只允许匿名用户?我们用于非公共ftp,所以要进行认证,不能匿名登录
AnonymousOnly no
# Disallow anonymous connections. Only allow authenticated users.
#设置为yes时,禁止匿名用户登录,只允许认证用户登录
NoAnonymous yes
# Syslog facility (auth, authpriv, daemon, ftp, security, user, local*)
# The default facility is "ftp". "none" disables logging.
#默认( facility )是 "ftp"。 "none" 将禁止日志。
SyslogFacility ftp
# Display fortune cookies
#设置用户登陆后的显示信息
# FortunesFile /usr/share/fortune/zippy
# Don't resolve host names in log files. Logs are less verbose, but
# it uses less bandwidth. Set this to "yes" on very busy servers or
# if you don't have a working DNS.
#//禁止反向解析,在日志文件中不解析主机名。
DontResolve yes
# Maximum idle time in minutes (default = 15 minutes)
#客户端允许的最大的空闲时间,
#MaxIdleTime 15
# LDAP configuration file (see README.LDAP)
#LDAP配置文件目录
# LDAPConfigFile /etc/pure-ftpd/pureftpd-ldap.conf
# MySQL configuration file (see README.MySQL)
#MySQL配置文件目录
# MySQLConfigFile /etc/pure-ftpd/pureftpd-mysql.conf
# Postgres configuration file (see README.PGSQL)
#PGSQL配置文件目录
# PGSQLConfigFile /etc/pure-ftpd/pureftpd-pgsql.conf
# PureDB user database (see README.Virtual-Users)
#删除注释,并启用,如果需要上面那几种数据库来存放用户信息,请自行删除注释
#此为虚拟用户数据库路径,我们创建的虚拟用户就保存在这里
PureDB /etc/pure-ftpd/pureftpd.pdb
# Path to pure-authd socket (see README.Authentication-Modules)
#验证服务pure-authd 的socket 路径
# ExtAuth /var/run/ftpd.sock
# If you want to enable PAM authentication, uncomment the following line
#启用 PAM 认证方式
PAMAuthentication yes
# If you want simple Unix (/etc/passwd) authentication, uncomment this
#unix认证方式,只用一种即可
# UnixAuthentication yes
# Please note that LDAPConfigFile, MySQLConfigFile, PAMAuthentication and
# UnixAuthentication can be used only once, but they can be combined
# together. For instance, if you use MySQLConfigFile, then UnixAuthentication,
# the SQL server will be asked. If the SQL authentication fails because the
# user wasn't found, another try # will be done with /etc/passwd and
# /etc/shadow. If the SQL authentication fails because the password was wrong,
# the authentication chain stops here. Authentication methods are chained in
# the order they are given.
# 'ls' recursion limits. The first argument is the maximum number of
# files to be displayed. The second one is the max subdirectories depth
#递归方式列出文件的数量及深度
LimitRecursion 100000 1
# Are anonymous users allowed to create new directories ?
#是否允许匿名用户创建文件目录
AnonymousCanCreateDirs no
# If the system is more loaded than the following value,
# anonymous users aren't allowed to download.
#设定负载阙值,当系统负载大于以下设定的数值后,将禁止匿名用户下载!
MaxLoad 2
# Port range for passive connections replies. - for firewalling.
#FTP启用主动模式时用到的端口范围,建议设置为31888 to 36888
#主要是不想去改防火墙了,用以前vsftp的防火墙端口规则
PassivePortRange 31888 36888
# Force an IP address in PASV/EPSV/SPSV replies. - for NAT.
# Symbolic host names are also accepted for gateways with dynamic IP
# addresses.
#强制一个IP地址使用被动响应( PASV/EPSV/SPSV replies)
#ForcePassiveIP 192.168.0.1
# Upload/download ratio for anonymous users.
#匿名用户和认证用户下载时的速度比例
# AnonymousRatio 1 10
# Upload/download ratio for all users.
# This directive superscedes the previous one.
#上传下载速度比例设置,全局变量
# UserRatio 1 10
# Disallow downloading of files owned by "ftp", ie.
# files that were uploaded but not validated by a local admin.
#不允许下载ftp属主的文件
AntiWarez yes
# IP address/port to listen to (default=all IP and port 21).
#服务监听的IP 地址和端口。(缺省是所有IP地址和21端口)
# Bind 127.0.0.1,21
# Maximum bandwidth for anonymous users in KB/s
#匿名用户带宽
# AnonymousBandwidth 8
# Maximum bandwidth for *all* users (including anonymous) in KB/s
# Use AnonymousBandwidth *or* UserBandwidth, both makes no sense.
#认证用户带宽
# UserBandwidth 8
# File creation mask.
# 177:077 if you feel paranoid.
#文件和目录的umask
Umask 133:022
# Minimum UID for an authenticated user to log in.
#用户ID至少要大于1000才能登陆
MinUID 1000
# Do not use the /etc/ftpusers file to disable accounts. We're already
# using MinUID to block users with uid < 1000
#是否使用/etc/ftpusers配置文件来禁用帐号,默认为no
UseFtpUsers no
# Allow FXP transfers for authenticated users.
#是否仅允许认证用户进行 FXP 传输?默认为no,这里改yes
AllowUserFXP yes
# Allow anonymous FXP for anonymous and non-anonymous users.
#是否对匿名用户和非匿名用户允许进行匿名 FXP 传输。
AllowAnonymousFXP no
# Users can't delete/write files beginning with a dot ('.')
# even if they own them. If TrustedGID is enabled, this group
# will have access to dot-files, though.
#用户不能删除和写点文件(文件名以 '.' 开头的文件),即使用户是文件的所有者也不行。
ProhibitDotFilesWrite no
# Prohibit *reading* of files beginning with a dot (.history, .ssh...)
#同上
ProhibitDotFilesRead no
# Never overwrite files. When a file whose name already exist is uploaded,
# it get automatically renamed to file.1, file.2, file.3, ...
#是否对已存在的文件自动重命名?必须no
AutoRename no
# Disallow anonymous users to upload new files (no = upload is allowed)
#设置yes禁止匿名用户上传新文件
AnonymousCantUpload yes
# Only connections to this specific IP address are allowed to be
# non-anonymous. You can use this directive to open several public IPs for
# anonymous FTP, and keep a private firewalled IP for remote administration.
# You can also only allow a non-routable local IP (like 10.x.x.x) to
# authenticate, and keep a public anon-only FTP server on another IP.
#设定仅允许来自以下IP地址的非匿名用户连接。
#TrustedIP 10.1.1.1
# If you want to add the PID to every logged line, uncomment the following
# line.
#如果需要为日志每一行添加 PID 去掉下面行的注释
LogPID yes
# Create an additional log file with transfers logged in a Apache-like format :
# fw.c9x.org - jedi [13/Dec/1975:19:36:39] "GET /ftp/linux.tar.bz2" 200 21809338
# This log file can then be processed by www traffic analyzers.
#log文件路径
AltLog clf:/var/log/pureftpd.log
# Create an additional log file with transfers logged in a format optimized
# for statistic reports.
# AltLog stats:/var/log/pureftpd.log
# Create an additional log file with transfers logged in the standard W3C
# format (compatible with most commercial log analyzers)
# AltLog w3c:/var/log/pureftpd.log
# Disallow the CHMOD command. Users can't change perms of their files.
#设置为yes时,不接受 CHMOD 命令。用户不能更改他们文件的属性。
#NoChmod yes
# Allow users to resume and upload files, but *NOT* to delete them.
#设置yes时,允许用户恢复和上传文件,不允许删除他们
#KeepAllFiles yes
# Automatically create home directories if they are missing
#用户主目录不存在的话,自动创建。
CreateHomeDir no
# Enable virtual quotas. The first number is the max number of files.
# The second number is the max size of megabytes.
# So 1000:10 limits every user to 1000 files and 10 Mb.
#删除注释后,启用配额管理,1000:10 就限制每一个用户只能使用 1000 个文件,共10Mb。
#Quota 1000:10
# If your pure-ftpd has been compiled with standalone support, you can change
# the location of the pid file. The default is /var/run/pure-ftpd.pid
#运行时的pid路径
#PIDFile /var/run/pure-ftpd.pid
# If your pure-ftpd has been compiled with pure-uploadscript support,
# this will make pure-ftpd write info about new uploads to
# /var/run/pure-ftpd.upload.pipe so pure-uploadscript can read it and
# spawn a script to handle the upload.
# Don't enable this option if you don't actually use pure-uploadscript.
# 如果你的 pure-ftpd 编译时加入了 pure-uploadscript 支持,这个指令将会使 pure-ftpd
# 发送关于新上传的情况信息到 /var/run/pure-ftpd.upload.pipe,这样 pure-uploadscript
# 就能读然后调用一个脚本去处理新的上传。
#这个功能用好了可以做很多事。。。
#CallUploadScript yes
# This option is useful with servers where anonymous upload is
# allowed. As /var/ftp is in /var, it save some space and protect
# the log files. When the partition is more that X percent full,
# new uploads are disallowed.
#限定上传文件占用硬盘的极限值,超过后不再接收上传数据
MaxDiskUsage 99
# Set to 'yes' if you don't want your users to rename files.
#是否禁止用户重命名已存在的文件
NoRename no
# Be 'customer proof' : workaround against common customer mistakes like
# 'chmod 0 public_html', that are valid, but that could cause ignorant
# customers to lock their files, and then keep your technical support busy
# with silly issues. If you're sure all your users have some basic Unix
# knowledge, this feature is useless. If you're a hosting service, enable it.
#设置为yes,防止chmod修改错误导致文件锁定
CustomerProof yes
# Per-user concurrency limits. It will only work if the FTP server has
# been compiled with --with-peruserlimits (and this is the case on
# most binary distributions) .
# The format is :
# For instance, 3:20 means that the same authenticated user can have 3 active
# sessions max. And there are 20 anonymous sessions max.
#3:20 意思是同一个认证用户最大可以有3个同时活动的进程。而且同时最多只能有20个匿名用户进程。
# PerUserLimits 3:20
# 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
# yes文件相同直接删除旧的,no先保留再更新
NoTruncate yes
# This option can accept three values :
# 0 : disable SSL/TLS encryption layer (default).
# 1 : accept both traditional and encrypted sessions.
# 2 : refuse connections that don't use SSL/TLS security mechanisms,
# including anonymous sessions.
# Do _not_ uncomment this blindly. Be sure that :
# 1) Your server has been compiled with SSL/TLS support (--with-tls),
# 2) A valid certificate is in place,
# 3) Only compatible clients will log in.
# TLS 1
# OpenSSL ciphers suite for TLS sessions.
# Prefix with -C: in order to require valid client certificates.
# If -C: is used, make sure that clients' public keys are installed
# on the server.
# SSL is disabled by default. TLS 1.0, 1.1 and 1.2 are available by
# default.
# TLSCipherSuite HIGH
# Certificate file, for TLS
# CertFile /etc/ssl/private/pure-ftpd.pem
# Listen only to IPv4 addresses in standalone mode (ie. disable IPv6)
# By default, both IPv4 and IPv6 are enabled.
#只允许IPV4连接
IPV4Only yes
# Listen only to IPv6 addresses in standalone mode (ie. disable IPv4)
# By default, both IPv4 and IPv6 are enabled.
# IPV6Only yes
# UTF-8 support for file names (RFC 2640)
# Define charset of the server filesystem and optionnally the default charset
# for remote clients if they don't use UTF-8.
# Works only if pure-ftpd has been compiled with --with-rfc2640
FileSystemCharset UTF-8
ClientCharset UTF-8
添加用户及用户组
添加虚拟用户ftpnow,寄生到系统用户名ftpuser
//pure-pw useradd 虚拟用户名 –u 寄生到系统用户名 –d FTP目录 –m(把用户密码加入PDB数据库中,不需要重启FTP)
按提示输入两次ftpnow用户的密码
修改目录的属主及用户
建立pure-ftpd虚拟用户数据
然后重启,试试用ftp客户端连接吧
centos 7.4 64bit系统下pure-ftpd的操作命令
启动pure-ftpd服务
停止pure-ftpd服务
重启pure-ftpd服务
pure-ftpd状态
设置pure-ftpd开机启动
1、删除pure-ftpd用户
这时,用户的信息会被从指定的 passwd 文件中删除,但是用户的 home 目录会被保留,需要手工删除。
2、修改pure-ftpd用户
3、显示pure-ftpd用户信息
在 /etc/pureftpd.passwd 文件中记录的信息,但不方便用户的阅读,因此 pure-ftpd 提供了显示用户信息的命令。其语法是:
后记:
(1)用后体验比vsftp好,配置简单,清晰明了,分分钟搞定,适合我这种懒人用
(2)生成列表产生的文件比vsftp大一点
pure-ftp连接不上,报错 530 Login authentication failed 处理方法
查看下日志:
其中核心报错为:“account disabled”账户被禁用,
查看pureftpd.conf的配置,其中:
MinUID 500
pure-ftpd配置中只允许uid大于等于500的,才可以登录ftp(系统安全考虑)
我们可以修改配置,把uid阈值调小,也可以在pure-ftp网页管理中设置一个uid大于500的用户。