In my job, data collection and data deliveries are either done via API or FTP. FTP has it’s drawbacks, but ultimately gets the job done. Some of those issues are more specific to the lack of improvements in the technology, efficiency of the protocol, scaling, availability, file-locking and active vs. passive connections vs. the Firewall security -and so on. Not all are impossible challenges, but unnecessary in today’s cloud orientated technology world.
We still can’t get rid of the ability to transfer exported data and deliver over a file transfer protocol, however, we can change the protocol and the data handler and create a secure method that’s much easier to deal with. While it’s possible to run FTP and SSL/TLS for security, SFTP provides a much less intrusive replacement.
In a past post, I offered a method which allowed users to create a secondary service that was dedicated to SFTP and not use SSH to connect to a console. later versions of openssh don’t support the same method due to shared memory overlap, but – if you really want to create an isolated and dedicated SFTP service, then consider docker instead. In this guide, I’m going to show how to secure your existing SSH for both remote console and SFTP-only.
Step one: SFTP vs SSH (Shell)
I’m going to refer to SSH as “shell access” and SFTP as just “sftp without shell access”. I also use debian, so you’ll just a have to adapt for your own distro.
My /etc/ssh/sshd_config looks like this:
Listen 7387 Listen 22 ... # applies to members of the 'sftponly' group and are # coming in on port 7387 Match Group sftponly LocalPort 7387 ChrootDirectory %h X11Forwarding no AllowTcpForwarding no ForceCommand internal-sftp -u 000
External firewall port-forwards port 7387 only.
I leave it up to you if you want to use password or keys.
Step two: add sftp as a shell
echo "/usr/lib/openssh/sftp-server" >> /etc/shells
Step three: Create the group and first user
Create the sftponly group; I like mine to be system accounts, but it does not have to be.
groupadd --system sftponly
Create the user:
~# useradd --shell /usr/lib/openssh/sftp-server --user-group --home-dir /path/to/sftproot/userdir --groups sftponly
Annoyingly, the sftp server chrootdir directive requires the sftp-root is owned by root.
~# chown root:root /path/to/sftproot/userdir
I recommend that users still use firewall ACL’s to limit who can access their SFTP server in the first place, but if you provide a service to anyone-anywhere, then consider basic isolation practices and enhance the security further.
- Isolate the host serving sftp service
- Run read-only and restricted r/w capability (docker is good for this)
- Disable password authentication, use RSA certificates with a password in it.
- If you need to use passwords make sure you enforce complex and long passwords! Here’s a neat one-liner for password generation
openssl rand -base64 15
- Can you also support a two-factor method? Google-auth is pretty easy to integrate with and there are more options available if you look around. A nice cheap two-factor is to use both an rsa pubkey with a password and the user password.
AuthenticationMethods "publickey,password publickey,keyboard-interactive"