[HOWTO] Add sftp access for ordinary users

Don't miss a thing. Post your questions and discussion about other uncategorized NAS features here.
micke
Experience counts
Posts: 1363
Joined: Sat Feb 06, 2010 2:42 pm
Location: Taipei, Taiwan

[HOWTO] Add sftp access for ordinary users

Post by micke »

The primary purpose of this HOWTO is to add sftp-only access for ordinary users in a chroot environment (i.e. they cannot access files outside the confined space we allocate for them). It should also be possible to use public key authentication (controlled by admin, though). The HOWTO also includes configuration for shell access, but you should only enable shell access to highly trusted user (more or less only users you would entrust with the admin password).

A QPKG file that creates the described configuration is attached to this post.

Requirements:
- You have installed and enabled Optware
- You are familiar with working from the command line
- You can edit text files on the system

A basic understanding of openSSH would help, too.

In the following text we assume the NAS is using a RAID configuration with the data in /share/MD0_DATA, if you have a single drive configuration or more than one volume and want to use a different volume then you have to replace MD0_DATA with the correct directory.

User configuration
In the web interface (Access Right Management->User Groups) we add two groups, one named ssh and the other sftponly.

Any user in the ssh group has shell access (and sftp access).
Any user in the sftponly group has only sftp access (in a chroot environment).

Assign users to the groups. Once again, be aware of the implications of enabling shell access to a user.

Install openssh
There are several different ways to install Optware's openssh and most of them replace the default ssh server. In this HOWTO we use a way that doesn't interfere with the default ssh server at all (also described as the "alternative way" in How To Replace SSH Daemon With OpenSSH). The benefit of this solution is that even if Optware would stop working for some reason we can still login using the default ssh server (remote replication jobs also continue to work when using a secure connection).

First we configure the default ssh server to run on a different port in the web interface (Network Services->Telnet/SSH)

Login as admin using the new port and install openSSH from the command line

Code: Select all

ipkg update
ipkg install openssh
Prepare directories
We create a new directory and corresponding subdirectories for the authorized keys (for optional public key authentication) and the chroot environment.

Code: Select all

/bin/mkdir -m 750 /share/MD0_DATA/openssh
/bin/chown admin:everyone /share/MD0_DATA/openssh
/bin/mkdir -m 710 /share/MD0_DATA/openssh/authorized_keys
/bin/chown admin:everyone /share/MD0_DATA/openssh/authorized_keys
/bin/mkdir -m 750 /share/MD0_DATA/openssh/sftpusers
/bin/chown admin:sftponly /share/MD0_DATA/openssh/sftpusers
Now, the chroot handling is very picky about the permission on all directories in the path and since we don't want to mess with the permissions on /share/MD0_DATA we create a new directory and bind mount /share/MD0_DATA/openssh to it. This directory must be re-created after a reboot and bind mounted again. We will automate that later.

Code: Select all

/bin/mkdir /openssh
/bin/mount --bind /share/MD0_DATA/openssh /openssh
For each user with sftp-only access we create a home directory in /openssh/sftpusers with restricted permissions only allowing the owner to access the directory (each user can relax that setting if they want to).

Code: Select all

for user in $(/bin/grep sftponly /etc/group | /bin/cut -d: -f4 | /bin/tr ',' ' '); do /bin/mkdir -m 700 /openssh/sftpusers/$user; /bin/chown $user:everyone /openssh/sftpusers/$user; done
When a new user is added to the sftponly group a home directory should also be created in /openssh/sftpusers.

Configure sshd
Open /opt/etc/openssh/sshd_config in your favourite editor (or do it on the desktop and then copy the modified file back to the NAS).

To simplify the chroot environment we must use sshd's internal sftp server. Locate the Subsystem option, comment it out and add the new option

Code: Select all

# override default of no subsystems
#Subsystem      sftp    /opt/libexec/sftp-server
Subsystem       sftp    internal-sftp
Last in the sshd_config file we add a Match block that is used to confine users in the sftponly group to the chroot environment

Code: Select all

Match Group sftponly
        ForceCommand internal-sftp
        ChrootDirectory /openssh/sftpusers
        X11Forwarding no
        AllowTcpForwarding no
This force the use of the internal sftp server, so that users in the sftponly group don't have the possibility to open a regular ssh session, assign users to the chroot environment in /openssh/sftpusers and prevent users from forwarding ports or starting remote X applications (the X11 forwarding is probably not required on a QNAP NAS, but it is included for completeness; if you ever attempt to implement a similar solution on a server running X11 it would be wise to prevent X11 forwarding)

To be able to use public key authentication for the sftp-only users we assign a new path to the public keys. Locate the AuthorizedKeysFile option (it should be commented out, but otherwise comment it out now) and add the new option

Code: Select all

#AuthorizedKeysFile     .ssh/authorized_keys
AuthorizedKeysFile      /openssh/authorized_keys/%u
This makes the server look for any public keys in a file with the same name as the user (%u is replaced with the username of the user being authenticated).

We also add a new option to only allow users in the ssh or sftponly groups to login.

Code: Select all

AllowGroups ssh sftponly
Save the file and exit the editor.

Now, we can test the new sshd configuration. Start a sshd process on an available port

Code: Select all

/opt/sbin/sshd -d -f /opt/etc/openssh/sshd_config -p 2222
and try to login from your desktop computer using a user with sftp-only access (on the given port).

If you have users with shell access you can try that, too, but you have to restart the sshd process, since it is a one-time only session.

If everything seems to be working you can start the openssh server and start using it.

Code: Select all

/opt/etc/init.d/S40sshd
Restore mount bind and start ssh server after reboot
To automatically create the /openssh directory, bind mount it to /share/MD0_DATA/openssh, and start the ssh server we can add the following to /etc/config/qpkg.conf (add it after the Optware section to make sure that Optware is up and running before our script runs)

Code: Select all

[openSSH]
Name = openSSH
Shell = /share/MD0_DATA/openssh/openssh.sh
and create this script in /share/MD0_DATA/openssh/openssh.sh

Code: Select all

#!/bin/sh
case "$1" in
  start)
    if [ -d /share/MD0_DATA/openssh ]; then
      /bin/mkdir -p /openssh
      /bin/mount --bind /share/MD0_DATA/openssh /openssh
    fi
    if [ -x /opt/etc/init.d/S40sshd ]; then
      /opt/etc/init.d/S40sshd
    fi
    ;;
  stop)
    umount /openssh
    ;;
  *)
    echo "Usage: $0 {start|stop}"
    exit 1
esac

exit 0
Remember to make the script executable

Code: Select all

/bin/chmod +x /share/MD0_DATA/openssh/openssh.sh
Optional configuration
To get usernames and group names instead of uid values an etc directory could be created in /openssh/sftpusers and either unmodified copies of /etc/passwd and /etc/group could copied to the directory or they could be modified to only include admin and the sftponly users in the passwd file and administrators, everyone, and sftponly in the group file to not give away any information about what other users and groups exist on the system.

Code: Select all

/bin/mkdir -m 755 /openssh/sftpusers/etc
/bin/cp /etc/passwd /openssh/sftpusers/etc
/bin/cp /etc/group /openssh/sftpusers/etc
/bin/chmod 644 /openssh/sftpusers/etc/{group,passwd}
When new users are added to the sftponly group the passwd and group files should also be updated.

To give the users a way to exchange files with each other a tmp directory could be created that all users would have write access to, but they could only delete their own files (using the sticky bit). This directory should probably be cleaned regularly by admin.

Code: Select all

mkdir -m 1777 /openssh/sftpusers/tmp
To use public authentication for the sftp-only users and the shell access users, the user should generate the private and public key on their desktop and in some secure way send the public key to admin. The admin user can then add the public key in a file with the same name as the user and placed in the /openssh/authorized_keys/ directory. Set restricted permissions on the file.

Code: Select all

/bin/chown user:everyone /openssh/authorized_keys/user
/bin/chmod 600 /openssh/authorized_keys/user
Now, the user can login without using a password (apart from whatever passphrase they might have assigned to the private key).

If all users (both sftp-only and shell access) use public key authentication then it is also possible to set PasswordAuthentication to no in sshd_config to further increase the security of the system.

I have tested the steps in this HOWTO on a TS-239 and a TS-419P.

Any feedback or suggestions for improvements are welcome.


EDIT:

I rewrote the openssh init script (/opt/etc/init.d/S40sshd) like this

Code: Select all

#!/bin/sh

[ -e /opt/etc/default/openssh ] && . /opt/etc/default/openssh

case "$1" in
  start)

    if [ "$SSHD_ENABLE" = "no" ]; then
        exit 1
    fi

    if [ -f /opt/var/run/sshd.pid ] ; then
      echo "sshd already running"
      exit 1
    fi

    umask 077

    /opt/sbin/sshd
    ;;

  stop)
    if [ -f /opt/var/run/sshd.pid ] ; then
      kill `cat /opt/var/run/sshd.pid`
    else
      if [ -n "$SSHD_NO_PID_KILLALL" ] ; then
        killall $SSHD_NO_PID_KILLALL
      else
        killall /opt/sbin/sshd
      fi
    fi

    rm -f /opt/var/run/sshd.pid
    ;;

  restart)
    $0 stop
    $0 start
    ;;

  *)
    echo "Usage: $0 {start|stop|restart}"
    exit 1
esac

exit 0
Now, when it is possible to start and stop the sshd using different commands I could update my own openssh script (/share/MD0_DATA/openssh/openssh.sh)

Code: Select all

#!/bin/sh
case "$1" in
  start)
    if [ -d /share/MD0_DATA/openssh ]; then
      /bin/mkdir -p /openssh
      /bin/mount --bind /share/MD0_DATA/openssh /openssh
    fi
    if [ -x /opt/etc/init.d/S40sshd ]; then
      /opt/etc/init.d/S40sshd start
    fi
    ;;

  stop)
    if [ -x /opt/etc/init.d/S40sshd ]; then
      /opt/etc/init.d/S40sshd stop
    fi
    /bin/grep -q openssh /etc/mtab
    if [ "$?" = "0" ]; then
      /bin/umount /openssh
      /bin/rmdir /openssh
    fi
    ;;

  *)
    echo "Usage: $0 {start|stop}"
    exit 1
esac

exit 0
Add an Enable option to the qpkg.conf file and it is possible to enable/disable sshd and the sftp configuration using the QPKG interface.

Code: Select all

[openSSH]
Name = openSSH
Enable = TRUE
Shell = /share/MD0_DATA/openssh/openssh.sh
QPKG
Optware must be installed before installing this QPKG file. If the default ssh server uses port 22 then the installed openssh locates a free port (starting with 222). The port that is used by openssh is included in the system log (in the log entry about the successful installation/upgrade of the QPKG).

At installation the ssh and sftponly groups are created unless they already exist and the openssh directory is created on the same volume that Public is located on (usually /share/MD0_DATA/ on a RAID system and /share/HDA_DATA/ on a single-drive).

If the openssh ipkg package from Optware isn't installed then it is installed automatically. Backups of the current sshd_config and S40sshd script are created (and if they haven't been removed also restored when the QPKG is removed). New versions of sshd_config and S40sshd are installed to support the sftp in a chroot environment.

By default home directories are created for the users in the sftponly group when openSSH is enabled. It will not touch any existing directories so when new users have been added to the sftponly group then it is safe to toggle the openSSH setting (disable/enable) in the QPKG interface to create the directories. To stop creating home directories by default for new users in the sftponly group the CREATE_SFTP_DIRS variable in /etc/init.d/openssh can be set to FALSE.

When the QPKG package is removed then it, as mentioned above, restores the sshd_config file in /opt/etc/openssh, the S40sshd init-script in /opt/etc/init.d, and restarts the sshd daemon using the original configuration file. It won't remove the ssh and sftponly groups. Neither does it remove the directory with the user data nor the openssh ipkg package.

/Mike
You do not have the required permissions to view the files attached to this post.
Last edited by micke on Thu Dec 02, 2010 11:05 pm, edited 2 times in total.
micke
Experience counts
Posts: 1363
Joined: Sat Feb 06, 2010 2:42 pm
Location: Taipei, Taiwan

Re: [HOWTO] Add sftp access for ordinary users

Post by micke »

I have created a first version of a QPKG that configures openSSH according to the HOWTO. I thought about removing the Optware requirement, but then I would have to be able to build openssh for the different architectures and currently I can only build and test for x86 and arm-x19 (test on TS-239 Pro and TS-419P). Also, if you already have Optware's openssh installed it would result in a third version on the NAS, which seems a bit unnecessary.

Apart from that Optware must be installed, it is also necessary to change the port for the default ssh daemon to something else than 22 in the web interface. Also, this package is only designed to work when either Optware's openssh isn't installed from the beginning or is running in parallel with the default ssh daemon. If you have replaced the default ssh daemon with the one from Optware then most likely this QPKG won't work.

At installation the ssh and sftponly groups are created unless they already exist and the openssh directory is created on the same volume that Public is located on (usually /share/MD0_DATA/ on a RAID system and /share/HDA_DATA/ on a single-drive).

If the openssh ipkg package from Optware isn't installed then it is installed automatically. Backups of the current sshd_config and S40sshd script are created (and if they haven't been removed also restored when the QPKG is removed). New versions of sshd_config and S40sshd are installed to support the sftp in a chroot environment.

By default home directories are created for the users in the sftponly group when openSSH is enabled. It will not touch any existing directories so when new users have been added to the sftponly group then it is safe to toggle the openSSH setting (disable/enable) in the QPKG interface to create the directories. To stop creating home directories by default for new users in the sftponly group the CREATE_SFTP_DIRS variable in /etc/init.d/openssh can be set to FALSE.

When the QPKG package is removed then it, as mentioned above, restores the sshd_config file in /opt/etc/openssh, the S40sshd init-script in /opt/etc/init.d, and restarts the sshd daemon using the original configuration file. It won't remove the ssh and sftponly groups. Neither does it remove the directory with the user data nor the openssh ipkg package.

/Mike
micke
Experience counts
Posts: 1363
Joined: Sat Feb 06, 2010 2:42 pm
Location: Taipei, Taiwan

Re: [HOWTO] Add sftp access for ordinary users

Post by micke »

Updated QPKG that checks the port used by a current installation of openssh from Optware and updates the new sshd_config file to use the same port. This also relax the requirement to always change the port number for the default ssh service; it is only if openssh from Optware is not installed at the time when the QPKG is installed that the port must be something else than 22 (if the default ssh service is enabled). I'm currently testing a version that locates a free port if 22 is used by the default ssh service.

This QPKG also fix a bug that enabled openSSH after a restart even if it was disabled before the restart.

The new QPKG can be installed without removing the previous version.

/Mike
micke
Experience counts
Posts: 1363
Joined: Sat Feb 06, 2010 2:42 pm
Location: Taipei, Taiwan

Re: [HOWTO] Add sftp access for ordinary users

Post by micke »

micke wrote:I'm currently testing a version that locates a free port if 22 is used by the default ssh service.
Added to version 0.3. Now the only requirement when installing this QPKG is that Optware is installed. Still, if openssh from Optware is installed on the NAS then I would assume that it is supposed to be the main ssh service and then it would probably make sense for it to use port 22, while the default ssh service uses another port (if it is still enabled), so I would still recommend that the port is changed in the web interface before installing this QPKG for the first time.

The port that is used by openssh is included in the system log (in the log entry about the successful installation/upgrade of the QPKG).

The new QPKG can be installed without removing the previous version.

Edit: A minor mistake in the package script would result in an uninstall script that wouldn't remove the QPKG directory when the package was removed. Fixed in the 0.4 version.

/Mike
micke
Experience counts
Posts: 1363
Joined: Sat Feb 06, 2010 2:42 pm
Location: Taipei, Taiwan

Re: [HOWTO] Add sftp access for ordinary users

Post by micke »

The install command in the busybox version on the NAS is completely unstable and can't be used for anything useful in a script, so I have replaced it in the QPKG installation script with a combination of mkdir and chown. The problem would only turn up at a fresh install (and only sometimes).

/Mike
No Expert
Know my way around
Posts: 179
Joined: Fri Sep 17, 2010 4:05 am

Re: [HOWTO] Add sftp access for ordinary users

Post by No Expert »

Mike,

I too am looking to enable SFTP for accessing my TS-110 (till now I've been using SCP).
I have tried on the default Admin account (port 22) but I've had no luck. Doing some searching I have found that this maybe because QNAP themselves have restricted such SFTP access: http://forum.qnap.com/viewtopic.php?f=1 ... cp#p108591

Now, I do have OpenSSH installed (which works fine by the way) and I'd like to enable SFTP using that.
At this stage I'm not worried about restricting access to users.

Therefore, if all I want is just to enable SFTP, would it be as simple as just adding the following to the sshd_config file?

Code: Select all

Subsystem       sftp    internal-sftp
micke
Experience counts
Posts: 1363
Joined: Sat Feb 06, 2010 2:42 pm
Location: Taipei, Taiwan

Re: [HOWTO] Add sftp access for ordinary users

Post by micke »

No Expert wrote: Therefore, if all I want is just to enable SFTP, would it be as simple as just adding the following to the sshd_config file?

Code: Select all

Subsystem       sftp    internal-sftp
Probably. Best way to find out is to add the line, start a separate sshd server on a different port, and try to login using sftp. If the public key authentication is working then it should login without any password prompt.

/Mike
User avatar
Eduardo
Easy as a breeze
Posts: 350
Joined: Tue Jun 30, 2009 2:08 am
Location: Sevilla (Spain)

Re: [HOWTO] Add sftp access for ordinary users

Post by Eduardo »

Hi Mike:

Installed your qpkg. Working nice. Just let me one question. How can I change the port 22 to another one?

This port is always target of attacks.

I tried editing sshd_config, but no results.

Regards
TS-259Pro+,TS-239 Pro. Firm 3.7.3 Build0801
2xSeagate ST32000542AS CC34 Raid 1 (+1 ST32000542AS Raid 1 ESATA/USB Backup)
Qpkg: MLDonkey, JRE, Micke OpenSSH, Micke Nasreport, Python, CrashPlan, Rsnap.
Ipkg: Rsnapshot, logrotate, heyu
================================================================================================
Looking forward to a (Prolific 2303 or ftdi) USB to serial driver!
micke
Experience counts
Posts: 1363
Joined: Sat Feb 06, 2010 2:42 pm
Location: Taipei, Taiwan

Re: [HOWTO] Add sftp access for ordinary users

Post by micke »

Eduardo wrote: How can I change the port 22 to another one?
Edit the port setting in /opt/etc/openssh/sshd_config and toggle the QPKG status (i.e. disable/enable).

/Mike
User avatar
Eduardo
Easy as a breeze
Posts: 350
Joined: Tue Jun 30, 2009 2:08 am
Location: Sevilla (Spain)

Re: [HOWTO] Add sftp access for ordinary users

Post by Eduardo »

Hi Mike:

Sorry. Another question.

Openssh is a Rsnapshot dependence. How to tell Rsnapshot to use the OpenSSH of your Qpkg?
TS-259Pro+,TS-239 Pro. Firm 3.7.3 Build0801
2xSeagate ST32000542AS CC34 Raid 1 (+1 ST32000542AS Raid 1 ESATA/USB Backup)
Qpkg: MLDonkey, JRE, Micke OpenSSH, Micke Nasreport, Python, CrashPlan, Rsnap.
Ipkg: Rsnapshot, logrotate, heyu
================================================================================================
Looking forward to a (Prolific 2303 or ftdi) USB to serial driver!
micke
Experience counts
Posts: 1363
Joined: Sat Feb 06, 2010 2:42 pm
Location: Taipei, Taiwan

Re: [HOWTO] Add sftp access for ordinary users

Post by micke »

Eduardo wrote: Openssh is a Rsnapshot dependence. How to tell Rsnapshot to use the OpenSSH of your Qpkg?
The QPKG uses openssh from Optware, so you don't have to make any modifications to rsnapshot.

/Mike
User avatar
Eduardo
Easy as a breeze
Posts: 350
Joined: Tue Jun 30, 2009 2:08 am
Location: Sevilla (Spain)

Re: [HOWTO] Add sftp access for ordinary users

Post by Eduardo »

micke wrote:
Eduardo wrote: Openssh is a Rsnapshot dependence. How to tell Rsnapshot to use the OpenSSH of your Qpkg?
The QPKG uses openssh from Optware, so you don't have to make any modifications to rsnapshot.

/Mike
Perfect Qpkg, then!

Many thanks indeed
TS-259Pro+,TS-239 Pro. Firm 3.7.3 Build0801
2xSeagate ST32000542AS CC34 Raid 1 (+1 ST32000542AS Raid 1 ESATA/USB Backup)
Qpkg: MLDonkey, JRE, Micke OpenSSH, Micke Nasreport, Python, CrashPlan, Rsnap.
Ipkg: Rsnapshot, logrotate, heyu
================================================================================================
Looking forward to a (Prolific 2303 or ftdi) USB to serial driver!
User avatar
Eduardo
Easy as a breeze
Posts: 350
Joined: Tue Jun 30, 2009 2:08 am
Location: Sevilla (Spain)

Re: [HOWTO] Add sftp access for ordinary users

Post by Eduardo »

micke wrote:Now, the chroot handling is very picky about the permission on all directories in the path and since we don't want to mess with the permissions on /share/MD0_DATA we create a new directory and bind mount /share/MD0_DATA/openssh to it. This directory must be re-created after a reboot and bind mounted again. We will automate that later.

For each user with sftp-only access we create a home directory in /openssh/sftpusers with restricted permissions only allowing the owner to access the directory (each user can relax that setting if they want to).
/Mike
Hi Mike:

Not sure to understand the utility/sense of this strategy. Shouldn't it be more logical to simply let the users to access to their shares instead of having new ones? should it be a good idea to use soft links to their shares?

Regards
TS-259Pro+,TS-239 Pro. Firm 3.7.3 Build0801
2xSeagate ST32000542AS CC34 Raid 1 (+1 ST32000542AS Raid 1 ESATA/USB Backup)
Qpkg: MLDonkey, JRE, Micke OpenSSH, Micke Nasreport, Python, CrashPlan, Rsnap.
Ipkg: Rsnapshot, logrotate, heyu
================================================================================================
Looking forward to a (Prolific 2303 or ftdi) USB to serial driver!
micke
Experience counts
Posts: 1363
Joined: Sat Feb 06, 2010 2:42 pm
Location: Taipei, Taiwan

Re: [HOWTO] Add sftp access for ordinary users

Post by micke »

Eduardo wrote: Not sure to understand the utility/sense of this strategy. Shouldn't it be more logical to simply let the users to access to their shares instead of having new ones? should it be a good idea to use soft links to their shares?
The whole point of a chroot'ed environment is to prevent access to files outside of the chroot, so soft-links won't work. Also, if the directories in the chroot were shares then the QNAP would mess up the permissions; it just loves to set the permissions to 777 (and with admin as owner) and that would make the "home directories" open to anyone. No more privacy.

If you have some kind of mixed environment then you could bind mount the share inside the chroot. For example, you could do something like this,

Code: Select all

cd /openssh/sftpusers/user1
/bin/mkdir share
/bin/mount --bind /share/user1/ share
Now, when user1 logs in using sftp the share is also available. You'll have to remount the directory after a reboot, though.

Maybe you could create the share directory inside the user's sftp directory -- that is, specify the path manually as /openssh/sftpusers/user1/share. This way the share directory is created inside user1's sftp directory, which can only be accessed by user1.

/Mike
User avatar
Eduardo
Easy as a breeze
Posts: 350
Joined: Tue Jun 30, 2009 2:08 am
Location: Sevilla (Spain)

Re: [HOWTO] Add sftp access for ordinary users

Post by Eduardo »

Hi Mike:

Thanks for your clear answer. Now, I can understand what you mean about the QNAP permissions mess up.

I'll try both ways to compare the results/pro-con.

Thanks a lot.
TS-259Pro+,TS-239 Pro. Firm 3.7.3 Build0801
2xSeagate ST32000542AS CC34 Raid 1 (+1 ST32000542AS Raid 1 ESATA/USB Backup)
Qpkg: MLDonkey, JRE, Micke OpenSSH, Micke Nasreport, Python, CrashPlan, Rsnap.
Ipkg: Rsnapshot, logrotate, heyu
================================================================================================
Looking forward to a (Prolific 2303 or ftdi) USB to serial driver!
Locked

Return to “Miscellaneous”