#!/bin/bash # SPDX-Version: 3.0 # SPDX-CreationInfo: 2025-02-13; WEIDNER, Marc S.; # SPDX-ExternalRef: GIT https://cendev.eu/marc.weidner/CISS.2025.debian.installer.git # SPDX-FileContributor: WEIDNER, Marc S.; Centurion Intelligence Consulting Agency # SPDX-FileCopyrightText: 2024-2025; WEIDNER, Marc S.; # SPDX-FileType: SOURCE # SPDX-License-Identifier: EUPL-1.2 OR LicenseRef-CCLA-1.0 # SPDX-LicenseComment: This file is part of the CISS.2025.hardened.installer framework. # SPDX-PackageName: CISS.2025.hardened.installer # SPDX-Security-Contact: security@coresecret.eu ########################################################################################### # 3.7.8. Functions - installation - setup network # ########################################################################################### # TODO collect Gateway and convert CCDIR ot n.n.n.n ########################################################################################### # Setup network # Globals: # FINAL_FQDN # FINAL_IPV4_ADDRESS # FINAL_IPV6 # FINAL_IPV6_ADDRESS # LOG_NIC # MODULE_ERR # MODULE_TXT # TARGET # network_autoconfig_enable # network_choose_interface_auto # network_choose_interface_static # network_ipv6 # network_static_hostname # network_static_ipv4address # network_static_ipv4gateway # network_static_ipv4nameserver_0 # network_static_ipv4nameserver_1 # network_static_ipv4nameserver_fallback_0 # network_static_ipv4netmask # network_static_ipv6address # network_static_ipv6gateway # network_static_ipv6nameserver_0 # network_static_ipv6nameserver_1 # network_static_ipv6nameserver_fallback_0 # network_static_ipv6netmask # network_timeout_dhcp # Arguments: # None ########################################################################################### 3_7_8_functions_installation_setup_network() { declare -g -x MODULE_ERR="3_7_8_functions_installation_setup_network" declare -g -x MODULE_TXT="Setup network" do_show_header "${MODULE_TXT}" # Initialize variables declare ADDR_GI="" declare ADDR_SI="" declare ADDR_YI="" declare DHCP_SRV="" declare FQDN="" declare HAS_NIC="" declare HAS_IPV4="" declare HAS_IPV6="" declare HAS_IPV4_CCIDR="" declare HAS_IPV6_CCIDR="" declare HAS_LINKIPV4="" declare HAS_LINKIPV6="" declare NIC="" # Check current network connection and configure variables HAS_NIC=$(ip -o link show | awk -F': ' '/state UP/ {print $2; exit}') HAS_IPV4_CCIDR=$(ip -4 -o addr show "${HAS_NIC}" | awk '{print $4; exit}') HAS_IPV4_SUBNET=$(do_generate_subnet "${HAS_IPV4_CCIDR}") HAS_IPV4=$(echo "$HAS_IPV4_CCIDR" | awk -F'/' '{print $1}') HAS_IPV4_GATEWAY=$(ip route show default dev "${HAS_NIC}" | awk '/^default/ {print $3; exit}') HAS_IPV6_CCIDR=$(ip -6 -o addr show "${HAS_NIC}" | awk '/scope global/ {print $4; exit}') if [[ -n ${HAS_IPV6_CCIDR} ]]; then HAS_IPV6=$(echo "${HAS_IPV6_CCIDR}" | awk -F'/' '{print $1}') fi HAS_LINKIPV4=$(ping -q -c 1 -W 1 -4 debian.org > /dev/null 2>&1 && echo "true" || echo "false") HAS_LINKIPV6=$(ping -q -c 1 -W 1 -6 debian.org > /dev/null 2>&1 && echo "true" || echo "false") do_log "info" "false" "Live environment DHCP information collection: timeout='${network_timeout_dhcp}' seconds." dhclient -v -1 "${HAS_NIC}" 2>&1 | timeout "${network_timeout_dhcp}" dhcpdump -i "${HAS_NIC}" >> "${LOG_NIC}" || true awk 'BEGIN {RS="---------------------------------------------------------------------------"; \ ORS="---------------------------------------------------------------------------"} \ NF {last=$0} END {print last}' "${LOG_NIC}" > "${LOG_NIC}".tmp && mv "${LOG_NIC}".tmp "${LOG_NIC}" do_log "info" "false" "Live environment DHCP information collection: collection completed." # Extract 'FQDN' from '${LOG_NIC}' FQDN=$(awk -F 'Host name' '/Host name/ {print $2}' "${LOG_NIC}" | xargs) # Extract 'YIADDR' (Your IP Address) from '${LOG_NIC}' ADDR_YI=$(awk -F 'YIADDR:' '/YIADDR/ {print $2}' "${LOG_NIC}" | awk '{print $1}' | xargs) # Extract 'SIADDR' (Server IP Address) from '${LOG_NIC}' ADDR_SI=$(awk -F 'SIADDR:' '/SIADDR/ {print $2}' "${LOG_NIC}" | awk '{print $1}' | xargs) # Extract 'Server Identifier' from '${LOG_NIC}' DHCP_SRV=$(awk -F 'Server identifier' '/Server identifier/ {print $2}' "${LOG_NIC}" | xargs) # Extract 'GIADDR' (Gateway IP Address) from '${LOG_NIC}' ADDR_GI=$(awk -F 'GIADDR:' '/GIADDR/ {print $2}' "${LOG_NIC}" | awk '{print $1}' | xargs) do_log "info" "false" "Live environment network check: HAS_NIC='${HAS_NIC}'." do_log "info" "false" "Live environment network check: HAS_IPV4_CCIDR='${HAS_IPV4_CCIDR}'." do_log "info" "false" "Live environment network check: HAS_IPV4_SUBNET='${HAS_IPV4_SUBNET}'." do_log "info" "false" "Live environment network check: HAS_IPV4_GATEWAY='${HAS_IPV4_GATEWAY}'." do_log "info" "false" "Live environment network check: HAS_IPV6_CCIDR='${HAS_IPV6_CCIDR}'." do_log "info" "false" "Live environment network check: HAS_LINKIPV4='${HAS_LINKIPV4}'." do_log "info" "false" "Live environment network check: HAS_LINKIPV6='${HAS_LINKIPV6}'." do_log "info" "false" "Live environment network check: FQDN='${FQDN}'." do_log "info" "false" "Live environment network check: ADDR_YI='${ADDR_YI}'." do_log "info" "false" "Live environment network check: ADDR_SI='${ADDR_SI}'." do_log "info" "false" "Live environment network check: DHCP_SRV='${DHCP_SRV}'." do_log "info" "false" "Live environment network check: ADDR_GI='${ADDR_GI}'." # Create network configuration file header. if [[ -f "${TARGET}"/etc/network/interfaces ]]; then rm "${TARGET}"/etc/network/interfaces do_log "info" "false" "Existing '${TARGET}/etc/network/interfaces' removed." fi touch "${TARGET}"/etc/network/interfaces chmod 0644 "${TARGET}"/etc/network/interfaces cat << EOF >> "${TARGET}"/etc/network/interfaces # This file describes the network interfaces available on your system # and how to activate them. For more information, see interfaces(5). source /etc/network/interfaces.d/* # The loopback network interface auto lo iface lo inet loopback EOF do_log "info" "false" "Header '${TARGET}/etc/network/interfaces' created." # Configure network interfaces based on 'preseed.yaml' and create network configuration files for IPv4. if [[ ${network_autoconfig_enable,,} == "true" && ${network_choose_interface_auto,,} == "true" ]]; then declare IFACE for IFACE in $(ls /sys/class/net || true); do if [[ -d "/sys/class/net/${IFACE}/device" ]]; then NIC="${IFACE}" break fi done if [[ -z ${NIC} ]]; then NIC="${network_choose_interface_static}" do_log "notice" "false" "No physical NIC detected automatically. Use the specified static NIC instead: '${network_choose_interface_static}'." else do_log "info" "false" "The first physical auto-detected NIC is: '${NIC}'." fi ### Reminder ### # auto: # For servers or systems with static interfaces that should always be available (e.g., eth0 on a server). # For configurations where the interface should be active regardless of the cable status. # allow-hotplug: # For systems with dynamic or removable network devices (e.g., laptops or USB adapters). # To avoid boot delays when interfaces are unavailable. cat << EOF >> "${TARGET}"/etc/network/interfaces # The primary network interface IPv4 auto "${NIC}" iface "${NIC}" inet dhcp EOF do_log "info" "false" "IPv4 on the primary NIC: '${NIC}' configured with DHCP." elif [[ ${network_autoconfig_enable,,} == "true" && ${network_choose_interface_auto,,} == "false" ]]; then NIC="${network_choose_interface_static}" cat << EOF >> "${TARGET}"/etc/network/interfaces # The primary network interface IPv4 auto "${NIC}" iface "${NIC}" inet dhcp EOF do_log "info" "false" "IPv4 on the primary NIC: '${NIC}' configured with DHCP." else do_log "warning" "false" "No NIC specified. 'network_choose_interface_static' was: '${network_choose_interface_static}'." fi if [[ ${network_autoconfig_enable,,} == "false" ]]; then cat << EOF >> "${TARGET}"/etc/network/interfaces # The primary network interface IPv4 auto "${network_choose_interface_static}" iface "${network_choose_interface_static}" inet static address "${network_static_ipv4address}" netmask "${network_static_ipv4netmask}" gateway "${network_static_ipv4gateway}" dns-nameservers "${network_static_ipv4nameserver_0}" "${network_static_ipv4nameserver_1}" "${network_static_ipv4nameserver_fallback_0}" EOF do_log "info" "false" "IPv4 on the primary NIC: '${network_choose_interface_static}' configured manually." else do_log "error" "false" "Network autoconfiguration 'network_autoconfig_enable' must be either 'true' or 'false'." fi # Configure network interfaces based on 'preseed.yaml' and create network configuration files for IPv6. if [[ ${network_autoconfig_enable} == "true" && ${HAS_LINKIPV6} == "true" ]]; then cat << EOF >> "${TARGET}"/etc/network/interfaces # The primary network interface IPv6 iface "${HAS_NIC}" inet6 dhcp EOF do_log "info" "false" "IPv6 on the primary NIC: '${HAS_NIC}' configured with DHCP." fi if [[ ${network_autoconfig_enable,,} == "false" && ${network_ipv6,,} == "true" ]]; then cat << EOF >> "${TARGET}"/etc/network/interfaces # The primary network interface IPv6 iface "${HAS_NIC}" inet6 static address "${network_static_ipv6address}"/"${network_static_ipv6netmask}" gateway "${network_static_ipv6gateway}" dns-nameservers "${network_static_ipv6nameserver_0}" "${network_static_ipv6nameserver_1}" "${network_static_ipv6nameserver_fallback_0}" EOF do_log "info" "false" "IPv6 on the primary NIC: '${HAS_NIC}' configured manually." fi # Until now, neither 'NetworkManager' nor 'systemd-resolved' are installed. # Therefore, '/etc/resolv.conf' is updated, too. # Create '/etc/resolv.conf' IPv4 entries. if [[ -f "${TARGET}"/etc/resolv.conf ]]; then rm "${TARGET}"/etc/resolv.conf do_log "info" "false" "Existing '${TARGET}/etc/resolv.conf' removed." fi touch "${TARGET}"/etc/resolv.conf chmod 0644 "${TARGET}"/etc/resolv.conf cat << EOF >> "${TARGET}"/etc/resolv.conf # Custom DNS IPv4 configuration for DHCP nameserver ${network_static_ipv4nameserver_0} nameserver ${network_static_ipv4nameserver_1} nameserver ${network_static_ipv4nameserver_fallback_0} EOF do_log "info" "false" "IPv4 nameserver at: '${TARGET}/etc/resolv.conf' configured manually." # Create '/etc/resolv.conf' IPv6 entries. if [[ ${network_autoconfig_enable,,} == "true" && ${HAS_LINKIPV6,,} == "true" ]]; then cat << EOF >> "${TARGET}"/etc/resolv.conf # Custom DNS IPv6 configuration for DHCP nameserver ${network_static_ipv6nameserver_0} nameserver ${network_static_ipv6nameserver_1} nameserver ${network_static_ipv6nameserver_fallback_0} EOF do_log "info" "false" "IPv6 nameserver at: '${TARGET}/etc/resolv.conf' configured manually." elif [[ ${network_autoconfig_enable,,} == "false" && ${network_ipv6,,} == "true" ]]; then cat << EOF >> "${TARGET}"/etc/resolv.conf # Custom DNS IPv6 configuration for DHCP nameserver ${network_static_ipv6nameserver_0} nameserver ${network_static_ipv6nameserver_1} nameserver ${network_static_ipv6nameserver_fallback_0} EOF do_log "info" "false" "IPv6 nameserver at: '${TARGET}/etc/resolv.conf' configured manually." fi # Ensure Internet Systems Consortium DHCP Client is not overwriting the static nameserver settings. if [[ ${network_autoconfig_enable,,} == "true" && ${HAS_LINKIPV6,,} == "true" ]]; then cat << EOF > "${TARGET}"/etc/dhcp/dhclient.conf # Custom DNS IPv4 and IPv6 configuration for DHCP supersede domain-name-servers \ ${network_static_ipv4nameserver_0}, \ ${network_static_ipv4nameserver_1}, \ ${network_static_ipv4nameserver_fallback_0}, \ ${network_static_ipv6nameserver_0}, \ ${network_static_ipv6nameserver_1}, \ ${network_static_ipv6nameserver_fallback_0}; EOF do_log "info" "false" "DHCP client configuration for IPv4 and IPv6 at: '${TARGET}/etc/dhcp/dhclient.conf' configured." elif [[ ${network_autoconfig_enable,,} == "false" && ${network_ipv6,,} == "true" ]]; then cat << EOF > "${TARGET}"/etc/dhcp/dhclient.conf # Custom DNS IPv4 and IPv6 configuration for DHCP supersede domain-name-servers \ ${network_static_ipv4nameserver_0}, \ ${network_static_ipv4nameserver_1}, \ ${network_static_ipv4nameserver_fallback_0}, \ ${network_static_ipv6nameserver_0}, \ ${network_static_ipv6nameserver_1}, \ ${network_static_ipv6nameserver_fallback_0}; EOF do_log "info" "false" "DHCP client configuration IPv4 and IPv6 at: '${TARGET}/etc/dhcp/dhclient.conf' configured." else cat << EOF > "${TARGET}"/etc/dhcp/dhclient.conf # Custom DNS IPv4 only configuration for DHCP supersede domain-name-servers \ ${network_static_ipv4nameserver_0}, \ ${network_static_ipv4nameserver_1}, \ ${network_static_ipv4nameserver_fallback_0}; EOF do_log "info" "false" "DHCP client configuration IPv4 only at: '${TARGET}/etc/dhcp/dhclient.conf' configured." fi # Export hostname and IPv4 and IPv6 addresses for further processing according to dynamic results and preseed.yaml settings. if [[ ${network_autoconfig_enable,,} == "true" ]]; then declare -g -r -x FINAL_FQDN="${FQDN}" declare -g -r -x FINAL_IPV4_ADDRESS="${ADDR_YI}" elif [[ ${network_autoconfig_enable,,} == "false" ]]; then declare -g -r -x FINAL_FQDN="${network_static_hostname}" declare -g -r -x FINAL_IPV4_ADDRESS="${network_static_ipv4address}" fi if [[ ${network_autoconfig_enable,,} == "true" && ${HAS_LINKIPV6,,} == "true" ]]; then declare -g -r -x FINAL_IPV6_ADDRESS="${HAS_IPV6}" declare -g -r -x FINAL_IPV6="${HAS_LINKIPV6}" elif [[ ${network_autoconfig_enable,,} == "false" && ${network_ipv6,,} == "true" ]]; then declare -g -r -x FINAL_IPV6_ADDRESS="${network_static_ipv6address}" fi do_show_footer "${MODULE_TXT}" } # vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh: