| #!/bin/bash |
| # |
| # Licensed to the Apache Software Foundation (ASF) under one |
| # or more contributor license agreements. See the NOTICE file |
| # distributed with this work for additional information |
| # regarding copyright ownership. The ASF licenses this file |
| # to you under the Apache License, Version 2.0 (the |
| # "License"); you may not use this file except in compliance |
| # with the License. You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, |
| # software distributed under the License is distributed on an |
| # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| # KIND, either express or implied. See the License for the |
| # specific language governing permissions and limitations |
| # under the License. |
| # |
| |
| # |
| # This script is provided as an example of how to parse the Kerberos CSV file. |
| # It is for illustrative purposes only and should not be used for any other purpose. |
| # |
| |
| ############################ |
| ## NOTE: |
| ## 1) This script should be executed on NameNode host as that host is guaranteed to have all the users needed while creating keytab file |
| ## 2) The script has been verified to work in gce environment and |
| ## vagrant environment documented at ambari wiki: https://cwiki.apache.org/confluence/display/AMBARI/Quick+Start+Guide |
| ########################### |
| |
| usage () { |
| echo "Usage: keytabs.sh <HOST_PRINCIPAL_KEYTABLE.csv> <SSH_LOGIN_KEY_PATH>"; |
| echo " <HOST_PRINCIPAL_KEYTABLE.csv>: CSV file generated by 'Enable Security Wizard' of Ambari"; |
| echo " <SSH_LOGIN_KEY_PATH>: File path to the ssh login key for root user"; |
| exit 1; |
| } |
| |
| ################### |
| ## processCSVFile() |
| ################### |
| processCSVFile () { |
| csvFile=$1; |
| csvFile=$(printf '%q' "$csvFile") |
| # Remove blank lines |
| sed -i '/^\s*$/d' $csvFile |
| touch generate_keytabs.sh; |
| chmod 755 generate_keytabs.sh; |
| |
| echo "#!/bin/bash" > generate_keytabs.sh; |
| echo "###########################################################################" >> generate_keytabs.sh; |
| echo "###########################################################################" >> generate_keytabs.sh; |
| echo "## " >> generate_keytabs.sh; |
| echo "## Ambari Security Script Generator" >> generate_keytabs.sh; |
| echo "## " >> generate_keytabs.sh; |
| echo "## Ambari security script is generated which should be run on the" >> generate_keytabs.sh; |
| echo "## Kerberos server machine." >> generate_keytabs.sh; |
| echo "## " >> generate_keytabs.sh; |
| echo "## Running the generated script will create host specific keytabs folders." >> generate_keytabs.sh; |
| echo "## Each of those folders will contain service specific keytab files with " >> generate_keytabs.sh; |
| echo "## appropriate permissions. There folders should be copied as the appropriate" >> generate_keytabs.sh; |
| echo "## host's '/etc/security/keytabs' folder" >> generate_keytabs.sh; |
| echo "###########################################################################" >> generate_keytabs.sh; |
| echo "###########################################################################" >> generate_keytabs.sh; |
| |
| rm -f commands.mkdir; |
| rm -f commands.chmod; |
| rm -f commands.addprinc; |
| rm -f commands.xst |
| rm -f commands.xst.cp |
| rm -f commands.chown.1 |
| rm -f commands.chmod.1 |
| rm -f commands.chmod.2 |
| rm -f commands.tar |
| |
| seenHosts=""; |
| seenPrincipals=""; |
| |
| echo "mkdir -p ./tmp_keytabs" >> commands.mkdir; |
| sed 1d $csvFile | while read line; do |
| hostName=`echo $line|cut -d , -f 1`; |
| service=`echo $line|cut -d , -f 2`; |
| principal=`echo $line|cut -d , -f 3`; |
| localUserName=`echo $line|cut -d , -f 5`; |
| keytabFile=`echo $line|cut -d , -f 6 | cut -d , -f 6 | rev | cut -d '/' -f 1 | rev`; |
| fullKeytabFilePath=`echo $line|cut -d , -f 6`; |
| keytabFilePath=${fullKeytabFilePath%/*}; |
| owner=`echo $line|cut -d , -f 7`; |
| group=`echo $line|cut -d , -f 9`; |
| acl=`echo $line|cut -d , -f 11`; |
| |
| if [[ $seenHosts != *$hostName* ]]; then |
| echo "mkdir -p ./keytabs_$hostName" >> commands.mkdir; |
| echo "chmod 755 ./keytabs_$hostName" >> commands.chmod; |
| echo "chown -R root:$group `pwd`/keytabs_$hostName" >> commands.chown.1 |
| echo "tar -cvf keytabs_$hostName.tar -C keytabs_$hostName ." >> commands.tar |
| seenHosts="$seenHosts$hostName"; |
| fi |
| |
| if [[ $seenPrincipals != *" $principal"* ]]; then |
| echo -e "kadmin.local -q \"addprinc -randkey $principal\"" >> commands.addprinc; |
| seenPrincipals="$seenPrincipals $principal" |
| fi |
| tmpKeytabFile="`pwd`/tmp_keytabs/$keytabFile"; |
| newKeytabPath="`pwd`/keytabs_$hostName$keytabFilePath"; |
| newKeytabFile="$newKeytabPath/$keytabFile"; |
| if [ ! -f $tmpKeytabFile ]; then |
| echo "kadmin.local -q \"xst -k $tmpKeytabFile $principal\"" >> commands.xst; |
| fi |
| if [ ! -d $newKeytabPath ]; then |
| echo "mkdir -p $newKeytabPath" >> commands.mkdir; |
| fi |
| echo "cp $tmpKeytabFile $newKeytabFile" >> commands.xst.cp |
| echo "chmod $acl $newKeytabFile" >> commands.chmod.2 |
| echo "chown $owner:$group $newKeytabFile" >> commands.chown.1 |
| done; |
| |
| |
| echo "" >> generate_keytabs.sh; |
| echo "" >> generate_keytabs.sh; |
| echo "###########################################################################" >> generate_keytabs.sh; |
| echo "# Making host specific keytab folders" >> generate_keytabs.sh; |
| echo "###########################################################################" >> generate_keytabs.sh; |
| cat commands.mkdir >> generate_keytabs.sh; |
| echo "" >> generate_keytabs.sh; |
| echo "###########################################################################" >> generate_keytabs.sh; |
| echo "# Changing permissions for host specific keytab folders" >> generate_keytabs.sh; |
| echo "###########################################################################" >> generate_keytabs.sh; |
| cat commands.chmod >> generate_keytabs.sh; |
| echo "" >> generate_keytabs.sh; |
| echo "###########################################################################" >> generate_keytabs.sh; |
| echo "# Creating Kerberos Principals" >> generate_keytabs.sh; |
| echo "###########################################################################" >> generate_keytabs.sh; |
| cat commands.addprinc >> generate_keytabs.sh; |
| echo "" >> generate_keytabs.sh; |
| echo "###########################################################################" >> generate_keytabs.sh; |
| echo "# Creating Kerberos Principal keytabs in host specific keytab folders" >> generate_keytabs.sh; |
| echo "###########################################################################" >> generate_keytabs.sh; |
| cat commands.xst >> generate_keytabs.sh; |
| cat commands.xst.cp >> generate_keytabs.sh; |
| echo "" >> generate_keytabs.sh; |
| echo "###########################################################################" >> generate_keytabs.sh; |
| echo "# Changing ownerships of host specific keytab files" >> generate_keytabs.sh; |
| echo "###########################################################################" >> generate_keytabs.sh; |
| cat commands.chown.1 >> generate_keytabs.sh; |
| echo "" >> generate_keytabs.sh; |
| echo "###########################################################################" >> generate_keytabs.sh; |
| echo "# Changing access permissions of host specific keytab files" >> generate_keytabs.sh; |
| echo "###########################################################################" >> generate_keytabs.sh; |
| #cat commands.chmod.1 |
| cat commands.chmod.2 >> generate_keytabs.sh; |
| echo "" >> generate_keytabs.sh; |
| echo "###########################################################################" >> generate_keytabs.sh; |
| echo "# Packaging keytab folders" >> generate_keytabs.sh; |
| echo "###########################################################################" >> generate_keytabs.sh; |
| cat commands.tar >> generate_keytabs.sh; |
| echo "" >> generate_keytabs.sh; |
| echo "###########################################################################" >> generate_keytabs.sh; |
| echo "# Cleanup" >> generate_keytabs.sh; |
| echo "###########################################################################" >> generate_keytabs.sh; |
| echo "rm -rf ./tmp_keytabs" >> generate_keytabs.sh; |
| echo "" >> generate_keytabs.sh; |
| echo "echo \"****************************************************************************\"" >> generate_keytabs.sh; |
| echo "echo \"****************************************************************************\"" >> generate_keytabs.sh; |
| echo "echo \"** Copy and extract 'keytabs_[hostname].tar' files onto respective hosts. **\"" >> generate_keytabs.sh; |
| echo "echo \"** **\"" >> generate_keytabs.sh; |
| echo "echo \"** Generated keytab files are preserved in the 'tmp_keytabs' folder. **\"" >> generate_keytabs.sh; |
| echo "echo \"****************************************************************************\"" >> generate_keytabs.sh; |
| echo "echo \"****************************************************************************\"" >> generate_keytabs.sh; |
| |
| rm -f commands.mkdir >> generate_keytabs.sh; |
| rm -f commands.chmod >> generate_keytabs.sh; |
| rm -f commands.addprinc >> generate_keytabs.sh; |
| rm -f commands.xst >> generate_keytabs.sh; |
| rm -f commands.xst.cp >> generate_keytabs.sh; |
| rm -f commands.chown.1 >> generate_keytabs.sh; |
| rm -f commands.chmod.1 >> generate_keytabs.sh; |
| rm -f commands.chmod.2 >> generate_keytabs.sh; |
| rm -f commands.tar >> generate_keytabs.sh; |
| # generate keytabs |
| sh ./generate_keytabs.sh |
| } |
| |
| ######################## |
| ## installKDC () : Install rng tools,pdsh on KDC host and KDC packages on all host. Modify krb5 file |
| ######################## |
| installKDC () { |
| csvFile=$1; |
| sshLoginKey=$2; |
| HOSTNAME=`hostname --fqdn` |
| scriptDir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" |
| krb5_new_conf=$scriptDir"/krb5.conf" |
| krb5_conf="/etc/krb5.conf" |
| #export additional path for suse and centos5 |
| PATH=$PATH:/usr/lib/mit/sbin/:/usr/kerberos/sbin/:/usr/sbin/:/sbin/ |
| # Install rng tools |
| installRngtools |
| # Install kdc server on this host |
| $inst_cmd $server_packages |
| # Configure /etc/krb5.conf |
| cp $krb5_conf $krb5_conf".bak" |
| cp $krb5_new_conf $krb5_conf |
| sed -i "s/\(kdc *= *\).*kerberos.example.com.*/\1$HOSTNAME/" $krb5_conf |
| sed -i "s/\(admin_server *= *\).*kerberos.example.com.*/\1$HOSTNAME/" $krb5_conf |
| # Create principal key and start services |
| if [[ ! -f $principal_file ]]; then |
| echo -ne '\n\n' | kdb5_util create -s |
| fi |
| eval $kdc_service_start |
| eval $kadmin_service_start |
| # Install pdsh on this host |
| $inst_cmd pdsh; |
| chown root:root -R /usr; |
| eval `ssh-agent` |
| ssh-add $sshLoginKey |
| hostNames=''; |
| |
| # remove empty lines |
| sed -i "/^\s*$/d" $csvFile; |
| |
| sed 1d $csvFile > $csvFile.tmp |
| while read line; do |
| hostName=`echo $line|cut -d , -f 1`; |
| if [ -z "$hostNames" ]; then |
| hostNames=$hostName; |
| continue; |
| fi |
| if [[ $hostNames != *$hostName* ]]; then |
| hostNames=$hostNames,$hostName; |
| fi |
| echo "hostNames $hostNames"; |
| done < $csvFile.tmp; |
| rm -f $csvFile.tmp |
| # Check all hosts for passwordless ssh |
| OLD_IFS=$IFS |
| IFS=, |
| for host in $hostNames; do |
| |
| checkSSH $host |
| done |
| IFS=$OLD_IFS |
| export PDSH_SSH_ARGS_APPEND="-q -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o PreferredAuthentications=publickey" |
| pdsh -R ssh -w $hostNames "$inst_cmd $client_packages" |
| pdsh -R ssh -w $hostNames "$inst_cmd pdsh" |
| pdsh -R ssh -w $hostNames chown root:root -R /usr |
| pdcp -R ssh -w $hostNames $krb5_conf $krb5_conf |
| } |
| |
| ######################## |
| ## distributeKeytabs () : Distribute the tar on all respective hosts root directory and untar it |
| ######################## |
| distributeKeytabs () { |
| shopt -s nullglob |
| filearray=(keytabs_*tar) |
| for i in ${filearray[@]}; do |
| derivedname=${i%.*} |
| derivedname=${derivedname##keytabs_} |
| echo $derivedname |
| scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no $i root@$derivedname:/ |
| ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no root@$derivedname "cd /;tar xvf $i --no-overwrite-dir" |
| done |
| } |
| |
| ######################## |
| ## getEnvironmentCMD () : get linux distribution type and package manager |
| ######################## |
| getEnvironmentCMD () { |
| os=`python -c 'import sys; sys.path.append("/usr/lib/ambari-server/lib/"); from ambari_commons import OSCheck; print OSCheck.get_os_family()'` |
| version=`python -c 'import sys; sys.path.append("/usr/lib/ambari-server/lib/"); from ambari_commons import OSCheck; print OSCheck.get_os_major_version()'` |
| os=$os$version; |
| case $os in |
| 'ubuntu12' ) |
| pkgmgr='apt-get' |
| inst_cmd="env DEBIAN_FRONTEND=noninteractive /usr/bin/$pkgmgr --allow-unauthenticated --assume-yes install -f " |
| client_packages="krb5-user libpam-krb5 libpam-ccreds auth-client-config" |
| server_packages="krb5-kdc krb5-admin-server $client_packages" |
| rng_tools="rng-tools" |
| principal_file="/etc/krb5kdc/principal" |
| kdc_service_start="service krb5-kdc start || service krb5-kdc status" |
| kadmin_service_start="service krb5-admin-server start || service krb5-admin-server status" |
| ;; |
| 'redhat5' ) |
| pkgmgr='yum' |
| inst_cmd="/usr/bin/$pkgmgr -y install " |
| client_packages="krb5-workstation" |
| server_packages="krb5-server krb5-libs krb5-auth-dialog $client_packages" |
| rng_tools="rng-utils" |
| principal_file="/var/kerberos/krb5kdc/principal" |
| kdc_service_start="service kadmin start; service kadmin status" |
| kadmin_service_start="service krb5kdc start || service krb5kdc status" |
| ;; |
| 'redhat6' ) |
| pkgmgr='yum' |
| inst_cmd="/usr/bin/$pkgmgr -y install " |
| client_packages="krb5-workstation" |
| server_packages="krb5-server krb5-libs krb5-auth-dialog $client_packages" |
| rng_tools="rng-tools" |
| principal_file="/var/kerberos/krb5kdc/principal" |
| kdc_service_start="service kadmin start; service kadmin status" |
| kadmin_service_start="service krb5kdc start || service krb5kdc status" |
| ;; |
| 'suse11' ) |
| pkgmgr='zypper' |
| inst_cmd="/usr/bin/$pkgmgr install --auto-agree-with-licenses --no-confirm " |
| client_packages="krb5-client" |
| server_packages="krb5 krb5-server $client_packages" |
| rng_tools="rng-tools" |
| principal_file="/var/lib/kerberos/krb5kdc/principal" |
| kdc_service_start="service kadmind start || service kadmind status" |
| kadmin_service_start="service krb5kdc start || service krb5kdc status" |
| ;; |
| esac |
| } |
| |
| ######################## |
| ## checkUser () : If the user executing the script is not "root" then exit |
| ######################## |
| checkUser () { |
| userid=`id -u`; |
| if (($userid != 0)); then |
| echo "ERROR: The script needs to be executed by root user" |
| exit 1; |
| fi |
| } |
| |
| ######################## |
| ## checkSSH () : If passwordless ssh for root is not configured then exit |
| ######################## |
| checkSSH () { |
| host=$1 |
| ssh -oPasswordAuthentication=no -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no $host "exit 0" && return_value=0 || return_value=$? && true |
| if [[ $return_value != 0 ]]; then |
| echo "ERROR: Passwordless ssh for user root is not configured for host $host" |
| exit 1; |
| fi |
| } |
| |
| ######################## |
| ## installRngtools () : Install and start rng-tools |
| ######################## |
| installRngtools () { |
| $inst_cmd $rng_tools |
| echo $inst_cmd $rng_utils |
| if [ $os == 'ubuntu12' ] || [ $os == 'suse11' ]; then |
| echo "HRNGDEVICE=/dev/urandom" >> /etc/default/rng-tools |
| /etc/init.d/rng-tools start || true |
| elif [ $os == 'redhat5' ]; then |
| /sbin/rngd -r /dev/urandom -o /dev/random -f -t .001 --background |
| else |
| sed -i "s/\(EXTRAOPTIONS *= *\).*/\1\"-r \/dev\/urandom\"/" "/etc/sysconfig/rngd" |
| # start rngd |
| /etc/init.d/rngd start |
| fi |
| } |
| |
| if (($# != 2)); then |
| usage |
| fi |
| |
| set -e |
| checkUser |
| getEnvironmentCMD |
| installKDC $@ |
| processCSVFile $@ |
| distributeKeytabs $@ |