Proftpd with Openssl and virtual users

From QNAPedia
Jump to: navigation, search

For detailed info, look here http://forum.qnap.com/viewtopic.php?f=90&t=3499&p=16283 and here viewtopic.php?f=90&t=2851&p=16280

This is how I did it...

First install Optware/ IPKG

You need Optware/IPKG

  1. a. Go to administration web login and go to Applications - QPKG Center and install Optware, also read http://wiki.qnap.com/wiki/Install_Optware_IPKG
  2. b. Don't forget to enable Optware in administration web login - Applications - QPKG Center (click 'Enable' ) after installation and then restart the NAS. If you have not restarted, you need at least to do

PATH=$PATH:/opt/bin:/opt/sbin


Installing stuff

First I go to a temp folder (so the littering files stays here)

mkdir /opt/temp
cd /opt/temp


Install (to install perl, you can also do like this http://wiki.qnap.com/wiki/Perl_5.8.8_Installation )

/opt/bin/ipkg update
/opt/bin/ipkg install proftpd
/opt/bin/ipkg install perl


Get ftpasswd

From the source (I did this), find your favorite downloading/mirror site here http://www.proftpd.org/ or download from ftp://ftp.proftpd.org/distrib/source/ :

cd /opt/temp
wget ftp://ftp-stud.fht-esslingen.de/pub/Mirrors/ftp.proftpd.net/devel/source/proftpd-cvs-20080226.tar.gz
tar xvfz proftpd-cvs-20080226.tar.gz
cp /opt/temp/proftpd-cvs-20080226/contrib/ftpasswd /opt/bin/
rm proftpd-cvs-20080226* -r


Or maybe you prefer to get it from castaglia.org? I guess you could do like this:

cd /opt/bin/
wget http://www.castaglia.org/proftpd/contrib/ftpasswd
chmod 700 ftpasswd


If you installed perl with ipkg, open ftpasswd and change it with (if you installed with http://wiki.qnap.com/wiki/Perl_5.8.8_Installation, you don't need to change it):


vi /opt/bin/ftpasswd


From:

#!/usr/bin/perl


To:

#!/opt/bin/perl


Make one virtual user to test with


mkdir /home/proftpusers
mkdir /home/proftpusers/bob
cd /opt/etc/ftpd
/opt/bin/ftpasswd --passwd --name=bob --uid=1001 --home=/home/proftpusers/bob --shell=/bin/false



Openssl


mkdir /opt/etc/openssl
chmod 600 /opt/etc/openssl
cd /opt/etc/openssl
touch sign.sh
vi sign.sh

I paste this into sign.sh:


#!/bin/sh
##
##  sign.sh -- Sign a SSL Certificate Request (CSR)
##  Copyright (c) 1998-2001 Ralf S. Engelschall, All Rights Reserved.
##
#   argument line handling
CSR=$1
if [ $# -ne 1 ]; then
    echo "Usage: sign.sign <whatever>.csr"; exit 1
fi
if [ ! -f $CSR ]; then
    echo "CSR not found: $CSR"; exit 1
fi
case $CSR in
   *.csr ) CERT="`echo $CSR | sed -e 's/\.csr/.crt/'`" ;;
       * ) CERT="$CSR.crt" ;;
esac
#   make sure environment exists
if [ ! -d ca.db.certs ]; then
    mkdir ca.db.certs
fi
if [ ! -f ca.db.serial ]; then
    echo '01' >ca.db.serial
fi
if [ ! -f ca.db.index ]; then
    cp /dev/null ca.db.index
fi

#   create an own SSLeay config
cat > ca.config <<EOT
[ ca ]
default_ca              = CA_own
[ CA_own ]
dir                     = .
certs                   = \$dir
new_certs_dir           = \$dir/ca.db.certs
database                = \$dir/ca.db.index
serial                  = \$dir/ca.db.serial
RANDFILE                = \$dir/ca.db.rand
certificate             = \$dir/ca.crt
private_key             = \$dir/ca.key
unique_subject          = no
# default key expiry set to 5 years but can be changed
default_days            = 1825
default_crl_days        = 30
default_md              = md5
preserve                = no
policy                  = policy_anything
[ policy_anything ]
countryName             = optional
stateOrProvinceName     = optional
localityName            = optional
organizationName        = optional
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional
EOT

#  sign the certificate
echo "CA signing: $CSR -> $CERT:"
openssl ca -config ca.config -out $CERT -infiles $CSR
echo "CA verifying: $CERT <-> CA cert"
openssl verify -CAfile ca.crt $CERT

#  cleanup after SSLeay
rm -f ca.config
rm -f ca.db.serial.old
rm -f ca.db.index.old

#  die gracefully
exit 0

Make sign.sh owned by root and executable


chown admin:administrators /opt/etc/openssl/sign.sh
chmod 700 /opt/etc/openssl/sign.sh 


Creating the Keys and Certificates


openssl genrsa -des3 -out ca.key 1024 
mv ca.key ca.key.orig
openssl rsa -in ca.key.orig -out ca.key
openssl req -new -x509 -days 1825 -key ca.key -out ca.crt
cp /opt/etc/openssl/ca.crt /opt/etc/ftpd/
openssl genrsa -des3 -out server.key 1024
mv server.key server.key.orig
openssl rsa -in server.key.orig -out server.key
cp /opt/etc/openssl/server.key /opt/etc/ftpd/ 

Prepare a certificate signing request (CSR). Important - when asked for a Common Name - enter localhost

openssl req -new -key server.key -out server.csr
./sign.sh server.csr
cp /opt/etc/openssl/server.crt /opt/etc/ftpd/ 

Setup proftpd

Create a user to run proftpd

addgroup nogroup
adduser -h /home/proftpusers/ -G nogroup -s /bin/false proftpduser


Lets change the config file, but first we do a backup of it:

cp /opt/etc/proftpd.conf /opt/etc/proftpd.conf.backup
vi /opt/etc/proftpd.conf


Change it to this:

    # This is a basic ProFTPD configuration file (rename it to
    # 'proftpd.conf' for actual use.  It establishes a single server
    # and a single anonymous login.  It assumes that you have a user/group
    # "nobody" and "ftp" for normal operation and anon.
    ServerName                      "FTP"
    ServerType                      standalone
    DefaultServer                   on
    WtmpLog                         off
    #MasqueradeAddress              ftp.yourdomain.com

    # Port 21 is the standard FTP port.
    Port                            21
    PassivePorts                    50000 50019
    UseReverseDNS off
    IdentLookups off

    # Umask 022 is a good standard umask to prevent new dirs and files
    # from being group and world writable.
    Umask                           022

    # To prevent DoS attacks, set the maximum number of child processes
    # to 30.  If you need to allow more than 30 concurrent connections
    # at once, simply increase this value.  Note that this ONLY works
    # in standalone mode, in inetd mode you should use an inetd server
    # that allows you to limit maximum number of processes per service
    # (such as xinetd).
    MaxInstances                    10

    <Global>
      RootLogin Off
      RequireValidShell off
    # Lets use our new virtual users
      AuthUserFile /opt/etc/ftpd/ftpd.passwd
      AuthOrder mod_auth_file.c
      AllowStoreRestart on
    #  TransferRate RETR 25
    #  TransferRate APPE,STOR 100:2048
    </Global>


    # Set the user and group under which the server will run.
    User                            proftpduser
    Group                           nogroup

    # To cause every FTP user to be "jailed" (chrooted) into their home
    # directory, uncomment this line.
    DefaultRoot ~

    # Normally, we want files to be overwriteable.
    AllowOverwrite          on

    # Bar use of SITE CHMOD by default
    <Limit SITE_CHMOD>
      DenyAll
    </Limit>

    # A basic anonymous configuration, no upload directories.  If you do not
    # want anonymous users, simply delete this entire <Anonymous> section.

    <IfModule mod_tls.c>
    TLSEngine on
    TLSLog /opt/var/proftpd/tls.log
    # Set the TLSProtocol to one of the following
    # SSLv23 - Use SSL3 for ctrl and TLS1 for data channels (works with most clients)
    # SSLv3  - Use only SSL3
    # TLSv1  - Use only TLS1
    TLSProtocol SSLv23

    # Clients are required to use FTP over SSL/TLS when talking to this server
    # off  - clients can connect using insecure FTP or secure FTP/SSL
    # ctrl - encrypt only the ctrl channel using FTP/SSL
    # data - encrypt only the data channel using FTP/SSL (not recommended)
    # on   - encrypt both the ctrl and data channels using FTP/SSL
    TLSRequired ctrl

    # Server's certificate
    TLSRSACertificateFile /opt/etc/ftpd/server.crt
    TLSRSACertificateKeyFile /opt/etc/ftpd/server.key

    # CA the server trusts
    TLSCACertificateFile /opt/etc/ftpd/ca.crt

    # Authenticate clients that want to use FTP over SSL/TLS
    # off - client SSL certificates are not requried
    # on  - client SSL certificates are required
    TLSVerifyClient off
    </IfModule>

Or if you want some logging, use this (I use this one):

    # This is a basic ProFTPD configuration file (rename it to
    # 'proftpd.conf' for actual use.  It establishes a single server
    # and a single anonymous login.  It assumes that you have a user/group
    # "nobody" and "ftp" for normal operation and anon.
    ServerName                      "FTP"
    ServerType                      standalone
    DefaultServer                   on
    WtmpLog                         off
    #MasqueradeAddress              ftp.yourdomain.com

    # Port 21 is the standard FTP port.
    Port                            21
    PassivePorts                    50000 50019
    UseReverseDNS off
    IdentLookups off

    # Umask 022 is a good standard umask to prevent new dirs and files
    # from being group and world writable.
    Umask                           022


    # To prevent DoS attacks, set the maximum number of child processes
    # to 30.  If you need to allow more than 30 concurrent connections
    # at once, simply increase this value.  Note that this ONLY works
    # in standalone mode, in inetd mode you should use an inetd server
    # that allows you to limit maximum number of processes per service
    # (such as xinetd).
    MaxInstances                    10

    # Logging options
    #
    TransferLog                     /opt/var/proftpd/xferlog.legacy
    #
    # Some logging formats
    #
    LogFormat                       default "%h %l %u %t \"%r\" %s %b"
    LogFormat                       auth    "%v [%P] %h %t \"%r\" %s"
    LogFormat                       write   "%h %l %u %t \"%r\" %s %b"
    #

    <Global>
      RootLogin Off
      RequireValidShell off
    # Lets use our new virtual users
      AuthUserFile /opt/etc/ftpd/ftpd.passwd
      AuthOrder mod_auth_file.c
      AllowStoreRestart on
    #  TransferRate RETR 25
    #  TransferRate APPE,STOR 100:2048
    #
    # Logging
    # file/dir access
    ExtendedLog             /opt/var/proftpd/access.log WRITE,READ write
    #
    # Record all logins
    ExtendedLog             /opt/var/proftpd/auth.log AUTH auth

    </Global>


    # Set the user and group under which the server will run.
    User                            proftpduser
    Group                           nogroup

    # To cause every FTP user to be "jailed" (chrooted) into their home
    # directory, uncomment this line.
    DefaultRoot ~

    # Normally, we want files to be overwriteable.
    AllowOverwrite          on

    # Bar use of SITE CHMOD by default
    <Limit SITE_CHMOD>
      DenyAll
    </Limit>

    # A basic anonymous configuration, no upload directories.  If you do not
    # want anonymous users, simply delete this entire <Anonymous> section.

    <IfModule mod_tls.c>
    TLSEngine on
    TLSLog /opt/var/proftpd/tls.log
    # Set the TLSProtocol to one of the following
    # SSLv23 - Use SSL3 for ctrl and TLS1 for data channels (works with most clients)
    # SSLv3  - Use only SSL3
    # TLSv1  - Use only TLS1
    TLSProtocol SSLv23

    # Clients are required to use FTP over SSL/TLS when talking to this server
    # off  - clients can connect using insecure FTP or secure FTP/SSL
    # ctrl - encrypt only the ctrl channel using FTP/SSL
    # data - encrypt only the data channel using FTP/SSL (not recommended)
    # on   - encrypt both the ctrl and data channels using FTP/SSL
    TLSRequired ctrl

    # Server's certificate
    TLSRSACertificateFile /opt/etc/ftpd/server.crt
    TLSRSACertificateKeyFile /opt/etc/ftpd/server.key

    # CA the server trusts
    TLSCACertificateFile /opt/etc/ftpd/ca.crt

    # Authenticate clients that want to use FTP over SSL/TLS
    # off - client SSL certificates are not requried
    # on  - client SSL certificates are required
    TLSVerifyClient off
    </IfModule>


Say you have a dir called 'uploads', where you like them to be able to upload files. Add this code just above </Global>

    # An upload directory that allows storing files but not retrieving
    # or creating directories.
    <Limit WRITE>
          DenyAll
    </Limit>
    <Directory /home/proftpusers/uploads/*>
    <Limit READ>
    DenyAll
    </Limit>
    <Limit STOR>
    AllowAll
    </Limit>
    </Directory>


If you get disconnection problems with your FTP client, as an example say you want to copy several files but after the first file the other files don't get copied. And you need to close and restart the client to continue and in your TLS log you see something like this:

Apr 18 05:27:33 mod_tls/2.4.3[12797]: client did not reuse SSL session, rejecting data connection (see the NoSessionReuseRequired TLSOptions parameter)


Then you can try to add

TLSOptions NoSessionReuseRequired

inside of

<IfModule mod_tls.c>
...
</IfModule>


Don't forget:

  • Pathnames in <Directory ...> must always be absolute (except inside <Anonymous>), and should not reference symbolic links
  • You may need to do a 'chmod 777' on the directory for this to work (dirs where you don't want 'them' to write you can have chmod 755)
  • After a change in proftpd.conf, restart proftpd ('ps' -> check the PID -> 'kill <pid>' -> '/opt/sbin/proftpd &'


About <Directory ...>
http://www.proftpd.org/docs/directives/linked/config_ref_Directory.html

About <Limit ...>
http://www.proftpd.org/docs/directives/linked/config_ref_Limit.html

-- More --
Configuration Directives by Functionality
http://www.castaglia.org/proftpd/doc/contrib/functional-directive-index.html

ProFTPD Configuration Directives By Context
http://www.castaglia.org/proftpd/doc/contrib/contextual-directive-index.html


EVEN MORE ----
Howtos, configs etc:
http://www.castaglia.org/proftpd/

Lets try it

/opt/sbin/proftpd & 


Since 1.3.2 is available for Qnap ipkg, so any FileZilla client should work with these settings:
GENERAL
Servertype: FTPES - FTP over explicit TLS/SSL
Logontype: Normal

TRANSFER SETTINGS

Transfer mode: Active