resources/functions
author Dan Fuhry <dan@fuhry.us>
Tue, 08 Jan 2013 23:21:25 -0500
changeset 2 700d61d93b1b
parent 0 3906ca745819
child 3 a044870a9d3d
permissions -rw-r--r--
Fix accidentally hardcoded ldap basedn

# :mode=shellscript:

krb5_packages="krb5-admin-server krb5-kdc"
ldap_packages="slapd ldap-utils"
sasl_packages="sasl2-bin libsasl2-modules-gssapi-mit"
radius_packages="freeradius freeradius-ldap freeradius-common"
http_packages="apache2.2-bin libapache2-mod-php5 libapache2-webauth libapache2-webkdc webauth-weblogin php-pear"

patch_hosts_file()
{
	sed -re '/^127\.0\.1\.1\s+/d' -i /etc/hosts
	#sed -re '/^10\.0\.2\.2\s+/d' -i /etc/hosts
	echo -e "127.0.1.1\tssoinabox.${domain}\tssoinabox" >> /etc/hosts
	#echo -e "10.0.2.2\tsso-clients.${domain}\tssoinabox" >> /etc/hosts
	
	echo -n "ssoinabox.$domain" > /etc/hostname
	hostname `cat /etc/hostname`
}

generate_krb5_config()
{
	cat <<EOF > /etc/krb5.conf
[libdefaults]
	default_realm = $krb5_realm
	dns_lookup_realm = false
	dns_lookup_kdc = false
	ticket_lifetime = 24h
	forwardable = yes

[realms]
	$krb5_realm = {
		kdc = ssoinabox.$domain:88
		admin_server = ssoinabox.$domain:749
		kcrap = ssoinabox.$domain:1999
	}

[domain_realm]
	$domain = $krb5_realm
	.$domain = $krb5_realm

[login]
	krb4_convert = true
	krb4_get_tickets = false

	
EOF
}

generate_slapd_config()
{
	cat <<EOF > /etc/ldap/slapd.conf
# vim: set ft=conf
include         /etc/ldap/schema/core.schema
include         /etc/ldap/schema/cosine.schema
include         /etc/ldap/schema/inetorgperson.schema
include         /etc/ldap/schema/nis.schema

pidfile		/var/run/slapd/slapd.pid	
argsfile	/var/run/slapd/slapd.args

# for replication
moduleload back_bdb.la
moduleload syncprov

disallow bind_anon

database	bdb
suffix		"$ldap_suffix"

authz-policy	from
authz-regexp	"^uid=([^,/]+)(,cn=${domain//\./\\.})?,cn=gssapi,cn=auth"    "cn=\$1,ou=People,$ldap_suffix"

rootdn		"cn=Manager,$ldap_suffix"
rootpw		${ldap_manager_pw_hash}

directory	/var/lib/ldap

index		objectClass	eq

sasl-realm	${krb5_realm}
sasl-host	ssoinabox.${domain}
sasl-secprops	noplain,noactive,noanonymous

#TLSCACertificateFile	/etc/ssl/certs/fixme.crt
#TLSCertificateFile		/etc/ssl/certs/fixme.crt
#TLSCertificateKeyFile	/etc/ssl/private/fixme.key

overlay		syncprov
syncprov-checkpoint	100	10
syncprov-sessionlog	100

##
# ACLs

access to dn="cn=ldap-reader,ou=Roles,$ldap_suffix"
	by anonymous auth

access to attrs=userPassword
	by self =xw
	by anonymous auth
	by * none

access to *
	by self write
	by dn="cn=ldap-reader,ou=Roles,$ldap_suffix" read
	by dn="cn=freeradius,ou=Roles,$ldap_suffix" read
	by dn="cn=replicator,ou=Roles,$ldap_suffix" read

# Lock down attributes a user shouldn't change
access to attrs="loginShell,homeDirectory,uidNumber,gidNumber,uid,cn"
	by self read
	by dn="cn=replicator,ou=Roles,$ldap_suffix" read
	by dn="cn=ldap-reader,ou=Roles,$ldap_suffix" read

access to *
	by anonymous auth
	by users read

EOF
}

generate_base_ldif()
{
	domainbit=`echo $domain | cut -d. -f1`
	gn="`echo $fullname | awk '{print \$1;}'`"
	sn="`echo $fullname | awk '{print \$2;}'`"
	cat <<EOF
dn: $ldap_suffix
objectClass: dcObject
objectClass: organization
o: $domain
dc: $domainbit

dn: cn=Manager,$ldap_suffix
cn: Manager
objectClass: top
objectClass: organizationalRole
description: LDAP admin entry with root level access to the server

dn: ou=People,$ldap_suffix
ou: People
objectClass: top
objectClass: organizationalUnit
description: User accounts representing people

dn: uid=$username,ou=People,$ldap_suffix
uid: $username
objectClass: top
objectClass: person
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: posixAccount
cn: $fullname
givenName: $gn
sn: $sn
loginShell: /bin/bash
homeDirectory: /home/users/$username
uidNumber: 501
gidNumber: 500
userPassword: {SASL}$username@$krb5_realm

dn: ou=Groups,$ldap_suffix
ou: Groups
objectClass: top
objectClass: organizationalUnit
description: POSIX user account groups

dn: cn=users,ou=Groups,$ldap_suffix
cn: users
objectClass: top
objectClass: posixGroup
description: Default POSIX group for users
gidNumber: 500

dn: cn=rtp,ou=Groups,$ldap_suffix
cn: rtp
objectClass: top
objectClass: posixGroup
description: POSIX group for people with root access to servers
gidNumber: 501
memberUid: $username

dn: ou=Roles,$ldap_suffix
ou: Roles
objectClass: top
objectClass: organizationalUnit
description: User accounts representing bots or other administrative functions

dn: cn=ldap-reader,ou=Roles,$ldap_suffix
cn: ldap-reader
objectClass: top
objectClass: organizationalRole
objectClass: simpleSecurityObject
description: Low-security account used for read-only LDAP access by NSS clients
userPassword: $ldap_reader_pw


EOF
}

configure_saslauthd()
{
	sed -re	's/^START=no$/START=yes/' \
		-e	's/^MECHANISMS=".+"$/MECHANISMS="kerberos5"/' \
		-i	/etc/default/saslauthd
}

generate_password()
{
	local length="${1:-64}"
	dd if=/dev/urandom bs=2048 count=1 2>/dev/null | tr -dc 'A-Za-z0-9' | cut -c 1-$length
}

build_kcrap()
{
	oldcwd="`pwd`"
	tempdir=`mktemp -d /tmp/kcrapXXXXXX`
	cd "$tempdir"
	wget https://aur.archlinux.org/packages/kc/kcrap/kcrap.tar.gz
	tar xzvf kcrap.tar.gz
	cd kcrap
	mkdir pkg src
	export srcdir="$PWD/src"
	export pkgdir="$PWD/pkg"
	. PKGBUILD
	wget "${source[0]}"
	for f in ${source[@]}; do
		f=`basename $f`
		ln -sf ../$f src/$f
	done
	cd "${srcdir}"
	for f in *.tar.bz2; do
		tar xjf $f
	done
	patch -p0 -i "$oldcwd/patches/kcrap-0.2.3-ntlm-extra.patch.patch"
	cd kcrap-0.2.3
	patch -p1 -i "$oldcwd/patches/kcrapclient.patch"
	cd ..
	build
	make install
	cp -v "test/kcrapclient" "/usr/local/bin/"
	cd "$oldcwd" && rm -rf "$tempdir"
	
	echo "/usr/local/lib" > /etc/ld.so.conf.d/usrlocal.conf
	ldconfig
}

configure_kcrap()
{
	cat <<EOF > /etc/kcrap_server.conf
[kcrap_server]
	port = 1999
	realm = $krb5_realm

[realms]
	$krb5_realm = {
		database_name = /var/lib/krb5kdc/principal
		key_stash_file = /etc/krb5kdc/stash
	}

EOF
}

configure_freerad()
{
	# mschap module needs to use our ntlm_auth program for auth requests
	sed -re 's/^#?(\s*)ntlm_auth = ".+"$/\1ntlm_auth = "\/usr\/local\/bin\/kcrapclient %{%{Stripped-User-Name}:-%{%{User-Name}:-None}} %{%{mschap:Challenge}:-00} %{%{mschap:NT-Response}:-00}"/' \
		-i /etc/freeradius/modules/mschap
	
	# configure ldap module with our settings
	sed -re	's/^(\s*)#?server = ".+"$/\1server = "ssoinabox.'$domain'"/' \
		-e	's/^(\s*)#?identity = ".+"$/\1identity = "cn=ldap-reader,ou=Roles,'$ldap_suffix'"/' \
		-e	's/^(\s*)#?password = .+$/\1password = "'$ldap_reader_pw'"/' \
		-e	's/^(\s*)#?basedn = ".+"$/\1basedn = "'$ldap_suffix'"/' \
		-i /etc/freeradius/modules/ldap
		
	# enable ldap for authorization and authentication
	for site in default inner-tunnel; do
		sed -rf `dirname $0`/resources/freerad-site-patcher.sed \
			-i /etc/freeradius/sites-available/$site
	done
	
	# give freerad access to the kerberos keytab
	setfacl -m u:freerad:r /etc/krb5.keytab
}

test_freerad()
{
	build_eapol_test > /dev/null
	set +e
	echo -n "Testing RADIUS auth via EAP/TTLS/PAP..."
	conf=`mktemp /tmp/frXXXXXX`
	cat <<EOF > $conf
network={
        ssid="example"
        key_mgmt=WPA-EAP
        eap=TTLS
        anonymous_identity="$username"
        identity="$username"
        password="$password"
        phase2="auth=PAP"
}

EOF
	if /usr/local/bin/eapol_test -s testing123 -c "$conf" 2>&1 > /dev/null; then
		echo "GOOD"
	else
		echo "BAD"
	fi
	echo -n "Testing RADIUS auth via PEAP/MSCHAPv2..."
	cat <<EOF > $conf
network={
        ssid="example"
        key_mgmt=WPA-EAP
        eap=PEAP
        anonymous_identity="$username"
        identity="$username"
        password="$password"
        phase2="autheap=MSCHAPv2"
}

EOF
	if /usr/local/bin/eapol_test -s testing123 -c "$conf" 2>&1 > /dev/null; then
		echo "GOOD"
	else
		echo "BAD"
	fi
	rm -f $conf
	set -e
}

generate_web_yaml()
{
	test -d /usr/local/etc/ssoinabox || mkdir -p /usr/local/etc/ssoinabox
	cat <<EOF > /usr/local/etc/ssoinabox/webcreds.yml
LDAP_BASEDN: $ldap_suffix

UID_MIN: 501
GID_MIN: 500

ldap_server: ldap://localhost:389/
ldap_manager:
  dn: cn=Manager,$ldap_suffix
  password: $ldap_manager_pw

ldap_user_basedn: ou=People,$ldap_suffix
ldap_group_basedn: ou=Groups,$ldap_suffix

kerberos_admin:
  principal: webkerb/admin
  password: $webkerb_pw

PHONE_EXT_MIN: 500

EOF
	
	chown root:www-data /usr/local/etc/ssoinabox/webcreds.yml
	chmod 640 /usr/local/etc/ssoinabox/webcreds.yml
}

configure_webkdc()
{
	cat <<EOF > /etc/webkdc/webkdc.conf
our \$KEYRING_PATH = '/var/lib/webkdc/keyring';
our \$TEMPLATE_PATH = '/usr/local/share/weblogin/ssoinabox/templates';
our \$TEMPLATE_COMPILE_PATH = '/var/cache/weblogin';
our \$URL = 'http://ssoinabox/webkdc-service';
our \$BYPASS_CONFIRM = 1;

EOF

	cat <<EOF > /etc/webkdc/token.acl
krb5:webauth/*@$krb5_realm id

EOF
	
	test -f /etc/webkdc/keytab && rm -f /etc/webkdc/keytab
	kadmin.local -q "ank -randkey service/webkdc"
	kadmin.local -q "ktadd -norandkey -k /etc/webkdc/keytab service/webkdc"
	
	chown root:www-data /etc/webkdc/keytab
	chmod 640 /etc/webkdc/keytab
}

configure_webauth()
{
	cat <<EOF > /etc/apache2/conf.d/webauth
WebAuthWebKdcPrincipal			service/webkdc
WebAuthLoginURL					"http://ssoinabox.$domain/login"
WebAuthWebKdcURL				"http://ssoinabox.$domain/webkdc-service"
WebAuthSSLRedirect				off
WebAuthRequireSSL				off
WebAuthDebug					on

EOF
	
	test -f /etc/webauth/keytab && rm -f /etc/webauth/keytab
	kadmin.local -q "ank -randkey webauth/ssoinabox.$domain"
	kadmin.local -q "ktadd -norandkey -k /etc/webauth/keytab webauth/ssoinabox.$domain"
	
	chown root:www-data /etc/webauth/keytab
	chmod 640 /etc/webauth/keytab
	
	# doesn't exist by default...?
	# chown www-data:www-data /var/lib/webauth/keyring
}

configure_apache2()
{
	cp `dirname $0`/resources/apache2-site.conf /etc/apache2/sites-available/ssoinabox
	sed -re "s/^(\s*)ServerName .+$/\1ServerName ssoinabox.$domain/" -i /etc/apache2/sites-available/ssoinabox
	
	a2ensite ssoinabox
	a2dissite default
}

build_kadm5()
{
	test -d tarballs || mkdir tarballs
	test -f tarballs/kadm5.tar.gz || wget -O tarballs/kadm5.tar.gz http://pecl.php.net/get/kadm5
	oldcwd="`pwd`"
	tempdir=`mktemp -d /tmp/kadm5XXXXXX`
	cd $tempdir
	
	tar xzf "$oldcwd/tarballs/kadm5.tar.gz"
	cd kadm5-*
	patch -p1 -i "$oldcwd/patches/kadm5.patch"
	phpize
	./configure
	make
	make install
	
	cd "$oldcwd" && rm -rf "$tempdir"
	echo "extension=kadm5.so" > /etc/php5/conf.d/kadm5.ini
}

build_eapol_test()
{
	test -x /usr/local/bin/eapol_test && return 0
	
	test -d tarballs || mkdir tarballs
	test -f tarballs/wpa_supplicant-1.1.tar.gz || wget -O tarballs/wpa_supplicant-1.1.tar.gz "http://hostap.epitest.fi/releases/wpa_supplicant-1.1.tar.gz"
	
	oldcwd="`pwd`"
	tempdir=`mktemp -d /tmp/wpasXXXXXX`
	cd $tempdir
	
	tar xzf "$oldcwd/tarballs/wpa_supplicant-1.1.tar.gz"
	cd wpa_supplicant-1.1/wpa_supplicant
	cp defconfig .config
	sed -re 's/^#?CONFIG_EAPOL_TEST=.+$/CONFIG_EAPOL_TEST=y/' -i .config
	make eapol_test
	cp -v eapol_test /usr/local/bin/
	
	cd "$oldcwd" && rm -rf "$tempdir"
}