Skip to main content
  1. Main/
  2. How-To/

Activated SFTP Accounts

·

This manual explains how you can run a SFTP server with passwords set by the users.

I’m running a little FTP server using the SFTP command provided by openSSH.
Because I don’t want to know the passwords of the users I’ve thought about a method to provide the user an interface so they can set the password of their account.

Warranty There is no warranty that this setup works for any system which provide the dependencies listed below. I'm just providing these information because it worked for me. If you have questions you can leave a message here but I decide whether I'll answer and help or not.

Features #

  • user has to activate his FTP account by setting his password
  • user can easily be deactivated
  • user can change his password after the account was reset

Requirements #

  • grep
  • SSH ;)

Installation #

  1. create 2 groups:

    groupadd ftpusers
    groupadd preftpusers
    
  2. grant users in group ftpusers only SFTP access by adding this to your /etc/ssh/sshd_config:

    Match Group ftpusers
         AllowAgentForwarding no
         AllowTcpForwarding no
         ChrootDirectory %h
         ForceCommand internal-sftp
         MaxAuthTries 3
         MaxSessions 5
         PasswordAuthentication yes
         PermitRootLogin no
         PermitTunnel no
         X11Forwarding no
    
  3. install daemon-script:

    #!/bin/bash
    
    SCRIPT="$(basename $0)"
    FIFOFILE="/tmp/${SCRIPT}.fifo"
    FTPGROUP="ftpusers"
    PREFTPGROUP="preftpusers"
    
    function cleanup ()
    {
        rm -f ${FIFOFILE}
        trap - INT TERM EXIT
    }
    trap 'cleanup && exit 0' INT TERM EXIT
    mkfifo -m 622 ${FIFOFILE} || exit 1
    exec 30<> ${FIFOFILE}
    
    while true
    do
        while read <&30
        do
            user="${REPLY}"
            groups=( $(groups ${user} 2>/dev/null) )
            echo "$(date) ${user}"
            [[ -z "${groups[@]}" ]] && continue
            if ! grep -xFf <(printf '%s\n' ${groups[@]}) <(printf '%s\n' ${FTPGROUP[@]}) >/dev/null && grep -xFf <(printf '%s\n' ${groups[@]}) <(printf '%s\n' ${PREFTPGROUP[@]}) >/dev/null
            then
                usermod -g ${FTPGROUP} -s /bin/false ${user}
            fi
        done
    done
    
  4. install login-shell:

    #!/bin/bash
    
    passwd || exit 1
    echo "${USER}" > /tmp/ftpusers.sh.fifo 2>/dev/null || exit 1
    
  5. install init-script (for Arch Linux only)

    #!/bin/bash
    
    . /etc/rc.conf
    . /etc/rc.d/functions
    
    PIDFILE="/var/run/ftpusers.sh.pid"
    PID=$(pidof -o %PPID -x ftpusers.sh)
    ck_pidfile ${PIDFILE} ftpusers.sh || rm -f ${PIDFILE}
    case "$1" in
      start)
        stat_busy "Starting ftpserver"
        [ -z "$PID" ] && <scriptspath>/ftpusers.sh >>/var/log/ftpusers.sh.log 2>&1 &
        if [ $? -gt 0 ]; then
          stat_fail
        else
          add_daemon ftpserver
          stat_done
        fi
        ;;
      stop)
        stat_busy "Stopping ftpserver"
        [ ! -z "$PID" ]  && kill $PID &> /dev/null
        if [ $? -gt 0 ]; then
          stat_fail
        else
          rm_daemon ftpserver
          stat_done
        fi
        ;;
      restart)
        $0 stop
        sleep 1
        $0 start
        ;;
      *)
        echo "usage: $0 {start|stop|restart}"
    esac
    exit 0
    

Usage #

add User #

  1. add user

    useradd -s /path/to/ftpfirstlogin.sh -g preftpusers <username>
    passwd <username>
    
  2. start the daemon-script:

    bash /path/to/ftpusers.sh
    

    or if you want to use the init-script just run:

    /etc/rc.d/ftpserver start
    
  3. now tell the user the temporary password

  4. the user has to login using SSH then he can set and his account will be activated

deactivate User #

Just remove the user from the group ftpusers.

reset password #

  1. change password of the user

  2. start daemon-script

  3. move user from ftpusers to preftpusers:

    usermod -g preftpusers -s /path/to/ftpfirstlogin.sh <username>
    
  4. user again can set his password using SSH

How it works #

  1. because of the config SSH allows members of ftpusers only to use SFTP commands
  2. by setting login-shell to ftpfirstlogin.sh this script is run every time the user logs in
  3. ftpfirstlogin.sh
    1. runs passwd
    2. send username to fifo of ftpusers.sh
  4. ftpusers.sh:
    1. creates a fifo and waits for input through it
    2. each input is checked wheather it is a valid user
    3. if the user is member of preftpusers the main group is set to ftpusers and the login shell is set to /bin/false