#! /bin/bash # # Copyright (c) Bull S.A. 2007 All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it would be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # # Further, this software is distributed without any warranty that it is # free of the rightful claim of any third person regarding infringement # or the like. Any license provided herein, whether implied or # otherwise, applies only to this software file. Patent licenses, if # any, provided herein do not apply to combinations of this program with # other software, or any other product whatsoever. # # You should have received a copy of the GNU General Public License along # with this program; if not, write the Free Software Foundation, Inc., 59 # Temple Place - Suite 330, Boston MA 02111-1307, USA. # # History: # 5/14/07: Created by Aime Le Rouzic (Aime.Le-Rouzic@bull.net) # # Purpose: # # This shell command takes care of setting a Kerberos NFS Client # # Written to be run by root on the machine to be the Kerberos NFS Client # # # Usage : # # krbnfscl {start | status } # start: First Kerberized NFS Server initialisation # status: Check the kerberised NFS client configuration is still OK # # krbnfscl start { -h | {-b } {-c } {-d } {-k } {-r } {-s } { -u } {-v}} # krbnfscl status { -h | {-b } {-k } {-r } {-s } {-v}} # # Description: # The krbnfscl command configures a kerberized NFS Client # # The command does some controls: # start: # - checks Kerberos Client package # - checks REALM is UPPER CASE # - checks host has a fully qualified domain name # - checks the /etc/services file lists the nfs service (port 2049) # - checks KDC,Kerberos Server and NFS Server are reachable # - checks the kerberos daemons are running (krb5kdc, kadmind) on the Kerberos Server # - checks the nfs server daemons are running on the NFS Server # - checks times is synchronised (<300s) with the KDC Server machine time # - checks the /etc/hosts file lists the fully-qualified domain name # as the first entry on the line with the machine's IP address, # - checks in /etc/resolv.conf the name server is the same as in /etc/resolv.conf # of the KDC Server # # status: # - checks REALM is UPPER CASE # - checks the /etc/services file lists the nfs service (port 2049) # - checks KDC,Kerberos Server and nfs Server are reachable # - checks kerberos daemons are running (krb5kdc, kadmind) on the Kerberos Server # - checks nfs server daemons are running on the NFS Server # - checks rpc.gssd and rpc.svcgssd are running # - checks time is synchronised (<300s) with the KDC Server machine time # - checks host has a fully qualified domain name # - checks the /etc/hosts file lists the fully-qualified domain name # as the first entry on the line with the machine's IP address, # - checks in /etc/resolv.conf name server is the same as in /etc/resolv.conf # of the KDC Server # # # Flags: # -b : kerberos server name # -c : directory where is located the krb5.conf file # -d : domain name for the Kerberos realm # -h : help to display the command syntax # -k : KDC server name # -r : realm for which the Kerberos server is to be configured # -s : nfs server name # -u : user name # -v : verbose mode # UsageStart="krbnfscl start { -h | {-b } {-c } {-d } {-k } {-r } {-s /dev/null 2>&1 if [ "$?" != 0 ] then echo "Kerberos Client Package not installed" exit 1 fi } CheckRPCGSSMod () { # Ask to load rpcsec_gss_krb5 module if necessary lsmod | grep rpcsec_gss_krb5 > /dev/null if [ "$?" != 0 ] then echo "You need to load the rpcsec_gss_krb5 module if not already in the kernel" echo "Do you want to have this command loading it: yes/no[no]" ANSWER="no" read ANSWER case $ANSWER in yes) modprobe rpcsec_gss_krb5 ;; *) ;; esac fi } CheckTime () { # check time is synchronised (<300s) with the KDC and Kerberos Server time echo "Let's check time is synchronised (<300s) with the KDC Server machine $KDC_SERVER time" timeKDC_SERVER=`ssh $KDC_SERVER date +%s` timeNFSCLIENT=`date +%s` if [ $timeKDC_SERVER -ge $timeNFSCLIENT ] then gaptime="$(( $timeKDC_SERVER - $timeNFSCLIENT ))" else gaptime="$(( $timeNFSCLIENT - $timeKDC_SERVER ))" fi if [ $((gaptime)) -gt 300 ] then echo " KDC server and NFS CLient times differ more than 5 minutes" exit 1 fi echo "Time is Synchronized with the time of the KDC server:$KDC_SERVER" vm "Difference time is: $gaptime seconds" } function CheckFQDN_NFSCLIENTNAME () { # Check host has a full qualified domain name # Check the /etc/hosts file lists the fully-qualified domain name as the first entry # on the line with the machine's IP address, and the machine's name must not be include # on the localhost line. FQDN_NFSCLIENTNAME=`/bin/hostname --fqdn` echo if [ $? != 0 ] then exit 1 fi if [ "$NFSCLIENTNAME" != "$FQDN_NFSCLIENTNAME" ] then echo "The hostname is not a FQDN name " echo "The hostname is: $NFSCLIENTNAME" echo "The Full Qualified Name is: $FQDN_NFSCLIENTNAME" echo "Do you want to set it: yes/no[yes]" ANSWER="yes" read ANSWER case $ANSWER in yes) NFSCLIENTNAME="$FQDN_NFSCLIENTNAME" hostname "$NFSCLIENTNAME" ;; *) ;; esac fi RETNAME=`awk '{ print $2}' /etc/hosts | grep "$FQDN_NFSCLIENTNAME" ` if [ "$RETNAME" != "$FQDN_NFSCLIENTNAME" ] then echo "In /etc/hosts, full qualified name:$FQDN_NFSCLIENTNAME" echo " should be first after the IP address" exit 1 fi grep "127.0.0.1" /etc/hosts | grep "$NFSCLIENTNAME" > /dev/null if [ $? == 0 ] then echo "The machine's name "$NFSCLIENTNAME" must not be included" echo "on the localhost line in /etc/hosts" exit 1 fi } function CheckREALM () { # Check REALM is fully qualified name and UPPER CASE REALM_UPPERCASE=`echo $REALM | tr "[a-z]" "[A-Z]"` while test "$REALM_UPPERCASE" != "$REALM" do echo "REALM: $REALM not uppercase, enter it again:"; read REALM ; done } function CheckEtcServices () { # Check the /etc/services file lists the nfs service (port 2049). RETVAL=1 while [ $RETVAL != 0 ] do grep nfs /etc/services | grep 2049 > /dev/null RETVAL=$? if [ $RETVAL != 0 ] then echo " /etc/services doesn't list the nfs service (port 2049)" exit 1 fi done } function CheckDNS () { # Check in /etc/resolv.conf the name server is the same as in KDC_SERVER:/etc/resolv.conf dnsdomainname > /dev/null if [ $? != 0 ] then echo "Bad domain name set in /etc/resolv.conf or Bad hostname" exit 1 fi if [ -r /etc/resolv.conf ] then NS_KDC_SERVER=`nslookup $KDC_SERVER | grep Server | cut -f3` if [ -z "NS_KDC_SERVER" ] then echo " $KDC_SERVER Name Server can't reached" exit 1 fi NS_NFSCLIENTNAME=`nslookup $NFSCLIENTNAME | grep Server | cut -f3` if [ -z "NS_NFSCLIENTNAME" ] then echo " $NFSCLIENTNAME Name Server can't reached" exit 1 fi if [ "$NS_KDC_SERVER" != "$NS_NFSCLIENTNAME" ] then echo " $NFSCLIENTNAME doesn't have the same nameserver as $KDC_SERVER" exit 1 fi else echo "/etc/resolv.conf not present" exit 1 fi } function CheckEnv () { CheckRPCGSSMod # Ask to load rpcsec_gss_krb5 module if necessary CheckEtcServices # Check the /etc/services file lists the nfs service (port 2049) CheckFQDN_NFSCLIENTNAME # Check host has a fully qualified domain name # Check the /etc/hosts file lists the fully-qualified domain name # as the first entry on the line with the machine's IP address CheckDNS # Check in /etc/resolv.conf name server is the same as in /etc/resolv.conf # of the KDC Server } function ping_check () { if ping $1 -c 5 > /dev/null; then : else echo "$KDC_SERVER is unreachable" exit 1 fi } function Check_KDC_KRB_NFS () { # check $KDC_SERVER reachable ping_check $KDC_SERVER # check krb5kdc running echo "Let's check the krb5kdc daemon is running on the KDC and Administration Server: $KDC_SERVER" `ssh $KDC_SERVER ps -e | grep krb5kdc > /dev/null` RETVAL=$? if [ $RETVAL -ne 0 ] then echo "krb5kdc daemon is not running" exit 1 fi echo "krb5kdc is running" echo # check $KRB_SERVER reachable ping_check $KRB_SERVER # check kadmind running echo "Let's check the kadmind is running on the KDC and Kerberos Administration Server: $KRB_SERVER" `ssh $KRB_SERVER ps -e | grep kadmind > /dev/null` RETVAL=$? if [ $RETVAL -ne 0 ] then echo "kadmind daemon is not running on $KRB_SERVER" exit 1 fi echo "kadmind is running" echo # check $NFS_SERVER reachable ping_check $NFS_SERVER # check nfs server daemons running echo "Let's check nfsd daemon is running on the NFS Server: $NFS_SERVER" `ssh $NFS_SERVER ps -e | grep nfsd > /dev/null` RETVAL=$? if [ $RETVAL -ne 0 ] then echo "nfs daemons are not running on: $NFS_SERVER" exit 1 fi echo "nfsd daemon is running" echo } function ResetKRBNFSCl () { # Delete files from the previous configuration rm /tmp/krb5cc* >/dev/null 2>&1 } function CreateKRB5Conf () { # Get the krb5.conf from the Kerberos Administration Server echo "Get the $KRB_CONF/krb5.conf file from $KRB_SERVER" scp root@$KRB_SERVER:$KRB_CONF/krb5.conf $KRB_CONF/krb5.conf > /dev/null RETVAL=$? if [ $RETVAL -ne 0 ] then echo "Error when getting krb5.conf file from the Kerberos Server" exit 1 fi mkdir /var/krb5 >/dev/null 2>&1 mkdir /var/krb5/log > /dev/null 2>&1 >/var/krb5/log/kadmin.log } AddPrincipalNFSCl () { # Create machine credentials for the client by creating a Kerberos V5 principal/instance name # of the form nfs/dns.name.of.client@REALM kadmin -q "addprinc -randkey nfs/$NFSCLIENTNAME" } AddKeyNFSCl () { # Add a key for the nfs principal in /etc/krb5.keytab kadmin -q "ktadd -k $KRB_CONF/krb5.keytab nfs/$NFSCLIENTNAME" chmod 600 $KRB_CONF/krb5.keytab } AddPrincipalUser () { # Add the principal for the user (given by -u in the command line) other than root allowed to do a mount # Don't forget user or users options in /etc/fstab for the mounting if [ "$NFSCLIENTUSER" != "onlyrootuser" ] then echo "Let's replace or add a principal for the user: $NFSCLIENTNAME" kadmin -q "delprinc $NFSCLIENTUSER" kadmin -q "addprinc $NFSCLIENTUSER" su $NFSCLIENTUSER -c "kinit" RETVAL=$? if [ $RETVAL -ne 0 ] then echo "Try again, last chance" su $NFSCLIENTUSER -c "kinit" RETVAL=$? if [ $RETVAL -ne 0 ] then exit 1 fi fi fi } function CheckTGT () { # Check the nfs krbtgt ticket echo "Let's check krbtgt ticket is in the cache /tmp/krb5cc_machine_$REALM" klist -e -c /tmp/krb5cc_machine_$REALM | grep krbtgt RETVAL=$? if [ $RETVAL != 0 ] then echo echo " nfs krbtgt ticket missing" exit 1 fi } function StartRpcGssd () { # Starts rpc.gssd daemon killall rpc.gssd > /dev/null 2>&1 if [ $modverbose != 0 ] then rpc.gssd -m -vvv else rpc.gssd -m fi } function CheckRpcGssd () { # Check rpc.gssd daemon is running ps -e | grep rpc.gssd > /dev/null RETVAL=$? if [ $RETVAL -ne 0 ] then echo "rpc.gssd not started" echo "Do you want to start it: yes/no[yes]" ANSWER="yes" read ANSWER case $ANSWER in yes) if [ $modverbose != 0 ] then rpc.gssd -m -vvv else rpc.gssd -m fi ;; *) ;; esac fi } function CheckRpcSvcGssd () { # Check rpc.svcgssd daemon is running on the NFS Server `ssh $NFS_SERVER ps -e | grep svcgssd > /dev/null` RETVAL=$? if [ $RETVAL -ne 0 ] then echo "rpc.svcgssd is not running on: $NFS_SERVER" exit 1 fi } # # Main section # start () { FinalizeStartConfiguration # Finalize the configuration after the command line processing TestKerberosInstall # Check Kerberos Client package is installed CheckEnv # Check synchronized times, hostname is FQDN, # /etc/resolv.conf,/etc/hosts, /etc/services Check_KDC_KRB_NFS # Check on KDC and Kerberos Server krb5kdc and kadmind daemons are running # Check nfs is started on the NFS Server CheckTime # Check time is synchronised (<300s) with the KDC and Kerberos Server time ResetKRBNFSCl # Delete files from the previous configuration CreateKRB5Conf # Get krb5.conf from the Kerberos Administration Server AddPrincipalNFSCl # Create machine credentials for the client. # This by creating a Kerberos V5 principal/instance name of the # form nfs/dns.name.of.client@REALM AddKeyNFSCl # Add a key for this principal in /etc/krb5.keytab AddPrincipalUser # Add a new principal for user other than root StartRpcGssd # Start rpc.gssd daemon } status () { FinalizeStatusConfiguration # Finalize the configuration after the command line processing CheckEnv # Check times ar synchronized, hostname is FQDN, # /etc/resolv.conf,/etc/hosts, /etc/services Check_KDC_KRB_NFS # Check KDC and Kerberos Server is running krb5kdc and kadmind daemons # Check nfs is started on the NFS Server CheckTime # Check time is synchronised (<300s) with the KDC and Kerberos Server time CheckRpcGssd # Check rpc.gssd is running CheckTGT # Check the krbtgt ticket } # # Main section # # See how we were called. case "$1" in start) # Command Line Processing OPTIND=2 while getopts :hvb:c:d:k:r:s:u: PARAMS do case $PARAMS in b) # Get the kerberos server name KRB_SERVER=$OPTARG ;; c) # Get the directory where is located the krb5.conf file KRB_CONF=$OPTARG ;; d) # Get the domain name for the Kerberos realm DOMAIN=$OPTARG ;; h) # help echo "$UsageStart" exit 0 ;; k) # Get the KDC server name KDC_SERVER=$OPTARG ;; r) # Get the REALM name REALM=$OPTARG ;; s) # Get the nfs server name NFS_SERVER=$OPTARG ;; u) # Get the user name NFSCLIENTUSER=$OPTARG ;; v) # Set verbose mode echo "Verbose mode set" modverbose=1 ;; *) echo "bad parameter: -$OPTARG" echo "$UsageStart" exit 1 ;; esac done start ;; status) # Command Line Processing OPTIND=2 while getopts :hvb:k:s: PARAMS do case $PARAMS in b) # Get the kerberos server name KRB_SERVER=$OPTARG ;; h) # help echo "$UsageStatus" exit 0 ;; k) # Get the KDC server name KDC_SERVER=$OPTARG ;; r) # Get the REALM name REALM=$OPTARG ;; s) # Get the nfs server name NFS_SERVER=$OPTARG ;; v) # Set verbose mode echo "Verbose mode set" modverbose=1 ;; *) echo "bad parameter: -$OPTARG" echo "$UsageStatus" exit 1 ;; esac done status ;; *) echo "Usage: $0 {start|status} -h" exit 1 ;; esac