Setting up sftp on Docker

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