summaryrefslogtreecommitdiffstats
path: root/raddb/mods-config/realm/freeradius-naptr-to-home-server.sh
diff options
context:
space:
mode:
Diffstat (limited to 'raddb/mods-config/realm/freeradius-naptr-to-home-server.sh')
-rwxr-xr-xraddb/mods-config/realm/freeradius-naptr-to-home-server.sh161
1 files changed, 161 insertions, 0 deletions
diff --git a/raddb/mods-config/realm/freeradius-naptr-to-home-server.sh b/raddb/mods-config/realm/freeradius-naptr-to-home-server.sh
new file mode 100755
index 0000000..66388d3
--- /dev/null
+++ b/raddb/mods-config/realm/freeradius-naptr-to-home-server.sh
@@ -0,0 +1,161 @@
+#!/bin/sh
+
+# This script looks up radsec srv records in DNS for the one realm
+# given as argument, and creates a home_server template based on the
+# information found.
+#
+# It currently ignores weight markers, but does sort servers on
+# priority marker, lowest number first. For host command this is
+# column 5, for dig it is column 1.
+#
+# It then tells FreeRADIUS (via radmin) that
+# there is a new home server.
+#
+# Note that in order for it to work, you need to have the
+# "control-socket" enabled.
+
+usage() {
+ echo "Usage: ${0} [OPTIONS] <realm> <optional NAPTR tag>"
+ echo " -d RADIUS_DIR Set radius directory"
+ echo " -t test (skip running radmin)"
+ exit 1
+}
+
+test -n "${1}" || usage
+
+RADDB=/etc/raddb
+RADMIN=y
+
+#
+# Parse command-line options
+#
+while [ `echo "$1" | cut -c 1` = "-" ]
+do
+ case "$1" in
+ -d)
+ RADDB=$2
+ shift;shift
+ ;;
+ -t)
+ RADMIN=
+ shift
+ ;;
+
+ *)
+ usage
+ ;;
+ esac
+done
+
+test -n "${2}" && NAPTRTAG="${2}" || NAPTRTAG="x-eduroam:radius.tls"
+
+DIGCMD=$(command -v dig)
+HOSTCMD=$(command -v host)
+PRINTCMD=$(command -v printf)
+
+#
+# These validations prevent rogue DNS records from pwning your RADIUS installation.
+#
+# See https://github.com/radsecproxy/radsecproxy/security/advisories/GHSA-56gw-9rj9-55rc
+# and https://www.usenix.org/conference/usenixsecurity21/presentation/jeitner
+#
+# The contents of these validation routines should NOT be changed without a deep understanding
+# of DNS!
+#
+validate_host() {
+ echo ${@} | tr -d '\n\t\r' | grep -E '^[_0-9a-zA-Z][-._0-9a-zA-Z]*$'
+}
+
+validate_port() {
+ echo ${@} | tr -d '\n\t\r' | grep -E '^[0-9]+$'
+}
+
+dig_it_srv() {
+ ${DIGCMD} +short srv $SRV_HOST | sort -n -k1 |
+ while read line; do
+ set $line
+ PORT=$(validate_port $3)
+ HOST=$(validate_host $4)
+ if [ -n "${HOST}" ] && [ -n "${PORT}" ]; then
+ $PRINTCMD "\tipaddr = ${HOST%.}\n\tport = ${PORT}\n"
+ fi
+ done
+}
+
+dig_it_naptr() {
+ ${DIGCMD} +short naptr "${REALM}" | grep $NAPTRTAG | sort -n -k1 |
+ while read line; do
+ set $line
+ TYPE=$3
+ HOST=$(validate_host $6)
+ if ( [ "$TYPE" = "\"s\"" ] || [ "$TYPE" = "\"S\"" ] ) && [ -n "${HOST}" ]; then
+ SRV_HOST=${HOST%.}
+ dig_it_srv
+ fi
+ done
+}
+
+host_it_srv() {
+ ${HOSTCMD} -t srv $SRV_HOST | sort -n -k5 |
+ while read line; do
+ set $line
+ PORT=$(validate_port $7)
+ HOST=$(validate_host $8)
+ if [ -n "${HOST}" ] && [ -n "${PORT}" ]; then
+ $PRINTCMD "\tipaddr ${HOST%.}:${PORT}\n"
+ fi
+ done
+}
+
+host_it_naptr() {
+ ${HOSTCMD} -t naptr "${REALM}" | grep $NAPTRTAG | sort -n -k5 |
+ while read line; do
+ set $line
+ TYPE=$7
+ HOST=$(validate_host ${10})
+ if ( [ "$TYPE" = "\"s\"" ] || [ "$TYPE" = "\"S\"" ] ) && [ -n "${HOST}" ]; then
+ SRV_HOST=${HOST%.}
+ host_it_srv
+ fi
+ done
+}
+
+REALM=$(validate_host ${1})
+if [ -z "${REALM}" ]; then
+ echo "realm \"${1}\" failed validation" >&2
+ usage
+fi
+
+if [ -x "${DIGCMD}" ]; then
+ SERVERS=$(dig_it_naptr)
+
+elif [ -x "${HOSTCMD}" ]; then
+ SERVERS=$(host_it_naptr)
+
+else
+ echo "${0} requires either \"dig\" or \"host\" command." >&2
+ exit 1
+fi
+
+if [ ! -n "${SERVERS}" ]; then
+ echo "No servers found" >&2
+ exit 1
+fi
+
+#
+# Just testing - don't do anything else.
+#
+if [ -z "${RADMIN}" ]; then
+ $PRINTCMD "home_server ${REALM} {\n${SERVERS}\n\t\$INCLUDE tls.conf\n}\n"
+ exit 0
+fi
+
+#
+# Print out the template, and include the site-local tls.conf file.
+#
+$PRINTCMD "home_server ${REALM} {\n${SERVERS}\n\t\$INCLUDE tls.conf\n}\n" > $RADDB/home_servers/$1
+
+#
+# @todo - use ${prefix} or some such thing to find radmin.
+#
+/usr/sbin/radmin -e "add home_server file $RADDB/home_servers/$1"