I like to avoid all those companies that lure you with cloud storage and then want money after you have used up a certain amount of Gigabytes. I also do not want to share my data with them, although they give you guarantees of keeping your data private. Nevertheless, for the majority of individuals it makes sense to either have cloud storage, local portable storage (e.g. USB stick, SD card, portable SSD disk etc.), or NAS storage. I have my own servers running at home (actually Virtual Machines running on a Workstation) and I decided to add external USB storage for one of the servers (NOTE: I would’ve used a partition on internal storage if I had enough available).
By using the functionality of the Secure Shell Daemon (SSHD) on my server, I can backup the data on my mobile phone, my tablet, and my laptop using a Secure File Transfer Protocol (SFTP) client. By backing up to my server I am basically creating my own Network Attached Storage (NAS)
Now that I’ve explained that my goal is to use storage on a server on my network using an SFTP App/application on your client device (e.g. Smartphone, laptop etc.) and the SSHD on your server, let’s get started on how to achieve this. I always use Linux so will only explain how I achieved my goal using Linux. This article assumes you know how to install a Linux server distribution and the SSH Daemon (SSHD), or that you already have it installed. For those of you who are impatient, and/or have good Linux know how here is the step-by-step guide using existing internal storage.
- Create a group with an meaningful name – groupadd sftp
- Create a directory for all user who will be using your network storage – mkdir /ftpusers
- Change the SSH configuration file /etc/ssh/sshd_config as follows:
Comment out “Subsystem sftp /usr/lib/openssh/sftp-server” and add the following lines at the end of the configuration file.
Subsystem sftp internal-sftp
Match Group sftp
ChrootDirectory /ftpusers
ForceCommand internal-sftp
AllowTcpForwarding no
- Restart the SSH daemon – service sshd restart
- Ensure the user and group root own the directory /ftpusers – chown root:root /ftpusers
- Ensure the read, write, execute permissions are correct – chmod 751 /ftpusers
- Create the individual user directories (let’s assume we will have a user called “smith”) – mkdir /ftpusers/smith
- Create users who will use this service (using the user “smith”) – useradd -g sftp -d /smith -s /sbin/nologin smith
- Give the user a password – passwd smith
- Change the ownership for the directory /ftpusers/smith – chown smith:root /ftpusers/smith
- Change the read, write, execute permissions on directory /ftpusers/smith – chmod 770 /ftpusers/smith
Following the above steps you should now be able to use your sftp client and login to your chroot jail environment and upload files.
It’s always good to understand why things work rather than just blindly follow instructions, especially if you’re having troubles and things didn’t work for you for some reason. Here is an explanation of the points above.
In point 1 we have created a group called “sftp” mainly for the SFTP sub-system running under the SSH Daemon, and in point 2 we have created the root directory of our chroot jail.
Point 3 causes all users who are in the group we created in point 1 to be chroot’d/jailed to the directory /ftpusers, basically meaning they cannot escape from the /ftpusers environment. I was interested as to why I needed to change the subsystem configuration from “sftp-server” to “internal-sftp” and found the following if you are interested – https://serverfault.com/questions/660160/openssh-difference-between-internal-sftp-and-sftp-server#660325
Points 5 and 6 are very important to follow correctly. I had the idea that I would give myself, the system administrator, full permissions on the chroot directory (e.g. “chown root:admin /ftpusers”, “chmod 771 /ftpusers”). DO NOT DO THIS! Always ensure the permission are 751 (I assume 750 is also fine). I was inquisitive to know why I couldn’t give a group write permissions and found this explanation from a SSHD developer – “We ban this because allowing a user write access to a chroot target is dangerously similar to equivalence with allowing write access to the root of a filesystem”. If you allow someone other than root write access you will get an error by login. I also strongly recommend not giving “world” write access (e.g. “chmod 771 /ftpusers”). If you do this User A will be able to see and access User B’s directory structure.
Point 8 is creating an SFTP user login for a user called “smith” who will be in the group “sftp and have the home directory “/ftpusers/smith”. Note the connection with the SSHD configuration in point 3! The user “smith” is in the group “sftp” so will be matched with the “Match Group” setting in the SSHD config file. As a result the user will be logged into a home home directory of “/ftpusers” as specified in the SSHD configuration plus “/smith” as specified in the “useradd” -d option in command useradd -g sftp -d /smith -s /sbin/nologin smith. Finally the -s /sbin/nologin is ensuring that the user cannot make any sort of shell login but only and SFTP login.
Further useful information
Data Redundancy
You may want to go that bit further put in some redundancy by making a backup of your backups in case your disk crashes. I have achieved this using the rsync command and making it a root cron task. The manual command would be something like this:
rsync -a /ftpusers/ /AnotherDisk/AnotherPartition/ftpusers-backup
or
rsync -a –delete /ftpusers/ /AnotherDisk/AnotherPartition/ftpusers-backup (which will remove any files at the destination that were removed at the source)
NOTE: I am recommending that your destination is not on the same device as your source. Obvious as to the reason why, isn’t it?
External Access
If you want to allow Internet access you will have to allow SSH, port 22, access through your firewall. If you are a typical home user with a DHCP IP address you’ll either have to access using the IP address of your router, or setup your own domain and Dynamic DNS service.
SFTP Clients
There are plenty out but I have used Easy FTP on Apple IOS devices which has a nice uncomplicated interface. WinSCP would be my choice for Windows and on Linux I use either use CLI commands or Nautilus
Conclusion
Well, that is it unless you want to backup your files directly to external storage. If you are wanting to put your users files on external storage then please read on.
Using External Storage for your SFTP users (or a newly installed disk)
The first thing to note is that if you do use external storage it is not expected that you remove the device and move it from PC to Laptop to Tablet etc. It will probably become obvious as to why as you read through this section. The main reason for using external storage is that you do not have enough internal storage, or want to save it for something else.
First of all ensure your external storage device is formatted using the ext2, ext3 or ext4 file system. The reason you want ext2, ext3 or ext4 is so that one can set directory ownership and permissions. You cannot set ownership and permissions on a ntfs, vfat formatted device (have you now figured out why your device is no longer really portable to another PC/Laptop/Tablet? I know Windows OS won’t recognise ext formatted devices, and I believe IOS also. Also the ownership on another Linux device may well be irrelevant).
Once your disk is formatted create a mount point (directory) where your device can be mounted. If you read all of the above we would want to mount things on /ftpusers, therefore you can create the mount point (directory) as described above (e.g. “mkdir /ftpusers”, “chown root:root /ftpusers”, “chmod 751 /ftpusers”). I would recommend not using “chmod 751 /ftpusers” as if your external storage is umounted for any reason then potentially root has the rights to write to your hard disk and fill it up. In this case I would go with “chmod 551 /ftpusers” and add extra security with the chattr command – “chattr +i /ftpusers” (It’s worth fully understanding this command). Note that the rights on the /ftpuser directory will be changed when your external storage is mounted! The mount command looks at the /etc/fstab file to see how your external storage should be mounted. This is described below.
Next find out the device. I find the easiest way is to do fdisk -l . To be really sure remove the external storage and do fdisk -l again and you should see that the device is missing. It’s a good chance that your device will be /dev/sdb1 (Disk /dev/sdb with the partition /dev/sdb1). Now ensure you can mount and umount the device (e.g mount /dev/sdb1 /ftpuser, umount /ftpusers).
You will need to modify the file system, /etc/fstab, so that the storage device mounts automatically after reboot. It’s also good to define things here, as the mount command get the information it needs /etc/fstab meaning you don’t have to remember all the options when mounting manually. You will need to find out the Universally Unique Identifier, UUID, of your device by entering the command blkid /dev/sdb1 (NOTE: I’ve assumed /dev/sdb1 is the partion, it could be different in your case). After finding the UUID add a line like this at the end of your /etc/fstab – UUID=123456ab-89ef-1234-9876-11a2b039f7c0 /ftpusers auto rw,nofail 0 0 – where the UUID value is the value you looked up with the command blkid /dev/sdb1
I hope you have found this article of interest. Please feel free to comment.