I needed to set up a secure ftp site, primarily to receive file based backups from a variety of servers hosted on AWS. Not surprisingly, there are a lot of choices out there.
Selecting the best one
Ability to run on docker was a must. Built-in Fail2Ban or similar capability was also essential. I was not looking for a ton of features, ideally, something simple and straight forward.
I looked at sftpgo, which while popular, just seemed way more complicated than I need. atmoz/sftp would work, but did not have any auto-ban feature. Then I stumbled on an atmoz/sftp fork, schnuckz/sftp. It is docker ready and includes Fail2Ban. That’s the one I went with.
Setup
Port forward port 2222 on the firewall.
Set up a persistent area.
sudo mkdir /dockerdata/sftp
Create the Compose file. The first launch will specify a test user (myftpuser), only for the purpose of creating the directory structure needed.
sftp: image: schnuckz/sftp:main container_name: sftp ports: # remap port 22 as this is used for ssh. - "2222:22" # Allow this container to have network admin capability so it can run fail2ban. cap_add: - NET_ADMIN volumes: # config folder for fail2ban, sshd, userkeys - /dockerdata/sftp:/config # stoarge is on the nas mount. - /mnt/nas/ftp:/home/sftpuser/ftp # This will be removed when we switch to user keys command: myftpuser:mypassword:1000:1000:ftp restart: unless-stopped
Launch the container.
docker-compose up -d sftp
Check that it’s running ok.
docker logs --tail="200" -f sftp
The underlying directory and file structure is now created, and the host keys are automatically generated.
Confirm that Fail2Ban is running.
tail -f /dockerdata/sftp/fail2ban/fail2ban.log
You should see log entries of the form “Starting Fail2ban…” and “Connected to fail2ban persistent database”.
Stop the container to proceed to the next step.
docker-compose stop sftp
Creating a User and User Keys
Edit the compose file and comment out the “command” entry.
We’ll set up a user “sftpuser”.
Generate the user private and public keys. These are used to authenticate the user.
cd /dockerdata/sftp/userkeys ssh-keygen
When prompted for the file name, enter the name of the user “sftpuser”.
It prompts for a passphrase. To skip this, just press Enter.
The private key sftpuser and public key sftpuser.pub are generated.
Now we create the user entry in users.conf.
sudo nano /dockerdata/sftp/sshd/users.conf
Add the user entry:
sftpuser::1000:1000
Launch the container.
docker-compose up -d sftp
Everything should now be good to go. Note that anytime you change user information, you must stop the container and do “up”. This is because the user info is cached.
Verify Operation
Copy the private key (/dockerdata/sftp/userkeys/sftpuser) to the client system(s) you wish to connect from.
On an Ubuntu client, it can be placed in your user folder under .ssh. By way of example, for user ubuntu, we place it in “/home/ubuntu/.ssh/”.
Set the permissions on the key file
chmod 600 sftpuser
Do a file upload with curl to test it out:
curl -v -u sftpuser: --key /home/ubuntu/.ssh/sftpuser -T sometestfile sftp://example.com:2222/ftp/
In my case, I have an ftp subdirectory on the host, adjust yours accordingly.
Save the image
Lastly, as this image came from a private collection, I like to save a copy of the image in case the archive goes away.
docker image save -o /somepath/schnuckz_sftp.tar schnuckz/sftp