Skip to content
This repository was archived by the owner on Apr 23, 2025. It is now read-only.

Commit b086bc2

Browse files
committed
feat: Add support for active mode
1 parent b78c6bd commit b086bc2

File tree

3 files changed

+45
-27
lines changed

3 files changed

+45
-27
lines changed

README.md

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,16 @@ services:
4949
# If NO_USER_FTP_POSTFIX is set, USER_FTP_POSTFIX is disabled and the user home directory is exposed over ftp
5050
# - USER_FTP_POSTFIX=/data
5151
# - NO_USER_FTP_POSTFIX=true
52-
53-
# - PUBLIC_HOST=custom-host.domain.tld # optional and only used for passive ftp, defaults to localhost
52+
53+
# optional and only used for passive ftp, defaults to 127.0.0.1
54+
# - PUBLIC_HOST=custom-host.domain.tld
5455
ports:
55-
# active ftp
56+
# ftp control
5657
- "21:21"
57-
# passive ftp ports, may differ if you configured them differently
58+
# active ftp
59+
- "20:20"
60+
# passive ftp ports, may differ if you configured them differently with PASSIVE_MIN_PORT_*
5861
- "10090-10100:10090-10100"
59-
6062
# sftp
6163
- "2022:2022"
6264
volumes:
@@ -87,25 +89,27 @@ Both can be used together, so you can use env vars and/or file-based user creati
8789

8890
You can further configure the ftp server using the following environment variables:
8991

90-
| Variable | Usage |
91-
|:--------------------|:------------------------------------------------------------|
92-
| PASSIVE_MIN_PORT | Minimum used passive port |
93-
| PASSIVE_MAX_PORT | Maximum used passive port |
94-
| PUBLIC_HOST | Public host |
95-
| UMASK | customize the ftp umask (default 022 => chmod 777) |
96-
| USER_FTP_POSTFIX | Override the path exposed over ftp, defaults to /data |
97-
| NO_USER_FTP_POSTFIX | Disable USER_FTP_POSTFIX, ftp access to user home directory |
92+
| Variable | Default | Usage |
93+
|:---------------------|:----------|:--------------------------------------------------------------------------------------|
94+
| PASSIVE_MODE_ENABLED | yes | Set to `yes` to enable and to `no`to disable passive mode support |
95+
| PASSIVE_MIN_PORT | 10090 | Minimum used passive port |
96+
| PASSIVE_MAX_PORT | 10100 | Maximum used passive port |
97+
| ACTIVE_MODE_ENABLED | yes | Set to `yes` to enable and to `no`to disable active mode support |
98+
| PUBLIC_HOST | 127.0.0.1 | Public host used for passive mode server address |
99+
| UMASK | 022 | customize the ftp umask |
100+
| USER_FTP_POSTFIX | *None* | Override the path exposed over ftp, defaults to /data |
101+
| NO_USER_FTP_POSTFIX | *None* | Disable `USER_FTP_POSTFIX` by setting to any value, ftp access to user home directory |
98102

99103
#### SFTP
100104

101105
> For SFTP there is currently no further configuration possible and necessary.
102106

103107
#### General settings
104108

105-
| Variable | Usage |
106-
|:-------------------|:-----------------------------------------------------------------------------------------------------------|
107-
| BANNER | Banner displayed at connect using SFTP or FTP |
108-
| ACCOUNT_<username> | Set the value to the password to set for <username>, this will create a user to be used with SFTP and FTP. |
109+
| Variable | Usage |
110+
|:---------------------|:-------------------------------------------------------------------------------------------------------------|
111+
| BANNER | Banner displayed at connect using SFTP or FTP |
112+
| ACCOUNT_`{username}` | Set the value to the password to set for `{username}`, this will create a user to be used with SFTP and FTP. |
109113

110114
#### Ports
111115

@@ -115,7 +119,8 @@ Default ports are:
115119

116120
| Port | Protocol |
117121
|:------------|:------------|
118-
| 21 | Active FTP |
122+
| 20 | Active FTP |
123+
| 21 | FTP control |
119124
| 10090-10100 | Passive FTP |
120125
| 2022 | SFTP |
121126

scripts/entrypoint.sh

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -80,24 +80,32 @@ configure_vsftpd() {
8080

8181
log "FTP" "Append custom config to vsftpd config"
8282
cat <<EOF >> $VSFTPD_CONFIG_FILE
83+
# chroot
8384
allow_writeable_chroot=YES
8485
chroot_local_user=YES
85-
ftpd_banner=${BANNER}
86-
listen_ipv6=NO
86+
passwd_chroot_enable=YES
8787
local_enable=YES
8888
local_root=${DATA_FOLDER}/\$USER${USER_FTP_POSTFIX}
8989
local_umask=${UMASK}
90-
passwd_chroot_enable=YES
91-
pasv_enable=YES
90+
user_sub_token=\$USER
91+
92+
# general
93+
ftpd_banner=${BANNER}
94+
listen_ipv6=NO
95+
write_enable=YES
96+
seccomp_sandbox=NO
97+
vsftpd_log_file=$(tty)
98+
99+
# passive mode
100+
pasv_enable=${PASSIVE_MODE_ENABLED:-'yes'}
92101
pasv_max_port=${PASSIVE_MAX_PORT}
93102
pasv_min_port=${PASSIVE_MIN_PORT}
94103
pasv_addr_resolve=NO
95104
pasv_promiscuous=${PASSIVE_PROMISCUOUS}
96105
pasv_address=${PUBLIC_HOST}
97-
seccomp_sandbox=NO
98-
user_sub_token=\$USER
99-
vsftpd_log_file=$(tty)
100-
write_enable=YES
106+
107+
# active mode
108+
connect_from_port_20=${ACTIVE_MODE_ENABLED:-'yes'}
101109
EOF
102110

103111
log "FTP" "Disable anonymous login"

tests/test_usage.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
from io import BytesIO
22
from tempfile import NamedTemporaryFile
33

4+
import pytest
5+
46

57
def test_crud_sftp(
68
chrooted_ftp_test_container,
@@ -38,7 +40,8 @@ def test_crud_sftp(
3840
assert [] == connection.listdir("/data")
3941

4042

41-
def test_crud_ftp(chrooted_ftp_test_container, create_ftp_connection, wait_for_container_to_be_started):
43+
@pytest.mark.parametrize("is_active", [True, False])
44+
def test_crud_ftp(chrooted_ftp_test_container, create_ftp_connection, wait_for_container_to_be_started, is_active):
4245
# Create account to use in test
4346
chrooted_ftp_test_container.with_env("ACCOUNT_pytest", "test")
4447

@@ -51,6 +54,8 @@ def test_crud_ftp(chrooted_ftp_test_container, create_ftp_connection, wait_for_c
5154
with chrooted_ftp_test_container:
5255
wait_for_container_to_be_started(chrooted_ftp_test_container)
5356
connection = create_ftp_connection(chrooted_ftp_test_container.get_exposed_port(21), "pytest", "test")
57+
if not is_active:
58+
connection.makepasv()
5459

5560
# Create file
5661
connection.storlines("STOR test.txt", BytesIO(b'test'))

0 commit comments

Comments
 (0)