#!/bin/bash -e # # Make a network of Kerberos realms and AFS cells suitable for testing # cross-realm and cross-cell token-setting functionality. Depends on FHS-ish # paths as used, for example, by Matthew Miller's OpenAFS packages. # # Each realm gets a user named "test" with UID 50000 and password "password". # Each realm is set up with two-way cross-realm with other realms: # krbtgt/$REALM1@$REALM2 and krbtgt/$REALM2@$REALM1 exist for each pair. # Each cell is set up with two-way cross-cell with other cells. # system:authuser@$realm1 exists in the PTS database for each $cell2 # Note that if the realm and cell name of the foreign cell differ, the # *realm* name is used to construct the group name. # # Each AFS server gets its cell key. Each system gets its host key, so # you could probably do NFS4 testing with these systems. # # Each cell must be manually initialized or started, after booting the VM, by # running the scripts which are placed in the superuser's home directory. # There is no root password -- this isn't for building production setups, got # that? # # There are probably bugs lurking if your AFS DB servers aren't also KDCs, # and there's no slave KDC support. # # The hostnames of the systems involved MUST be resolvable, forward and # reverse, using DNS. # # Configuration is picked up from ./make-afsnet.conf. Read on for info on # the format of this file. # if test -s make-afsnet.conf ; then . ./make-afsnet.conf else # Network configuration for our test hosts. For every test host we set # up, we'll need corresponding REALM, CELL, KRBROLE, and AFSROLE # variables. Each host will know about all of the realms and cells # defined here. Define HOST1, HOST2, etc. HOST1=cell2a.boston.redhat.com # These settings are shared between each host. GATEWAY=172.16.83.254 NETMASK=255.255.252.0 SEARCH=boston.redhat.com DNS1=172.16.76.10 DNS2=172.16.52.28 DNS3=172.16.52.27 # Extra packages to install beyond the base system. YUMCONF=/yum.conf PACKAGES="openafs-server krb5-server afs-krb5 pam_krb5 vim-enhanced" # Kerberos/AFS configuration for the servers. List krb5 servers for # any given realm BEFORE clients of that realm. All AFS DB servers # must also be krb5 realm servers. Set NULLCELLINSTANCE%d=yes for # hosts in a given cell to change its principal from afs/cell@REALM to # afs@REALM. Note that I haven't done that in cases where the realm # name and the cell name differ. # Recognized values for KRBROLE are "server" and "client". # Recognized values for AFSROLE are "db", "vol", and "client" (though # "client" hasn't been tested. REALM1=REALM-A.EXAMPLE.COM CELL1=realm-a.example.com KRBROLE1=server AFSROLE1=db fi # End of configuration # # Require a template installed image so that we don't have to install # packages that often. # template=$1 if test "x$template" = x ; then echo Usage: `basename $0` "template-image.img" exit 1 fi tmpdir=`mktemp -d /tmp/make-afsnetXXXXXX` if test -z "$tmpdir" ; then echo "Error creating temporary directory!" exit 1 fi cleanup() { for mountpoint in ./*.root ; do if test -d $mountpoint ; then umount $mountpoint/proc || : umount $mountpoint/dev || : umount $mountpoint || : rmdir $mountpoint fi done rm -fr $tmpdir } trap cleanup EXIT touch $tmpdir/realm-list touch $tmpdir/cell-list hostnum=1; while test x`eval echo \\$HOST$hostnum` != x ; do HOST=`eval echo \\$HOST$hostnum` ADDR=`getent hosts $HOST | head -n 1 | awk '{print $1}'` SHOST=`getent hosts $HOST | head -n 1 | awk '{print $2}' | cut -f1 -d.` REALM=`eval echo \\$REALM$hostnum` echo $REALM >> $tmpdir/realm-list CELL=`eval echo \\$CELL$hostnum` echo $CELL >> $tmpdir/cell-list KRBROLE=`eval echo \\$KRBROLE$hostnum` if test x$KRBROLE = xclient ; then touch $tmpdir/krbclient-list.$REALM echo $HOST >> $tmpdir/krbclient-list.$REALM fi AFSROLE=`eval echo \\$AFSROLE$hostnum` if test x$AFSROLE = xdb ; then touch $tmpdir/celldb-list.$CELL printf "%-20s#%s\n" $ADDR $HOST >> $tmpdir/celldb-list.$CELL fi if test x$AFSROLE = xvol ; then touch $tmpdir/cellvol-list.$CELL echo $HOST >> $tmpdir/cellvol-list.$CELL fi : echo Host $SHOST will be a $KRBROLE in realm $REALM, and a $AFSROLE in cell $CELL. hostnum=$((hostnum+1)) done # # Create a krb5.conf naming our realms # cat > $tmpdir/krb5.conf << EOF [logging] default = FILE:/var/log/krb5libs.log kdc = FILE:/var/log/krb5kdc.log admin_server = FILE:/var/log/kadmind.log [libdefaults] default_realm = @REALM@ dns_lookup_realm = false dns_lookup_kdc = false ticket_lifetime = 24h forwardable = yes [realms] EOF hostnum=1; while test x`eval echo \\$HOST$hostnum` != x ; do HOST=`eval echo \\$HOST$hostnum` REALM=`eval echo \\$REALM$hostnum` KRBROLE=`eval echo \\$KRBROLE$hostnum` hostnum=$((hostnum+1)) if test x$KRBROLE = xserver ; then cat >> $tmpdir/krb5.conf << EOF $REALM = { kdc = $HOST admin_server = $HOST } EOF fi done cat >> $tmpdir/krb5.conf << EOF [domain_realm] EOF hostnum=1; while test x`eval echo \\$HOST$hostnum` != x ; do HOST=`eval echo \\$HOST$hostnum` REALM=`eval echo \\$REALM$hostnum` hostnum=$((hostnum+1)) cat >> $tmpdir/krb5.conf << EOF $HOST = $REALM EOF done cat >> $tmpdir/krb5.conf << EOF [kdc] profile = /var/kerberos/krb5kdc/kdc.conf [appdefaults] pam = { debug = false ticket_lifetime = 36000 renew_lifetime = 36000 forwardable = true krb4_convert = false } EOF # # Create a template KDC configuration file. # cat > $tmpdir/kdc.conf << EOF [kdcdefaults] acl_file = /var/kerberos/krb5kdc/kadm5.acl dict_file = /usr/share/dict/words admin_keytab = /var/kerberos/krb5kdc/kadm5.keytab v4_mode = nopreauth [realms] @REALM@ = { master_key_type = des-cbc-crc supported_enctypes = des3-hmac-sha1:normal arcfour-hmac:normal des-hmac-sha1:normal des-cbc-md5:normal des-cbc-crc:normal des-cbc-crc:v4 des-cbc-crc:afs3 } EOF # # Create a template kadm5.acl file. # cat > $tmpdir/kadm5.acl << EOF */admin@@REALM@ * EOF # # Create the CellServDB file. # touch $tmpdir/CellServDB for cell in `sort -u $tmpdir/cell-list` ; do if test -s $tmpdir/celldb-list.$cell ; then echo ">$cell #Cell name" >> $tmpdir/CellServDB cat $tmpdir/celldb-list.$cell >> $tmpdir/CellServDB fi done # # Create the BosConfig file for a DB server. # cat > $tmpdir/BosConfig.db << EOF restarttime 11 0 4 0 0 checkbintime 3 0 5 0 0 bnode simple ptserver 1 parm /usr/libexec/openafs/ptserver end bnode simple vlserver 1 parm /usr/libexec/openafs/vlserver end bnode simple buserver 1 parm /usr/libexec/openafs/buserver end bnode fs fs 1 parm /usr/libexec/openafs/fileserver parm /usr/libexec/openafs/volserver parm /usr/libexec/openafs/salvager end EOF # # Create the BosConfig file for a volume server. # cat > $tmpdir/BosConfig.vol << EOF restarttime 11 0 4 0 0 checkbintime 3 0 5 0 0 bnode fs fs 1 parm /usr/libexec/openafs/fileserver parm /usr/libexec/openafs/volserver parm /usr/libexec/openafs/salvager end EOF # # Create the script for setting up a DB server. # cat > $tmpdir/init-afs-db-server << EOF #!/bin/bash # # Remove any data in this cell's database and volume storage areas # mkdir -p /vicepa rm -fr /var/openafs/db/* /var/openafs/logs/* /var/openafs/S* /var/openafs/s* /vicep?/* touch /vicepa/AlwaysAttach # # Load the AFS kernel module # /sbin/depmod -a lsmod|grep -q libafs||insmod /usr/lib/openafs/libafs-\`uname -r\`-\`uname -m\`.ko # # Start up the servers in noauth mode. The servers will initialize their # databases. Give them a little bit of time to do that. # /usr/sbin/bosserver -noauth bos adduser localhost admin -localauth sleep 10 # Create an admin user (might already exist, we don't care about that). /usr/kerberos/sbin/kadmin.local -q 'ank -pw admin admin' # Create a root.cell volume for the local cell on this server. while ! vos create localhost /vicepa root.cell 500 -localauth ; do continue done # Create pts entries for the local cell pts createuser admin 1 -noauth pts adduser admin system:administrators pts createuser test 50000 -noauth # Create pts entries for users in foreign cells EOF for REALM in `sort -u $tmpdir/realm-list` ; do realm=`echo $REALM | tr '[A-Z]' '[a-z]'` echo "if test x$REALM != x@REALM@ ; then" >> $tmpdir/init-afs-db-server echo " pts creategroup system:authuser@$realm -owner system:administrators -cell @CELL@" >> $tmpdir/init-afs-db-server echo "fi" >> $tmpdir/init-afs-db-server done cat >> $tmpdir/init-afs-db-server << EOF # Switch to querants-must-authenticate mode bos setauth localhost on -noauth sleep 5 bos status localhost -localauth EOF # # Create the script for setting up a volume server. # cat > $tmpdir/init-afs-vol-server << EOF #!/bin/bash # # Remove any data in this server's volume storage areas # mkdir -p /vicepa rm -fr /vicep?/* touch /vicepa/AlwaysAttach # # Load the AFS kernel module # /sbin/depmod -a lsmod|grep -q libafs||insmod /usr/lib/openafs/libafs-\`uname -r\`-\`uname -m\`.ko # # Start up the servers in noauth mode. The servers will initialize their # databases. Give them a little bit of time to do that, then switch to # querants-must-authenticate mode. # /usr/sbin/bosserver -noauth bos adduser localhost admin -localauth sleep 10 bos setauth localhost on -noauth sleep 5 bos status localhost -localauth EOF # # Create the script for starting up an AFS server. # cat > $tmpdir/start-afs-server << EOF #!/bin/bash # # Load the AFS kernel module # /sbin/depmod -a lsmod|grep -q libafs||insmod /usr/lib/openafs/libafs-\`uname -r\`-\`uname -m\`.ko # # Start up the servers in noauth mode. The servers will initialize their # databases. Give them a little bit of time to do that, then switch to # querants-must-authenticate mode. # /usr/sbin/bosserver -noauth sleep 5 bos setauth localhost on -noauth sleep 5 bos status localhost -localauth EOF # # Create scripts for replicating root.cell to volume servers from DB servers. # for cell in `sort -u $tmpdir/cell-list` ; do if test -s $tmpdir/cellvol-list.$cell ; then echo '#!/bin/bash' > $tmpdir/replicate-afs-cell-root-volume.$cell echo '# Replicate root.cell to plain-old volume servers for this cell.' >> $tmpdir/replicate-afs-cell-root-volume.$cell for volserver in `sort -u $tmpdir/cellvol-list.$cell` ; do echo "while ! vos addsite $volserver /vicepa root.cell -localauth ; do" >> $tmpdir/replicate-afs-cell-root-volume.$cell echo " continue" >> $tmpdir/replicate-afs-cell-root-volume.$cell echo "done" >> $tmpdir/replicate-afs-cell-root-volume.$cell done fi done # # Mount each of the host images and copy in configuration files # hostnum=1; while test x`eval echo \\$HOST$hostnum` != x ; do HOST=`eval echo \\$HOST$hostnum` ADDR=`getent hosts $HOST | head -n 1 | awk '{print $1}'` SHOST=`getent hosts $HOST | head -n 1 | awk '{print $2}' | cut -f1 -d.` REALM=`eval echo \\$REALM$hostnum` CELL=`eval echo \\$CELL$hostnum` NULLCELLINSTANCE=`eval echo \\$NULLCELLINSTANCE$hostnum` KRBROLE=`eval echo \\$KRBROLE$hostnum` AFSROLE=`eval echo \\$AFSROLE$hostnum` hostnum=$((hostnum+1)) # Derive the cell instance for this cell, for determining the principal if test x$NULLCELLINSTANCE = xyes ; then CELLI= else CELLI=$CELL fi # Get the names of the other realms and cells OTHERREALMS= for OTHERREALM in `sort -u $tmpdir/realm-list` ; do if test x$OTHERREALM != x$REALM ; then OTHERREALMS="$OTHERREALMS $OTHERREALM" fi done OTHERCELLS= for OTHERCELL in `sort -u $tmpdir/cell-list` ; do if test x$OTHERCELL != x$CELL ; then OTHERCELLS="$OTHERCELLS $OTHERCELL" fi done REALMCLIENTS= if test -s $tmpdir/krbclient-list.$REALM ; then for OTHERCLIENT in `sort -u $tmpdir/krbclient-list.$REALM` ; do if test x$OTHERCLIENT != x$HOST ; then REALMCLIENTS="$REALMCLIENTS $OTHERCLIENT" fi done fi # Mount the image umount $SHOST.root/proc 2> /dev/null || : umount $SHOST.root/dev 2> /dev/null || : umount $SHOST.root 2> /dev/null || : mkdir -p `pwd`/$SHOST.root test -s $SHOST.img || install -m600 $template $SHOST.img mount -o loop $SHOST.img $SHOST.root mount --bind /dev $SHOST.root/dev mount --bind /proc $SHOST.root/proc # Create directories in which we'll be creating files, in case # they're not already there mkdir -p $SHOST.root/etc/openafs/server mkdir -p $SHOST.root/etc/sysconfig/network-scripts mkdir -p $SHOST.root/etc/samba mkdir -p $SHOST.root/root # Basic network setup echo ${SEARCH:+search $SEARCH} > $SHOST.root/etc/resolv.conf echo ${DNS1:+nameserver $DNS1} >> $SHOST.root/etc/resolv.conf echo ${DNS2:+nameserver $DNS2} >> $SHOST.root/etc/resolv.conf echo ${DNS3:+nameserver $DNS3} >> $SHOST.root/etc/resolv.conf getent hosts localhost > $SHOST.root/etc/hosts echo NETWORKING=yes > $SHOST.root/etc/sysconfig/network echo HOSTNAME=$HOST >> $SHOST.root/etc/sysconfig/network echo GATEWAY=$GATEWAY >> $SHOST.root/etc/sysconfig/network echo DEVICE=eth0 > $SHOST.root/etc/sysconfig/network-scripts/ifcfg-eth0 echo BOOTPROTO=none >> $SHOST.root/etc/sysconfig/network-scripts/ifcfg-eth0 echo IPADDR=$ADDR >> $SHOST.root/etc/sysconfig/network-scripts/ifcfg-eth0 echo NETMASK=$NETMASK >> $SHOST.root/etc/sysconfig/network-scripts/ifcfg-eth0 # Install additional packages now so that we can wipe out the defaults. PS1= chroot $SHOST.root << EOF PATH=$PATH:/usr/sbin:/usr/kerberos/sbin:/sbin if test -n "$PACKAGES" ; then yum -c ${YUMCONF:-/etc/yum.conf} install $PACKAGES fi EOF # Kerberos configuration mkdir -p $SHOST.root/var/kerberos/krb5kdc rm -f $SHOST.root/var/kerberos/krb5kdc/{.k,}* rm -f $SHOST.root/etc/krb5.keytab* rm -f $SHOST.root/tmp/{krb5cc,tkt}* cat $tmpdir/krb5.conf | sed s,@REALM@,$REALM,g > $SHOST.root/etc/krb5.conf if test x$KRBROLE = xserver ; then cat $tmpdir/kdc.conf | sed s,@REALM@,$REALM,g > $SHOST.root/var/kerberos/krb5kdc/kdc.conf cat $tmpdir/kadm5.acl | sed s,@REALM@,$REALM,g > $SHOST.root/var/kerberos/krb5kdc/kadm5.acl fi # AFS rm -f $SHOST.root/etc/openafs/server/* rm -f $SHOST.root/etc/openafs/*Cell* echo $CELL > $SHOST.root/etc/openafs/ThisCell cp /dev/null $SHOST.root/etc/openafs/CellAlias cp $tmpdir/CellServDB $SHOST.root/etc/openafs/ if test x$AFSROLE != xclient ; then echo $REALM > $SHOST.root/etc/openafs/server/krb.conf echo $CELL > $SHOST.root/etc/openafs/server/ThisCell cp $tmpdir/CellServDB $SHOST.root/etc/openafs/server/CellServDB cp $tmpdir/BosConfig.$AFSROLE $SHOST.root/etc/openafs/BosConfig cat $tmpdir/init-afs-$AFSROLE-server | sed -e s,@CELL@,$CELL,g -e s,@REALM@,$REALM,g > $SHOST.root/root/init-afs-$AFSROLE-server if test x$AFSROLE = xdb ; then if test -s $tmpdir/replicate-afs-cell-root-volume.$CELL ; then mv $tmpdir/replicate-afs-cell-root-volume.$CELL $SHOST.root/root/replicate-afs-cell-root-volume fi fi cp $tmpdir/start-afs-server $SHOST.root/root/ chmod +x $SHOST.root/root/*-afs-* fi # Initialize the Kerberos database, if we need to. Also set up a key # for the local cell while we're here. if test -s $tmpdir/krb5.keytab.afs.$CELL ; then cp -f $tmpdir/krb5.keytab.afs.$CELL $SHOST.root/etc/ fi if test -s $tmpdir/krb5.keytab.host.$HOST ; then cp -f $tmpdir/krb5.keytab.host.$HOST $SHOST.root/etc/krb5.keytab fi export REALMCLIENTS KRBROLE OTHERREALMS AFSROLE PACKAGES export REALM CELLI CELL HOST YUMCONF PS1= chroot $SHOST.root << EOF PATH=$PATH:/usr/sbin:/usr/kerberos/sbin:/sbin if test x$KRBROLE = xserver ; then rm -f /var/kerberos/krb5kdc/{principal,.principal,.k5}* yes | kdb5_util create -s /sbin/chkconfig --level 345 krb5kdc on /sbin/chkconfig --level 345 krb524 on kadmin.local -q "ank -pw password test" if test -n "$OTHERREALMS" ; then for arealm in $OTHERREALMS ; do kadmin.local -q "ank -pw \$arealm.cross.$REALM krbtgt/\$arealm@$REALM" kadmin.local -q "ank -pw $REALM.cross.\$arealm krbtgt/$REALM@\$arealm" done fi kadmin.local -q "ank -randkey -e des-cbc-crc:afs3 afs${CELLI:+/$CELLI}@$REALM" kadmin.local -q "ktadd -k /etc/krb5.keytab.afs.$CELL -e des-cbc-crc:afs3 afs${CELLI:+/$CELLI}@$REALM" kadmin.local -q "ank -randkey host/$HOST@$REALM" kadmin.local -q "ktadd host/$HOST@$REALM" if test -n "$REALMCLIENTS" ; then for client in $REALMCLIENTS ; do kadmin.local -q "ank -randkey host/\$client@$REALM" kadmin.local -q "ktadd -k /etc/krb5.keytab.host.\$client host/\$client@$REALM" done fi fi if test x$AFSROLE != xclient ; then asetkey add 3 /etc/krb5.keytab.afs.$CELL afs${CELLI:+/}$CELLI@$REALM fi grep -v ^test: /etc/passwd > /etc/passwd.cleared cat /etc/passwd.cleared > /etc/passwd && rm -f /etc/passwd.cleared echo "test:x:50000:50000:Test User in cell \"$CELL\" and realm \"$REALM\":/afs/$CELL/users/test:/bin/bash" >> /etc/passwd authconfig --nostart --kickstart --enablekrb5 EOF # Save an AFS keytab file which we created, if there is one. if test -s $SHOST.root/etc/krb5.keytab.afs.$CELL ; then mv -f $SHOST.root/etc/krb5.keytab.afs.$CELL $tmpdir/ fi # Save any host keytab files which we created, if there are any. for keytab in $SHOST.root/etc/krb5.keytab.host.* ; do test -s $keytab && mv -f $keytab $tmpdir/ done # Make logs easy-to-read, for me. touch $SHOST.root/var/log/{messages,secure,debug} chmod +r $SHOST.root/var/log/{messages,secure,debug} done : $SHELL