#! /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 Server # # Written to be run by root on the machine to be the Kerberos NFS Server # # Usage : # # krbnfssv {start | status } # start: First Kerberized NFS Server initialisation # status: Check the kerberised NFS Server configuration is still OK # # krbnfssv start { -h | {-b } {-c } {-d } {-k } {-r } {-v}} # krbnfssv status { -h | {-b } {-k } {-v}} # # Description: # The krbnfssv command configures a kerberized NFS Server # # The command does some controls: # start: # - checks Kerberos Client package # - checks REALM is UPPER CASE # - checks the /etc/services file lists the nfs service (port 2049) # - checks KDC and Kerberos Server are reachable # - checks kerberos daemons running (krb5kdc, kadmind) on the Kerberos Server # - checks time is synchronised (<300s) with the KDC Server machine time # - checks hostname is a full 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 # - checks nfs server daemons are running # status: # - checks KDC and Kerberos Server are reachable # - checks kerberos daemons running (krb5kdc, kadmind) on the Kerberos Server # - checks the /etc/services file lists the nfs service (port 2049) # - checks time is synchronised (<300s) with the KDC Server machine time # - checks hostname is a full 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 # - checks nfs server daemons are running # # 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 # -v : verbose mode # - display more messages # - start rpc.svcgssd with verbose mode ( rpc.svcgssd -vvv) UsageStart="krbnfssv start { -h | {-b } {-c } {-d } {-k } {-r } {-v}}" UsageStatus="krbnfssv status { -h | {-b } {-k } {-v}}" # Defaults Environment KRB_CONF="" # Directory where to find the kerberos configuration file REALM="" # Contains the real name DOMAIN="" # Domain name of the Kerberos realm KDC_SERVER="" # Kdc server name KRB_SERVER="" # Admin kerberos server name NFSSERVERNAME=`/bin/hostname` # The machine running the command is the NFS Server modverbose=0 # Verbose mode # # Functions # vm () { # verbose messages print if [ $modverbose != 0 ] then echo "$1" fi } FinalizeStartConfiguration () { # Finalizes the configuration after the command line processing (option start) if [ -z "$REALM" ]; then echo " Enter the REALM name" read REALM fi CheckREALM if [ -z "$DOMAIN" ]; then echo " Enter the Domain Name" read DOMAIN fi if [ -z "$KDC_SERVER" ]; then echo " Enter the KDC Server Name" read KDC_SERVER fi if [ -z "$KRB_SERVER" ]; then echo " Enter the Kerberos Administration Server Name" read KRB_SERVER fi if [ -z "$KRB_CONF" ]; then echo " Enter the directory where to put the Kerberos krb5.conf file" read KRB_CONF fi # # list a summary echo "Here are the parameters from which the Kerberos NFS Server configuration" echo " will be build: " echo " Kerberos REALM: $REALM" echo " Domain Name: $DOMAIN" echo " KDC Server Name: $KDC_SERVER" echo " Kerberos Administration Server Name: $KRB_SERVER" echo " ............................" echo " Kerberos Configuration File: $KRB_CONF/krb5.conf" # do you agree echo "Do you agree with this Kerberos NFS Server configuration: yes/no[no]" ANSWER="no" read ANSWER case $ANSWER in yes) ;; *) echo " You need to restart the command to change it" exit 0 ;; esac } FinalizeStatusConfiguration () { # Finalize the configuration after the command line processing (option status) if [ -z "$KDC_SERVER" ]; then echo " Enter the KDC server Name" read KDC_SERVER fi if [ -z "$KRB_SERVER" ]; then echo " Enter the Kerberos Administration server Name" read KRB_SERVER fi } function TestKerberosInstall () { # Check Kerberos the client package is installed type kinit >/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 [ "$?" ] 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 Server machine time echo "Let's check time is synchronised (<300s) with the KDC Server machine: $KDC_SERVER time" timeKDC_SERVER=`ssh $KDC_SERVER date +%s` timeNFSSERVER=`date +%s` if [ $timeKDC_SERVER -ge $timeNFSSERVER ] then gaptime="$(( $timeKDC_SERVER - $timeNFSSERVER)) " else gaptime="$(( $timeNFSSERVER - $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" echo } function CheckFQDN_NFSSERVERNAME () { # Check hostname is a full qualified 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_NFSSERVERNAME=`/bin/hostname --fqdn` echo if [ $? != 0 ] then exit 1 fi if [ "$NFSSERVERNAME" != "$FQDN_NFSSERVERNAME" ] then echo "The hostname is not a FQDN name " echo "The hostname is: $NFSSERVERNAME" echo "The Full Qualified Name is: $FQDN_NFSSERVERNAME" echo "Do you want to set it: yes/no[yes]" ANSWER="yes" read ANSWER case $ANSWER in yes) NFSSERVERNAME="$FQDN_NFSSERVERNAME" hostname "$NFSSERVERNAME" ;; *) ;; esac fi RETNAME=`awk '{ print $2}' /etc/hosts | grep "$FQDN_NFSSERVERNAME" ` if [ "$RETNAME" != "$FQDN_NFSSERVERNAME" ] then echo "In /etc/hosts, full qualified name:$FQDN_NFSSERVERNAME" echo " should be first after IP address" exit 1 fi grep "127.0.0.1" /etc/hosts | grep "$NFSSERVERNAME" > /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 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 name server is the same as in KDC_SERVER:/etc/resolv.conf 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_NFSSERVERNAME=`nslookup $NFSSERVERNAME | grep Server | cut -f3` if [ -z "NS_NFSSERVERNAME" ] then echo " $NFSSERVERNAME Name Server can't reached" exit 1 fi if [ "$NS_KDC_SERVER" != "$NS_NFSSERVERNAME" ] then echo " $NFSSERVERNAME 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) CheckDNS # Check in /etc/resolv.conf the name server is the same as in /etc/resolv.conf # of the KDC Server CheckFQDN_NFSSERVERNAME # Check hostname is 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 } function ping_check () { if ping $1 -c 5 > /dev/null; then : else echo "$KDC_SERVER 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 daemon 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 running echo "Let's check the nfsd daemon is running" ps -e | grep nfsd > /dev/null RETVAL=$? if [ $RETVAL -ne 0 ] then echo "nfsd daemon not running" echo "Do you want to have this command loading it: yes/no[no]" ANSWER="no" read ANSWER case $ANSWER in yes) service nfs start ;; *) exit 1 ;; esac fi echo "nfsd daemon is running" echo } function ResetKRBNFSSv () { # 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 the Kerberos server: $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 } function AddPrincipalNFSSv () { # Create credentials for the server by creating a Kerberos V5 principal/instance name # of the form nfs/dns.name.of.server@REALM echo " Create credentials for the server by creating a Kerberos V5 principal:nfs/$NFSSERVERNAME" kadmin -q "addprinc -randkey nfs/$NFSSERVERNAME" } function AddKeyNFSSv () { # Add a key for the nfs principal in /etc/krb5.keytab echo " Add a key for the nfs principal nfs/$NFSSERVERNAME" kadmin -q "ktadd -e des-cbc-crc:normal -k $KRB_CONF/krb5.keytab nfs/$NFSSERVERNAME" chmod 600 $KRB_CONF/krb5.keytab } function StartRpcSvcGssd () { # Start rpc.svcgssd daemon killall rpc.svcgssd > /dev/null 2>&1 if [ $modverbose != 0 ] then rpc.svcgssd -vvv else rpc.svcgssd fi } function CheckRpcSvcGssd () { # Check rpc.svcgssd daemon is running ps -e | grep rpc.svcgssd > /dev/null RETVAL=$? if [ $RETVAL -ne 0 ] then echo "rpc.svcgssd 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.svcgssd -vvv else rpc.svcgssd fi ;; *) ;; esac fi } function DoExport () { exportfs -r } function DisplayExportList { # Display the current export list echo "Let's display the current export list" exportfs -v echo if [ $modverbose != 0 ] # Control export uses RPCSEC_GSS security then exportfs -v | grep gss > /dev/null RETVAL=$? if [ $RETVAL -ne 0 ] then echo "export not using RPCSEC_GSS security" echo fi fi } start () { FinalizeStartConfiguration # Finalize the configuration after the command line processing TestKerberosInstall # Check Kerberos client package CheckEnv # Check synchronised 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 ResetKRBNFSSv # Delete files from the previous configuration CreateKRB5Conf # Get krb5.conf from the Kerberos Administration Server AddPrincipalNFSSv # Create credentials for the server AddKeyNFSSv # Add a key for the nfs principal in /etc/krb5.keytab StartRpcSvcGssd # Start rpc.svcgssd daemon DoExport } status () { FinalizeStatusConfiguration # Finalize the configuration after the command line processing CheckEnv # Check syncronized 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 CheckRpcSvcGssd # Check rpc.svcgssd is running DisplayExportList # Display the current export list } # # Main section # # See how we were called. case "$1" in start) # Command Line Processing OPTIND=2 while getopts :hvb:c:d:k:r: 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) DOMAIN=$OPTARG # Get the domain name for the Kerberos realm ;; h) # help echo "$UsageStart" exit 0 ;; k) # Get the KDC server name KDC_SERVER=$OPTARG ;; r) # Get the REALM name REALM=$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: 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 ;; 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}" exit 1 esac