GithubHelp home page GithubHelp logo

proftpd / proftpd Goto Github PK

View Code? Open in Web Editor NEW
498.0 34.0 187.0 72.69 MB

ProFTPD source code

Home Page: http://www.proftpd.org

License: GNU General Public License v2.0

C 91.72% Shell 3.93% Perl 0.69% Makefile 0.42% PHP 1.78% M4 1.32% Roff 0.13%
proftpd c unix ftp-server ftp ftps ftpd sftp sftp-server scp

proftpd's Introduction

ProFTPD 1.3.x README

Status

GitHub Actions CI Status CirrusCI Build Status Coverage Status CodeQL Analysis Coverity Scan Status Release License

Introduction

ProFTPD is a highly configurable FTP daemon for Unix and Unix-like operating systems. See the README.ports file for more details about the platforms on which ProFTPD in known or thought to build and run.

ProFTPD grew from a desire for a secure and configurable FTP server. It was inspired by a significant admiration of the Apache web server. Unlike most other Unix FTP servers, it has not been derived from the old BSD ftpd code base, but is a completely new design and implementation.

ProFTPD's extensive configurability provides systems administrators great flexibility in user authentication and access controls, including virtual users and easy chroot() FTP sessions for individual users.

ProFTPD is popular with many service providers for delivering update access to user web pages, without resorting to Unix shell accounts.

Latest Release

see RELEASE_NOTES for an overview of the changes in this release.

Major Features

  • A single main configuration file, with directives and directive groups patterned after those of the Apache web server.
  • Per directory ".ftpaccess" configuration similar to Apache's ".htaccess".
  • Designed to run either as a stand-alone server or from inetd/xinetd.
  • Multiple virtual FTP servers and anonymous FTP services.
  • Multiple password files.
  • Shadow password support, including support for expired accounts.
  • Multiple authentication methods, including PAM, LDAP, SQL, and RADIUS.
  • Virtual users.
  • ProFTPD never executes any external program at any time. There is no SITE EXEC command, and all file and directory listings are generated internally, without using an external ls command.
  • Anonymous FTP and other chroot directories do not require any specific directory structure, executable programs or other system files.
  • Modular architecture with an API that facilitates well structured extensions to meet user needs.
  • Visibility of directories or files controlled based on Unix style permissions or user/group ownership.
  • Logging and utmp/wtmp support. Extensible, customizable logging is available.
  • If supported by the capabilities the host system, it can run as a non-privileged user in stand-alone mode, thwarting attacks aimed at exploiting "root" privileges.
  • GPLv2 source license. The source code is available to audit.

Documentation

Installation Overview

For detailed installation instructions, see the INSTALL file in the root directory of the source distribution.

The ProFTPD source distribution is designed to be configured using the GNU autotools, so compiling and installing follows the familiar command sequence of

./configure
make
make install

However, a significant portion of ProFTPD's configurability is done at compile time, so it is highly recommended that you read INSTALL and all of the README.* files that pertain to your platform and desired features before building the sources.

ProFTPD uses a single configuration file. A few examples are included in the sample-configurations/ subdirectory of the source distribution.

On most systems, the inetd or xinetd configuration must be changed, either to remove the current ftpd entry to run ProFTPD standalone, or to change the current ftpd entry to use the proftpd daemon.

Questions

If you have questions, please ask them on the appropriate mailing lists.

If you don't understand the documentation, please tell us, so we can explain it better. The general idea is: if you need to ask for help, then something needs to be fixed so you (and others) don't need to ask for help. Asking questions helps us to know what needs to be documented, described, and/or fixed.

proftpd's People

Contributors

adamkorcz avatar anthrazz avatar antorell avatar baumgartnerniels avatar bkmit avatar byshen avatar castaglia avatar chrisrd avatar dshachter avatar edux avatar ffontaine avatar fpl avatar fweimer-rh avatar gczuczy avatar gdsotirov avatar gildasio avatar gsauthof avatar jorrit avatar licaon-kter avatar manuelm avatar natefoo avatar offsides avatar pghmcfc avatar polter-rnd avatar pzeidler-dlr avatar rk295 avatar sashan avatar submachine avatar thesamesam avatar zeha avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

proftpd's Issues

Update bundled libtool

ProFTPD currently ships with a bundled version libtool; it was last updated to version 2.2.4 in Bug#3331. The latest stable version of libtool is now 2.4.6. Consider updating the bundled version, particularly due to new platforms (e.g. Android, ARM chips, etc for mobile devices).

Check snprintf return values for errors

The ProFTPD source code checks for error return values from many system calls/functions. However, one particularly sensitive family of functions which should be checked are the *snprintf library functions. ProFTPD should ideally be checking the return values of each of these calls, looking for overflows/full buffers (and, if necessary, simply ending that session/process).

Note that due to the different behaviors of *snprintf calls across Unix versions, this work will probably need configure support, for detecting the semantics of the *snprintf library functions available (and thus how, exactly, to check for errors).

mod_sftp.c: error initializing session: Permission denied

Using Proftpd 1.3.6 RC1, on Scientific Linux 6.1 (RHEL6 clone) I am unable to get sftp to work.

mod_sftp.c: error initializing session: Permission denied

SELinux is disabled with kernel parameter, so that is not the cause.

It says Permission denied, but it does not say what it is attempting to do, thus I am having a hard time figuring this out.

Googling this message, I found the following unresolved report:
https://forums.proftpd.org/smf/index.php?topic=11779.0

Debug log from

# proftpd -4n -d 20 -c /etc/proftpd/proftpd.conf
16:18:05,998 r99.no proftpd[9332]: using TCP receive buffer size of 87380 bytes
16:18:05,998 r99.no proftpd[9332]: using TCP send buffer size of 16384 bytes
16:18:05,998 r99.no proftpd[9332]: testing Unix domain socket using S_ISFIFO
16:18:05,998 r99.no proftpd[9332]: testing Unix domain socket using S_ISSOCK
16:18:05,998 r99.no proftpd[9332]: using S_ISSOCK macro for Unix domain socket detection
16:18:05,999 r99.no proftpd[9332]: using 'UTF-8' as local charset for UTF-8 conversion
16:18:05,999 r99.no proftpd[9332]: retrieved UID 99 for user 'nobody'
16:18:06,000 r99.no proftpd[9332]: retrieved GID 99 for group 'nobody'
16:18:06,000 r99.no proftpd[9332]: mod_dso/0.5: loading 'mod_sftp.c'
16:18:06,000 r99.no proftpd[9332]: mod_dso/0.5: loaded module 'mod_sftp' (from '/usr/libexec/proftpd/mod_sftp.so', last modified on Fri Sep 18 09:35:21 2015)
16:18:06,000 r99.no proftpd[9332]: mod_sftp/1.0.0: using OpenSSL 1.0.1e-fips 11 Feb 2013
16:18:06,000 r99.no proftpd[9332]: <IfModule>: using 'mod_sftp.c' section at line 17
16:18:06,000 r99.no proftpd[9332]: ROOT PRIVS at mod_sftp.c:1107
16:18:06,000 r99.no proftpd[9332]: RELINQUISH PRIVS at mod_sftp.c:1110
16:18:06,000 r99.no proftpd[9332]: mod_sftp/1.0.0: unable to use '/etc/ssh/ssh_host_ecdsa_key' as host key, as it is group- or world-accessible
16:18:06,000 r99.no proftpd[9332]: ROOT PRIVS at mod_sftp.c:1107
16:18:06,000 r99.no proftpd[9332]: RELINQUISH PRIVS at mod_sftp.c:1110
16:18:06,000 r99.no proftpd[9332]: mod_sftp/1.0.0: unable to use '/etc/ssh/ssh_host_rsa_key' as host key, as it is group- or world-accessible
16:18:06,017 r99.no proftpd[9332]: UseReverseDNS off, returning IP address instead of DNS name
16:18:06,017 r99.no proftpd[9332] 185.91.65.10: 
16:18:06,017 r99.no proftpd[9332] 185.91.65.10: Config for SFTP server:
16:18:06,017 r99.no proftpd[9332] 185.91.65.10: ServerIdent
16:18:06,017 r99.no proftpd[9332] 185.91.65.10: DefaultServer
16:18:06,017 r99.no proftpd[9332] 185.91.65.10: DefaultRoot
16:18:06,017 r99.no proftpd[9332] 185.91.65.10: AuthPAMConfig
16:18:06,017 r99.no proftpd[9332] 185.91.65.10: AuthOrder
16:18:06,017 r99.no proftpd[9332] 185.91.65.10: UserID
16:18:06,018 r99.no proftpd[9332] 185.91.65.10: UserName
16:18:06,018 r99.no proftpd[9332] 185.91.65.10: GroupID
16:18:06,018 r99.no proftpd[9332] 185.91.65.10: GroupName
16:18:06,018 r99.no proftpd[9332] 185.91.65.10: SFTPEngine
16:18:06,018 r99.no proftpd[9332] 185.91.65.10: SFTPOptions
16:18:06,018 r99.no proftpd[9332] 185.91.65.10: SFTPHostKey
16:18:06,018 r99.no proftpd[9332] 185.91.65.10: SFTPHostKey
16:18:06,020 r99.no proftpd[9332] 185.91.65.10: ROOT PRIVS at keys.c:599
16:18:06,020 r99.no proftpd[9332] 185.91.65.10: RELINQUISH PRIVS at keys.c:602
16:18:06,020 r99.no proftpd[9332] 185.91.65.10: ROOT PRIVS at keys.c:599
16:18:06,020 r99.no proftpd[9332] 185.91.65.10: RELINQUISH PRIVS at keys.c:602
16:18:06,021 r99.no proftpd[9332] 185.91.65.10: mod_lang/1.1: binding to text domain 'proftpd' using locale path '/usr/share/locale'
16:18:06,021 r99.no proftpd[9332] 185.91.65.10: mod_lang/1.1: using locale files in '/usr/share/locale'
16:18:06,023 r99.no proftpd[9332] 185.91.65.10: ROOT PRIVS at mod_ctrls.c:1199
16:18:06,023 r99.no proftpd[9332] 185.91.65.10: RELINQUISH PRIVS at mod_ctrls.c:1201
16:18:06,023 r99.no proftpd[9332] 185.91.65.10: ROOT PRIVS at mod_rlimit.c:541
16:18:06,023 r99.no proftpd[9332] 185.91.65.10: RELINQUISH PRIVS at mod_rlimit.c:544
16:18:06,023 r99.no proftpd[9332] 185.91.65.10: set core resource limits for daemon
16:18:06,023 r99.no proftpd[9332] 185.91.65.10: retrieved group ID: 99
16:18:06,023 r99.no proftpd[9332] 185.91.65.10: setting group ID: 99
16:18:06,023 r99.no proftpd[9332] 185.91.65.10: SETUP PRIVS at main.c:2436
16:18:06,023 r99.no proftpd[9332] 185.91.65.10: ROOT PRIVS at main.c:1743
16:18:06,023 r99.no proftpd[9332] 185.91.65.10: opening scoreboard '/var/run/proftpd/proftpd.scoreboard'
16:18:06,023 r99.no proftpd[9332] 185.91.65.10: RELINQUISH PRIVS at main.c:1770
16:18:06,023 r99.no proftpd[9332] 185.91.65.10: ROOT PRIVS at inet.c:385
16:18:06,023 r99.no proftpd[9332] 185.91.65.10: RELINQUISH PRIVS at inet.c:459
16:18:06,023 r99.no proftpd[9332] 185.91.65.10: ProFTPD 1.3.6rc1 (devel) (built Fri Sep 18 2015 09:34:44 CEST) standalone mode STARTUP
16:18:06,023 r99.no proftpd[9332] 185.91.65.10: ROOT PRIVS at pidfile.c:58
16:18:06,023 r99.no proftpd[9332] 185.91.65.10: RELINQUISH PRIVS at pidfile.c:61
16:18:07,877 r99.no proftpd[9333] 185.91.65.10: ROOT PRIVS at main.c:1177
16:18:07,877 r99.no proftpd[9333] 185.91.65.10: RELINQUISH PRIVS at main.c:1181
16:18:07,877 r99.no proftpd[9333] 185.91.65.10: no matching vhost found for 10.0.10.20#1022, using 'SFTP server' listening on wildcard address
16:18:07,877 r99.no proftpd[9333] 185.91.65.10 (77.40.194.196[77.40.194.196]): ROOT PRIVS at main.c:986
16:18:07,877 r99.no proftpd[9333] 185.91.65.10 (77.40.194.196[77.40.194.196]): SETUP PRIVS at main.c:991
16:18:07,877 r99.no proftpd[9333] 185.91.65.10 (77.40.194.196[77.40.194.196]): session requested from client in unknown class
16:18:07,877 r99.no proftpd[9333] 185.91.65.10 (77.40.194.196[77.40.194.196]): performing module session initializations
16:18:07,877 r99.no proftpd[9333] 185.91.65.10 (77.40.194.196[77.40.194.196]): ROOT PRIVS at keys.c:1969
16:18:07,877 r99.no proftpd[9333] 185.91.65.10 (77.40.194.196[77.40.194.196]): RELINQUISH PRIVS at keys.c:1976
16:18:07,877 r99.no proftpd[9333] 185.91.65.10 (77.40.194.196[77.40.194.196]): ROOT PRIVS at keys.c:1969
16:18:07,877 r99.no proftpd[9333] 185.91.65.10 (77.40.194.196[77.40.194.196]): RELINQUISH PRIVS at keys.c:1976
16:18:07,877 r99.no proftpd[9333] 185.91.65.10 (77.40.194.196[77.40.194.196]): mod_sftp.c: error initializing session: Permission denied
16:18:07,877 r99.no proftpd[9333] 185.91.65.10 (77.40.194.196[77.40.194.196]): mod_sftp/1.0.0: scrubbing 2 passphrases from memory
16:18:07,878 r99.no proftpd[9333] 185.91.65.10 (77.40.194.196[77.40.194.196]): FTP session closed.

Config used:

ServerName                      "SFTP server"
ServerAdmin                     root@localhost
ServerIdent                     off
DefaultServer                   on

DefaultRoot                     ~
UseReverseDNS                   off

AuthPAMConfig                   proftpd
AuthOrder                       mod_auth_pam.c* mod_auth_unix.c

User                            nobody
Group                           nobody

LoadModule mod_sftp.c

<IfModule mod_sftp.c>
    Port 1022
    SFTPEngine on

    SFTPOptions InsecureHostKeyPerms
    SFTPHostKey /etc/ssh/ssh_host_ecdsa_key
    SFTPHostKey /etc/ssh/ssh_host_rsa_key
</IfModule>

proftpd restart with localhost binding fail in already binding notice

when use the config :

DefaultAddress localhost
SocketBindTight on
UseIPv6 off

on host with dual stack ipv6.

proftpd start and listen on localhost...

# netstat -lnput | grep :21
tcp        0      0 127.0.0.1:21                0.0.0.0:*                   LISTEN      98832/proftpd
# telnet localhost 21
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 ProFTPD 1.3.6rc3 Server (ProFTPD Default Installation) [127.0.0.1]

they work fine... but they have this message in log...

Apr 24 03:04:10 myserver proftpd[98832]: localhost - opening scoreboard '/opt/srv/proftpd/var/proftpd.scoreboard'
Apr 24 03:04:10 myserver proftpd[98832]: localhost - opening scoreboard '/opt/srv/proftpd/var/proftpd.scoreboard'
Apr 24 03:04:10 myserver  proftpd[98832]: localhost - notice: 'ProFTPD Default Installation' (127.0.0.1:21) already bound to 'ProFTPD Default Installation'
Apr 24 03:04:10 myserver  proftpd[98832]: localhost - bindings.c:259: notice: unable to create ipbind '127.0.0.1#21': Address already in use
Apr 24 03:04:10 myserver proftpd[98832]: localhost - ProFTPD 1.3.6rc3 (git) (built Sun Apr 24 2016 02:51:22 CEST) standalone mode STARTUP

if use 127.0.0.1 in DefaultAddress they dont have any more notice in log...

for information i use github compiled version...

Remove unused FSIO "canonical" functions

There are several FSIO functions for operating on "canonical" paths which are not used:

int pr_fsio_stat_canon(const char *path, struct stat *st);
int pr_fsio_lstat_canon(const char *path, struct stat *st);
int pr_fsio_readlink_canon(const char *path, char *buf, size_t buflen);
int pr_fsio_rename_canon(const char *rnfr, const char *rnto);
int pr_fsio_unlink_canon(const char *name);
int pr_fsio_link_canon(const char *target_path, const char *link_path);
int pr_fsio_symlink_canon(const char *target_path, const char *link_path);
int pr_fsio_truncate_canon(const char *path, off_t len);
int pr_fsio_chmod_canon(const char *name, mode_t mode);
int pr_fsio_chown_canon(const char *name, uid_t uid, gid_t gid);

These "canonical" variants should be removed from the API because they are unused. The remaining two "canonical" variants which are used:

int pr_fsio_chdir_canon(const char *path, int hidesymlink);
pr_fh_t *pr_fsio_open_canon(const char *name, int flags);

should be evaluated to see if the callers can be rewritten to use the non-canonical variants, thus simplifying the FSIO API further and keeping it consistent.

I could not create etc/ directory

Hey all,

I could not create etc/ directory in FTP user root directory.
Through FTP client = Permissions denied
Server log (proftpd) = Permissions denied error 550

Allow MasqueradeAddress in <Global> sections

The MasqueradeAddress directive is currently not allowed in <Global> sections, only in <VirtualHost> or "server config" sections. This means that sites which have multiple vhosts behind a stateful, FTP-aware middlebox need to set MasqueradeAddress per-vhost.

Now that the HOST command is implemented, the situation becomes more annoying. Consider that now, there can be quite a few different vhosts on the same IP address, only differentiated by name -- and yet right now, each of those name-based <VirtualHost> sections would require its own MasqueradeAddress directive.

Thus there currently are good, compelling reasons for allowing MasqueradeAddress in <Global> sections.

add socket activation support

Right now proftpd supports both standalone and inetd modes. Having the latter it should be rather easy to add systemd's socket activation support so it can be nicely integrated with modern distributions.

list: invalid command

Hi
I've Debian 7.9 with proftpd 1.3.4a-5+deb7u3, and when I connect with FileZilla I've no problem, but when using ftp from bash I connect successfully but I can't use command "list", I receive "invalid command error". "ls" works fine. my problem is that php seems to using "list", not "ls", so my scripts don't work

Make PBSZ optional

We've found a broken client, which doesn't do PBSZ before PROT, and by RFC2228 proftpd is refusing the client because of this. I would like to ask to make PBSZ optional, because even in the source it's forced to 0, and to the best of my knowledge, it doesn't raise any security issues as well.

As per email discussion with castaglia, I've created a patch, and will create a pull request for it.

The path introduces a new TLSOptions option named "RequirePBSZ", and PBSZ will only be required if that flag is present. If the flag is not specified, then PBSZ is optional.

Convert IDN domain to IDNA

ATM our open-source project https://i-mscp.net/ need to store the idn-domain in database, because proftpd is not converting idn to idna. The correct way should be to store idna in database and automatically convert idn to idna (ascii), may if first auth will fail.
Example:
test@exämple.tld -> [email protected]

ATM we need to use idn (test@exämple.tld), ascii-format will not work.

Update mod_ldap documentation

The doc/contrib/mod_ldap.html docs are not in sync with the actual directives in the current mod_ldap code; they need to be updated.

Release of 1.3.5a

Hey there,
are there any plans when 1.3.5a will be available in main repositories of Debian Jessie? Atm I have problems with the TLS auth (it's slow) and would like to upgrade to 1.3.5a. I know I can compile the sources by myself, but I would prefer the already compiled packages :-)

Segfault running LIST or NLST on Mac

I also submitted this here http://bugs.proftpd.org/show_bug.cgi?id=4156, not sure if you still use that bug tracking system.

LIST and NLST are crashing proftpd for me. In fsio.c pr_fsio_opendir calls
pr_fs_setcwd(pr_fs_getcwd()). That ends up effectively calling strlcpy(cwd,
cwd, sizeof(cwd)), which segfaults.

OS X 10.10

I'm running proftpd as non-root. "users.txt" has a single user with my pid/gid
and a home directory owned by me as well.

ServerType standalone
Port 2123
DefaultAddress 127.0.0.1

AuthUserFile /tmp/proftpd/users.txt
AuthOrder mod_auth_file.c

PidFile /tmp/proftpd/proftpd.pid
ScoreboardFile /tmp/proftpd/proftpd.scoreboard
TransferLog /tmp/proftpd/transfer.log

User muir
Group staff

Allow configuration directive to define HiddenStores temp filename format/pattern

Currently ProFTPD only uses one filename format for the HiddenStore temp files:

.in.whateverfilename

A feature to allow this filename format to be controlled by configuration would be nice.

Example, the directive might be:

HiddenStoreFilenamePattern mytempfileprefix-$filename.inprogress

where $filename is the name of the file being uploaded, the filename the temp file will be renamed to.

Producing the following example temp file for an upload file of "datafile1.txt":

mytempfileprefix-datafile1.txt.inprogress

This would allow apps/scripts/services to ignore specific file extensions rather than just the dotfile hidden file format. This would be useful in my case as the target filesystem is being exported to other services/uses.

Implement API for more human-readable error strings

The ProFTPD code base (and its modules) often use strerror(3) for logging/reporting errors to admins/users. Unfortunately, simply logging the strerror(3) value for a given errno is not very useful, unless you're a developer and you have the context of that error/log message already in mind.

To provide for more useful/human-friendly error reporting, I'm thinking that ProFTPD could have an Error API which, among other things, provides something like that the libexplain library does; in fact, many of the error strings that I might use will probably be cribbed from that library.

The goal of this effort is to provide better log messages, good enough to help more and more users/admins be able to correct the problem themselves. Use cases include:

  • User asks about a particular log message in the mailing lists/IRC; usually a back-and-forth is needed
  • Admin researches a particular log messages on the Internet looking for known causes, solutions

This better Error API should not support i18n (configurable) strings. Why not? These strings will most likely be logged along with the other ProFTPD logging, which is not localized.

Encrypt the OTP seeds in the database using symmetric key

The mod_auth_otp module should support having a server (or daemon) wide key, which can be used for decrypting the OTP seeds retrieved from the SQL database. Likewise, the auth-otp tool should support using this key for encrypting those seeds. The encryption mechanism should be a symmetric key; the key itself can be random data (64-bits?).

Deprecate GroupPassword

I thought the GroupPassword directive had been deprecated already, but it is still implemented in the code. I think this is a dangerous and probably unused directive, and should be deprecated/removed entirely.

Provide configuration "lint" tool

For debugging proftpd configuration issues, it would be nice if proftpd had a "lint" tool for its configuration file(s). This tool would point out things like:

  • empty configuration sections/contexts
  • unresolvable DNS names
  • vhost DNS names which resolve to same IP addresses as other vhosts
  • directives which are not globally applied

etc.

The output of the tool (ftplint?) should be a pretty-printed/formatted, valid proftpd.conf with no overrides, with all <Global> directives merged in, all Include files included.

Enforce minimum SSH key length

Some security-conscious sites might wish to configure mod_sftp such that the keys used for authentication, e.g. user publickey authentication, are longer than some minimum key length.
See this StackExchange question on the topic.

Make TLSServerCipherPreference default to on/true

The TLSServerCipherPreference directive tells mod_tls to the server's ciphersuite priority, rather than the clients. In almost every case, this is the desired behavior.

That being the case, why not make TLSServerCipherPreference default to on (rather than off)? It will help keep mod_tls from violating the principle of least surprise.

Write howto doc discussing verification of uploads

There are often questions about how an FTP/SFTP client can know that a file was uploaded completely, and how the server can know that it has received the entire file properly. Write a document that talks about the issues involved with questions like these, covering integrity, completion, in-flight-ness, resumed uploads, etc. Assumptions about corruption in transit (handled by FTPS and SFTP, but not FTP), and how these are not really the main issue/problem.

This document should cover things like HiddenStores, APPE and REST wrinkles, the new HASH command (and its SFTP check-file equivalent), etc. For example, how to know when to move/process uploaded files, as in a staging directory scenario. Heuristics like file size, timestamps, etc -- and their drawbacks/caveats.

There are quite a few StackExchange posts the swirl around this topic:

And some tutorial/articles about this on other sites:

Also want to talk about which FTP/SFTP clients can make use of the integrity checking mechanisms, e.g. SmartFTP, lftp, WinSCP, FileZilla?

What about libraries/mechanisms like inotify, et al (e.g. Python inotify for FTP)?

trying to compile mov_vroot with the current proftpd master

Attempting to compile the latest in proftpd git with the latest in mod_vroot and the follwing compile errors are showing up. This has only occurred recently. Last time I ran this was about a month ago without incident.

This is on Centos7

gcc -DHAVE_CONFIG_H -DLINUX -I.. -I../include -I/usr/include -I/usr/include/mysql -I/usr/include/mysql -DBAN_LIST_MAXSZ=8096 -Wall -c mod_vroot.c
mod_vroot.c: In function 'set_vrootserverroot':
mod_vroot.c:1518:19: warning: dereferencing 'void ' pointer [enabled by default]
if (cmd->argv[1][pathlen - 1] != '/') {
^
mod_vroot.c:1518:3: error: void value not ignored as it ought to be
if (cmd->argv[1][pathlen - 1] != '/') {
^
make[1]: *
* [mod_vroot.o] Error 1
make[1]: Leaving directory `/tmp/proftpd/modules'
make: *** [modules] Error 2

HiddenStoreTempDir - Feature to specify temporary directory of uploads until they are complete

In combination with the HiddenStores and DeleteAbortedStores directives, I was hoping to get a feature to allow uploads to go to a temporary directory while in progress then be moved into the target destination on success.

Something like:

HiddenStoreTempDir /var/proftpdtmp

This way my target directory is not polluted by the .in.whateverfilename temp files while in progress.
I have a requirement to do this since an application we have watches directories for new files and we're hoping to avoid changing our application code just to suit this proftpd behaviour.

See also: #46 "Allow configuration directive to define HiddenStores temp filename format/pattern"

Avoid logging of "Login timeout exceeded, disconnected"

I am using ProFTP 1.3.5 under CentOS 5.9.

I have a log inspecter installed in my server and I receive a lot entries in /var/log/messages like:

Nov 12 00:12:01 server1 proftpd[12575]: 256.256.256.256 (127.0.0.1[127.0.0.1]) - Login timeout exceeded, disconnected

I would know if exists a way to hide or redirect the output to another output file log for the log lines "Login timeout exceeded, disconnected" so I can have a less verbose /var/log/messages

Support configurable certificate settings in LDAP SSL/TLS connections

Here's a long-awaiting patch that I found years ago and adapted for 1.3.3-1.3.5 (afaik).
Might require some additional work/close review, but it works for me as expected with 1.3.5 on Linux x86_64.

--- contrib/mod_ldap.c.orig 2013-11-24 04:45:28.000000000 +0400
+++ contrib/mod_ldap.c  2014-05-16 13:13:12.326617345 +0400
@@ -142,7 +142,14 @@
             *ldap_attr_memberuid = "memberUid",
             *ldap_attr_ftpquota = "ftpQuota",
             *ldap_attr_ftpquota_profiledn = "ftpQuotaProfileDN",
-            *ldap_attr_ssh_pubkey = "sshPublicKey";
+            *ldap_attr_ssh_pubkey = "sshPublicKey",
+            *ldap_tls_ca_cert_dir,
+            *ldap_tls_ca_cert_file,
+            *ldap_tls_cert_file,
+            *ldap_tls_cipher_suite,
+            *ldap_tls_crl_file,
+            *ldap_tls_dh_file,
+            *ldap_tls_key_file;
 #ifdef HAS_LDAP_INITIALIZE
 static char *ldap_server_url;
 #endif /* HAS_LDAP_INITIALIZE */
@@ -152,7 +159,9 @@
            ldap_forcedefaultuid = FALSE, ldap_forcedefaultgid = FALSE,
            ldap_forcegenhdir = FALSE, ldap_protocol_version = 3,
            ldap_dereference = LDAP_DEREF_NEVER,
-           ldap_search_scope = LDAP_SCOPE_SUBTREE;
+           ldap_search_scope = LDAP_SCOPE_SUBTREE,
+           ldap_tls_crl_check = -1,
+           ldap_tls_require_cert = -1;

 static struct timeval ldap_querytimeout_tv;
 #define PR_LDAP_QUERY_TIMEOUT_DEFAULT      5
@@ -196,6 +205,86 @@
   struct berval bindcred;
 #endif

+  if (ldap_tls_ca_cert_dir) {
+    res = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTDIR, ldap_tls_ca_cert_dir);
+    if (res != LDAP_OPT_SUCCESS) {
+      pr_log_pri(PR_LOG_ERR, MOD_LDAP_VERSION ": pr_ldap_connect(): Setting LDAP_OPT_X_TLS_CACERTDIR option failed: %s", ldap_err2string(res));
+      pr_ldap_unbind();
+      return -1;
+    }
+    pr_log_debug(DEBUG3, MOD_LDAP_VERSION ": set LDAP_OPT_X_TLS_CACERTDIR to %s", ldap_tls_ca_cert_dir); 
+  }
+ 
+  if (ldap_tls_ca_cert_file) {
+    res = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE, ldap_tls_ca_cert_file);
+    if (res != LDAP_OPT_SUCCESS) {
+      pr_log_pri(PR_LOG_ERR, MOD_LDAP_VERSION ": pr_ldap_connect(): Setting LDAP_OPT_X_TLS_CACERTFILE option failed: %s", ldap_err2string(res));
+      pr_ldap_unbind();
+      return -1;
+    }
+    pr_log_debug(DEBUG3, MOD_LDAP_VERSION ": set LDAP_OPT_X_TLS_CACERTFILE to %s", ldap_tls_ca_cert_file); 
+  }
+ 
+  if (ldap_tls_cert_file) {
+    res = ldap_set_option(NULL, LDAP_OPT_X_TLS_CERTFILE, ldap_tls_cert_file);
+    if (res != LDAP_OPT_SUCCESS) {
+      pr_log_pri(PR_LOG_ERR, MOD_LDAP_VERSION ": pr_ldap_connect(): Setting LDAP_OPT_X_TLS_CERTFILE option failed: %s", ldap_err2string(res));
+      pr_ldap_unbind();
+      return -1;
+    }
+    pr_log_debug(DEBUG3, MOD_LDAP_VERSION ": set LDAP_OPT_X_TLS_CERTFILE to %s", ldap_tls_cert_file); 
+  }
+ 
+  if (ldap_tls_cipher_suite) {
+    res = ldap_set_option(NULL, LDAP_OPT_X_TLS_CIPHER_SUITE, ldap_tls_cipher_suite);
+    if (res != LDAP_OPT_SUCCESS) {
+      pr_log_pri(PR_LOG_ERR, MOD_LDAP_VERSION ": pr_ldap_connect(): Setting LDAP_OPT_X_TLS_CIPHER_SUITE option failed: %s", ldap_err2string(res));
+      pr_ldap_unbind();
+      return -1;
+    }
+    pr_log_debug(DEBUG3, MOD_LDAP_VERSION ": set LDAP_OPT_X_TLS_CIPHER_SUITE to %s", ldap_tls_cipher_suite); 
+  }
+ 
+  if (ldap_tls_dh_file) {
+    res = ldap_set_option(NULL, LDAP_OPT_X_TLS_DHFILE, ldap_tls_dh_file);
+    if (res != LDAP_OPT_SUCCESS) {
+      pr_log_pri(PR_LOG_ERR, MOD_LDAP_VERSION ": pr_ldap_connect(): Setting LDAP_OPT_X_TLS_DHFILE option failed: %s", ldap_err2string(res));
+      pr_ldap_unbind();
+      return -1;
+    }
+    pr_log_debug(DEBUG3, MOD_LDAP_VERSION ": set LDAP_OPT_X_TLS_DHFILE version to %s", ldap_tls_dh_file); 
+  }
+ 
+  if (ldap_tls_key_file) {
+    res = ldap_set_option(NULL, LDAP_OPT_X_TLS_KEYFILE, ldap_tls_key_file);
+    if (res != LDAP_OPT_SUCCESS) {
+      pr_log_pri(PR_LOG_ERR, MOD_LDAP_VERSION ": pr_ldap_connect(): Setting LDAP_OPT_X_TLS_KEYFILE option failed: %s", ldap_err2string(res));
+      pr_ldap_unbind();
+      return -1;
+    }
+    pr_log_debug(DEBUG3, MOD_LDAP_VERSION ": pr_ldap_connect(): set LDAP_OPT_X_TLS_KEYFILE to %s", ldap_tls_key_file); 
+  }
+
+  if (ldap_tls_crl_check != -1) {
+    res = ldap_set_option(NULL, LDAP_OPT_X_TLS_CRLCHECK, (void *)&ldap_tls_crl_check);
+    if (res != LDAP_OPT_SUCCESS) {
+      pr_log_pri(PR_LOG_ERR, MOD_LDAP_VERSION ": pr_ldap_connect(): Setting LDAP_OPT_X_TLS_CRLCHECK option failed: %s", ldap_err2string(res));
+      pr_ldap_unbind();
+      return -1;
+    }
+    pr_log_debug(DEBUG3, MOD_LDAP_VERSION ": set LDAP_OPT_X_TLS_CRLCHECK to %d", ldap_tls_crl_check); 
+  } 
+ 
+  if (ldap_tls_require_cert != -1) {
+    res = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, (void *)&ldap_tls_require_cert);
+    if (res != LDAP_OPT_SUCCESS) {
+      pr_log_pri(PR_LOG_ERR, MOD_LDAP_VERSION ": pr_ldap_connect(): Setting LDAP_OPT_X_TLS_REQUIRE_CERT option failed: %s", ldap_err2string(res));
+      pr_ldap_unbind();
+      return -1;
+    }
+    pr_log_debug(DEBUG3, MOD_LDAP_VERSION ": set LDAP_OPT_X_TLS_REQUIRE_CERT to %d", ldap_tls_require_cert); 
+  }
+
 #ifdef HAS_LDAP_INITIALIZE
   (void) pr_log_writefile(ldap_logfd, MOD_LDAP_VERSION,
     "attempting connection to URL %s",
@@ -2029,6 +2118,130 @@
   return PR_HANDLED(cmd);
 }

+MODRET
+set_ldap_tls_ca_cert_dir(cmd_rec *cmd)
+{
+  CHECK_ARGS(cmd, 1);
+  CHECK_CONF(cmd, CONF_ROOT | CONF_VIRTUAL | CONF_GLOBAL);
+
+  add_config_param_str(cmd->argv[0], 1, cmd->argv[1]);
+  return PR_HANDLED(cmd);
+}
+
+MODRET
+set_ldap_tls_ca_cert_file(cmd_rec *cmd)
+{
+  CHECK_ARGS(cmd, 1);
+  CHECK_CONF(cmd, CONF_ROOT | CONF_VIRTUAL | CONF_GLOBAL);
+
+  add_config_param_str(cmd->argv[0], 1, cmd->argv[1]);
+  return PR_HANDLED(cmd);
+}
+
+MODRET
+set_ldap_tls_cert_file(cmd_rec *cmd)
+{
+  CHECK_ARGS(cmd, 1);
+  CHECK_CONF(cmd, CONF_ROOT | CONF_VIRTUAL | CONF_GLOBAL);
+
+  add_config_param_str(cmd->argv[0], 1, cmd->argv[1]);
+  return PR_HANDLED(cmd);
+}
+
+MODRET
+set_ldap_tls_cipher_suite(cmd_rec *cmd)
+{
+  CHECK_ARGS(cmd, 1);
+  CHECK_CONF(cmd, CONF_ROOT | CONF_VIRTUAL | CONF_GLOBAL);
+
+  add_config_param_str(cmd->argv[0], 1, cmd->argv[1]);
+  return PR_HANDLED(cmd);
+}
+
+MODRET
+set_ldap_tls_crl_check(cmd_rec *cmd)
+{
+  int value;
+  config_rec *c;
+
+  CHECK_ARGS(cmd, 1);
+  CHECK_CONF(cmd, CONF_ROOT | CONF_VIRTUAL | CONF_GLOBAL);
+
+  if (strcasecmp(cmd->argv[1], "none") == 0) {
+    value = LDAP_OPT_X_TLS_CRL_NONE;
+  } else if (strcasecmp(cmd->argv[1], "peer") == 0) {
+    value = LDAP_OPT_X_TLS_CRL_PEER;
+  } else if (strcasecmp(cmd->argv[1], "all") == 0) {
+    value = LDAP_OPT_X_TLS_CRL_ALL;
+  } else {
+    CONF_ERROR(cmd, "LDAPTLSCrlCheck: expected a valid LDAP_OPT_X_TLS_CRLCHECK option (none, peer, all).");
+  }
+
+  c = add_config_param("LDAPTLSCrlCheck", 1, NULL);
+  c->argv[0] = pcalloc(c->pool, sizeof(int));
+  *((int *) c->argv[0]) = value;
+  return PR_HANDLED(cmd);
+}
+
+MODRET
+set_ldap_tls_dh_file(cmd_rec *cmd)
+{
+  CHECK_ARGS(cmd, 1);
+  CHECK_CONF(cmd, CONF_ROOT | CONF_VIRTUAL | CONF_GLOBAL);
+
+  add_config_param_str(cmd->argv[0], 1, cmd->argv[1]);
+  return PR_HANDLED(cmd);
+}
+
+MODRET
+set_ldap_tls_crl_file(cmd_rec *cmd)
+{
+  CHECK_ARGS(cmd, 1);
+  CHECK_CONF(cmd, CONF_ROOT | CONF_VIRTUAL | CONF_GLOBAL);
+
+  add_config_param_str(cmd->argv[0], 1, cmd->argv[1]);
+  return PR_HANDLED(cmd);
+}
+
+MODRET
+set_ldap_tls_key_file(cmd_rec *cmd)
+{
+  CHECK_ARGS(cmd, 1);
+  CHECK_CONF(cmd, CONF_ROOT | CONF_VIRTUAL | CONF_GLOBAL);
+
+  add_config_param_str(cmd->argv[0], 1, cmd->argv[1]);
+  return PR_HANDLED(cmd);
+}
+
+MODRET
+set_ldap_tls_require_cert(cmd_rec *cmd)
+{
+  int value;
+  config_rec *c;
+
+  CHECK_ARGS(cmd, 1);
+  CHECK_CONF(cmd, CONF_ROOT | CONF_VIRTUAL | CONF_GLOBAL);
+
+  if (strcasecmp(cmd->argv[1], "never") == 0) {
+    value = LDAP_OPT_X_TLS_NEVER;
+  } else if (strcasecmp(cmd->argv[1], "hard") == 0) {
+    value = LDAP_OPT_X_TLS_HARD;
+  } else if (strcasecmp(cmd->argv[1], "demand") == 0) {
+    value = LDAP_OPT_X_TLS_DEMAND;
+  } else if (strcasecmp(cmd->argv[1], "allow") == 0) {
+    value = LDAP_OPT_X_TLS_ALLOW;
+  } else if (strcasecmp(cmd->argv[1], "try") == 0) {
+    value = LDAP_OPT_X_TLS_TRY;   
+  } else {
+    CONF_ERROR(cmd, "LDAPTLSRequireCert: expected a valid LDAP_OPT_X_TLS_REQUIRE_CERT option (never, hard, demand, allow, try).");
+  }
+
+  c = add_config_param("LDAPTLSRequireCert", 1, NULL);
+  c->argv[0] = pcalloc(c->pool, sizeof(int));
+  *((int *) c->argv[0]) = value;
+  return PR_HANDLED(cmd);
+}
+
 /* Initialization routines
  */

@@ -2279,6 +2492,22 @@
     }
   }

+  ldap_tls_ca_cert_dir =  (char *)get_param_ptr(main_server->conf, "LDAPTLSCACertDir", FALSE);
+  ldap_tls_ca_cert_file = (char *)get_param_ptr(main_server->conf, "LDAPTLSCACertFile", FALSE);
+  ldap_tls_cert_file =    (char *)get_param_ptr(main_server->conf, "LDAPTLSCertFile", FALSE);
+  ldap_tls_cipher_suite = (char *)get_param_ptr(main_server->conf, "LDAPTLSCipherSuite", FALSE);
+  ldap_tls_crl_file =     (char *)get_param_ptr(main_server->conf, "LDAPTLSCrlFile", FALSE);
+  ldap_tls_dh_file =      (char *)get_param_ptr(main_server->conf, "LDAPTLSDHFile", FALSE);
+  ldap_tls_key_file =     (char *)get_param_ptr(main_server->conf, "LDAPTLSKeyFile", FALSE);
+  ptr = get_param_ptr(main_server->conf, "LDAPTLSCrlCheck", FALSE);
+  if (ptr) {
+    ldap_tls_crl_check = *((int *) ptr);
+  }
+  ptr = get_param_ptr(main_server->conf, "LDAPTLSRequireCert", FALSE);
+  if (ptr) {
+    ldap_tls_require_cert = *((int *) ptr);
+  }
+
   return 0;
 }

@@ -2309,7 +2538,15 @@
   { "LDAPServer",      set_ldapserver,         NULL },
   { "LDAPUsers",       set_ldapuserlookups,        NULL },
   { "LDAPUseTLS",      set_ldapusetls,         NULL },
-
+  { "LDAPTLSCACertDir",        set_ldap_tls_ca_cert_dir,   NULL },
+  { "LDAPTLSCACertFile",   set_ldap_tls_ca_cert_file,  NULL },
+  { "LDAPTLSCertFile",     set_ldap_tls_cert_file,     NULL },
+  { "LDAPTLSCipherSuite",  set_ldap_tls_cipher_suite,  NULL },
+  { "LDAPTLSCrlCheck",     set_ldap_tls_crl_check,     NULL },
+  { "LDAPTLSCrlFile",      set_ldap_tls_crl_file,      NULL },
+  { "LDAPTLSDHFile",       set_ldap_tls_dh_file,       NULL },
+  { "LDAPTLSKeyFile",      set_ldap_tls_key_file,      NULL },
+  { "LDAPTLSRequireCert",  set_ldap_tls_require_cert,  NULL },
   { NULL, NULL, NULL },
 };

Inconsistent results from XSHA1

Problem: using ProFTPD 1.3.5, my FTP client sends the XSHA1 command for an 8 GB file.

If the command is issued three times for the same file, XSHA1 returns three different hash values.

Is this a bug?

Break up single conf.h header file

Currently, the conf.h header file itself is a convenience header, for pulling in almost all of the other API header files. As such, this means the generated .o files are larger than they need to be, including code/definitions which are not used.

To be more disciplined about necessary includes, I am thinking to keep the existing conf.h as is, but to create a new platform.h header alongside the conf.h file, just for system headers. The core source files and modules will then start including platform.h and the API-specific headers as needed; the conf.h header will be retain, at least for a while, for third-party modules.

Enable stacktrace logging by default

Currently, ProFTPD has some support for logging stacktraces in e.g. the face of a SIGSEGV signal -- but only if the --enable-devel=stacktrace compile-time option is used. Those stacktrace logging can be very useful when diagnosing errors, and especially when users report errors. That being the case, why not have stacktrace support enabled by default, rather than disabled by default? There would then be a --disable-stacktrace compile-time option offered, of course.

Note that in order for stacktrace logging to work, the installed binaries must not be stripped. Thus when working on this feature, make sure to adjust the Makefiles' install targets accordingly.

VRootAlias not working (unix permissions ???)

Hi Castaglia.

First off all, thanks for you support with all ProFTPD docummentation. I have learned a LOT with your contributions.

There is just one thing that is really giving me headaches.. VRootAlias

Here they are:

this one I can access, list/create files/directories

VRootAlias /tmp ~/tmp-vroot-alias

and this I CAN JUST ACCESS... I cannot list/create files/directories

VRootAlias /storage/0001a/10001a/encoding/input ~/0001a-input

FTP USER:
encodingcom:x:514:500::/storage/encodingcom:/sbin/nologin

And here they are in the filesystem (EXT4 - LVM).

/tmp (WORKING)

Directory
drwxrwxrwt. 3 root root 4096 Oct 14 21:58 tmp

Directory Files
-rw-r--r--. 1 encodingcom storage 0 Oct 10 01:40 teste
-rw-------. 1 root root 0 Sep 5 14:47 yum.log
-rw-------. 1 root root 4195 Sep 5 15:30 yum_save_tx-2014-09-05-15-30XPmgVj.yumtx
-rw-------. 1 root root 15507 Sep 16 18:14 yum_save_tx-2014-09-16-18-14eymISj.yumtx
-rw-------. 1 root root 268 Sep 25 16:16 yum_save_tx-2014-09-25-16-163gt7om.yumtx

/storage/0001a/10001a/encoding/input (NOT WORKING)

drwxrwxrwx. 2 encodingcom storage 4096 Oct 14 21:38 input

Directory Files
-rwxrwxrwx. 1 encodingcom storage 0 Oct 14 21:39 123
-rwxrwxrwx. 1 encodingcom storage 5 Oct 8 15:42 asgard

Running proftpd with -dn10 (no daemonize + debug 10), I've got this message when I sent a refresh command in the encoding/input directory, thorugh FileZilla. I belive that Filezilla tries to list the directory, but debug mode informs about filename too long (???)

  • mod_facts/0.1: error stat'ing '/0001a-input/asgard': File name too long

The proftpd.log records this message when a I try to crate a file..

  • [15/Oct/2014:01:50:08 +0000] 192.168.50.237 user:encodingcom [PASV - 227] pid:1740
  • [15/Oct/2014:01:50:08 +0000] 192.168.50.237 user:encodingcom [STOR - 550] pid:1740

I have set SELINUX as disabled in my CentOS.

  • Linux ivan-centos-vm 2.6.32-431.el6.x86_64 #1 SMP Fri Nov 22 03:15:09 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
  • SELinux status: disabled

About the /storage directory, I have created another directory inside of it, and performed a VRootAlias inside a VirtualHost, as well as inside this VirtualHost, I've also created a VRootAlias to the same CURSED /storage/0001a/10001a/encoding/input. The cursed, is still cursed.. and the new VRootAlias, works fine. Why?

/storage/teste (VRootAlias working)

Directory
drwxr-xr-x. 3 root root 4096 Oct 14 21:40 teste

Directory files
-rwxrwxrwx. 1 root root 0 Oct 14 21:39 123
-rwxrwxrwx. 1 root root 0 Oct 10 03:32 1234
-rw-r--r--. 1 root root 0 Oct 10 04:55 123456
-rwxr-xr-x. 1 root root 5 Oct 14 21:40 asgard
drwxrwxrwx. 2 root root 4096 Oct 10 03:32 qaz

Also, here is my config file. PLEASE, help me :(.

+++++++++++++++++++++++++++++++++++++
ServerName "VM Ivan"
ServerIdent on "testing proftpd"
ServerAdmin [email protected]
DefaultServer on
DefaultAddress 192.168.50.59

SocketbindTight on

Umask 022

DefaultRoot ~ !adm
VRootEngine on
VRootAlias /tmp ~/tmp-vroot-alias
VRootAlias /storage/0001a/10001a/encoding/input ~/0001a-input

Log options

LogFormat default "%h %l %u %t "%r" %s %b --- %J"

LogFormat default "%t %a user:%U [%m %f %s] pid:%P"
LogFormat auth "%v [%P] %h %t "%r" %s"

UseReverseDNS off

MaxInstances 200
MaxClientsPerUser 35

AuthPAMConfig proftpd
AuthOrder mod_auth_unix.c

AuthOrder mod_auth_unix.c mod_sql.c

User nobody
Group nobody

UseSendfile off

Timeout options

TimeoutLogin 120

Fake permissions

DirFakeUser on ~
DirFakeGroup on ftp

Store options

DeleteAbortedStores on
HiddenStores on

<VirtualHost 192.168.50.99>
ServerAdmin [email protected]
ServerName "FTP encodingcom VH"
ServerIdent on "VH for VRootAlias"

Set Umask: FILE (base mode 666) + DIRECTORY (base mode 777)

Umask   0002    0002

jail the user to its home directory (encodingcom)

DefaultRoot ~

proftp virtual chroot

VRootEngine on

VRootAlias log file, for all operations realated with aliases

VRootLog    /var/log/proftpd/vroot.log

allow symlinks

VRootOptions    allowSymlinks

last parameters are directories which will point to folders outside of the home directory

VRootAlias  /storage/0001a/10001a/encoding/input    ~/0001a-input       
VRootAlias  /storage/0001a/10001a/encoding/output   ~/0001a-output

VRootAlias  /storage/2093w/12093w/encoding/input    ~/2093w-input   
VRootAlias  /storage/2093w/12093w/encoding/output   ~/2093w-output

VRootAlias  /storage/2312x/12312x/encoding/input    ~/2312x-input
VRootAlias  /storage/2312x/12312x/encoding/output   ~/2312x-output

VRootAlias  /storage/2386u/12386u/encoding/input    ~/2386u-input   
VRootAlias  /storage/2386u/12386u/encoding/output   ~/2386u-output

VRootAlias  /storage/teste              ~/storage-teste

VRootAlias  /storage/9000/19000/encoding        ~/9000
VRootAlias  /storage/9000/19000/encoding/input  ~/9000-input
VRootAlias  /storage/9000/19000/encoding/output ~/9000-output

list all files including those whose names start with "."

ListOptions -a

<Directory ~>

    <Limit ALL>
        AllowAll
    </Limit>

</Directory>

ExtendedLog /var/log/proftpd/access.log WRITE,READ default
ExtendedLog /var/log/proftpd/auth.log AUTH auth
ExtendedLog /var/log/proftpd/proftpd.log ALL default

DebugLevel 10

AllowOverwrite yes

AllowAll

AllowAll

+++++++++++++++++++++++++++++++++++++

Clean up *.gcno files

The ProFTPD build system will clean up *.o files as part of the clean and distclean targets; these targets also need to remove any *.gcno files generated due use of the --coverage build flags.

Limited configuration directive parameter length

Hello,

I`m trying to set custom TLSCipherSuite ciphers but Proftpd cut the list.

TLSCipherSuite -ALL:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:
ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:SRP-RSA-AES-256-CBC-SHA:
SRP-AES-256-CBC-SHA:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDH-RSA-AES256-GCM-SHA384:
ECDH-ECDSA-AES256-GCM-SHA384:ECDH-RSA-AES256-SHA384:ECDH-ECDSA-AES256-SHA384:ECDH-RSA-AES256-SHA:ECDH-ECDSA-AES256-SHA:
AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:PSK-AES256-CBC-SHA:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:
ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:SRP-RSA-AES-128-CBC-SHA:
SRP-AES-128-CBC-SHA:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-CAMELLIA128-SHA:
ECDH-RSA-AES128-GCM-SHA256:ECDH-ECDSA-AES128-GCM-SHA256:ECDH-RSA-AES128-SHA256:ECDH-ECDSA-AES128-SHA256:ECDH-RSA-AES128-SHA:
ECDH-ECDSA-AES128-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:PSK-AES128-CBC-SHA:
CAMELLIA256-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:
ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:SRP-RSA-AES-256-CBC-SHA:
SRP-AES-256-CBC-SHA:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:
DHE-RSA-CAMELLIA256-SHA:ECDH-RSA-AES256-GCM-SHA384:ECDH-ECDSA-AES256-GCM-SHA384:ECDH-RSA-AES256-SHA384:
ECDH-ECDSA-AES256-SHA384:ECDH-RSA-AES256-SHA:ECDH-ECDSA-AES256-SHA:AES256-GCM-SHA384:AES256-SHA256:
AES256-SHA:CAMELLIA256-SHA:PSK-AES256-CBC-SHA:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:
ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:
SRP-RSA-AES-128-CBC-SHA:SRP-AES-128-CBC-SHA:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:
DHE-RSA-AES128-SHA:DHE-RSA-CAMELLIA128-SHA:ECDH-RSA-AES128-GCM-SHA256:ECDH-ECDSA-AES128-GCM-SHA256:
ECDH-RSA-AES128-SHA256:ECDH-ECDSA-AES128-SHA256:ECDH-RSA-AES128-SHA:ECDH-ECDSA-AES128-SHA:
AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:CAMELLIA128-SHA:PSK-AES128-CBC-SHA:ECDHE-RSA-AES256-GCM-SHA384:
ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:
ECDHE-ECDSA-AES256-SHA:SRP-RSA-AES-256-CBC-SHA:SRP-AES-256-CBC-SHA:DHE-RSA-AES256-GCM-SHA384:
DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-CAMELLIA256-SHA:ECDH-RSA-AES256-GCM-SHA384:
ECDH-ECDSA-AES256-GCM-SHA384:ECDH-RSA-AES256-SHA384:ECDH-ECDSA-AES256-SHA384:ECDH-RSA-AES256-SHA:
ECDH-ECDSA-AES256-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:CAMELLIA256-SHA:PSK-AES256-CBC-SHA:
ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:
ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:SRP-RSA-AES-128-CBC-SHA:SRP-AES-128-CBC-SHA:
DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-CAMELLIA128-SHA:
ECDH-RSA-AES128-GCM-SHA256:ECDH-ECDSA-AES128-GCM-SHA256:ECDH-RSA-AES128-SHA256:ECDH-ECDSA-AES128-SHA256:
ECDH-RSA-AES128-SHA:ECDH-ECDSA-AES128-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:CAMELLIA128-SHA:
PSK-AES128-CBC-SHA:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:
ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:SRP-RSA-AES-256-CBC-SHA:
SRP-AES-256-CBC-SHA:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-CAMELLIA256-SHA:
ECDH-RSA-AES256-GCM-SHA384:ECDH-ECDSA-AES256-GCM-SHA384:ECDH-RSA-AES256-SHA384:ECDH-ECDSA-AES256-SHA384:
ECDH-RSA-AES256-SHA:ECDH-ECDSA-AES256-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:CAMELLIA256-SHA:
PSK-AES256-CBC-SHA:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:
ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:SRP-RSA-AES-128-CBC-SHA:SRP-AES-128-CBC-SHA:
DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-CAMELLIA128-SHA:ECDH-RSA-AES128-GCM-SHA256:
ECDH-ECDSA-AES128-GCM-SHA256:ECDH-RSA-AES128-SHA256:ECDH-ECDSA-AES128-SHA256:ECDH-RSA-AES128-SHA:ECDH-ECDSA-AES128-SHA:
AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:CAMELLIA128-SHA:PSK-AES128-CBC-SHA

But Proftpd reports

warning: handling possibly truncated configuration data at line 27 of '/etc/proftpd/tls.conf'
warning: handling possibly truncated configuration data at line 37 of '/etc/proftpd/tls.conf'
fatal: unknown configuration directive 'M-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:SRP-RSA-AES-256-CBC-SHA:SRP-AES-256-CBC-SHA:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-CAMELLIA256-SHA:ECDH-RSA-AES256-GCM-SHA384:ECDH-ECDSA-AES256-GCM-SHA384:ECDH-RSA-AES256-SHA384:ECDH-ECDSA-AES256-SHA384:ECDH-RSA-AES256-SHA:ECDH-ECDSA-AES256-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:CAMELLIA256-SHA:PSK-AES256-CBC-SHA:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:SRP-RSA-AES-128-CBC-SHA:SRP-AES-128-CBC-SHA:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-CAMELLIA128-SHA:ECDH-RSA-AES128-GCM-SHA256:ECDH-ECDSA-AES128-GCM-SHA256:ECDH-RSA-AES128-SHA256:ECDH-ECDSA-AES128-SHA256:ECDH-RSA-AES128-SHA:ECDH-ECDSA-AES128-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:CAMELLIA128-SHA:PSK-AES128-CBC-SHA:ECDHE-RSA-AES256-GCM-' on line 37 of '/etc/proftpd/tls.conf'

If I set to less cipher list

TLSCipherSuite -ALL:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:
ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:SRP-RSA-AES-256-CBC-SHA:
SRP-AES-256-CBC-SHA:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDH-RSA-AES256-GCM-SHA384:
ECDH-ECDSA-AES256-GCM-SHA384:ECDH-RSA-AES256-SHA384:ECDH-ECDSA-AES256-SHA384:ECDH-RSA-AES256-SHA:ECDH-ECDSA-AES256-SHA:
AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:PSK-AES256-CBC-SHA:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:
ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:SRP-RSA-AES-128-CBC-SHA:
SRP-AES-128-CBC-SHA:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-CAMELLIA128-SHA:
ECDH-RSA-AES128-GCM-SHA256:ECDH-ECDSA-AES128-GCM-SHA256:ECDH-RSA-AES128-SHA256:ECDH-ECDSA-AES128-SHA256:
ECDH-RSA-AES128-SHA:ECDH-ECDSA-AES128-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:PSK-AES128-CBC-SHA:CAMELLIA256-SHA256

Proftpd reports

Checking syntax of configuration file
Syntax check complete.

Disable building of mod_ident by default

The mod_ident module is so little used these days that it should no longer be included in the build by default. Instead, sites which want mod_ident will need to explicitly request that it be built (e.g. as a shared/DSO module).

For backward/forward-compatible configurations, use:

<IfModule mod_ident.c>
  IdentLookups off
</IfModule>

ProFTPD compiling on OpenBSD fails

I've been using ProFTPD on OpenBSD for more than 9 years and just wanted to add my ¢2:

I can confirm it compiles fine with these options enabled:

--enable-ipv6
--enable-openssl
--enable-pcre
--enable-nls

and these modules compile/work without additional patches:

  mod_core.c
  mod_xfer.c
  mod_rlimit.c
  mod_auth_unix.c
  mod_auth_file.c
  mod_auth.c
  mod_ls.c
  mod_log.c
  mod_site.c
  mod_delay.c
  mod_facts.c
  mod_ident.c
  mod_tls.c
  mod_ban.c
  mod_sql.c
  mod_sql_sqlite.c
  mod_sftp.c
  mod_sftp_sql.c
  mod_ifsession.c
  mod_lang.c

The only problem I faced was about 'mod_ctrls.c' (along with '--enable-ctrls'):

--- src/ctrls.c.orig    Wed May 29 00:02:02 2013
+++ src/ctrls.c Tue Nov 25 09:48:38 2014
@@ -1117,7 +1117,7 @@ int pr_ctrls_issock_unix(mode_t sock_mode) {
 #if defined(SO_PEERCRED)
 static int ctrls_get_creds_peercred(int sockfd, uid_t *uid, gid_t *gid,
     pid_t *pid) {
-  struct ucred cred;
+  struct sockpeercred cred;
   socklen_t credlen = sizeof(cred);

   if (getsockopt(sockfd, SOL_SOCKET, SO_PEERCRED, &cred, &credlen) < 0) {

It's the only thing you need to build it on OpenBSD (checked with 5.6/i386), so maybe some #if/#ifdef magic is needed for the OpenBSD platform.

Use the IP_FREEBIND setsockopt(2) option where available

The IP_FREEBIND socket option, where available, allows for binding to IP address which does not (yet) exist.

This is useful, for example, for daemons integrating with systemd. When proftpd wants to bind to particular IP address during system start, there is no way how to determine that the network interface is really configured and the IP address is available.

See the similar request made for Apache httpd to support this: https://bz.apache.org/bugzilla/show_bug.cgi?id=58725

Fix handling of TLSServerInfoFile for OpenSSL API idiosyncracies

In the master branch, the mod_tls module supports a TLSServerInfoFile directive. This is implemented using OpenSSL's SSL_CTX_use_serverinfo_file API. However, per OpenSSL Issue #719, that API needs to be called again, after a call to SSL_CTX_use_certificate, e.g. for servers with multiple certificates configured. Thus mod_tls needs to be updated to make the multiple function calls, in order for TLSServerInfoFile to work as expected.

Username based load-balancing

Hello,

Here is a FTP architecture design topic, with (I think) a feature request.

Situation :

Let's assume several storage servers, let's take 2 for this example :

serverA
serverB

Then, of course several users, each one has its files on one of the storage servers.
For example :

serverA : user1, user2
serverB : user3, user4

The storage infrastructure is growing, perfect !
We must add a new storage server, and migrate some users.
Our example then changes to the following :

serverA : user1, user2
serverB : user3
serverC : user4, user5

user4 has migrated from serverB to serverC.

Request :

In order to avoid annoying users giving them a new FTP address each time their files are migrated (serverC instead of serverB for user4 in our example), I would like be able to add a FTP load-balancer.
All users would then be able to reach their files using a unique FTP address (the load-balancer's one), even if their files have migrated from a storage server to another.

The load-balacing must then be based on username : the load-balancer takes the incoming FTP login connections, and according to the username, redirect them to the correct server.
In order to optimize bandwith, DSR (Direct Server Return) is a must-have so that each file transfer is directly established between the target server and the FTP client, without going through the load-balancer, which would without DSR act as a bottleneck.
For security reasons, TLS should be supported for incoming connections.

All servers and load-balancer could share a common users authentication method (LDAP, SQL)...
A user password will then be the same for the 2 authentications steps (load-balancer, then target server).

The target server info could also be found in this authentication source (a specific field in LDAP, SQL)...

Do you think we could think about such a solution ?
Would really be awesome 👍

Thank you very much TJ / ProFTPD team !

Best regards,

Ben

solaris11's proftpd(bundle) doesn't load pam_close_session

hello.
First, I am sorry that I can't speak English well.

Proftpd was installed on solaris11 by bundle.
when exit of ftp connection, proftpd doesn't load pam_close_session.
So I can't recognize logout of ftp from PAM.

I think that 2 routine is not necessary in solaris11

  1. modules/mod_auth_pam.c -> pam_auth()

    if defined(SOLARIS2) || defined(HPUX10) || defined(HPUX11)

    if (success)
    pam_error = pam_close_session(pamh, 0);

    if (pamh)
    pam_end(pamh, pam_error);
    pamh = NULL;

    endif

  2. modules/mod_auth_pam.c - auth_pam_exit_ev()

    ifndef SOLARIS2

    pam_end(pamh, 0);
    pamh = NULL;

    endif

I did test proftpd that excepted above 2 routine.
New proftpd operated well.
( No loading pam_close_session in Login and Loading pam_close_session in Logout)

How about..?

Thank you.

Use posix_fadvise(), when available, for log files

The posix_advise function, where available, can be used to give hints to the kernel about expected access patterns for a file. When writing log files, for example, proftpd can advise the kernel that the application does not expect to read back in the data written out, e.g.:

posix_fadvise(logfd, 0, 0, POSIX_FADV_DONTNEED);

This should allow the kernel to not keep that data in the buffer cache, freeing up that buffer cache for other uses more rapidly.

This would apply to ExtendedLog, TransferLog, TraceLog, and any per-module logging.

mod_ban whitelisting doesn't work

I am observing issues with mod_ban whitelisting (for clientconnectrate) using mod_ifsession. The whitelisting doesn't work. See config snippet for config details. In addition to the server config, I have tested IfClass whitelist within IfModule mod_ban.c and *_Global *_sections to rule out all possibilities but it doesn't help.

Config Snippet
https://gist.github.com/pwnmagic/70f0bee17f1d2973890a

ProFTPD Version
1.3.4c

Related Info
This could be related to the bugfixes made in 1.3.3 with respect to mod_ban and mod_ifsesion (http://sourceforge.net/p/proftp/mailman/message/24628031/)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.