From the Terminal
I recently wanted to share a bunch of files with a friend over the internet. These files were on my mediacenter which is a Windows machine running a RAID. This machine was already sharing these files on a Windows file share but I didn't want to expose these files to the internet. Since my workstation was a Linux box already running SSH server on port 22 with SSH key authentication already working I figured the cleanest thing would be to add a new user and set the home directory to the network share with the shell disabled. Easier said than done so I'm writing this post to discuss some blockers I encountered and how I solved them.
First I needed to add a new user. This is the command I used in Gentoo however in most Linux distros you will likely need to use adduser instead.
sudo useradd ftp -M -N -s /sbin/nologin -R /dev/null
- -M Don't create a home directory
- -N No user group
- -s /sbin/nologin sets the shell to nologin to disable any logins
- -R /dev/null sets the home directory to /dev/null to disable the home directory
Now we need to edit sshd_config for this specific user.
Near the bottom of the file we add this to the config.
Match User ftp AuthorizedKeysFile /etc/ssh/authorized_keys_%u ForceCommand internal-sftp AllowTCPForwarding no X11Forwarding no ChrootDirectory /home/ftp
Since the AuthorizedKeysFile depends on having a home directory by default we must override that setting to specify a different one for just this one user. Configure that as you would normally.
For security reasons we disable AllowTCPForwarding so people can't use your SFTP as a free proxy and X11 forwarding so that people can't access your X session. Finally we need to use a chroot directory.
My initial instinct was to directly use my media center mount as /mnt/mediacenter/ but this was failing since that directory was a network share. SFTP server requires that the chroot directory is owned by root. So despite us setting this user to not use a home directory I decided to use /home/$user for that reason anyway. But in this case I set it as owned by root instead of the user like normal. Now I had to setup some link to the mediacenter mount. Soft links will not work with SFTP so instead I used the mount command like so.
sudo mount --bind /mnt/mediacenter/Library/Anime/ /home/ftp/Anime
Now we can test it. I decided to use my laptop.
There you have it. A fully secure SFTP over SSH.
This technique should work well with WSL1 and WSL2 as well if you're using Windows.
With OpenSSH, port forwarding is configured using the -L option.
You can initiate a port forwarding operation with this command:
ssh -L 80:example.com:80 technex.us
In this example we are telling OpenSSH to open port 80 on the current machine to example.com on port 80 from the server we are connecting to. In this case the server is technex.us.
Don't forget that anyone can connect to this port on your machine so you might want to limit connects to localhost by telling OpenSSH to listen on a specific IP. In this case you can specify 127.0.0.1 like so:
ssh -L 127.0.0.1:80:example.com:80 technex.us
Since this is OpenSSH you can actually use the alias you specified in your ~/.ssh/config file.
I talk more about the OpenSSH config file here.
Building on top of that guide if you want to maintain a port forward everytime you connect to a specific machine you can use this syntax:
Host alias HostName technex.us User user IdentityFile /Users/user/.ssh/mykey_rsa LocalForward 127.0.0.1:80 example.com:80
Now you can simply type in ssh alias in terminal and be connected with a port forward.