Skip to content

Instantly share code, notes, and snippets.

@wangweij
Created September 1, 2015 07:19
Show Gist options
  • Save wangweij/f42f286dba8d5fdc79c5 to your computer and use it in GitHub Desktop.
Save wangweij/f42f286dba8d5fdc79c5 to your computer and use it in GitHub Desktop.
A script to create multiple KDCs with trust relations
#! /bin/bash
if [ "$1" = "" ]; then
cat <<___
Usage: $(basename $0) relations+
Each relation is a string describing a trusted path. This command
creates all KDCs with the relations and basic principals
including a user and a service, and starts them up.
For example, "make_kdcs.sh 123 234" will create 4 KDCs in the realms
K1, K2, K3, K4 listening on ports 9001, 9002, 9003, 9004 of the
localhost, each having config files in a sub-directory of the
current working directory. 123 means a client in K1 can authenticate
to K3 through K2, 234 means a client in K2 can authenticate to K4
through K3. Read the krb5.conf for details.
Define LOCALHOST, or "localhost" will be used.
___
fi
ALLKDC=
# Creates one KDC name K$1 on $LOCALHOST:900$1, adds one user principal and one
# service principal and starts the KDC.
function _create_kdc {
if [ ! -d K$1 ]; then
echo Creating realm K$1
mkdir K$1
ALLKDC="$ALLKDC $1"
(
cd K$1
make_kdc.sh K$1 $LOCALHOST 900$1 > /dev/null
. ./startup
initkdc > /dev/null
startkdc
echo " addprinc host/host.k$1"
addprinc host/host.k$1 > /dev/null 2>& 1
echo " addprinc u$1 p$1"
addprinc u$1 p$1 > /dev/null 2>& 1
)
fi
}
# Creates trust relationship from K$1 rto K$2
function _create_x {
if [ ! -e rel_$1_$2 ]; then
touch rel_$1_$2
XPASS=`od -t x1 < /dev/urandom | sed -e 's/ //g' | head -n1`
echo " addprinc krbtgt/K$2@K$1 $XPASS"
(
cd K$1
. ./startup
addprinc krbtgt/K$2@K$1 $XPASS > /dev/null 2>& 1
)
(
cd K$2
. ./startup
addprinc krbtgt/K$2@K$1 $XPASS > /dev/null 2>& 1
)
fi
}
# Starts here
if [ "$LOCALHOST" = "" ]; then
LOCALHOST=localhost
fi
killallkdc 2> /dev/null
# Ungrouped form of [capaths], lines like
# cRealm sRealm = intermediate
# They will be grouped by cRealm when writing into krb5.conf
CAPATHS=
# Go thru all relations. A relation looks like "12345" which means clients in K1
# can finally access services in K5 thru this capath.
for a in $@; do
echo Creating relation $a
LAST=""
LEN=${#a}
CREALM=${a:0:1}
SREALM=${a:${LEN}-1:1}
for (( i=0; i<${LEN}; i++ )); do
THIS=${a:$i:1}
_create_kdc $THIS
if [ "$LAST" != "" ]; then
_create_x $LAST $THIS
fi
LAST=$THIS
if [ $SREALM != $THIS -a $CREALM != $THIS ]; then
CAPATHS="${CAPATHS}K${CREALM} K${SREALM} = K${THIS}\n"
fi
done
if [ ${LEN} = 2 ]; then
CAPATHS="${CAPATHS}K${CREALM} K${SREALM} = .\n"
fi
done
ALLREALMS=
ALLDOMAINS=
for k in $ALLKDC; do
ALLREALMS="${ALLREALMS}K$k = {\n kdc = $LOCALHOST:900$k\n}\n"
ALLDOMAINS="${ALLDOMAINS}.k$k = K$k\n"
done
ALLCAPATHS=$(printf "$CAPATHS" | perl -e '
while (<STDIN>) {
if (/K(.) (K. = .*)/) {
$path{$1} .= " $2\n";
}
}
for $k (keys %path) {
print "K$k = {\n".$path{$k}."}\n";
}
')
FIRST=true
for k in $ALLKDC; do
(
cd K$k
echo "modifying K$k..."
if [ "$FIRST" = "true" ]; then
echo "(cd K$k; . ./startup; killallkdc; startkdc; )" >> ../restart_all
else
echo "(cd K$k; . ./startup; startkdc; )" >> ../restart_all
fi
FIRST=false
perl -0 -i -pe 's/\[realms\][^\[]+/\[realms\]\n'"$ALLREALMS"'\n/' krb5.conf
cp krb5.conf ../krb5_$k.conf
perl -0 -i -pe 's/\[domain_realm\].*//s' krb5.conf
printf "[domain_realm]\n$ALLDOMAINS" >> krb5.conf
printf "\n[capaths]\n$ALLCAPATHS\n" >> krb5.conf
)
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment