Difference between revisions of "NFS - Automate attaching / detaching of shares"

From Blue-IT.org Wiki

Line 94: Line 94:
 
  su udevmount -c /bin/bash
 
  su udevmount -c /bin/bash
  
Execute the following script on your ''nfs server''
+
Execute the following script on your ''nfs server'' as user ''udevmount''
 
  #!/bin/sh
 
  #!/bin/sh
 
  #
 
  #
Line 103: Line 103:
 
  for client in $CLIENTLIST
 
  for client in $CLIENTLIST
 
  do
 
  do
 +
  ssh $client "mkdir -p ~/.ssh; chmod 700 ~/.ssh"
 
   scp id_dsa.pub $client:~/.ssh/id_dsa.pub_${HOSTNAME}
 
   scp id_dsa.pub $client:~/.ssh/id_dsa.pub_${HOSTNAME}
 
   ssh $client "cat ~/.ssh/id_dsa.pub_${HOSTNAME} \
 
   ssh $client "cat ~/.ssh/id_dsa.pub_${HOSTNAME} \
Line 111: Line 112:
  
 
Here the version for a single client in one line ;)
 
Here the version for a single client in one line ;)
  CLIENT=mySingleClient;scp id_dsa.pub $CLIENT:~/.ssh/id_dsa.pub_${HOSTNAME}; ssh $NFS_SERVER "cat ~/.ssh/id_dsa.pub_${HOSTNAME} >> ~/.ssh/authorized_keys2; rm ~/.ssh/id_dsa.pub_${HOSTNAME}"
+
  CLIENT=mySingleClient;ssh $CLIENT "mkdir -p ~/.ssh; chmod 700 ~/.ssh";scp id_dsa.pub $CLIENT:~/.ssh/id_dsa.pub_${HOSTNAME}; ssh $NFS_SERVER "cat ~/.ssh/id_dsa.pub_${HOSTNAME} >> ~/.ssh/authorized_keys2; rm ~/.ssh/id_dsa.pub_${HOSTNAME}"
  
 
If you now try to
 
If you now try to

Revision as of 23:54, 18 August 2007

Prerequisites and what this article is NOT about

The Prerequisites to understand and handle this article are:

  • Administrative privileges to the system
  • Profound knowledge of
    • user administration,
    • bash editing,
    • nfs administration

This article does not cover the nfs administration of a linux/unix system.

The solution shown here is in principle scalable to any system. But specially the way nfs clients are handled here is only a quick hack, not threaded and therefore only useful for small networks with about a couple of PCs. Further development is possible.

This solution requires a new unpriviledged user, that is in the sudoers list allowed to do the mount and unmount command. Additionally it requires the instantiation of passwordless ssh connections between the machines for this user.

For some systems, this might be an security whole.

The problem: add or removing shares

Mainly the intention of this HowTo was the problem, that in case you are removing an exported - and mounted - nfs file system from a network this will have severe side effects:

  • All applications depending on the file system will fail/hang
  • The Desktop Manager which will be left in an unusable state for minutes
  • Drives will not be synced, data loss can occur

The solution: Publisher/Subscriber Pattern

If a nfs exported filesystem is removed from the nfs server, it must also be removed on all computers that are connected to the nfs server. This machine therefore has to have a list of these computers. In the view of the publisher/subscriber pattern it is the publisher.

The nfs clients are the subscribers. That's the way nfs is used. They provide the mechanisms to add or remove files from the server.

Therefore they must connect to the server - and that's the problem of most of the current nfs client implementations: Mostly, they connect in certain time intervals to the nfs servers in the network. The publisher pattern however wants the subscribers (clients) to be reported immediately, when the system state changed, e.g. a drive is unmounted.

All informations in the /etc/exports

The one and only file on the nfs server to handle

  • nfs shares
  • possibly connected clients

is the /etc/exports.

Shares

It is easy to extract all exported shares of the nfs server with a little bash and awk charm and store it in a bash variable called EXPORTS

EXPORTS=`cat /etc/exports | grep -v ^# | grep " " | cut -f 1 | awk '{system("echo -n " $1 "----")}' | sed s/----/"  "/g`

It filters out all commentary lines, all empty lines, and writes them - devided by spaces - in the string.

Clients

It could be possible, to extract these information for each share of this file with a little bash magic. Feel free to do this. It also might be possible to write all this in perl ;) Drop me a mail, if you made something new.

In this solution I quickly source the variables of each nfs server in a configuration file, called nfs_clientlist.sh:

############################################################
### PLEASE EDIT ############################################
############################################################

# All CLIENTLIST that use the nfs server on this machine
CLIENTLIST=" server_giga ibmr31 ibmr31_w "

# The hostname of this machine.
# Might be different with more than on network card.
#THISHOST=$HOSTNAME
THISHOST=printer_giga

############################################################

Trigger the remotely mount/unmount of shares

For the nfs servers machine to be able trigger the mount/unmount on connected clients there might be two way's:

  • Writing a client/server program that communicates on a special port.
  • Issuing a bash mount/umount via ssh on the remote machine

The first approach might be possible in e.g. perl/pyhton, but for my purposes connection/reconnecting via ssh fits my needs.

Prepare every PC in the network

To be able to trigger the mount/unmount on each client we need a user has the following abilities:

  • Part of sudoers for mount/umount
  • Passwordless reachable via ssh

Create an unpriviledged user with ssh

Log in as root and create an unpriviledged user with a unique user id (in my case 130) and give it the password udevmount. Because we enable passwordless login via ssh a secure password makes no sin. Afterwards we create the ssh keys. Please press just ENTER until the key generation is finished. We don not use a password!

useradd -g 0 -m -u 130 -s /bin/bash udevmount
passwd udevmount
su udevmount -c /bin/bash
ssh-keygen -t dsa

As root, add the user to the sudoers file:

visudo

Add the two lines

udevmount ALL=(ALL) NOPASSWD: /bin/mount
udevmount ALL=(ALL) NOPASSWD: /bin/umount

Export the ssh keys from the nfs server to each client

On each nfs server you have to attach the generated public key to the authorized_keys2 file of the client you want to connect to.

Login as user udevmount:

su udevmount -c /bin/bash

Execute the following script on your nfs server as user udevmount

#!/bin/sh
#
# /root/bin/ssh_helper.sh

source /root/bin/nfs_clientlist.sh

for client in $CLIENTLIST
do
 ssh $client "mkdir -p ~/.ssh; chmod 700 ~/.ssh"
 scp id_dsa.pub $client:~/.ssh/id_dsa.pub_${HOSTNAME}
 ssh $client "cat ~/.ssh/id_dsa.pub_${HOSTNAME} \
   >> ~/.ssh/authorized_keys2; \
   rm ~/.ssh/id_dsa.pub_${HOSTNAME}"
 chmod 600 id_dsa.pub
done

Here the version for a single client in one line ;)

CLIENT=mySingleClient;ssh $CLIENT "mkdir -p ~/.ssh; chmod 700 ~/.ssh";scp id_dsa.pub $CLIENT:~/.ssh/id_dsa.pub_${HOSTNAME}; ssh $NFS_SERVER "cat ~/.ssh/id_dsa.pub_${HOSTNAME} >> ~/.ssh/authorized_keys2; rm ~/.ssh/id_dsa.pub_${HOSTNAME}"

If you now try to