ProFTPD module mod_log

## ProFTPD module `mod_log`

This module is contained in the `mod_log.c` file for ProFTPD 1.3.x, and is compiled by default.

## Directives

- AllowLogSymlinks
- ExtendedLog
- LogFormat
- ServerLog
- SystemLog

### AllowLogSymlinks

Syntax: AllowLogSymlinks on|off
Default: None
Context: server config, `<VirtualHost>`, `<Global>`
Module: mod_log
Compatibility: 1.2.2rc2 and later

By default, the server will the path of any configured `SystemLog`, any configured `TransferLog`s, and any configured `ExtendedLog`s 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.

### ExtendedLog

Syntax: ExtendedLog path [cmd-classes [format-name]]
Default: None
Context: server config, `<VirtualHost>`, `<Global>`, `<Anonymous>`
Module: mod_log
Compatibility: 1.1.6p11 and later

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 commands 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

This table shows the supported command classes:

Command Class | FTP Commands
`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.

If a format-name parameter is used, `ExtendedLog` will use the named `LogFormat`. Otherwise, the default format of "%h %l %u %t \"%r\" %s %b" is used.

For example, to log all read and write operations to `/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

See also: `AllowLogSymlinks`, `LogFormat`, `TransferLog`

### LogFormat

Syntax: LogFormat format-name format-string
Default: LogFormat default "%h %l %u %t \"%r\" %s %b"
Context: server config
Module: mod_log
Compatibility: 1.1.6p11 and later

The `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 "%%".

The default `LogFormat` is:

      "%h %l %u %t \"%r\" %s %b"

which produces log entries in the Common Log Format.

The following meta sequences/variables are available and are replaced as indicated when logging.

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
`%{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-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)

See also: `ExtendedLog`, `TransferLog`

### ServerLog

Syntax: ServerLog path|"none"
Default: None
Context: server config, `<VirtualHost>`, `<Global>`
Module: mod_log
Compatibility: 1.2.8rc1 and later

The `ServerLog` directive is used to configure a `<VirtualHost>`-specific logfile at the given path, rather than a single `SystemLog` for the entire configuration.

A path value of "none" will disable file logging for that vhost; this can be used to override a global `ServerLog` setting.

### SystemLog

Syntax: SystemLog path|"none"
Default: None
Context: server config
Module: mod_log
Compatibility: 1.1.6p11 and later

The `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).

Use of this directive overrides any facility set by the `SyslogFacility` directive.

A path value of "none" will disable logging for the entire daemon.

## Installation

The `mod_log` module is compiled by default.

## Usage

Frequently Asked Questions

Question: I have configured ProFTPD to use DNS names in my `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.

"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:

      $ 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.

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 `%h` variable, rather than the DNS name, in these situations.

Question: How can I get the reason a client was disconnected, for whatever reason, logged to my `ExtendedLog`?
Answer: You can use the `%E` `LogFormat` variable for this, in conjunction with the `EXIT` log class.

For example, assume you have configured the following:

      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.

With the above, when the `MaxConnectionsPerUser` is reached, your log would have a line like:

      127.0.0.1: user=tj disconnect_reason="Denied by MaxConnectionsPerUser"

© Copyright 2002-2017 The ProFTPD Project
All Rights Reserved