I have a set of SSH keys to login to accounts and servers. However, ever since I moved my main work profile to a USB drive (for sync and ease of use among other reasons) I have been unable to directly use the SSH keys in the profile for authentication, having to create local copies instead.
Normal SSH workflow usually goes
ssh-add $HOME/.ssh/id_server_key
ssh username@domain
Which works without problems. However, to prevent each machine from having a copy of my keys I moved them to an xexternal drive, USB formatted as vfat
. Then workflow should become like this:
ssh-add /run/media/myself/USB/.ssh/id_server_key
ssh username@domain
…Which doesn't work. SSH complains about doing something to protect me:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: UNPROTECTED PRIVATE KEY FILE! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Permissions 0644 for 'id_server_key' are too open. It is required that your private key files are NOT accessible by others. This private key will be ignored. bad permissions: ignore key: id_server_key Permission denied (publickey).
Which, while I can understand, it's not really protecting me in this case.
The USB drive automounts in my distro, with a fmask of (I think) 022
. I could unmount and remount the USB drive with a fmask of 077
but that would (1) require superuser privilege each time and (2) affect every single file in the device, not only the SSH keys.
I've tried creating a symlink to the key, even with previous use of umask
as I've seen in some tips&tricks:
cd .ssh
umask 077
ln -s /run/media/myself/USB/.ssh/id_server_key
But the permissions can not be used this way for a symbolic link, so I get nothing.
So, what options do I have here available if the goal is to not have a physical copy of the key on the machine? One of the machines is a family laptop that goes to various places, so I have an interest in avoiding some of the keys being discovered.
So far I've considered the following:
- Is there for example an option to force SSH (
ssh-add
primarily) to accept the keys from the external device? (I presume there should be – most programs follow a "I-know-what-I'm-doing" flag, but so far I can't find it in the manpage. - Setting a
bindfs
over the.ssh/
directory, but the problem is that the directory is non-empty (as it containsknown_hosts
and other data). fuse-zip
-ing the keys over/dev/shm
seems to be a possible path as well.
EDIT: As per @Gilles 's comment, yes, bindfs
solves the issue. After a checking of the manpage, initial testing succeeded using the following invocation:
bindfs -n -r -p 0700 -o nonempty /run/media/myself/USB/.ssh/ ~/.ssh
Which binds disallowing access from other users (apparently even from root
!), read-only, with reflected 0700
permissions. That reflection was the part that I lacked when working with bindfs originally. The nonempty
flag was needed because of preexisting files such as known_hosts
. This preserves the original workflow exactly except for an extra warning messae about not being able to add information to known_hosts
(which in the end I might not mind).
Of course, I'm bindfs-ing to another directory now (in /dev/shm) as originally suggested to make things slightly easier.
I'm not as conspiranoid so as to encfs
my USB drive (yet) so privacy-wise this is good enough for me.
Best Answer
ssh-add
doesn't have an option to bypass its check of the key permissions. You could recompile the program and disable the check.A bindfs should work. You don't need to mount it at
~/.ssh
, mount it at a special-purpose location and write a script that doesssh-add ~/.ssh-private-keys-bindfs
.Note that ssh is right in that your setup is pretty insecure. You must make sure never to plug that drive into a computer where you are not the sole user.