I’m just dumping this here for now; maybe some day a bit of commentary might follow.
I needed a quick, easy and (hopefully) secure way to spin up an SFTP server. Since I don’t want to get into complex configuration, a Docker container seems a safe choice as it isolates the SFTP server from the host. Thankfully the openssh server speaks SFTP too and conveniently supports an “SFTP-only” mode in which users aren’t presented with a shell after login.
FROM ubuntu:22.04
EXPOSE 2222
RUN apt-get update && apt-get install -y openssh-server openssh-client
RUN groupadd sftponly
RUN useradd -m -d /sftp -g sftponly sftpuser
RUN echo "sftpuser:password" | chpasswd
RUN mkdir /etc/ssh/sftp
RUN chown root:root /etc/ssh/sftp
RUN chmod 755 /etc/ssh/sftp
RUN sed -i 's/#Subsystem\tsftp\t\/usr\/lib\/openssh\/sftp-server/Subsystem\tsftp\tinternal-sftp/g' /etc/ssh/sshd_config
RUN sed -i 's|^#Port 22|Port 2222|g' /etc/ssh/sshd_config
RUN echo "Match Group sftponly" >> /etc/ssh/sshd_config
RUN echo " ChrootDirectory %h" >> /etc/ssh/sshd_config
RUN echo " ForceCommand internal-sftp" >> /etc/ssh/sshd_config
RUN echo " AllowTcpForwarding no" >> /etc/ssh/sshd_config
RUN echo " X11Forwarding no" >> /etc/ssh/sshd_config
RUN echo " PasswordAuthentication yes" >> /etc/ssh/sshd_config #Important for testing, consider disabling for production
# Create the sftp user's home directory and set appropriate permissions
RUN chown sftpuser:sftponly /sftp
RUN mkdir /sftp || echo already exists
RUN chown root:root /sftp # Correct ownership
RUN chmod 755 /sftp # Correct permissions
# Create the sftp user's actual data directory inside /sftp
RUN mkdir /sftp/data
RUN chown sftpuser:sftponly /sftp/data # sftpuser owns the data directory
RUN chmod 700 /sftp/data #Restrict access to the data directory
# Generate SSH host keys
RUN ssh-keygen -A
# Generate SSH host keys *before* starting sshd
RUN /etc/init.d/ssh start && /etc/init.d/ssh stop
# Start the SSH server
CMD ["/usr/sbin/sshd", "-De"]