openbsd-ports/net/openafs/files/openafs-setup
ajacoutot 9b9cb3fe51 - s/LOCALBASE/PREFIX
- s/%SYSCONFDIR%/etc where it makes sense (e.g. /etc/rc.conf.local will
always be /etc/rc.conf.local whatever value ${SYSCONFDIR} is set to)
- use SUBST_CMD
- don't hardcode /usr/local
- precise license marker
- s/definately/definitely/ (from sthen@)

"looks good" sthen@, ok todd@
2008-10-12 17:31:17 +00:00

518 lines
14 KiB
Bash
Executable File

#!/bin/sh
# Copyright (c) 2001-2004 Todd T. Fries <todd@OpenBSD.org>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
afsp=${PREFIX}/libexec/openafs
PATH=${PREFIX}/sbin:${PREFIX}/bin:$PATH
DIR=`mktemp -d /tmp/_openafs.XXXXXXXXXX` || exit 1
trap 'rm -rf $DIR; exit 1' 0 1 2 3 13 15
OUTPUT=$DIR/_1
# (borrowed from install.sub)
# Ask for user input.
#
# $1 = the question to ask the user
# $2 = the default answer
#
# Save the user input (or the default) in $resp.
#
# Allow the user to escape to shells ('!') or execute commands
# ('!foo') before entering the input.
ask() {
local _question=$1 _default=$2
set -o noglob
while :; do
echo -n "$_question "
[[ -z $_default ]] || echo -n "[$_default] "
read resp
case $resp in
!) echo "Type 'exit' to return to install."
sh
;;
!*) eval ${resp#?}
;;
*) : ${resp:=$_default}
break
;;
esac
done
set +o noglob
}
# Ask for user input until a non-empty reply is entered.
#
# $1 = the question to ask the user
# $2 = the default answer
#
# Save the user input (or the default) in $resp.
ask_until() {
resp=
while [[ -z $resp ]] ; do
ask "$1" "$2"
done
}
# Ask the user for a y or n, and insist on 'y', 'yes', 'n' or 'no'.
#
# $1 = the question to ask the user
# $2 = the default answer (assumed to be 'n' if empty).
#
# Return 'y' or 'n' in $resp.
ask_yn() {
local _q=$1 _a=${2:-no} _resp
typeset -l _resp
while :; do
ask "$_q" "$_a"
_resp=$resp
case $_resp in
y|yes) resp=y ; return ;;
n|no) resp=n ; return ;;
esac
done
}
# Logging routine
#
# $1 = -c or 1st arg
# $2 = ...
#
# log all arguments
sc=0
log() {
local prompt=":"
if [ "$1" = "-c" ]; then
prompt="#"
shift
else
let sc=sc+1
fi
dfmt="%H:%M:%S"
printf "%s %02d%s " "$(date +"${dfmt}")" $sc "$prompt"
# use echo, because printf(1) treats varargs as one arg per line, ugh
echo "$@"
}
# Create a principal in kerberos.
#
# $1 = principal
# $2 = extra arg..
#
# Delete the principal first before re-adding it to make sure proper
# attributes exist.
kadd() {
local principal=$1
log creating principal: $principal
shift
kadmin del $principal > /dev/null 2>&1
log -c kadmin add "$@" $principal
kadmin add \
--{pw-,}expiration-time=never \
--max-ticket-life="1 month" \
--max-renewable-life="2 months" \
--attributes="" \
"$@" $principal
}
# Re-try a command until success.
#
# $@ = full command to try
#
retry() {
local try=1
log -c "$@"
while ! $@
do
let try=try+1
log -c "$@ : try $try"
sleep 2
done
}
# Make an afs volume.
#
# $1 = volume name
# $2 = volume mount point
#
# Any user can read volumes created here.
mkvol() {
local vol=$1 mnt=$2
log "Creating afs volume $1 to be mounted at $mnt"
retry vos create $h /vicepa $vol
retry fs mkm $mnt $vol
retry fs sa $mnt system:anyuser rl
}
cat <<__EOT
===========================================================================
Welcome to the OpenAFS server1 setup script!
This script will assist you in setting up your first afs server.
It will use OpenAFS for the AFS server, but arla's afsd that comes with
OpenBSD for the AFS client.
It will use heimdal KerberosV that comes with OpenBSD.
It presumes you have previously successfully setup a KerberosV realm,
you have the password to an administrative principal in the KerberosV realm,
you are running it as root, and you have created at least one partition
for OpenAFS to use for data storage. Partitions should be mounted under
/vicepa, /vicepb, /vicepc, etc.
===========================================================================
__EOT
#
# Sanity checks
#
# Require root.
if [[ `/usr/bin/whoami` != "root" ]]
then
echo "Please run this script as root. Thanks."
exit
fi
if [[ `mount|grep " /vicepa "` = "" ]]
then
echo "Could not find any filesystem mounted at /vicepa"
echo "Without this OpenAFS will not function."
echo "Please mount a partition under /vicepa"
echo "A /vicepa directory will not work as"
echo "OpenAFS"
exit
fi
#
# Setup site specific variables
#
# Ask user for variables if not passed on the command line.
if ! [ "$6" ]
then
cat <<__EOT
The hostname for this afs server should resolve in dns but
definitely reside in /etc/hosts. e.g. afs0.example.com.
__EOT
while :; do
ask_until "System hostname?" "$(hostname)"
h=${resp}
if [[ `grep $h /etc/hosts` = "" ]]
then
echo "Could not find /etc/hosts entry for $h."
continue
fi
break
done
cat <<__EOT
The IPv4 IP address for this afs server should resolve in dns but
definitely reside in /etc/hosts. e.g. 192.168.1.200.
__EOT
while :; do
ask_until "System IP?" "$(host $h | \
awk '/has address/{print $4}')"
ip=${resp}
if [[ `grep $ip /etc/hosts` = "" ]]
then
echo "Could not find /etc/hosts entry for $ip."
continue
fi
break
done
cat <<__EOT
The cell name is typically a dns name. e.g. example.com.
__EOT
ask_until "AFS Cell Name?" "${h#*.}"
c=${resp}
cat <<__EOT
The realm name is the KerberosV REALM, typically the capitalized dns name.
e.g. REALM.COM. Use something different at the expense of your sanity.
Really.
__EOT
ask_until "KerberosV REALM?" "$(echo "$c"|tr "[a-z]" "[A-Z]")"
R=${resp}
cat <<__EOT
This is an existing KerberosV principal with the ability to
create and delete other kerberos principals. e.g. todd/admin.
__EOT
ask_until "KerberosV principal for kerberos administration?" \
"todd/admin"
p=${resp}
cat <<__EOT
This principal will be deleted if it exists, and in any event
created again with specific attributes. It will be used to administer afs
in a similar way that \`root' can administrate OpenBSD. Tread lightly when
using this principal.
__EOT
ask_until "KerberosV princiapl for afs administration?" "todd/afs"
A=${resp}
cat <<__EOT
Just a sample user to create a basic homedir and account on afs with.
__EOT
ask_until "KerberosV princiapl for example user?" "todd"
u=${resp}
else
# for advanced users, this script can be started with the above
# pre-populated via arguments
h="$1" ip="$2" c="$3" R="$4" p="$5" A="$6" u="$7"
fi
pp=$(echo "$p"|sed 's,/,.,')
pA=$(echo "$A"|sed 's,/,.,')
cat <<__EOT
Confirm these look correct:
hostname : $h
IP address : $ip
cellname : $c
realm : $R
krb admin : $p (pts name: $pp)
afs admin : $A (pts name: $pA)
sample user: $u
The next step *DESTROYS* all existing OpenAFS configuration on this system,
including any openafs data on all /vicep* partitions!
__EOT
ask_yn "Are you really sure that you're ready to proceed?"
[[ $resp == n ]] && { echo "Ok, try again later.\n" ; exit ; }
echo
log "preparing ${SYSCONFDIR}/{open,}afs /usr/afs /var/openafs..."
kdestroy
pkill -9 afsd
umount /afs > /dev/null 2>&1
[ -d /var/spool/afs ] && rm -rf /var/spool/afs/*
if [ "$(pgrep bosserver)" ]
then
bos shutdown localhost -noauth -wait > /dev/null 2>&1
fi
if [ "$(pgrep bosserver)" ]
then
bos shutdown localhost -localauth -wait > /dev/null 2>&1
fi
pkill -9 buserver ptserver vlserver fileserver volserver bos bosserver
rm -rf ${SYSCONFDIR}/openafs /usr/afs /var/openafs
rm -rf /vicep*/{V*,AFSIDat,Lock}
rm -f /etc/kerberosV/krb5.keytab
mkdir -p ${SYSCONFDIR}/openafs/server /usr/afs /var/spool/afs
mkdir -m 700 /var/openafs
echo "f $ip" > /var/openafs/NetInfo
echo "$R" > ${SYSCONFDIR}/openafs/server/krb.conf
log updating /etc/afs/CellServDB ${SYSCONFDIR}/openafs/server/CellServDB
# borrowed from /etc/security, backup CellServDB
_fnchg() {
echo "$1" | sed 's/^\///;s/\//_/g'
}
csdb=/etc/afs/CellServDB
CURdb=/var/backups/$(_fnchg $csdb).current
BACKdb=/var/backups/$(_fnchg $csdb).backup
if [ -s $CURdb ]; then
diff -ua $CURdb $csdb > $OUTPUT
if [ -s $OUTPUT ]; then
cp -p $CURdb $BACKdb
cp -p $csdb $CURdb
chown root:wheel $CURdb $BACKdb
fi
else
cp -p $csdb $CURdb
chown root:wheel $CURdb
fi
# put back arla's CellServDB when this script exits
trap 'rm -rf $DIR; cp $CURdb $csdb; exit 1' 0 1 2 3 13 15
echo ">$c # $c" > $DIR/CellServDB
echo "$ip #$h" >> $DIR/CellServDB
cat $DIR/CellServDB | \
tee -a $csdb ${SYSCONFDIR}/openafs/server/CellServDB
echo $c | tee ${SYSCONFDIR}/openafs/server/ThisCell > /etc/afs/ThisCell
ln -s /var/openafs/db /usr/afs/db
ln -s ${SYSCONFDIR}/openafs/server /usr/afs/etc
if [ "$(pgrep bosserver)" ]
then
pkill bosserver
fi
log authenticating $p@$R
retry kinit $p@$R
kadd host/$h --random-key
retry kadmin ext host/$h
chmod 0400 /etc/kerberosV/krb5.keytab
kadd afs/$c --random-key
log creating ${SYSCONFDIR}/openafs/server/KeyFile
retry kadmin ext -k $DIR/afsv5key afs/$c
log -c ktutil copy $DIR/afsv5key AFSKEYFILE:${SYSCONFDIR}/openafs/server/KeyFile
ktutil copy $DIR/afsv5key AFSKEYFILE:${SYSCONFDIR}/openafs/server/KeyFile
chmod 600 ${SYSCONFDIR}/openafs/server/KeyFile
rm $DIR/afsv5key
log When asked for a password below, the answer will set it.
let sc=sc-1
kadd $A
log "Disabling arla admin commands (use openafs commands on servers):"
retry chmod 644 /usr/sbin/{bos,pts,vos,fs}
log starting unauthenticated bosserver
retry bosserver -log -syslog -noauth
retry bos setcellname $h $c -noauth
log creating buserver/ptserver/vlserver entries with bos
retry bos create $h buserver simple $afsp/buserver -cell $c -noauth
retry bos create $h ptserver simple $afsp/ptserver -cell $c -noauth
retry bos create $h vlserver simple $afsp/vlserver -cell $c -noauth
log setting up pts memberships, $pA as initial afs admin
retry pts createuser -name $u -id `id -u $u` -cell $c -noauth
retry pts createuser -name $pA -cell $c -noauth
retry pts adduser $pA system:administrators -cell $c -noauth
retry pts mem system:administrators -cell $c -noauth
retry pts listentries -cell $c -noauth
retry bos adduser $h $pA -cell $c -noauth
retry bos addhost $h $h -noauth
retry bos shutdown $h -cell $c -noauth -wait
log getting status of bos config
retry bos status $h -noauth -cell $c -long
log creating fs entry with bos
retry bos create $h fs fs $afsp/{fileserver,volserver,salvager} -cell $c -noauth
retry bos restart $h -all -cell $c -noauth
log getting partition list
retry vos listpart $h -noauth
log creating root.afs
retry vos create $h /vicepa root.afs -noauth
retry vos create $h /vicepa root.cell -noauth
sync;sync
sleep 5
sync;sync
retry bos shutdown $h -cell $c -noauth -wait
pkill -HUP bosserver
sleep 3
# don't put back CellServDB
trap 'rm -rf $DIR; exit 1' 0 1 2 3 13 15
log starting authenticated bosserver
retry bosserver -log -syslog
retry bos restart $h -all -cell $c -localauth
log starting afs client
mkdir -p /afs
[ "$(mount | egrep "^/afs")" ] || mount -t xfs /dev/xfs0 /afs
retry /usr/libexec/afsd -z --log=/var/log/afsd.log
log authenticating $A
retry kinit $A
retry pts listentries
# do this on reboot
grep "^afs=YES" /etc/rc.conf.local > /dev/null 2>&1 || \
echo afs=YES >> /etc/rc.conf.local
retry ls /afs
log setting permissions/creating volumes
retry fs sa /afs system:anyuser rl
retry fs flushvolume /afs
retry fs mkm /afs/.$c root.cell -cell $c -rw -fast
retry fs flushvolume /afs/.$c
retry fs sa /afs/.$c system:anyuser rl
retry fs flushvolume /afs/.$c
cat <<__EOT> /afs/.$c/robots.txt
# noticed at ualberta.ca, attempt to prevent robots from traversing afs
User-Agent: *
Disallow: /
__EOT
mkvol user /afs/.$c/u
mkvol user.todd /afs/.$c/u/todd
mkvol mirror /afs/.$c/mirror
log Add some remote afs cells
# significant remote afs cells of note, and/or install mirrors as a basic
# set of remote cells for our example root.afs
set -A rc \
$c \
ualberta.ca \
stacken.kth.se \
grand.central.org \
su.se \
mrow.org
i=0
while [ i -lt ${#rc[*]} ]
do
log -c fs mkm /afs/${rc[$i]} root.cell -cell ${rc[$i]} -fast
fs mkm /afs/${rc[$i]} root.cell -cell ${rc[$i]} -fast
let i=i+1
done
log adding replication sites for root.afs, root.cell
retry vos addsite $h /vicepa root.afs
retry vos addsite $h /vicepa root.cell
retry vos addsite $h /vicepa mirror
log initial release of replicated volumes
retry vos release root.afs
retry vos release root.cell
retry vos release mirror
# add files of note to /etc/changelist
addchg() {
while [ "$1" ]
do
f="$1"
shift
if egrep "^${f}$" /etc/changelist > /dev/null 2>&1; then
continue
fi
echo "$f" >> /etc/changelist
done
}
addchg /etc/kerberosV/krb5.conf
addchg "+/etc/kerberosV/krb5.keytab"
addchg /etc/afs/{CellServDB,ThisCell,afsd.conf}
addchg ${SYSCONFDIR}/openafs/{BosConfig,server/{CellServDB,ThisCell,UserList,krb.conf}}
addchg "+${SYSCONFDIR}/openafs/server/KeyFile"
addchg /var/openafs/NetInfo
addchg "+/var/openafs/sysid"
addchg "+/var/openafs/db/bdb.DB0"
addchg "+/var/openafs/db/bdb.DBSYS1"
addchg "+/var/openafs/db/prdb.DB0"
addchg "+/var/openafs/db/prdb.DBSYS1"
addchg "+/var/openafs/db/vldb.DB0"
addchg "+/var/openafs/db/vldb.DBSYS1"
# Pat on the back.
cat <<__EOT
CONGRATULATIONS! Your OpenAFS server setup has been successfully completed,
and is now running.
Please read ${PREFIX}/share/openafs/README.OpenBSD for further details;
be sure to note the startup and shutdown script examples.
__EOT