mod_log
This module is contained in the mod_log.c file for
ProFTPD 1.3.x, and is compiled by default.
<VirtualHost>, <Global>
By default, the server will the path of any configured
SystemLog, any configured
TransferLogs, and any
configured ExtendedLogs to see if they
are symbolic links. If the paths are symbolic links, proftpd
will refuse to log to that link unless explicitly configured to do so via
this AllowLogSymlinks directive.
Security Note: This behaviour should not be allowed unless for a very good reason. By allowing the server to open symbolic links with its root privileges, you are allowing a potential symlink attack where the server could be tricked into overwriting arbitrary system files. You have been warned.
<VirtualHost>, <Global>, <Anonymous>
The ExtendedLog directive allows customizable logfiles to be
generated, either globally or per <VirtualHost>. The
path argument should contain an absolute pathname to a logfile which
will be appended to when proftpd starts; the pathname should
not be to a file in a nonexistent directory, to a world-writable
directory, or be a symbolic link (unless
AllowLogSymlinks is set to
on). Multiple logfiles, potentially with different command classes and
formats) can be created. Optionally, the cmd-classes parameter can be
used to control which types of commands are logged. If no command classes are
specified, ProFTPD logs all commands by default. Note that passwords
are hidden. If used, the cmd-classes parameter is a comma-delimited
(with no whitespace) list of which command classes to log.
In proftpd-1.2.8rc1 and later, the path argument can
be of the form "syslog:level". The "syslog:" prefix
configures mod_log to write the ExtendedLog data
to syslog rather than to a file. The level configures the syslog
level at which to log the data. For example:
ExtendedLog syslog:info ALL default
In
This table shows the supported command classes:
If a format-name parameter is used,
For example, to log all read and write operations to
See also:
The
The default
The following meta sequences/variables are available and are replaced as
indicated when logging.
See also:
The
The options supported by the
To enable an option, preface the option name with a '+' (plus) character;
to disable the option, use a '-' (minus) character prefix. For example:
The
The
A path value of "none" will disable file logging for that vhost;
this can be used to override a global
The
Use of this directive overrides any facility set by the
A path value of "none" will disable logging for the entire daemon.
If you find that your ProFTPD installation appears to be ignoring your
Frequently Asked Questions
Question: Why are successful logins no longer being
logged, after upgrading to ProFTPD 1.3.6, even though I am using the
Why not? The
For having successful logins logged once more, use the following in your
Question: I configured
A slightly different
Question: I have configured ProFTPD to use DNS names
in my
"Properly verifying" an IP address, in this case, means resolving the DNS name
for an IP address and then resolving that DNS name back to its IP
addresses:
If the DNS name does not resolve back to the original IP address, then that
DNS name is not used, as that DNS name is considered "unreliable"; only
reliable information is logged (and used elsewhere). Thus ProFTPD
resorts to logging just the client IP address for the
Question: How can I get the reason a client was
disconnected, for whatever reason, logged to my
For example, assume you have configured the following:
With the above, when the
proftpd-1.3.10rc1 and later, the cmd-classes parameter
also handles additional rules for refining the specific commands/requests to be
logged. The cmd-classes parameter of comma-separated command
classes can be followed by a +, then a comma-separated list
of specific commands/request be explicitly logged (or omitted). For example:
ExtendedLog syslog:info SFTP+!READ,!WRITE default
This says to log all of the requests in the SFTP command class,
and to omit (via ! negation prefix) the READ and
WRITE requests.
Command Class
FTP Commands
ALLAll commands except the
EXIT pseudo-command (default)
NONENo commands
AUTHAuthentication commands:
ACCT, PASS,
REIN, USER
INFOInformational commands:
FEAT, HELP,
MDTM, QUIT, PWD, STAT,
SIZE, SYST, XPWD
DIRSDirectory commands:
CDUP, CWD,
LIST, MKD, MLSD, MLST,
NLST, RMD, XCWD, XCUP,
XMKD, XRMD
READFile reading:
RETR
WRITEFile/directory writing or creation:
APPE, MFF,
MFMT, MKD, RMD, RNFR,
RNTO, STOR, STOU,
XMKD, XRMD
MISCMiscellaneous commands:
ABOR, ALLO,
EPRT, EPSV, MODE,
NOOP, OPTS, PASV,
PORT, REST, RNFR,
RNTO, SITE, SMNT,
STRU, TYPE
SECRFC2228-related security FTP commands:
AUTH,
CCC, PBSZ, PROT. Note:
this class also includes SSH key exchange commands.
EXITLogs the configured
LogFormat at session exit.
NOTE: EXIT is not part of the
ALL command class, in order to preserve
backward-compatible ALL behavior.ExtendedLog will
use the named LogFormat. Otherwise, the
default format of "%h %l %u %t \"%r\" %s %b" is used.
/var/log/ftp.log using the default format, use:
ExtendedLog /var/log/ftp.log READ,WRITE
and to log all read and write operations to /var/log/ftp.log
using your own LogFormat named "custom", use:
LogFormat custom ...
ExtendedLog /var/log/ftp.log READ,WRITE custom
AllowLogSymlinks,
LogFormat,
TransferLog
LogFormat
Syntax: LogFormat format-name format-string
Default: LogFormat default "%h %l %u %t \"%r\" %s %b"
Context: server config, <Global>
Module: mod_log
Compatibility: 1.1.6p11 and later
LogFormat directive can be used to create a custom logging
format for use with the ExtendedLog
directive. Once created, the format can be referenced by the specified
format-name. The format-string parameter can consist of
any combination of letters, numbers and symbols. The special character '%' is
used to start a meta sequence/variable (see below). To insert a literal '%'
character, use "%%".
LogFormat is:
"%h %l %u %t \"%r\" %s %b"
which produces log entries in the Common Log Format.
Variable
Value
%a Remote client IP address
%A Anonymous login password, or "UNKNOWN" for regular logins
%{basename} Last component of path, i.e. just the file or directory name.
%b Number of bytes sent for this command
%c Client connection class, or "-" if undefined
%d Directory name (not full path) for:
CDUP,
CWD, LIST, MLSD, MKD,
NLST, RMD, XCWD, XCUP,
XMKD, XRMD
%D Directory path (full path) for:
CDUP,
CWD, LIST, MLSD, MKD,
NLST, RMD, XCWD, XCUP,
XMKD, XRMD
%E End-of-session reason
%{epoch} Unix epoch; seconds since January 1, 1970
%{NAME}e Contents of environment variable NAME
%f Absolute path of the filename stored or retrieved (not chrooted)
%F Filename stored or retrieved, as the client sees it
%{file-modified} Indicates whether a file is modified (i.e. already exists): "true" or "false"
%{file-size} Indicates the file size after data transfer, or "-" if not applicable
%{gid} GID of authenticated user
%g Primary group of authenticated user
%h Remote client DNS name
%H Local IP address of vhost/server hosting/handling the session
%I Total number of "raw" bytes read in from network
%{iso8601} shorthand form of
%{%Y-%m-%d %H:%M:%S}t,%{millisecs}, e.g. "2013-01-30 20:14:05,670"
%J Command arguments received from client, e.g. "file.txt"
%l Remote username (from
identd), or "UNKNOWN" if IdentLookup
failed
%L Local IP address contacted by client
%m Command (method) name received from client, e.g.
RETR
%{microsecs} 6 digit value of the microseconds of the current time
%{millisecs} 3 digit value of the milliseconds of the current time
%O Total number of "raw" bytes written out to network
%p Local port
%P Local server process ID (pid)
%{protocol} Current protocol: "ftp", "ftps", "ssh2", "sftp", "scp"
%r Full command received from client
%R Response time, in milliseconds
%{remote-port} Remote client port
%s Numeric FTP response code (status); see RFC 959 Section 4.2.1
%S Response message sent to client (available since 1.3.1rc1)
%t Current local time
%{format}t Current local time using
strftime(3) format
%T Time taken to transfer file, in seconds
%{transfer-failure} Reason for data transfer failure (if applicable), or "-"
%{transfer-millisecs} Time taken to transfer file, in milliseconds
%{transfer-port} Remote port used for data transfer
%{transfer-speed} Data transfer speed, in KB/s
%{transfer-status} Status of data transfer: "success", "failed", "cancelled", "timeout", or "-"
%{transfer-type} Data transfer type: "binary" or "ASCII" (if applicable), or "-"
%u Authenticated local username
%U USER name originally sent by client
%{uid} UID of authenticated user
%v Local server
ServerName
%V Local server DNS name
%{version} ProFTPD version
%w Absolute path for the
RNFR path ("whence" a rename comes)ExtendedLog,
TransferLog
LogOptions
Syntax: LogOptions opt1 ... optN
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_core
Compatibility: 1.3.7rc4 and later
LogOptions directive can be used to change the format
of the SystemLog messages, e.g.
adding/remove certain fields of data. These options also apply to
all module logging; ProFTPD logging is centralized, and the
LogOptions are applied to any/all logging.
LogOptions directive are:
All of these options are enabled by default, except for the
RoleBasedProcessLabels option.
# Log messages without timestamps or hostname
LogOptions -Hostname -Timestamp
RoleBasedProcessLabels option changes the label
just for the PID, from e.g.:
proftpd[1234]
to one of the following, depending on whether the process is the master
daemon process, or a forked session process:
daemon[2345]
session[34567]
This is useful, for example, when relying on systemd logging:
LogOptions -Timestamp -Hostname +RoleBasedProcessLabels
ServerLog
Syntax: ServerLog path|"none"
Default: None
Context: server config, <VirtualHost>, <Global>
Module: mod_log
Compatibility: 1.2.8rc1 and later
ServerLog directive is used to configure a
<VirtualHost>-specific logfile at the given path,
rather than a single SystemLog for the
entire configuration.
ServerLog setting.
SystemLog
Syntax: SystemLog path|"none"
Default: None
Context: server config, <Global>
Module: mod_log
Compatibility: 1.1.6p11 and later
SystemLog directive disables ProFTPD's use of the
syslog mechanism and instead redirects all logging output to the
specified path. The path should contain an absolute path,
and should not be to a file in a nonexistent directory, in a world-writable
directory, or be a symbolic link (unless
AllowLogSymlinks is set to
on).
SyslogFacility
directive.
SystemLog configuration entirely, and your ProFTPD
service is managed/run by systemd, then you may be encountering
this FAQ.
Installation
The mod_log module is compiled by default.
Usage
SystemLog directive?
Answer: The default log level was changed from
DEBUG to NOTICE in ProFTPD 1.3.6; see
Bug#3983. And
the "Login successful" log message is logged at the INFO level,
which means that it will not be logged by default.
INFO log level is for "normal operating conditions"
(see the log levels howto), and successful
logins are considered normal, and thus are not noteworthy or needed for logging.
Failed logins, however, are logged at the NOTICE
log level.
proftpd.conf:
SyslogLevel INFO
SystemLog in my ProFTPD configuration, but ProFTPD still logs only to syslog. What is missing?
Answer: The most common cause for this behavior is the
use of systemd for running ProFTPD. In particular, the systemd unit file for ProFTPD in some installations unexpectedly uses the
--nodaemon command-line option, e.g.:
# /usr/lib/systemd/system/proftpd.service
...
[Service]
Type = simple
Environment = PROFTPD_OPTIONS=
EnvironmentFile = -/etc/sysconfig/proftpd
ExecStartPre = /usr/sbin/proftpd --configtest
ExecStart = /usr/sbin/proftpd --nodaemon $PROFTPD_OPTIONS
ExecReload = /bin/kill -HUP $MAINPID
PIDFile = /run/proftpd/proftpd.pid
...
When ProFTPD is started with the -n/--nodaemon command-line option,
it will only log to stdout, and not to any configured log files.
This configuration is useful, for example, when running ProFTPD in a Docker
container.
systemd unit file for ProFTPD will work just
as well, and will honor the SystemLog configuration as
expected:
...
[Service]
Type = forking
Environment = PROFTPD_OPTIONS=
EnvironmentFile = -/etc/sysconfig/proftpd
ExecStartPre = /usr/sbin/proftpd --configtest $PROFTPD_OPTIONS
ExecStart = /usr/sbin/proftpd $PROFTPD_OPTIONS
ExecReload = /bin/kill -HUP $MAINPID
PIDFile = /run/proftpd/proftpd.pid
...
proftpd.conf using:
UseReverseDNS on
But in my ExtendedLog, I still see IP addresses rather than the
DNS names I expect to see. How can that happen?
Answer: The
LogFormat %h is what is used
to log DNS names. The logged value might be an IP address if ProFTPD cannot
properly verify that the client IP address resolves to a DNS name.
$ host 10.1.2.3
3.2.1.10.in-addr.arpa domain name pointer host.domain.example.com.
$ host host.domain.example.com
host.domain.example.com has address 10.4.5.6
In this example, the IP address 10.1.2.3 does not resolve back to itself via
DNS, but rather to a different IP address.
%h variable,
rather than the DNS name, in these situations.
ExtendedLog?
Answer: You can use the %E
LogFormat variable for this, in
conjunction with the EXIT log class.
MaxConnectionsPerUser 2
and you would like your ExtendedLog to record when this limit
is reached. To do this, you would use something like the following:
LogFormat eos "%a: user=%U disconnect_reason=\"%E\""
ExtendedLog /var/log/proftpd/ext.log EXIT eos
Of course, you can include other logging classes than just EXIT;
the above is just an example.
MaxConnectionsPerUser is reached,
your log would have a line like:
127.0.0.1: user=tj disconnect_reason="Denied by MaxConnectionsPerUser"
© Copyright 2002-2025 The ProFTPD Project
All Rights Reserved