Mount Windows network drives with sshfs and samba
(Odd) Scenario:
Mounted network drives are not accessible outside your home (aka. workplace).
You have another place you go to and need to access the same network drives, but have no vpn between the second place and home. This solution solves the vpn problem, as mounts via sshfs is secure. The final mounting of network drives is done locally with samba, pointing to the sshfs share.
Requirements:
Two physical locations with two linux servers, both running samba. Local network on both places.
Windows pc (this code is only tested on Windows 11), on which you code the code.
If you're using Linux for both clients and servers, you may just use the sshfs part of this description.
Solution short description:
Your home server (Location 1) is the main server.
Your holiday home server (Location 2) is the mount server for sshfs shares from your home server.
When sshfs shares are mounted on location 2, we can access them via samba locally and make them accessible as windows network drives.
Thus, you can access the location 1 physical drives from location 2 locally with samba while the encrypted transfer between location 1 and 2 is handled by sshfs.
You can then access your code directly and save from code prog, no secondhand transfer via sftp and no more disconnected network drives.
The last part is about mounting network drives automatically based on ip segment.
Server setup:
Let's start with the servers. I use Ubuntu server, preferably the LTS version.
We need the same user on both servers, let's call him 'bart'. This will be the user you use to save your code when you're coding away back home.
The servers here are 'barks' (location 1) and 'klimt' (location 2).
Say location 1 is where you store data, and location 2 is where you go to and want to connect to these data.
Location 1 (barks): Ip 213.88.145.219, local subnet ip 192.168.62.8
Location 2 (klimt): Local subnet ip 192.168.72.5 (Public ip does not matter in this description)
To mount the sshfs shares the easiest way, you would use public key authentication between the servers. Log in as the bart user on your home server (location 1) and create ssh keys (if you don't have them already) by typing:
ssh-keygen -t rsa -b 4096
This will create a key pair of public and private keys. Just hit enter for all sequential questions from the script, we accept the defaults. And NO pass phrase.
The command will also create the directory .ssh/ under barts home directory, which is what we're really after here. So, we now have the directory /home/bart/.ssh, which contains the two keys:
bart@barks:~$ cd .ssh
bart@barks:~/.ssh$ ll
total 16
drwx------ 2 bart bart 4096 Mar 30 11:49 ./
drwxr-x--- 3 bart bart 4096 Mar 30 11:49 ../
-rw------- 1 bart bart 3369 Mar 30 11:49 id_rsa
-rw-r--r-- 1 bart bart 736 Mar 30 11:49 id_rsa.pub
Next, do the same at the server at location 2, so that both servers have a .ssh/ directory with key pairs. To make them able to communicate over ssh without passwords, we need to add a file inside the .ssh directory on location 1 which contains the public key from location 2. So we copy it from klimt with the command:
ssh-copy-id -i /home/bart/.ssh/id_rsa.pub bart@213.88.145.219
The ip in this command is barks' ip. You need to type the password for bart at barks, hopefully for the last time. In the .ssh/ directory in /home/bart at barks we can now see the new file authorized_keys, with the public key of server klimt.
bart@barks:~/.ssh$ cat authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDNZjXRxryLZ9tK+HC/JBgx5pZ7P/WF4abMKez0zxXHcAUboTtE96KNPuTTbwJKEx/d6PMFHdO6Xq5WKR9sdG7amsjx1vML4IFkDFBKiJTGZtfBka1oHnUTcOm1D2OdkRcuvRvTdT1PJHzPPFFpvqTCl74KTlY512cKxTE5IjjABe1y2iLvf1e0zd2BCN3t6xkmwtRC7o15IjSxsFJqcBuT4sSHc6Bvv2EfwFgfUO8T1WPmUVmSOPzlRY0W8KWgPayzq2P2PnLBpkEZ+uTwmJIJBztdFj3RuRsz5ulyD0wRJLBa1ISAPyAECvvXdtUU9tAvtoMsvhhkfM1tIw+6rBgLhJUpC/xxiFZrn+skFjehUYS/5Ld3X10wRJLBa1ISAPyAECvvXdtUrriuMKcKX629eHBrH4DUW1T0usUmGExsSrh+ETfG3KGso+Kv8J8eX19JUr5ehiv25Ht/IP9MyHNPN3+xNx3qKZtxnCFrHRZvZykXX1U3CHumYh1N6rHCzcoHgSvRPhNj44dvs6B6hL2dk6YUZSFFtzpfSw/I/40iFzMUxkeadRsVmcTa2/WJu67siUHE2puBwYvnUaV95kbEmu1AHKUdHEB2dk6YUZSFFtzpfSw/I/40iFzUeOOPedzSa43V51ditDZlXtqz4iFwws+DFXH339Ao0kEfB+yJ6Q== bart@klimt
To test this authentication, we go to server 2 and ssh to server 1:
ssh bart@213.88.145.219
You should be logged in directly, no password asked.
It is of course possible to just use a password and type it in on file system mount as the command runs, but the easy way is to use public key.
Next, we need to install sshfs on both servers. On Ubuntu, the command is:
bart@barks:~/.ssh$ sudo apt install sshfs
The sshfs does not need any central configuration as it uses the server ssh configuration, but we need to change one parameter in the /etc/fuse.conf, uncomment the user_allow_other, to allow other users than root to read and write to the sshfs shares:
bart@barks:~/.ssh$ sudo vi /etc/fuse.conf
# The file /etc/fuse.conf allows for the following parameters:
#
# user_allow_other - Using the allow_other mount option works fine as root, in
# order to have it work as user you need user_allow_other in /etc/fuse.conf as
# well. (This option allows users to use the allow_other option.) You need
# allow_other if you want users other than the owner to access a mounted fuse.
# This option must appear on a line by itself. There is no value, just the
# presence of the option.
user_allow_other
# mount_max = n - this option sets the maximum number of mounts.
# Currently (2014) it must be typed exactly as shown
# (with a single space before and after the equals sign).
#mount_max = 1000
We are now ready to mount shares from barks at klimt, first we create a mount point on klimt, in the root:
bart@klimt:/$ pwd
/
bart@klimt:/$ sudo mkdir development
bart@klimt:/$ sudo chmod bart:bart development
bart@klimt:/$ cd development
bart@klimt:/development$ ls
bart@klimt:/development$
As for now, the directory is empty. If you already have a development directory on your main server, you don't need to do anything there. We have this directory on barks:
bart@barks:~/development$ ls
about2.html about_ssi.html features.html index2.html index_text.html products.html recruiting_modtechd.html shorts.html
about3.html about_ssi.shtml funstuff.html index3.html recruiting.html recruiting_techd.html
It has the same path as the mount point on klimt (this is not necessary).
Now we can mount /home/barks/development on barks to klimt. First we run df -h to see the current mounts:
bart@klimt:~/development$ df -h
Filesystem Size Used Avail Use% Mounted on
tmpfs 774M 2.9M 771M 1% /run
/dev/mapper/ubuntu--vg-ubuntu--lv 196G 86G 101G 46% /
tmpfs 3.8G 0 3.8G 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
/dev/sda2 974M 254M 653M 28% /boot
/dev/sda1 511M 6.1M 505M 2% /boot/efi
tmpfs 774M 4.0K 774M 1% /run/user/0
Then the sshfs mount command on klimt on location 2:
bart@klimt:~/development$ sshfs bart@213.88.145.219:/home/bart/development /development -o allow_other
The syntax is simple:
sshfs user@hostip:/path/to/mount /localpath/to/mount
The -o allow_other option is needed if you're gonna use samba to access the files. You could also add a -p port_number if your ssh server is running at a different port than default 22. Now the share is mounted as /development and may be shared by samba.
bart@klimt:/root$ df -h
Filesystem Size Used Avail Use% Mounted on
tmpfs 774M 2.9M 771M 1% /run
/dev/mapper/ubuntu--vg-ubuntu--lv 196G 86G 101G 46% /
tmpfs 3.8G 0 3.8G 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
/dev/sda2 974M 254M 653M 28% /boot
/dev/sda1 511M 6.1M 505M 2% /boot/efi
tmpfs 774M 4.0K 774M 1% /run/user/0
bart@213.88.145.219:/home/bart/development 451G 11G 421G 3% /development
bart@klimt:/development$ ls
about2.html about_ssi.html features.html index2.html index_text.html products.html recruiting_modtechd.html shorts.html
about3.html about_ssi.shtml funstuff.html index3.html recruiting.html recruiting_techd.html
If you don't use windows, you may stop here, the rest is for setting up this share on samba and mounting samba shares as Windows network drives, using automatic parsing by ip segment.
Some commands if you have ssh at a different port than the default (22):
# Copying id_rsa.pub to the remote server, ssh port is 132244
ssh-copy-id -i /home/bart/.ssh/id_rsa.pub - p 132244 bart@213.88.145.219
# Mounting sshfs share, ssh port is 132244
sshfs -p 132244 bart@213.88.145.219:/home/bart/development /development -o allow_other
Setting up Samba shares
From now on, this description uses only server klimt at local ip 192.168.72.5, the sshfs share is up and running and we assume that it handles the encrypted transfer between the two. We assume you already have samba at location 1 with shares mounted as network drives. If not, use the same method on location 1 as below.
A lot of great samba tutorials exists, so I assume you have some experience for the main setup and go right to the share definintions for this purpose, and make a quick one of that as well, as this is not the main purpose of this article.
At the bottom of /etc/samba/smb.conf at server at location 2, add a section for your share:
[mountname]
comment=Development
read only = no
browsable = yes
valid users = bart
writable = yes
path = /development
Save the file and restart samba. The share should now be available to mount as a windows network disk. You could use hostname:
or ip address:
You should tick of for persistent connection and save the credentials. And use the drive letter you will later automount to. When you have confirmed that you have access to the share, remove the connection by right clicking in windows explorer and select Disconnect.
Now the authentication is stored in the windows registry and we will instead mount the share automatically by one of two methods described here:
On windows startup or by manually running a bat script.
I recommend the last, as the availiability of the samba share is dependent on the sshfs sharing. Only if you have a permanent sshfs share at location 2 is it wise to use method 1.
Mount drives based on ip segment
Both methods are based on batch scripts, the difference is that when mounting drives on windows startup, it is stored in the windows startup folder.
The script is two parts, first we find the network segment, then we parse it tru a switch statement to handle the correct section. Let's say we named our share 'development' instead of 'mountname', the bat file would looke like this:
@echo off
rem Network section, find ip and ip segment
for /f "delims=[] tokens=2" %%a in ('ping -4 -n 1 %ComputerName% ^| findstr [') do set NetworkIP=%%a
FOR %%a IN (%NetworkIP%) DO FOR %%b IN (%%~na) do set NetworkIPSeg=%%b
2>NUL CALL :CASE_%NetworkIPSeg%
EXIT /B
rem Mount section, mount drives based on ip segment
rem Location 1
:CASE_192.168.62
echo.
echo You are on the Location 1 network, local network segment is %NetworkIPSeg%, host BARKS
net use R: \\BARKS\development /persistent:no
GOTO END_CASE
rem Location 2
:CASE_192.168.72
echo.
rem Prior to this, the barks shares must be mounted on klimt with sshfs
echo You are on the Location 2 network, local network segment is %NetworkIPSeg%, host KLIMT
echo.
net use R: \\KLIMT\development /persistent:no
GOTO END_CASE
rem No location
:DEFAULT_CASE
echo.
echo No network drives assigned for this ip segment.
echo.
GOTO END_CASE
:END_CASE
echo Mounted network locations:
net use | findstr "Microsoft Windows"
echo.
rem pause
GOTO :EOF
Note that the drive letter is the same for the mounts, and as they are non-persistent, they will unmount when you reboot. If this script is autoloaded when windows start (actually, it's when you log in), it will automatically load the correct drive and use the same drive letter no matter the location. Personally, I like to do it manually so I just have a big drive icon sitting on my desktop pointing to the bat script.
For executing script on windows startup:
Copy the script file in windows explorer. Run the windows key + R to start run commands.
Type shell:startup in the field. This will open the folder for startup scripts. Paste in the bat script and close the folder window. You could also create a new shortcut and point it to the bat script original location, this may be more elegant and easier to update.
As for the sshfs mounting, you could make a bash script to run this, especially if you have several mounts. Here's a quick example:
#!/bin/bash
sshfs bart@213.88.145.219:/home/bart/development /development-o allow_other
sshfs bart@213.88.145.219:/home/bart/imageshare /imageshare -o allow_other
sshfs bart@213.88.145.219:/home/bart/customers /customers -o allow_other
systemctl restart smbd.service
That's it. Now when going to location 2 you can use your data, on the same drive letter, just as when at home.
Subscribe to my newsletter
Read articles from Knut Møgster directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Knut Møgster
Knut Møgster
In my daytime job I code for an online printshop. I’m also sysadmin for their servers, and, on a good day, able to manage their network. Pretty much your all round guy.