Proftpd

更新日期: 2022-06-22

 

目錄

介紹

Proftpd 是一個功能十分強大的 FTP Server 來. 它有纇似 Apache 的 Configure,

如 <Directory "Path">  ............. </Directory>

而且它還有 ".ftpaccess" 這是 run-time confure 的能力.

它同時支援加密了的 ftpssftp

 


安裝

 

# Ubuntu

apt-get install proftpd-basic

# Centos ( epel )

yum install proftpd proftpd-utils

 


基本的 proftpd 設定檔

 

Debian

Proftpd 的主設定檔在 /etc/proftpd/proftpd.conf

如果要開機時自動啟動它, 那就要將 /etc/default/proftpd 檔內的 RUN 改為 "yes"
 

Centos 6

/etc/proftpd.conf

 


Checking

 

-v, --version                # Print version number and exit

ProFTPD Version 1.3.3g

-l, --list                       # List all compiled-in modules

Compiled-in modules:
  mod_core.c
  mod_xfer.c
  mod_auth_unix.c
  mod_auth_file.c
  mod_auth.c
  mod_ls.c
  ...

P.S.

Centos6 modules path: /usr/libexec/proftpd

-S, --serveraddr     # Specify IP address for server config

-t                          # test config

Checking syntax of configuration file
 - Fatal: unknown configuration directive 'SFTPClientAlive' on line 13 of '/etc/proftpd.d/sftp.conf'

 


我的設定值

 

我的 Proftpd 設定, 歡迎參考 ^ , ^

##################   Share Configure   ###################

# Set the message displayed on connect
# ServerIdent off|on string
# off => displays "[hostname] FTP server ready."
ServerIdent               on "FTP Server ready."

# 它用來指定要載入那些 modules,  可用的 module 存放在 /usr/lib/proftpd
# proftpd 相當 Pro , 它可以在執行時 insmod/rmmod !!  (ModuleControlsACLs)
# defaulf 是會載入以下 modules
#   mod_tls,  mod_dynmasq, mod_quotatab, mod_ratio,
#   mod_delay, mod_ctrls, AdminControlsEngine
Include                   /etc/proftpd/modules.conf

# 載入其他的設定檔
# 而這裡的是 mod_tls modules 的設定
Include                   /etc/proftpd/tls.conf

#################################
# 啟動
#################################

# server 不以 inetd 形式來執行
ServerType              standalone

# 當找不到 "virtual server" 時, 是否用 primary server (自動進入 primary server)
# Only a single server configuration can be set as the DefaultServer.
# 如果 Off, 那用戶就會收到 message
# "no server available to service your request"
# "500 Sorry, no server available to handle request on x.x.x.x"
DefaultServer           on

# Proftpd 啟動後的執行身份
User                    vftp
Group                   vftp

#################################
# Server 資訊
#################################
# 顯示資訊而已, 可有可無.
# ServerName -- Configure the name displayed to connecting users
ServerName             "ProFTPD server"

DeferWelcome           on

DisplayLogin           /home/ftp/welcome.msg
DisplayChdir           .message true

#################################
# IP & Port
#################################
# 是否啟用 IPv6 的協定
# 不會 listen "tcp        0      0 :::21"
UseIPv6            off

# CMD Port
# 0 effectively turns off that server (如果啟動 sftp 時就用到此設定)
Port               21

# 當 FTP Server 在 firewall 後時(NAT), 必須的設定來
PassivePorts       9001 9100

# 亦可以用 MasqueradeAddress  <ip> 這格式表示
MasqueradeAddress  datahunter.org

# 當網絡沒有 Fix IP 時, 這是必須的設定來. 它是由 
# 它是指每隔多久(秒)再檢查及更新 MasqueradeAddress 的 ip, 在 log 會有
# myserver: mod_dynmasq/0.2: MasqueradeAddress 'datahunter.org' has not changed addresses
DynMasqRefresh     600

#DisplayLogin welcome.msg
#DisplayFirstChdir .message
# 它們是存放在 Home 目錄的,
# welcome.msg 是 login 時顯示的
# DisplayFirstChdir 是進入目錄時顯示的

# sets the the address the main server instance will bind to
# DefaultAddress [ dns-names|ip-addresses seperated with spaces]
# Default: none
# Context: server config
DefaultAddress x.x.x.x

# A specific listen connection is created for each additional address.
# proftpd creates two sockets again, however one is bound to 10.0.0.1, port 21
# and the other to 10.0.0.2, port 2001. Because these sockets are "tightly"
# bound to IP addresses, port 21 can be reused on any address OTHER than
# 10.0.0.1, and visa-versa with 10.0.0.2, port 2001. 
# One side-effect of setting SocketBindTight to on is that connections to non-bound addresses will result in 
# a "connection refused" message rather than the typical "500 Sorry, no server available to handle request 
# on xxx.xxx.xxx.xxx.", due to the fact that no listen socket has been bound to the particular address/port pair. 
# This may or may not be aesthetically desirable, depending on your circumstances.
SocketBindTight on

#################################
# 資源
#################################

# 是否嘗試把用戶的 ip 轉譯成 domain name
UseReverseDNS       off

# 支援幾多個 concurrent connections
MaxInstances          30

#################################
# 人數限制
#################################

# 同時可以有多少個 authenticated clients
MaxClients                 15                "本站只支援同時 15 人在線 !!"

# 每 ip 最多可有幾多個連接
MaxClientsPerHost          9                 "你的網絡已有多個同戶在這裡了 !!"

# 每 account 只可有 3 個連接
MaxClientsPerUser          3                  "一個 account 只可同時做 3 件事"

# 最多 8 人共用一 account
MaxHostsPerUser            8                  "你登入的帳戶已有多人在使用中 ~"

#################################
# Timeout
#################################

# 在幾多秒內要完成 USER/PASS 登入
TimeoutLogin          30

# port 20 及 21 沒有資料傳遞
TimeoutIdle            300

# port 20 存在, 但沒有資料傳遞
TimeoutStalled        600

#################################
# 特性
#################################

# attempt to identify the remote username
# ident protocol (RFC1413)
# Default on
IdentLookups        off

# 列出檔案的形式
# -l 是指 "one file per line"
ListOptions         "-l"

# 是否顯示 Symlinks
# Default on
# off => proftpd displays the link as a directory entry of type 'l' (link) 
#        with the ownership and permissions of the actual link.

ShowSymlinks        on

# 可以續存上載 (upload)
AllowStoreRestart   on

# multiline responses as per RFC 959 ( Code 200 )
MultilineRFC2228    off

# 系統用 GMT 時間 (Default: on) 
TimesGMT            off

# ascii(Default) | binary
# ascii => carriage-return/linefeed translation will be performed
DefaultTransferMode binary

#################################
# 安全
#################################

# 用法 DefaultRoot  directory [group-expression,  .... ]
# Default: DefaultRoot /
#
# 將所有用戶都鎖在 /home/ftp/share 內, 不可離開這 Folder
# DefaultRoot                   /home/ftp/share
#
# Cause every FTP user except adm to be chrooted into their home directory
# 如果改為 "~" 的話, 那則是鎖在每用戶的 "家目錄" 內
# group-expression 是指要鎖的 group, 不鎖的就用 !group 表示
DefaultRoot                     ~ !adm

# 由於我是用 "虛擬用戶" 的, 所以是否要有 ValidShell 都不重要
# 因為它們本身都不能登入系統的
RequireValidShell                off

# root 不能 login
RootLogin                        off

Umask                            022  022

# disconnected & logged
MaxLoginAttempts                 2

# 如果中 以上 regular expression ,
# 那會有 msg "Forbidden command" 給 client
DenyFilter                          \*.*/

#  files 可以被 overwrite
AllowOverwrite                   on

# PORT port 可以不用於 ftp control connection port 的 IP ( 20 及 21)
# 用來實現 FXP 及  FTP over SSH
AllowForeignAddress              on

################################
# 本機帳戶
################################

# Use pam to authenticate (default) and be authoritative
AuthPAMConfig                   proftpd
AuthOrder                       mod_auth_pam.c* mod_auth_unix.c

################################
# 虛擬戶
################################

#Include                   /etc/proftpd/vuser.conf

################################
# Log Format
################################

Include                   /etc/proftpd/log.conf

##############################
# 其他 modules 的設定
##############################

DelayEngine              on

ControlsEngine           off
ControlsMaxClients       2
ControlsLog              /var/log/proftpd/controls.log
ControlsInterval         5
ControlsSocket           /var/run/proftpd/proftpd.sock

AdminControlsEngine      off

##############################
# Share Config 
##############################

<Directory />
   AllowOverwrite off
</Directory>

<Directory /home/ftp/share>
    TransferRate RETR 50
    # 限速 每進程 50kbyte/sec
    <Limit WRITE>
         Denyall
    </Limit>
</Directory>

# 可以上載檔案, 不過不可以查看及覆寫已上載的檔案
<Directory /home/ftp/upload/*>
    Umask  022  022
    <Limit READ WRITE>
        Denyall
    </Limit>
    <Limit STOR>
        Allowall
    </Limit>
</Directory>

# anonymous user setting
Include                   /etc/proftpd/anonymous.conf

# VirtualHost Configure
Include                   /etc/proftpd/virtualhosts.conf

################## END Share Configure ###################

 


log

 

There are three main types of logs that a proftpd daemon can generate:

  • TransferLog
  • SystemLog
  • ExtendedLog

/etc/proftpd/log.conf

# module: mod_core
# Default: None 
# xferlog format log (man 5 xferlog)
# upload(i) & download(o) & delete (d) log ONLY
TransferLog            /var/log/proftpd/xferlog

# module: mod_log
# The SystemLog directive disables proftpd's use of the syslog mechanism
# and instead redirects all logging output to the specified path
# login & logout loxferlog ONLY
SystemLog              /var/log/proftpd/proftpd.log

# create a custom logging format for use with the ExtendedLog directive
# LogFormat: format-name format-string
LogFormat default      "%h %l %u %t \"%r\" %s %b"
LogFormat auth         "%v [%P] %h %t \"%r\" %s"

# 支援 Multiple logfiles
ExtendedLog /var/log/ftp.log READ,WRITE

# Disable sendfile by default (since it breaks displaying the download speeds in ftptop and ftpwho)
UseSendfile             off

ServerLog path

The ServerLog directive is used to configure a <VirtualHost>-specific logfile at the given path,

rather than a single SystemLog for the entire configuration.

LogFormat variables:

%h     Remote client DNS name
%l      Remote username (from identd), or "UNKNOWN" if IdentLookup failed
%u      Authenticated local username
%t      Current local time
%r      Full command received from client
%s      Numeric FTP response code (RFC 959)
%b      Number of bytes sent for this command

%a                    Remote client IP address
%F                    Filename stored or retrieved
%{protocol}           Current protocol: "ftp", "ftps", "ssh2", "sftp", "scp"
%T                    Time taken to transfer file, in seconds
%{transfer-failure}   Reason for data transfer failure (if applicable), or "-"
%{transfer-status}    Status of data transfer: "success", "failed", "cancelled", "timeout", or "-"

ExtendedLog path [cmd-classes [format-name]]

cmd-classes parameter is a comma-delimited (with no whitespace) list of which commands to log:

ALL     All commands except the EXIT pseudo-command (default)
NONE    No commands
AUTH    Authentication commands: ACCT, PASS, REIN, USER
INFO    Informational commands: FEAT, HELP, MDTM, QUIT, PWD, STAT, SIZE, SYST, XPWD
DIRS    Directory commands: CDUP, CWD, LIST, MKD, MLSD, MLST, NLST, RMD, XCWD, XCUP, XMKD, XRMD
READ    File reading: RETR
WRITE   File/directory writing or creation: APPE, MFF, MFMT, MKD, RMD, RNFR, RNTO, STOR, STOU, XMKD, XRMD
MISC    Miscellaneous commands: ABOR, ALLO, EPRT, EPSV, MODE, NOOP, OPTS, PASV, PORT, REST, RNFR, RNTO, SITE, SMNT, STRU, TYPE
SEC     RFC2228-related security FTP commands: AUTH, CCC, PBSZ, PROT
EXIT    Logs the configured LogFormat at session exit.
NOTE:   EXIT is not part of the ALL command class, in order to preserve backward-compatible ALL behavior.

My Setting

# log setting
SFTPLog     /dev/null
LogFormat   sftp-transfer-log "%a %{protocol} %u %t \"%r\" %s %{transfer-status} %b %T"
ExtendedLog /var/log/proftpd/transfer.log AUTH,READ,WRITE sftp-transfer-log

Output

login fail:

s.s.s.s ssh2 - [05/Mar/2019:16:35:44 +0800] "USER sftp_username" 331 - - -
s.s.s.s ssh2 - [05/Mar/2019:16:35:46 +0800] "PASS (hidden)" 530 - - -

login success

s.s.s.s ssh2 sftp_username [05/Mar/2019:08:36:23 +0000] "PASS (hidden)" 230 - - -

upload

s.s.s.s scp sftp_username [05/Mar/2019:08:32:38 +0000] "STOR /test-file.txt" - success 4 0.003

download

s.s.s.s scp sftp_username [05/Mar/2019:08:33:35 +0000] "RETR /test-file.txt" - success 4 0.003

remove

s.s.s.s sftp sftp_username [05/Mar/2019:08:38:05 +0000] "DELE /test-file.txt" 250 - 4 -
s.s.s.s sftp sftp_username [05/Mar/2019:08:38:05 +0000] "REMOVE /test-file.txt" 0 - - -

 


LoadModule

 

IfModule: 由 mod_core 提供

LoadModule: Build 時要有 --enable-dso 才有 LoadModule

LoadModule mod_sftp.c
<IfModule mod_sftp.c>
    Include                   /etc/proftpd.d/sftp.conf
</IfModule>

 


有關執行檔

主程式:

/usr/sbin/proftpd                       FTP daemon

資訊:

它們都是透過 /var/run/proftpd/proftpd.scoreboard 獲得資訊~

ftpcount           # show the current number of connections per server/virtualhost (C6 Package: proftpd-utils)

ftptop              # 即時狀況 (PID, S, USER, CLIENT, SERVER, TIME, COMMAND) (C6 Package: proftpd-utils)

ftpwho            # 查看有什麼人在 FTP 上, 以及當時人數 (C6 Package: proftpd-utils)

ftpmail            # monitor transfer log and send email when files uploaded (C6 Package: proftpd-utils)

ftpstats           # 檔案目錄的上下載及流量統計

管理 tools:

ftpasswd                     # 管理虛擬用戶檔 (C6 Package: proftpd-utils)

ftpquota                      # 管理用戶 Quota (C6 Package: proftpd-utils)

ftpdctl                         # ProFTPD control program

ftpscrub                       # scrub the proftpd scoreboard file of stale entries

ftpshut                        # 定時關 FTP 服務器的指令

proftpd-gencert           # 建立 TLS 要用的檔案

 


Limit 的動作

 

CWD     Change Working Directory,變換目錄之意

MKD     MaKe Directory,可建立目錄與否

RNFR    ReName FRom,可更改檔名與否

DELE    DELEt,可刪除檔案語法

RMD     ReMove Directory,可移除目錄與否

RETR    RETRieve,下載之意!由 Server 傳送資料到 Client

READ    讀取目錄用的資訊

WRITE   寫入(上載)

STOR    STORe, 上傳

ALL       全部的動作!

 


虛擬用戶

 

介紹

ftpasswd 指令是用來建立虛擬用戶的資料庫

資料庫的格式與 /etc/passwd 差不多

Proftpd 設定

/etc/proftpd/vuser.conf

# Virtual User Setting

# 只用虛擬用戶認證
# mod_auth_unix.c 是系統用戶
AuthOrder                mod_auth_file.c

# 虛擬用戶認證檔的所在地
AuthUserFile             /etc/proftpd/ftpd.passwd
AuthGroupFile            /etc/proftpd/ftpd.group
RequireValidShell        off

# make listed files appear to be owned by the logged-in user
# DirFakeUser On|Off [username]
# "On"   DirFakeUser will display all files as being owned by user 'ftp'
# "~"    display the current user's username
# Client 會"看到"所有檔案都是屬於 ftp 這用戶的
DirFakeUser              on       ftp
DirFakeGroup             on       ftp

# FTP 以 vftp 身分行
# 因為 proftpd 啟動後再沒 root process, 所以此身份要 R/W 到 /home/ftproot
User                     vftp
Group                    vftp

# Chroot
DefaultRoot              ~

準備

# vuser

groupadd -g 3001 vftp

useradd -u 3001 -g 3001 vftp -d /home/ftproot -m

chmod 770 /home/ftproot/

# pw file

mkdir /etc/proftpd

cd /etc/proftpd

touch ftpd.passwd ftpd.group

chgrp vftp ftpd.passwd ftpd.group

chmod 640 ftpd.passwd ftpd.group

Help

ftpasswd --help

ftpasswd --version

1.3.0

 


ftpasswd

 

建立用戶

# 必須 cd 到相應 Folder

# 它會更新在當前目錄的 ftpd.passwd (如果它不存在會自動建立它)

cd /etc/proftpd

# --uid 及 --gid 會 map 成主機上的真實用戶,

# --file      Write output to specified file, rather than "./ftpd.passwd"

grep vftp /etc/passwd

vftp:x:2004:2004::/home/ftproot:/bin/false

ftpasswd --passwd --name=tim --uid=2004 --gid=2004 --home=/home/ftproot/tim --shell=/bin/false

P.S.

--passwd 是必須的 ( --passwd, --group, or --hash )

'--passwd' specify whether ftpasswd is to operate on a passwd(5) format file

--name --uid --gid --home --shell 都是必須

建立 home directory

mkdir /home/ftproot/tim -p

chown vftp. /home/ftproot -R

chmod 770 /home/ftproot -R

更改 Password:

ftpasswd --passwd --change-password --name guest

建立群組

ftpasswd --group --gid 2004 --name ftpgroup

Delete:

--delete-user

ftpasswd --passwd --delete-user -name myfriends

--delete-group

Lock / Unlock Account

-l, --lock

-u, --unlock

其他選項:

--not-system-password

Double-checks the given password against the system password for the user,

and requests that a new password be given if the entered password is the same as the system password.

 


CLI Usage

 

ftpshut

當有 /etc/shutmsg 存在時, Proftpd 會根據它的時間設定來關站

Usage

ftpshut [ -R ] [ -l min ] time [ warning-message ]

# 刪除 /etc/shutmsg (即不關了)

ftpshut -R

# 在晚上 11:30 之後不能再 login, 12:00 關站

ftpshut -l 30 0000 "站快關了, 請明天再來啦"

                                             


ftps - TLS 加密認證 (module mod_tls)

 

ftps port

  • explicit: 21/tcp
  • Implicit: 990/tcp

 * By default, mod_tls requires that the same SSL session be used data transfers,

    which includes uploads, downloads, and directory listings.

建立公匙及私匙:

Openssl:

openssl req -new -x509 -days 365 -nodes \
-out /etc/proftpd/ssl/proftpd.crt \
-keyout /etc/proftpd/ssl/proftpd.key

chmod 0400 /etc/ssl/private/proftpd.key

FTPS 的主設定檔 (ftps.conf)

proftpd.conf

# ftps
TLSSessionCache     internal: 1800
Include             /opt/proftpd/etc/proftpd.d/ftps/ftps.conf

ftps.conf

<VirtualHost 0.0.0.0>
    # 啟用 TLS Engine
    # (Client 可以選擇是不是用 TLS 連接)
    TLSEngine                     on

    # 當不設定而 21/TCP 又沒使用時就會用 21
    Port                          990

    # TLSRequired on/off/ctrl/data
    # off: 不用 TLS 時仍可用原來的 login 方式
    # on:  Both channels (ctrl+data)
    TLSRequired                   on

    # Log
    TLSLog                        /var/log/proftpd/ftps.log

    # TLSProtocol ALL -SSLv3
    TLSProtocol                   TLSv1.2

    # 公匙及私匙存放的地方
    TLSRSACertificateFile         /etc/proftpd/ssl/proftpd.crt
    TLSRSACertificateKeyFile      /etc/proftpd/ssl/proftpd.key
    TLSCertificateChainFile       /etc/proftpd/ssl/ca-bundle

    # Diffie-Hellman(DH) file
    TLSDHParamFile                /etc/proftpd/ssl/dhparams.pem

    # configure various optional behavior of mod_tls
    # Default: None
    # AllowDotLogin: ~/.tlslogin 是否有相應的公匙, 如果有就不再問 Password login
    TLSOptions                    AllowDotLogin

    # Client Authentication. Default: off
    # Client 連線時檢查他們的 certificate 是否同一 CA 簽發 (TLSCACertificatePath)
    TLSVerifyClient               off

    # maximum number of seconds for mod_tls to accept an SSL/TLS handshake
    # Default: 300
    TLSTimeoutHandshake           60
</VirtualHost>

Session Cache Setting (mod_tls_shmcache)

# Syntax: TLSSessionCache "off"|type:/info [timeout]
# Modern FTP clients often create multiple simultaneous connections to an FTP server
# If the TLSSessionCache directive is not used, then OpenSSL's default internal SSL session caching will be used.

LoadModule mod_tls_shmcache.c

TLSSessionCache shm:/file=/var/run/proftpd/sesscache

Session Cache & Renegotiate Key

By default, mod_tls uses OpenSSL's "internal" session cache, cache timeout of 5 minutes

(which is an in-memory caching of SSL session IDs.)

  * Some FTPS clients, do not support server-initiated SSL/TLS renegotiations.

# TLSRenegotiate ["ctrl" secs] ["data" Kbytes] ["timeout" secs]|["required" on|off]|"none"

# ctrl = control channels, data = data channels

# TLSRenegotiate ... required off   <= 選擇性換 key

# TLSRenegotiate ... none           <= 不需要換 key

# TLSRenegotiate ... timeout <sec>  <= 多久要完成換 key

By default, mod_tls will perform renegotiations if supported,

on the control channel after 4 hours, and on the data channel after one gigabyte of transferred data.

TLSRenegotiate ctrl 1500 timeout 300
TLSSessionCache internal: 1800

TLSCertificateChainFile 與 TLSCACertificatePath

TLSCertificateChainFile

all-in-one file where you can assemble the certificates(Certificate chain order)
It is especially useful to avoid conflicts with CA certificates when using "client authentication"

TLSCACertificatePath has the same effect for the certificate chain construction,
it has the side-effect that client certificates issued by this same CA certificate are also accepted on client authentication.

This starts with the issuing CA certificate of the server certificate and can range up to the root CA certificate.
This server certificate chain is sent to the client, in addition to the server's certificate.

TLSCACertificatePath

The CA certificates in the file are then used to verify client certificates, if presented.

This directive is only meaningful if TLSVerifyClient is set to on; otherwise, no client verification occurs.

Centos 6 設定

/etc/sysconfig/proftpd

PROFTPD_OPTIONS="-DTLS"

/etc/proftpd.conf

<IfDefine TLS>
    Include /etc/proftpd/ftps.conf
</IfDefine>

TLS (FTPS) for remote clients only

<Class local>
  From ...
</Class>

<IfModule mod_tls.c>
  # Normal mod_tls configuration here
  <IfClass local>
    # Don't require FTPS from local clients
    TLSRequired off
  </IfClass>
  <IfClass !local>
    # Require FTPS from remote/non-local clients
    TLSRequired on
  </IfClass>
</IfModule>

lftp client

lftp pc

  lftp> set ftp:ssl-allow yes

  lftp> user user

 


sftp (mod_sftp)

 

說明:

This module supports

  • SFTP / SCP file transfer protocols;
  • Publickey / Password authentication authentication
  • Quotas ( mod_quotatab )
  • Throttled transfers ( mod_shaper )

 * It does not support shell access

Check Package

ls  /usr/libexec/proftpd | grep mod_sftp

mod_sftp_pam.so
mod_sftp.so
mod_sftp_sql.so

mod_sftp_pam

mod_sftp_pam V.S. mod_auth_pam?

The difference is that the mod_auth_pam module does not echo the prompt,

provided by the underlying PAM library/modules, back to the FTP client;

this mod_sftp_pam module will echo any prompt back to the connecting SSH2 client.

This makes using onetime-password PAM modules

/etc/proftpd.conf

#### sftp
LoadModule mod_sftp.c
<IfModule mod_sftp.c>
    Include                   /etc/proftpd/sftp.conf
</IfModule>

 

VirtualHost

/etc/proftpd/sftp.conf

<VirtualHost IP1 IP2>

# Default: off
SFTPEngine    on

Port          22

# /etc/logrotate.d/proftpd 內有 "/var/log/proftpd/*.log", 所以我們 log 到那裡
# systemctl reload proftpd.service("/usr/bin/killall -HUP proftpd")
SFTPLog       /var/log/proftpd/sftp.log

# This is how the server identifies itself to clients.
# The keys configured as part of the SSH2 key exchange process
# gen key 方法: https://datahunter.org/openssh#gen_host_key
SFTPHostKey   /etc/proftpd/sftp/ssh_host_rsa_key
SFTPHostKey   /etc/proftpd/sftp/ssh_host_dsa_key
SFTPHostKey   /etc/proftpd/sftp/ssh_host_ecdsa_key

# 選項認證方式: publickey, hostbased, keyboard-interactive, password
# Chains of methods: SFTPAuthMethods publickey+password
SFTPAuthMethods password publickey

# per-user files of authorized keys
# i.e. SFTPAuthorizedUserKeys file:~/.sftp/authorized_keys
# Central location:
SFTPAuthorizedUserKeys file:/etc/proftpd/sftp/authorized_keys/%u

# SFTPClientAlive count interval
# mod_sftp to send messages to a client, through the encrypted channe every "interval"
# If "count" client alive messages are sent without receiving any response messages from the client,
# the client will be disconnected.
# Default: None
SFTPClientAlive 3 10

# SFTPCompression on|off|delayed
# delayed: parameter tells mod_sftp to support a custom extension used by OpenSSH,
#          where compression is not actually enabled until after the client has successfully authenticated.
SFTPCompression delayed

# Default: 10
# simultaneously open channels permitted for a client
# Most well-behaved SSH2 clients only ever open one channel.
#  * channels 是不同於 connection. 一個 connection 可以有多個 channels
SFTPMaxChannels 3

# It will be sent to the client prior to authentication.
SFTPDisplayBanner /etc/proftpd/sftp/banner.txt

</VirtualHost>

VirtualHost

Syntax: <VirtualHost ip-address|dns-name|nic >

By using the Port directive inside a <VirtualHost> section, it is possible to create a virtual server which uses the same IP address as the master server

RFC 7151, which defined a HOST FTP command. ProFTPD virtual hosts are IP-based and name-based.

    (When proftpd parses this section on startup, it will resolve the given DNS name to its IP address and use that)

ie.

<VirtualHost 0.0.0.0>
    Port 22
    ...
</VirtualHost>

 

Anything inside of a <Global> section is applied to every server configuration in the file,

    to every <VirtualHost> as well as the default "server config" server.

proftpd.conf

<Global>
  # Umask 022 is a good standard umask to prevent new dirs and files
  # from being group and world writable
  Umask                         022
  # Allow users to overwrite files and change permissions
  AllowOverwrite                yes
  <Limit ALL SITE_CHMOD>
    AllowAll
  </Limit>
  # Virtual User setting
  User                     vftp
  Group                    vftp
  DefaultRoot              ~
  RequireValidShell        off
  AuthOrder                mod_auth_file.c
  AuthUserFile             /opt/proftpd/etc/ftpd.passwd
  AuthGroupFile            /opt/proftpd/etc/ftpd.group
  DirFakeUser              on
  DirFakeGroup             on
  # Other setting
  TimesGMT                 off
  DefaultTransferMode      binary
  ShowSymlinks             off
</Global>

Turn Off DefaultServer

# "of"f: no fallback when a matching vhost cannot be found
DefaultServer off
# "0": will effectively disable/turn off that server
Port 0

Testing

service proftpd restart

netstat -ntlp | grep proftpd

tcp        0      0 :::22       :::*      LISTEN      17996/proftpd

telnet localhost 22

SSH-2.0-mod_sftp/0.9.7
....

Troubleshoot

Apr 11 13:12:10 mod_sftp/0.9.7[3795]: authentication request for user '?????' blocked by 'USER' handler
Apr 11 13:12:10 mod_sftp/0.9.7[3795]: disconnecting (Protocol error)

The keyboard-interactive authentication method is only offered to clients if the mod_sftp_pam module is present.

The hostbased authentication method is only offered to clients if the SFTPAuthorizedHostKeys directive is configured.

The publickey authentication method is only offered to clients if the SFTPAuthorizedUserKeys directive is configured.

sftp 進階設定

# specify the list of cipher algorithms that mod_sftp should use
SFTPCiphers aes128-cbc aes192-cbc aes256-cbc aes128-ctr aes192-ctr aes256-ctr

# Default: mod_sftp source code comes with a dhparams.pem file
# If for any reason you find that you need to generate your own SFTPDHParamFile
# openssl dhparam -outform PEM nbits >> dhparams.pem
SFTPDHParamFile dhparams.pem

# Default: All extensions except vendorID and xattr are enabled by default.
SFTPExtensions +copyFile +checkFile -versionSelect

# session rekey policy
# Require rekeying after 30 minutes, or 4 GB.  If the rekeying is not
# completed within 5 minutes of a rekey request, disconnect the client.
SFTPRekey required 1800 4096 300

# Setting for winscp
SFTPOptions IgnoreSCPUploadPerms IgnoreSCPUploadTimes

SFTPOptions

To configure various optional behavior of mod_sftp

May 11 04:17:23 mod_sftp/0.9.7[3725]: error checking '/3.0mb.7z' for LSTAT: No such file or directory
May 11 04:17:23 mod_sftp/0.9.7[3725]: error checking '/3.0mb.7z.filepart' for LSTAT: No such file or directory
May 11 04:17:24 mod_sftp/0.9.7[3725]: error changing access time '/3.0mb.7z': No such file or directory

IgnoreSCPUploadPerms

When an SCP client uploads a file, the desired permissions on the file are sent to the server as part of the upload.

IgnoreSCPUploadTimes

Use this option to have mod_sftp silently ignore any timestamps sent by SCP clients as part of the upload.

SFTP Client

* winscp 要用 sftp mode 才 login 到 (scp mode 唔得, 因為 proftpd 係shell 的)

* filezilla 用 fzsftp.exe 去連 sftp - SFTP module for FileZilla based on PuTTY's psftp component

 


在 Configure file 內可用的變數

 

%T    目前的時間

%F    所在硬碟剩下的容量

%C    目前所在的目錄

%R    Client 端的主機名稱

%L    Server 端的主機名稱

%U    使用者帳號名稱

%N    目前的主機連線人數

%M    最大允許連線人數

%E    FTP 主機管理員的 email

%i    本次上傳的檔案數目

%o    本次下載的檔案數量

%t    本次上傳+下載的檔案數量

 


Anonymous User

 

# Centos 6

# Disable anonymous logins

No <Anonymous> contexts mean that proftpd will not allow anonymous logins.

# Enable this anonymous logins

/etc/sysconfig/proftpd

PROFTPD_OPTIONS="-DANONYMOUS_FTP"

/etc/proftpd.conf

<IfDefine ANONYMOUS_FTP>
  <Anonymous ~ftp>
  .......
  </Anonymous>
</IfDefine>

 


ExtendedLog(mod_log)

 

ExtendedLog - Allows customizable logfiles to be generated

 

ExtendedLog path [cmd-classes [log-format-name]]

Default: None

cmd-classes: "All" commands except the "EXIT" pseudo-command

i.e.

ExtendedLog /var/log/ftp.log READ,WRITE custom

LogFormat formant-name format-var

# Formats of Variable

%t                  Current local time # "[11/May/2018:10:11:00 +0000]"

%{iso8601}     shorthand form of '%{%Y-%m-%d %H:%M:%S}t,%{millisecs}'

%{protocol}     Current protocol: "ftp", "ftps", "ssh2", "sftp", "scp"

%P                  Local server process ID (pid)

%a                 Remote client IP address

%u                 Authenticated local username

%r                 Full command received from client

%s                 Numeric FTP response code (status)

%b                 Number of bytes sent for this command

# Define the log formats

LogFormat      default "%{iso8601}\[%{protocol}\]\[%P\] - %a - %u \"%r\" %s %b"
ExtendedLog    /var/log/proftpd/transfer.log ALL default

# Upload File Example

 * 很多 WRITE ...

"OPEN /3.0mb.7z" - 0
"WRITE 3d5afeaf2e84d5f3 0 16384" 0 16384
"WRITE 3d5afeaf2e84d5f3 16384 16384" 0 32768
"WRITE 3d5afeaf2e84d5f3 32768 16384" 0 49152
....
"STOR /3.0mb.7z" 226 3060697
"CLOSE 3d5afeaf2e84d5f3" 0 3060697

 


Auto Ban

 

Module: mod_ban <- 提供 dynamic "ban" lists

banned user, host, or class from logging in to the server
(it does not prevent the banned user, host, or class from connecting to the server)

設定

MaxLoginAttempts 1

<IfModule mod_ban.c>
  BanEngine  on
  BanLog     /var/log/proftpd/ban.log

  # ban data is not kept across daemon stop/starts
  BanTable   /var/data//proftpd/ban.tab

  # %a: client IP address
  BanMessage "Host %a has been banned"

  # If the same client reaches the MaxLoginAttempts limit 2 times
  # within 10 minutes, automatically add a ban for that client that
  # will expire after one hour.
  # MaxLoginAttempts = Host ban
  BanOnEvent MaxLoginAttempts 2/00:10:00 01:00:00

  # Allow the "ftpadm" to manually add/remove bans
  BanControlsACLs all allow user ftpadm
</IfModule>

BanControlsACLs

Syntax: BanControlsACLs  actions  permission  "user"|"group"  list

actions: ban/permit/all

permission: allow|deny

user: access lists of users

list = comma-delimited list of user: ftpadm

Remark

 * If "deny" is used, then the list of users or groups cannot use actions all others are allowed.

 * Multiple BanControlsACLs directives may be used to configure ACLs for different control actions

Cli Usage

ftpdctl ban user username

ftpdctl ban host 1.2.3.4

ftpdctl ban info [-e|-v]

MaxLoginAttempts

log msg

BanOnEvent MaxLoginAttempts 2/00:10:00 01:00:00

The above BanOnEvent rule says that the same client (i.e. source IP address)

which reaches the MaxLoginAttempts limit 2 times within 10 minutes will be banned.

The most common reason is that the MaxLoginAttempts directive does not function:

If you test by connecting to proftpd, trying a bad password once, disconnecting,

then connecting again and trying the same bad password again,

you will not be hitting the MaxLoginAttempts limit.

原因

Remember that the MaxLoginAttempts directive configures a limit to the number of bad login attempts for the same connection;

it does not configure limit on the number of bad login attempts across multiple connections.

The default MaxLoginAttempts value for proftpd is 3.

  => Which means that simply connecting, trying a bad login attempt once, then disconnecting,

       will not trigger the MaxLoginAttempts limit.

解決

MaxLoginAttempts 1

"1" in order to make mod_ban behave the way that most administrators assume it will.

 


User 的 Limit 設定

 

Proftpd 的 "Order"

#                      先    後

Default: Order allow,deny

 * "Order" does not match Apache's interpretation

    an Order of "Allow,Deny" allows access by default, unless denied by a Deny directive;

可 Limits 的 action

 - ALL:      All FTP commands ( but not LOGIN )

 - DIRS:    CDUP, CWD, LIST, MDTM, MLSD, MLST, NLST, PWD, RNFR, STAT, XCUP, XCWD, XPWD

 - LOGIN:  client logins

 - READ:   RETR, SIZE

 - WRITE:  APPE, DELE, MKD, RMD, RNTO, STOR, STOU, XMKD, XRMD

Examples

<Directory /path/to/uploads>
  <Limit ALL>
    DenyAll
  </Limit>
</Directory>

# 登入限制

# Default: on
# Module: mod_auth

RequireValidShell on             # (/etc/shells)
UseFtpUsers on                   # (/etc/ftpusers) - If the user's name is found in this file, FTP access is denied.

# 限制 IP Login

Usage:

Allow [ ["from"] "all"|"none"|host|network[,host|network[,...]]]

Default: Allow from all

<Limit LOGIN>
  # These are trusted addresses
  Allow from 1.2.3.4 5.6.7.8
  Allow from trusted-domain.com
  # Everyone else is denied
  DenyAll
</Limit>

 * By default, the expression is parsed as a boolean "OR" list

# 限制 Account Login

# Allow 部份 User Login

<Limit LOGIN>
        AllowUser sftpuser1
        AllowUser sftpuser2,sftpuser3
        DenyAll
</Limit>

# Allow 部份 User By regular expression

<Limit LOGIN>
  # A regular expression AllowUser directive
  AllowUser regex ^ftp
  # An AND-evaluated DenyUser directive
  DenyUser AND system,test
</Limit>

Limit user read only

* directory recursively

<Directory ~>
  <Limit WRITE>
    DenyAll
  </Limit>
</Directory>

# only to the contents of dir, not to the directory itself.

<Directory /path/to/dir/*>

# will only match that single directory level

<Directory /path/to/*/dir>

# character is replaced with the user's home directory.

'~'

 * 相對於 chroot 後的 Directory

 


Compile From Source

 

mkdir /usr/src/proftpd -p; cd /usr/src/proftpd

SRC=proftpd-1.3.6d                                     # Work on Centos 6

wget ftp://ftp.proftpd.org/distrib/source/${SRC}.tar.gz      # 19M

tar -zxf ${SRC}; cd ${SRC}

yum install openssl-devel pam-devel libcap-devel

Config proftpd

./configure \
  --prefix=/opt/proftpd \
  --disable-ipv6 \
  --disable-ident \
  --enable-facl \
  --enable-openssl \
  --enable-shadow \
  --enable-auth-pam \
  --enable-static \
  --with-modules=mod_auth_pam:mod_sftp:mod_tls

Remark

  • --enable-facl            #enable support for POSIX ACLs
  • --disable-ident         # disable use of ident (RFC1413) lookups (default=no)
  • --enable-openssl      # enable OpenSSL support (default=no)
  • --enable-shadow      # force compilation of shadowed password support
  • --enable-auth-pam   # enable PAM support

Output

...
--------------
Build Summary
--------------
Building the following static modules:
  mod_auth_pam
  mod_sftp
  mod_tls
  mod_cap

make -j

make install

Check configure opts

./proftpd -V

module

mod_auth_pam

# Select PAM service name
# Default: ftp
# This assumes, that you have a PAM service named foobar
# configured in your /etc/pam.conf file or /etc/pam.d directory.

AuthPAMConfig foobar

mod_auth_file

http://www.proftpd.org/docs/modules/mod_auth_file.html

mod_cap

http://www.proftpd.org/docs/modules/mod_cap.html

 


logrotate

 

/etc/logrotate.d/proftpd

/var/log/proftpd/*.log
/var/log/proftpd/xferlog {
    compress
    missingok
    notifempty
    sharedscripts
    compress
    delaycompress
    rotate 4
    postrotate
        test -f /opt/proftpd/var/proftpd.pid && /usr/bin/killall -HUP proftpd || :
    endscript
}

 

 


Quota

 

Enable Plugin

/etc/proftpd.conf

...
Include /etc/proftpd.d/quota.conf

/etc/proftpd.d/quota.conf

LoadModule mod_quotatab.c
LoadModule mod_quotatab_file.c

# mkdir /var/lib/proftpd
QuotaLimitTable file:/var/lib/proftpd/ftpquota.limittab
QuotaTallyTable  file:/var/lib/proftpd/ftpquota.tallytab

QuotaEngine on

說明:

There are two such quota tables:

 - limit table

 - tally table for maintaining the current tally, or number of bytes/files used

 * Note that there is only one type of limit in effect at a given time;

    mod_quotatab does not combine multiple user/group/class/all limits for the same client.

QuotaTallyTable

module to locate and use the table containing the quota tally

QuotaTallyTable source-type:source-info

QuotaLimitTable

the table containing the quota limit, the maximum number of bytes and/or files defined for use by specific users, groups, classes, etc

QuotaLimitTable source-type:source-info

soft & hand limit

"soft" is a little less strict, for it will allow a user to exceed the quota limit by one file only.

For example, assume a user's tally is close their limit. That user uploads a large file, one that pushes the tally up over the quota limit.

If the user's limit type is "soft", the large file will be allowed, but any other uploads are denied

(until the user deletes some files, and brings their tally back down below the quota limit).

"hard": the large file will be deleted once uploaded, and a message returned to the client informing them of this.

Other Setting

QuotaDefault

# to be used when a limit is not found for the current user

Format:

QuotaDefault quota-type per-session limit-type bytes-avail-in bytes-avail-out 
 bytes-avail-xfer files-avail-in files-avail-out files-avail-xfer

ie.

QuotaDefault user false hard 10485760 0 0 0 0 0

QuotaDisplayUnits

Note that this directive does not affect how the quota values are stored in the quota table, only their presentation to the user.

i.e.

QuotaDisplayUnits Kb

QuotaShowQuotas

# Default: on

response to a SITE QUOTA request.

Use of this SITE command can be controlled via <Limit>, e.g.:

  <Limit SITE_QUOTA>
    AllowUser tj
    DenyAll
  </Limit>

QuotaOptions (Default: None)

QuotaOptions ScanOnLogin

to recursively scan the user's home directory when the user logs in,

and to update the tally entry for that user, if any, with the number of bytes and files found.

Note that these scans will cause a longer login time for the user

如果唔設定它, 那就要人手 update tally

# 找出 tim 現有的 file 數量

find ~tim -type f | wc -l

ftpquota --update-record --type tally -Q user --Fu 16 -N tim

mod_quotatab_file

provides the file-specific "driver" for storing quota table information in files. (Binary)

建立它的 tool: ftpquota (creating and managing these file-based tables)

zero or less for a bytes limit as "unlimited"

# Using a file-based limit table

QuotaLimitTable file:/usr/local/proftpd/ftpquota.limittab

# Using a file-based tally table

# Default  係找出當前目錄的 ftpquota.tallytab

QuotaTallyTable file:/usr/local/proftpd/ftpquota.tallytab

建立 DB file

ftpquota: Perl script

cd /var/lib/proftpd

ftpquota --create-table --type=limit

ftpquota --create-table --type=tally

Showing DB info.

ftpquota --show-records --type=limit

-------------------------------------------
  Name: tim
  Quota Type: User
  Per Session: False
  Limit Type: Hard
    Uploaded bytes:     unlimited
    Downloaded bytes:   unlimited
    Transferred bytes:  unlimited
    Uploaded files:     unlimited
    Downloaded files:   unlimited
    Transferred files:  unlimited

Per Session flag: true

which means that the limits will only be applied to this session.

When this happens, mod_quotatab will not update the tally table.

ftpquota --show-records --type=tally --table-path=/var/lib/proftpd/ftpquota.tallytab

ftpquota: Usage

  • --add-record         # Create a new record with the specified limits.
  • --delete-record      # Deletes a quota record from the table.  
  • --update-record     # Updates a quota record with the specified limits.
    ("ftpquota: unable to add record: matching record already exists")

Opts

-L, --limit-type              # Specifies the type of limit ("hard"(default) or "soft")

-Q, --quota-type          # Specifies a "quota type" for this record ("user", "group", "class", or "all")

-Bu, --bytes-upload      # Specifies the limit of the number of bytes that may be uploaded.

--units X                       # "B" or "byte", "Kb" or "kilo", "Mb" or "mega", and "Gb" or "giga"

--Fu, --files-upload       # Specifies the limit of the number of files that may be uploaded.

-N, --name                   # Specifies a name for the quota record.

--Fx, --files-xfer (Defaults to -1 (unlimited))

Specifies the limit of the number of files that may be transferred, including uploads and downloads. 

Note that any value less than or equal to zero will be treated as "unlimited".

--Fd, --files-download

Specifies the limit of the number of files that may be downloaded

i.e.

# cd /var/lib/proftpd

# 建立一隻有關 tim 的 record, all "unlimited" by default

ftpquota --add-record --type=limit -Q user -N tim

# 設定只可以 upload 20 個 file

ftpquota --update-record --type limit -Q user --Fu 20 -N tim

 


Plugin

 

  • mod_deflate - For suppporting MODE Z compression of data transfers
  • mod_wrap - /etc/hosts.allow and /etc/hosts.deny
  • mod_wrap2

 


Doc

 

 

 

 

 

Creative Commons license icon Creative Commons license icon