My story with using ssh keys authorization and NFS.
I’ve had a problem with setting up NFS server to work with dynamically started up digitalocean droplets.
Before they started up I didn’t know their ip address, so I couldn’t add them to the /etc/exports file, so they couldn’t boot up with the NFS mounted right away.
I was concerned about speed – I wanted my newly spawned droplet to be usable right away, so I tried to figure out how to “authorize” my new hosts n the spot.
I tried ssh tunelling. It was pretty cool. But it slowed down the connection a little (overhead of encrypting, even when using the simplest encrypting mechanism).
Also, for some reason, on ubuntu whenever some client connected to the NFS, the mdworker would start using 100% CPU time. That was obviously unacceptable.
So what I did instead:
In network scripts, after the interfaces are up, I use ssh to “knock” to the nfs server, saying “hey, it’s me, and I got inside using this key here, so, if you could please add me to your /etc/exports file, while my buddies are trying to mount you remotely, that would be great, ok bye. :)”
Nfs server reloads it right away and the process that’s been waiting to do the mount, does the mount.
Here is the snippet:
I’m assuming you created a local user (I call it “exporter” further on) that you are able to login to without a password (using keys).
We will use exportfs to reload the /etc/exports . We will run it as a non-root user, so we need to use sudo.
# visudo
add a line like:
exporter ALL= NOPASSWD: /usr/sbin/exportfs -a
Save the file.
Now create a script:
/home/exporter/addMeToExportsAndReload.sh
#!/bin/bash MYIP=`/bin/echo $SSH_CLIENT | /usr/bin/awk '{ print $1}'` /bin/echo " /export $MYIP(rw,fsid=0,insecure,no_subtree_check,async) /export/users $MYIP(rw,nohide,insecure,no_subtree_check,async) /export/nginx $MYIP(rw,nohide,insecure,no_subtree_check,async) " >> /etc/exports /usr/bin/sudo /usr/sbin/exportfs -a
Make it executable:
$ chmod +x /home/exporter/addMeToExportsAndReload.sh
For user exporter to be able to echo anything to the /etc/exports we will have to give him a bit more permissions.
# chgrp exporter /etc/exports
# chmod g+w /etc/exports
And in the ~exporter/.ssh/authorized_keys file add
command="/home/exporter/addMeToExportsAndReload.sh"
at the beginning of the line (before ssh-rsa) with the key that we will use for the authorization.
It should start like:
command="/home/exporter/addMeToExportsAndReload.sh" ssh-rsa AAAAB3N(..)
Now, whenever remote server logs in to the exporter account, using the ssh-rsa key, they will add their own ip to the export file, and then reload NFS.
That’s all for the server.
Now, the client.
You have to find out how to add script to be loaded immediately after the network is up. For ubuntu, I create two files: /etc/network/if-up.d/001nfsmount
#!/bin/sh /bin/mount /home/ &
And /etc/network/if-up.d/002nfsknock :
#!/bin/sh /usr/bin/ssh exporter@NFS_SERVER_IP /bin/chmod -x /etc/network/if-up.d/002nfsknock
We make it non-executable after boot up, so the next time we start up the server, we don’t put the same entry to the /etc/exports on the server again.
You might consider creating another script (and another ssh user) that removes the entries for you when you are shutting down.
Make sure they are executable
# chmod +x /etc/network/if-up.d/001nfsmount
chmod +x /etc/network/if-up.d/002nfsknock
Add mount file to fstab:
# echo "NFS_SERVER_IP:/ /nfs nfs4 port=2049,rsize=8192,wsize=8192,rw,bg,nosuid,noauto 0 0" >> /etc/fstab
Go ahead and restart your server, you are ready to go!