A dead simple alpine-based docker container to allow users only access their own home directory.
- slim FTP server
- SFTP support
- support for passive mode
- every user is jailed into his own root directory
- Add user entry in form username:password into a file mounted under
/opt/chrooted-ftp/users
. - Mount the desired host volume under
/data/username
- Fire up the server.
- Expose port
21
(also see the sample docker-compose) - Your user can connect to the ftp server, only seeing their files
- Expose port
2022
(also see the sample docker-compose) - If you want to keep the host keys across restarts make sure to mount
/opt/chrooted-ftp/ssh_hostkeys
- Your user can connect to the sftp server on port 2022, the root directory /data contains all files
version: '3.2'
services:
ftp:
image: timoreymann/chrooted-ftp
environment:
- "BANNER=Welcome to my dockerized FTP!"
# USER_FTP_POSTFIX determines the ftp directory inside user home directory and defaults to /data if not set
# If NO_USER_FTP_POSTFIX is set, USER_FTP_POSTFIX is disabled and the user home directory is exposed over ftp
# - USER_FTP_POSTFIX=/data
# - NO_USER_FTP_POSTFIX=true
# optional and only used for passive ftp, defaults to 127.0.0.1
# - PUBLIC_HOST=custom-host.domain.tld
ports:
# ftp control
- "21:21"
# active ftp
- "20:20"
# passive ftp ports, may differ if you configured them differently with PASSIVE_MIN_PORT_*
- "10090-10100:10090-10100"
# sftp
- "2022:2022"
volumes:
# Sample mount for user foo
- /var/www/html:/data/foo
# Mount user list
- ./ftp_users:/opt/chrooted-ftp/users
# Make sure to keep host keys across restarts
- ./ssh_host_keys:/opt/chrooted-ftp/ssh_hostkeys
Users can be configured using the /opt/chrooted-ftp/users
file.
The syntax is username:password
, once per line.
There is also the default user bob
with password s3cr3tCand!
. This user is gone at the moment you mount the users
file.
If using files is not your thing you can also create users with env vars, see the list in General settings for more information. Both can be used together, so you can use env vars and/or file-based user creation.
You can further configure the ftp server using the following environment variables:
Variable | Default | Usage |
---|---|---|
PASSIVE_MODE_ENABLED | yes | Set to yes to enable and to no to disable passive mode support |
PASSIVE_MIN_PORT | 10090 | Minimum used passive port |
PASSIVE_MAX_PORT | 10100 | Maximum used passive port |
ACTIVE_MODE_ENABLED | yes | Set to yes to enable and to no to disable active mode support |
PUBLIC_HOST | 127.0.0.1 | Public host used for passive mode server address |
UMASK | 022 | customize the ftp umask |
USER_FTP_POSTFIX | None | Override the path exposed over ftp, defaults to /data |
NO_USER_FTP_POSTFIX | None | Disable USER_FTP_POSTFIX by setting to any value, ftp access to user home directory |
For SFTP there is currently no further configuration possible and necessary.
Variable | Usage |
---|---|
BANNER | Banner displayed at connect using SFTP or FTP |
ACCOUNT_{username} |
Set the value to the password to set for {username} , this will create a user to be used with SFTP and FTP. |
You must take care of opening/mapping the ports via docker to match your docker configuration.
Default ports are:
Port | Protocol |
---|---|
20 | Active FTP |
21 | FTP control |
10090-10100 | Passive FTP |
2022 | SFTP |
I recommend exposing them as they are to the host, but you can also change them on the host.
See docker docs for more information.
For example usage, see the docker-compose example file above.
The problem this container is solving is the following:
I want to provide ftp for some users, but i dont want to configure the chroot stuff and so on.
So this container is doing exactly that. You can mount /data
as your volume the subfolders are per user.
So you can mount for example a website for a user under /data/bob
and your host volume
is /var/www/bobs.homepage.digital
. Its just that simple.
Under the hood the image is based on alpine and vsftpd. So it size and resource usage is really low.
VSFTPD and SFTP work completely different when it comes to chroot.
VSFTPD works with the user homes out of the box while SFTP chroot requires the common start folder to be owned by root.
To make it work with both, the structure is like this:
/data | user root
<user> | Home folder, owned by root:root
/data | Data folder, owned by <user> - override with USER_FTP_POSTFIX (or disable with NO_USER_FTP_POSTFIX)
This structure allows FTP to acess the data directly, while via SFTP you need to prepend the path /data
I love your input! I want to make contributing to this project as easy and transparent as possible, whether it's:
- Reporting a bug
- Discussing the current state of the configuration
- Submitting a fix
- Proposing new features
- Becoming a maintainer
To get started please read the Contribution Guidelines.