From 670e521ea0d37e18255d1047cd52ce09ab1d8970 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Thu, 29 Feb 2024 16:29:57 +0100 Subject: [slx-network] Overhaul DHCP trigger, generation of resolv.conf, hosts --- .../slx-network/scripts/udhcpc-trigger.stage3 | 139 +++++++++++---------- 1 file changed, 70 insertions(+), 69 deletions(-) diff --git a/modules.d/slx-network/scripts/udhcpc-trigger.stage3 b/modules.d/slx-network/scripts/udhcpc-trigger.stage3 index 664600a6..fa771868 100755 --- a/modules.d/slx-network/scripts/udhcpc-trigger.stage3 +++ b/modules.d/slx-network/scripts/udhcpc-trigger.stage3 @@ -15,11 +15,15 @@ MAIN_NETIF="$SLX_PXE_NETIF" readonly MAIN_NETIF if [[ "$1" != "bound" && "$1" != "renew" ]] \ - || [ "$interface" != "${MAIN_NETIF}" ] \ - || [ -z "$ip" ]; then + || [ "$interface" != "${MAIN_NETIF}" ] \ + || [ -z "$ip" ]; then exit 0 fi +log() { + echo "${MAIN_NETIF}: $*" +} + ## ## CORE NETWORK CONFIGURATION ## @@ -30,16 +34,16 @@ fi # objey the renew request by the client and hands out a new address if [ -n "$SLX_PXE_CLIENT_IP" ]; then #...some address is already configured... - if [ "x${SLX_PXE_CLIENT_IP}" != "x${ip}" ]; then + if [ "${SLX_PXE_CLIENT_IP}" != "${ip}" ]; then #...it's a different one, reconfigure... - echo "..reconfiguring '${SLX_PXE_CLIENT_IP}' to '${ip}'." + log "reconfiguring from '${SLX_PXE_CLIENT_IP}' to '${ip}'" # remove default route and let it be added again below, as it might get lost when changing the primary address on the interface - ip route del default 2>/dev/null - ip addr del "$SLX_PXE_CLIENT_IP" dev "${interface}" 2>/dev/null + ip route del default + ip addr del "$SLX_PXE_CLIENT_IP" dev "${interface}" fi else #...no address configured yet, just add... - echo "..adding ${ip}.." + log "adding ${ip}" fi if ! ip addr show dev "${interface}" | grep -qF "inet ${ip}/"; then ip addr add "${ip}/$(ipcalc -s -p "${ip}" "${subnet}" | sed s/.*=//)" dev "${interface}" @@ -49,10 +53,10 @@ fi # Same procedure for default gateway if [ -n "$router" ]; then if [ -n "$SLX_PXE_GATEWAY" ] && [ "$SLX_PXE_GATEWAY" != "$router" ]; then - echo "..reconfiguring default gw from '$SLX_PXE_GATEWAY' to '$router'." - ip route del default 2>/dev/null + log "reconfiguring default gw from '$SLX_PXE_GATEWAY' to '$router'" + ip route del default fi - ip route add default via "$router" + ip route add default via "$router" dev "${MAIN_NETIF}" echo "SLX_DHCP_GATEWAY='$router'" >> "$NETWORK_CONF" fi @@ -67,9 +71,9 @@ reverse_lookup() { [ -z "$dns" ] && return [ -z "$1" ] && return timeout 3 nslookup "$1" | awk '{ - if ($2 == "name") { print $4; exit; } + if ($2 == "name") { print gensub("\.$", "", "", $4); exit; } if ($1 == "Name:") { ok = 1 } - if (ok && $1 == "Address") { print $4; exit; } + if (ok && $1 == "Address") { print gensub("\.$", "", "", $4); exit; } }' } @@ -77,34 +81,61 @@ echo "# From DHCP in stage 3.1" >> "$NETWORK_CONF" # DNS/domain? if [ -n "$dns" ]; then - echo "..got DNS.." + log "DNS servers: $dns" echo "SLX_DNS='$dns'" >> "$NETWORK_CONF" + for srv in $dns; do + echo "nameserver $srv" >> "/etc/resolv.conf" + done +else + dns="$( < /etc/resolv.conf awk '$1 == "nameserver" {printf "%s ", $2}' )" fi -for srv in $dns; do - echo "nameserver $srv" >> "/etc/resolv.conf" -done # always check DNS -echo "Checking DNS record for this host..." -[ -z "$fqdn" ] && fqdn="$(reverse_lookup "$ip")" +log "checking reverse DNS record for this host" +[ -n "$fqdn" ] && [[ "$fqdn" != *.* ]] && fqdn= +[ -z "$fqdn" ] && fqdn="$( reverse_lookup "$ip" )" [ -z "$fqdn" ] && [ -n "$hostname" ] && [ -n "$domain" ] && fqdn="${hostname}.${domain}" -# Otherwise, retry DNS one time + +# retry DNS one time if [ -z "$fqdn" ]; then + log "found no way to generate FQDN, trying reverse lookup one more time" sleep 1 - fqdn="$(reverse_lookup "$ip")" + fqdn="$( reverse_lookup "$ip" )" +fi +if [ -n "$fqdn" ]; then + fqdn_hostname="${fqdn%%.*}" + fqdn_domain="${fqdn#*.}" fi -[ -n "$fqdn" ] && fqdn_hostname="${fqdn%%.*}" -if [ -z "$domain" ]; then - echo "Getting domain via DNS, as DHCP didn't supply one.." - domain="${fqdn#*.}" +if [ -z "$hostname" ] && [ -n "$fqdn_hostname" ]; then + hostname="${fqdn_hostname}" + log "using hostname from DNS, as DHCP didn't supply one" +fi +if [ -z "$hostname" ] && [ -n "$SLX_PXE_HOSTNAME" ]; then + hostname="$SLX_PXE_HOSTNAME" + log "using hostname from KCL, as DHCP/DNS didn't supply one" +fi +if [ -z "$hostname" ]; then + hostname="noname-${ip//./-}" + log "got no hostname via DHCP, DNS or KCL, using fallback '$hostname'" +fi +if [ -z "$domain" ] && [ -n "$fqdn_domain" ]; then + domain="${fqdn_domain}" + log "using domain from DNS, as DHCP didn't supply one" fi +domain="${domain%% *}" # in case domain is a list, some DHCP servers did that in the past instead of using search + +# Normalize to lowercase +for var in hostname domain fqdn search fqdn_hostname fqdn_domain SLX_PXE_HOSTNAME; do + declare "$var"="${!var~~}" +done + # Add domain to list of search domains if not in there yet if [ -n "$domain" ] && [ -n "$search" ]; then FOUND=no for sd in $search; do - [ "x$sd" = "x$domain" ] && FOUND=yes + [ "$sd" = "$domain" ] && FOUND=yes done [ "$FOUND" = "no" ] && search="$domain $search" elif [ -n "$domain" ]; then @@ -126,51 +157,21 @@ if [ -n "$ntpsrv" ]; then echo "SLX_DHCP_NTP='$ntpsrv'" >> "$NETWORK_CONF" fi -# Hostname -if [ -n "$hostname" ]; then - if [ -n "$SLX_PXE_HOSTNAME" ] && [ "$hostname" != "$SLX_PXE_HOSTNAME" ]; then - echo "KCL and DHCP hostnames differ... assuming some KCL hack." - echo " -> Prefering KCL: '$SLX_PXE_HOSTNAME'." - hostname="$SLX_PXE_HOSTNAME" - fi - if [ -n "$fqdn_hostname" ] && [ "$hostname" != "$fqdn_hostname" ]; then - echo "DHCP hostname differs from DNS hostname." - echo " -> Prefering DNS: '$fqdn_hostname'." - hostname="$fqdn_hostname" - fi -else - echo "No hostname specified in DHCP, checking DNS record." - # We ignore the corner case where DHCP didn't supply a hostname but - # there is a hardcoded one via KCL as it seems unlikely, log it nonetheless - if [ -n "$SLX_PXE_HOSTNAME" ]; then - echo "DHCP didn't supply a hostname but one was supplied by KCL?" \ - "This seems strange but using KCL hostname anyways." - hostname="$SLX_PXE_HOSTNAME" - else - # regular fallback to DNS and noname-* if needed - if [ -n "$fqdn_hostname" ]; then - echo "Using DNS record hostname: '$fqdn_hostname'." - hostname="$fqdn_hostname" - else - # no fallback hostname from DNS, use IP address - hostname="noname-${ip//./-}" - fqdn="${hostname}.invalid" - fi - if [ -n "$domain" ]; then - fqdn="${hostname}.${domain%% *}" # in case domain is a list - fi - fi -fi +declare -a localnames=() +[ -n "$fqdn" ] && localnames+=( "$fqdn" ) +[ -n "$hostname" ] && localnames+=( "$hostname" ) +[ -n "$fqdn_hostname" ] && [ "$hostname" != "$fqdn_hostname" ] && localnames+=( "$fqdn_hostname" ) +[ -n "$SLX_PXE_HOSTNAME" ] && [ "$hostname" != "$SLX_PXE_HOSTNAME" ] && localnames+=( "$SLX_PXE_HOSTNAME" ) -if [ -n "$hostname" ]; then - [ -z "$fqdn" ] && fqdn="$hostname" - echo "..setting hostname $hostname (fqdn: $fqdn).." - echo "$hostname" > "/proc/sys/kernel/hostname" - echo "$hostname" > "/etc/hostname" - echo "127.0.0.1 localhost" > "/etc/hosts" - echo "$ip $fqdn $hostname" >> "/etc/hosts" - echo "SLX_HOSTNAME='$hostname'" >> "$NETWORK_CONF" -fi +{ +echo "127.0.0.1 localhost" +echo "127.0.1.1 ${localnames[*]}" +} > "/etc/hosts" + +log "setting hostname $hostname, FQDN $fqdn" +echo "$hostname" > "/proc/sys/kernel/hostname" +echo "$hostname" > "/etc/hostname" +echo "SLX_HOSTNAME='$hostname'" >> "$NETWORK_CONF" touch /.network set +x -- cgit v1.2.3-55-g7522