From the Terminal

How to securely share a network mount through an existing SSH server

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.

Maui Turtle

Just testing the social media image embedding

Getting MacOS style hotkeys working in GNU/Linux

Over the years I've used every operating system. Sometimes all at once. Recently I've taken to using Linux as my primary desktop operating system. Everything I need runs natively on Linux and because I have full control over my environment I never have down time due to forced updates. This is my desktop after all so I'm really switching from Windows where the Control key modifier paradigm is more or less the same as Linux. Still I didn't want to compromise on anything with this new configuration and there was one thing missing from my Macbook that I really wanted.

Of course what I'm talking about is the Command key or more colloquially known simply as the Apple Key and all the shortcuts and hot keys built into macOS that make it such a joy to use.

"Linux lets you change whatever you want."

Is a common thing that people say to bring up a positive aspect of GNU/Linux. Is this actually true though? Take for example my issue at hand: Changing copy/paste hotkeys for all programs. In truth, some tasks are so big in their scope few users would ever be capable of accomplishing them. At least not without a lot of contextual knowledge.

Getting macOS style hotkeys is actually an extremely difficult task in Linux. Especially when you want to avoid faking it by binding some keys to other keys on a per application basis.

Then there's the question of why do it at all?

The truth is I just got tired of accidentally sending SIGINTs when switching to terminal and then accidentally triggering the wrong thing when switching out of terminal. I've just gotten so used to not having to context switch my brain in macOS between programs. It's one of the things that truly makes my Macbook Pro more pleasant to use.

So that's my first reason. Muscle memory.

My second reason is simply that Command/Meta is directly next to the space bar and I just like having a shorter stretching span for my hand.


Making it work

For the most part GUI applications written for Linux tend to make a lot of assumptions about what hotkeys can and should be in a very opinionated way. Some types of programs require full customization (like code editors) while others like browsers tend to force certain hotkeys. Desktop managers do provide their own hotkey bindings. For example most KDE based applications will use your settings from KDE's "System Settings" to set hotkeys. Meanwhile in Gnome you can use dbind to set your keybinds.

Of course Cut/Copy/Paste is not enough. It would actually be quite jarring to use CTRL+T for opening a new tab immediately after using Command+V to paste something. Indeed if you go down this path you'll end up having to redefine your hotkeys for well..... everything. It is unfortunate as well that applications these days are extremely hostile to user settings.

Despite the hurdles in front of me I decided to try to make it work.

The first thing I did was swap Left Alt and Left Meta on my keyboard. This was actually pretty easy to do with keyboard mapping configs with the KDE GUI simply known as "System Settings". This was simply to make my normal windows keyboard place the buttons in the positions a real mac keyboard would have. None of this is necessary if you have a real Apple layout keyboard. This setting is only active while in my X session so any alternative TTYs would revert back to my stock layout. If I had a real Apple layout keyboard though this is not necessary at all.

This setting is saved to the text file ~/.config/kxkbrc.

$ cat kxkbrc 

Now with this setting I am able to fake the same key mapping as a real macOS keyboard would have in my desktop session. So far so good. Now I manually changed all my hotkeys in my code editors, terminal applications, and even in the System Settings app I just mentioned to set global hot keys for all KDE applications. This took some time but was very straight forward for the most part.

I went above and beyond even changing my shortcuts for things like Select All.

While this worked for KDE applications I had to also make this change for GTK+ based programs as well. Luckily this would also cover Chrome, Discord, Elements, and a number of other Electron based programs that I use on a regular basis.

I was lucky that VSCode let me change everything but it was very annoying have to redo all the system based hotkeys like Set cursor to start of the line (in macOS this is Meta+Left Arrow) for each and every place I wanted to use it.

Some websites also use Meta+C for example in Github hitting Meta+C will actually take focus and bring you to the Add Comment UI when in a thread so sometimes on even with Firefox set to use Meta+C to copy something I am not actually able to use my hotkey because the website overrides it.

With GTK I ended up editing `~/.config/gtk-3.0/gtk.css` and setting these hotkeys.

@binding-set gtk-super-cut-copy-paste
        bind "<super>x" { "cut-clipboard" () };
        bind "<super>c" { "copy-clipboard" () };
        bind "<super>v" { "paste-clipboard" () };
        bind "<super>a" { "select-all" (1) };
        bind "<super>z" { "undo" () };

* {
        -gtk-key-bindings: gtk-super-cut-copy-paste

I might add more but for now this got me to where I wanted with most GTK+ applications. Note that if you plan to run any of programs designed to run as root that use GTK+ such as GParted you should also link or copy this config file to the root account home directory as well.

So in the end it is possible. I was able to achieve what I wanted with all but one program. But it was a huge pain. It's really difficult to figure out what settings do what in a Linux environment even when there is documentation. It's typical for documentation to exist for say GTK+ 2.0 and GTK+ 3.0 but there is no over arching best practice guide for what one should do when they want to cover all programs in an environment.



It Doesn't Have to Be This Way

The Linux ecosystem can and should do better. The ability to do whatever you want is a double edged sword where even though you can in theory change things, in practice however, sometimes changing things is so onerous that staying sane in the process is a task in itself.

So please if you are a Linux user space developer check the GTK+ 2.0 (~/.gtkrc-2.0), GTK+ 3.0 (~/.config/gtk-3.0/gtk.css) and KDE global shortcut configs (~/.config/kdeglobals) when you probe for the environment during startup so that people can choose their own hotkeys for their desktop environment or simply use the C libraries of each and use the hotkeys present.

Better yet, if you are a developer that already supports various input methods for macOS, Linux, and Windows you can simply provide a toggle for users.

It would be beneficial to Linux Desktop environments to agree to a standard config file for hotkeys allowing users to bind keys as they see fit rather than lurching from one weird keybinding config to the next with no centralization to speak off.