I never really liked NFS, so I wanted another way to mount a drive from my QNAP NAS onto my linux machine. As I haven’t found any sort of instruction for that online, I’ll post how I did it here, in case anybody searches for the same thing.
The how is hurdled mostly by the fact that you cannot install SSHFS onto QTS, as the package ist not available for it. But as so often, the solution is Docker. We’ll just create an Ubuntu-Container where we can install SSHFS, and mount the directory we want to share as a volume. This of course requires that you have a NAS with Container Station, allowing to use Docker Containers.
File contents
Dockerfile
FROM ubuntu:22.04
ARG PASSWORD
RUN apt update && \
apt install -y bash git vim curl zsh htop tmux unzip nano ca-certificates wget sudo sshfs openssh-server && \
echo "user_allow_other" | sudo tee -a /etc/fuse.conf && \
mkdir /var/run/sshd && \
echo "root:${PASSWORD}" | chpasswd && \
sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
CMD ["/usr/sbin/sshd", "-D"]
docker-compose.yml
services:
sshfs:
container_name: sshfs_1
build: ubuntu/sshfs
ports:
- 2024:22
privileged: true
volumes:
- /share/Backups:/mnt/dockersshfs
Setting up the Container
- Log into the NAS’s local network
ssh
to your NAS to set up the container[1]https://raptorkwok.medium.com/using-dockerfile-in-qnap-nas-8b4107cc49e9 - eg.ssh admin@YOUR_NAS_HOSTNAME.local
- In that ssh-session, run[2]If anybody knows how to allow the ‘–squash’ option in QTS, tell me! I hate that it lists the intermediate layers in the UI:
cd /tmp mkdir sshfs_docker && cd sshfs_docker vi my_password # hit <i>, paste the Password you want to use, hit <esc>, type ":wq", hit <enter> vi Dockerfile # hit <i>, paste Dockerfile content, hit <esc>, type ":wq", hit <enter> docker build --no-cache -t ubuntu/sshfs --build-arg PASSWORD=$(cat my_password) --pull . rm my_password
- Now that the image is built, you should be able to, in the QTS Web-UI, open Container Station and find our newly built one unter
Images
. TheApplication
tab would allow you to just paste ourdocker-compose.yml
file, as however the keyprivileged
is not allowed there, we have to enter the contents of the docker-compose.yml manually:- For that, go to the
Containers
tab →new
/Create
→Advanced mode
, enter our nameubuntu/sshfs
as the image - Hit
Next
→Publish New Port
and enter our Port mapping to the Container’s port 22 - Go to
Advanced Settings
→Storage
and manually enter our Volume-Mapping. On the container-side, the path/mnt/dockersshfs
is as good as any, however you’ll want to replace the/share/Backups
I used here with the directory you want to publish. Generally in QTS, the publicly accessible directories are all mounted under/share/
, so you may want tols
that. - Finally, go to
Runtime
, activatePrivileged Mode
, andApply
→Next
→Finish
to build the container.
- For that, go to the
- Verify that it works on the ssh-session by going into the container (
docker exec -it sshfs-1 /bin/bash
) andcd
ing to where you mounted the drive. Exit using <CTRL+D>. - From your machine, try
Navigate to the respective path, and voilà, your NAS should be mounted!
sshfs root@YOUR_NAS_HOSTNAME.local:/mnt/dockersshfs /path/to/your/local/mountdir -p 2024`
Only problem here is, that we can only access the NAS if we’re in the same local network. The best way to emulate from the outside is by using a Virtual Private Network aka VPN.
Setting up the VPN
QVPN[3]https://www.qnap.com/en/how-to/faq/article/how-to-set-up-a-vpn-server-on-qnap-nas-behind-the-router
Theoretically, using the NAS’s own VPN-software would be a great idea. For that, the steps would be roughly the following:
- Install & Setup QVPN. Decide for a VPN Server and change its default port (
VPN Server
→OpenVPN
). - Install and setup QuFirewall - Follow eg.[4]https://www.qnap.com/en/how-to/faq/article/how-to-setup-qufirewall-to-allow-vpn-connections
- In your router, setup port forwarding for the port you selected. How exactly that works depends on your model, on my FritzBox Port-Forwarding is found unter
Internet
→Shares
→Portshares
. You can also activateIndependent Port Sharing
for you NAS, which allows for UPnPUniversal Plug and Play. - Download the config, eg. the
.ovpn
file in the case of OpenVPN. - Use online port scanners or
nmap
from your local machine (with port & IP as the contents from theremote
section in the .ovpn file) to check if the port is accessible from outside. If it’sfiltered
, that tends to mean that the port-forwarding did not work correctly (especially ifsudo lsof -i -P | grep <portnumber>
on the NAS shows that the VPN works on the NAS) - You can activate UPnP on the NAS using its web UI →
MyQNAPcloud
→DDNS
, given that you created a MyQNAPcloud Link. If you activated all UPnP configs on your router[5]https://www.giga.de/hardware/fritzbox/tipps/fritzbox-upnp-aktivieren-so-gehts-richtig/
see also https://forum.heimnetz.de/threads/myfritz-adresse.1173/,
https://forum.vodafone.de/t5/Archiv-Internet-Ger%C3%A4te/Fritz-Box-6490-Port-Forwarding-funktioniert-nicht/td-p/2076106/page/2, it should show “Good” under UPnP forwarded services. - ….after a deep dive into my own FritzBox however, I noticed that having a public IP is apparently actually not that common - mine is 100.64.XX.XX, which means it’s using Carrier-Grade NAT[6]https://avm.de/service/wissensdatenbank/dok/FRITZ-Box-7490/3749_Erreichbarkeit-der-FRITZ-Box-im-Internet-prufen/, which means it’s not really public[7]Can also check that by going to https://www.myfritz.net/devices/#/. I assumed that shouldn’t be a problem and I can just use IPv6, but it doesn’t work with that as well - maybe the reason is that in my case, the FritzBox is not what’s connected with the internet, but just to the fibreoptic-modem, and both of them use Carrier-Grade NAT.
FritzBox VPN[8]https://avm.de/service/vpn/wireguard-vpn-zur-fritzbox-am-smartphone-oder-tablet-einrichten/
After all the useless hassle, instead I just noticed that I can just use the Wireguard-VPN-Service of my FritzBox (OS ≥ 7.5)
Internet
→Shares
→VPN (WireGuard)
. Set up the connection and download the WireGuard-config.- locally:
sudo apt install -y wireguard
, to then just connect asnmcli connection import type wireguard file "/path/to/wg_config.conf"
- You should now be able to connect to your NAS from outside your network. If you go to https://www.qlink.to/YOUR_NAS_NAME, it should forward you to a 192.168 range IPv4 - which is the IP of your NAS in your local network!
One-Line-Mount
Now to mount the NAS in one line we need a bit of trickery, and two commands that actually require root-rights. As I don’t want to enter the password for that every time, I’m using visudo
to add my user to those not requiring a password for these commands. Note that this is a security risk, so only do it if you know what you’re doing! Run sudo visudo
, and add the following to line there, replacing <YOUR_USERNAME> with your username:
<YOUR_USERNAME> ALL= NOPASSWD: /usr/bin/nmap, /usr/bin/wg
This assumes that nmap
and wg
are under the given path, which you can figure out using the which
command. Further, you may want to add an environment-variable for the hostname of your NAS into your .bashrc
. The one-liner uses nmap
to scan all hosts of the subnet (which it figures out using the wg
command)[9]The -o
part ensures KDE does not freeze, see https://serverfault.com/a/639735:
sshfs root@$(sudo nmap -sn -T5 $(sudo wg show wg_config | awk '/allowed ips/{print $3}' | tr -d ',') | awk -v nas_hostname="$NAS_HOSTNAME" '$0 ~ nas_hostname {match($0, /\(([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/, ip); print ip[1]}'):/mnt/dockersshfs /path/to/your/local/mountdir -p 2024 -o reconnect,ServerAliveInterval=15,ServerAliveCountMax=3
Obviously this command cannot be added to the fstab, but at least it can be made to a single command. Oh how I love command chaining.