diff --git a/configure b/configure index 970e5b3..8a9607c 100755 --- a/configure +++ b/configure @@ -391,6 +391,13 @@ function load_default_config() { LOCALES="C.UTF-8 UTF-8" LOCALE="C.utf8" + SYSTEMD_NETWORKD=true + SYSTEMD_NETWORKD_INTERFACE_NAME="en*" + SYSTEMD_NETWORKD_DHCP=true + SYSTEMD_NETWORKD_ADDRESSES=("192.168.1.100" "fd00::1") + SYSTEMD_NETWORKD_GATEWAY="192.168.1.1" + SYSTEMD_INITRAMFS_SSHD=false + function disk_configuration() { #create_zfs_centric_layout swap=8GiB type="$DEFAULT_BOOT_TYPE" encrypt=true compress=zstd pool_type=standard /dev/sdX create_classic_single_disk_layout swap=8GiB type="$DEFAULT_BOOT_TYPE" luks=true root_fs=ext4 /dev/sdX @@ -409,7 +416,7 @@ function load_default_config() { SELECT_MIRRORS_LARGE_FILE=false ADDITIONAL_PACKAGES=() - INSTALL_SSHD=true + ENABLE_SSHD=true ROOT_SSH_AUTHORIZED_KEYS="" # All settings are unsaved. @@ -467,6 +474,12 @@ function on_off_label() { on_off_str "$1" "${prefix}[*]" "${prefix}[ ]" } +function on_off_label_inverted() { + local var=$1 + shift + on_off_label "$(is_on "$var" && echo false || echo true)" "$@" +} + function is_on() { [[ "$1" == true ]] } @@ -843,6 +856,12 @@ MENU_ITEMS=( "KEYMAP_INITRAMFS" "LOCALES" "LOCALE" + "SYSTEMD_NETWORKD" + "SYSTEMD_INITRAMFS_SSHD" + "SYSTEMD_NETWORKD_INTERFACE_NAME" + "SYSTEMD_NETWORKD_DHCP" + "SYSTEMD_NETWORKD_ADDRESSES" + "SYSTEMD_NETWORKD_GATEWAY" "--------" "STAGE3_VARIANT" "PORTAGE_SYNC_TYPE" @@ -854,7 +873,7 @@ MENU_ITEMS=( "SELECT_MIRRORS" "SELECT_MIRRORS_LARGE_FILE" "--------" - "INSTALL_SSHD" + "ENABLE_SSHD" "ROOT_SSH_AUTHORIZED_KEYS" "ADDITIONAL_PACKAGES" ) @@ -1274,6 +1293,73 @@ function LOCALE_menu() { fi } +function SYSTEMD_NETWORKD_tag() { echo "Configure network"; } +function SYSTEMD_NETWORKD_label() { on_off_label "$SYSTEMD_NETWORKD"; } +function SYSTEMD_NETWORKD_show() { [[ $STAGE3_VARIANT == *systemd* ]]; } +function SYSTEMD_NETWORKD_help() { echo "Enable systemd-network to configure networking on the new system."; } +function SYSTEMD_NETWORKD_menu() { + on_off_toggle "SYSTEMD_NETWORKD" + UNSAVED_CHANGES=true +} + +function SYSTEMD_INITRAMFS_SSHD_tag() { echo " ├ Enable sshd in initramfs"; } +function SYSTEMD_INITRAMFS_SSHD_label() { on_off_label "$SYSTEMD_INITRAMFS_SSHD" " ├ "; } +function SYSTEMD_INITRAMFS_SSHD_show() { [[ $STAGE3_VARIANT == *systemd* ]] && is_on "$SYSTEMD_NETWORKD"; } +function SYSTEMD_INITRAMFS_SSHD_help() { echo "Install and enable sshd in the initramfs. This can be used to unlock encrypted partitions / ZFS via ssh, or to get an emergency shell. Visit https://github.com/gsauthof/dracut-sshd for more information."; } +function SYSTEMD_INITRAMFS_SSHD_menu() { + on_off_toggle "SYSTEMD_INITRAMFS_SSHD" + UNSAVED_CHANGES=true +} + +function SYSTEMD_NETWORKD_INTERFACE_NAME_tag() { echo " ├ Interface Name"; } +function SYSTEMD_NETWORKD_INTERFACE_NAME_label() { echo " ├ ($(ellipsis 20 "$SYSTEMD_NETWORKD_INTERFACE_NAME"))"; } +function SYSTEMD_NETWORKD_INTERFACE_NAME_show() { [[ $STAGE3_VARIANT == *systemd* ]] && is_on "$SYSTEMD_NETWORKD"; } +function SYSTEMD_NETWORKD_INTERFACE_NAME_help() { echo "The network interface(s) to configure. Defaults to all interfaces matching en*."; } +function SYSTEMD_NETWORKD_INTERFACE_NAME_menu() { + dialog \ + --title "Network Interface Name" \ + --inputbox "Enter the network interface name which should be configured. Can include wildcards." \ + "${INPUTBOX_SIZE[@]}" "$SYSTEMD_NETWORKD_INTERFACE_NAME" + SYSTEMD_NETWORKD_INTERFACE_NAME="$dialog_out" + UNSAVED_CHANGES=true +} + +function SYSTEMD_NETWORKD_DHCP_tag() { echo " └ Static IP"; } +function SYSTEMD_NETWORKD_DHCP_label() { on_off_label_inverted "$SYSTEMD_NETWORKD_DHCP" " └ "; } +function SYSTEMD_NETWORKD_DHCP_show() { [[ $STAGE3_VARIANT == *systemd* ]] && is_on "$SYSTEMD_NETWORKD"; } +function SYSTEMD_NETWORKD_DHCP_help() { echo "Use DHCP to obtain network configuration."; } +function SYSTEMD_NETWORKD_DHCP_menu() { + on_off_toggle "SYSTEMD_NETWORKD_DHCP" + UNSAVED_CHANGES=true +} + +function SYSTEMD_NETWORKD_ADDRESSES_tag() { echo " ├ Addresses"; } +function SYSTEMD_NETWORKD_ADDRESSES_label() { echo " ├ ($(ellipsis 20 "${SYSTEMD_NETWORKD_ADDRESSES[*]}"))"; } +function SYSTEMD_NETWORKD_ADDRESSES_show() { [[ $STAGE3_VARIANT == *systemd* ]] && is_on "$SYSTEMD_NETWORKD" && is_off "$SYSTEMD_NETWORKD_DHCP"; } +function SYSTEMD_NETWORKD_ADDRESSES_help() { echo "A space-separated list of addresses to assign to the network interface."; } +function SYSTEMD_NETWORKD_ADDRESSES_menu() { + dialog \ + --title "Network Addresses" \ + --inputbox "A space-separated list of addresses to assign to the network interface." \ + "${INPUTBOX_SIZE[@]}" "${SYSTEMD_NETWORKD_ADDRESSES[*]}" + # shellcheck disable=SC2206 + SYSTEMD_NETWORKD_ADDRESSES=($dialog_out) + UNSAVED_CHANGES=true +} + +function SYSTEMD_NETWORKD_GATEWAY_tag() { echo " └ Gateway"; } +function SYSTEMD_NETWORKD_GATEWAY_label() { echo " └ ($(ellipsis 20 "$SYSTEMD_NETWORKD_GATEWAY"))"; } +function SYSTEMD_NETWORKD_GATEWAY_show() { [[ $STAGE3_VARIANT == *systemd* ]] && is_on "$SYSTEMD_NETWORKD" && is_off "$SYSTEMD_NETWORKD_DHCP"; } +function SYSTEMD_NETWORKD_GATEWAY_help() { echo "The gateway address for the network."; } +function SYSTEMD_NETWORKD_GATEWAY_menu() { + dialog \ + --title "Network Gateway" \ + --inputbox "The gateway address for the network." \ + "${INPUTBOX_SIZE[@]}" "$SYSTEMD_NETWORKD_GATEWAY" + SYSTEMD_NETWORKD_GATEWAY="$dialog_out" + UNSAVED_CHANGES=true +} + function STAGE3_VARIANT_tag() { echo "Stage3 variant & Init system"; } function STAGE3_VARIANT_label() { echo "($STAGE3_VARIANT)"; } function STAGE3_VARIANT_show() { return 0; } @@ -1330,7 +1416,7 @@ function PORTAGE_GIT_MIRROR_menu() { --title "Select portage git mirror" \ --inputbox "Enter the portage git mirror that should be used to sync the portage tree." \ "${INPUTBOX_SIZE[@]}" "$PORTAGE_GIT_MIRROR" - PORTAGE_GIT_MIRROR=($dialog_out) + PORTAGE_GIT_MIRROR="$dialog_out" UNSAVED_CHANGES=true } @@ -1343,7 +1429,7 @@ function GENTOO_MIRROR_menu() { --title "Select gentoo mirror" \ --inputbox "Enter the initial gentoo mirror that should be used for the system (or until mirrorselect is run). You need to enter the FULL PATH to the tree including relevant subdirectories. Leave this as it is if in doubt!" \ "${INPUTBOX_SIZE[@]}" "$GENTOO_MIRROR" - GENTOO_MIRROR=($dialog_out) + GENTOO_MIRROR="$dialog_out" UNSAVED_CHANGES=true } @@ -1393,12 +1479,12 @@ function SELECT_MIRRORS_LARGE_FILE_menu() { UNSAVED_CHANGES=true } -function INSTALL_SSHD_tag() { echo "Install sshd"; } -function INSTALL_SSHD_label() { on_off_label "$INSTALL_SSHD"; } -function INSTALL_SSHD_show() { return 0; } -function INSTALL_SSHD_help() { echo "Install and enable sshd on the new system. A reasonably secure sshd configuration will be provided. It will by default only allow ed25519 keys, restrict key exchange algorithms to a reasonable subset, disable any password based authentication, and only allow root to login."; } -function INSTALL_SSHD_menu() { - on_off_toggle "INSTALL_SSHD" +function ENABLE_SSHD_tag() { echo "Enable sshd"; } +function ENABLE_SSHD_label() { on_off_label "$ENABLE_SSHD"; } +function ENABLE_SSHD_show() { return 0; } +function ENABLE_SSHD_help() { echo "Install and enable sshd on the new system. A reasonably secure sshd configuration will be provided. It will by default only allow ed25519 keys, restrict key exchange algorithms to a reasonable subset, disable any password based authentication, and only allow root to login."; } +function ENABLE_SSHD_menu() { + on_off_toggle "ENABLE_SSHD" UNSAVED_CHANGES=true } @@ -1476,6 +1562,13 @@ KEYMAP_INITRAMFS=${KEYMAP_INITRAMFS@Q} LOCALES=${LOCALES@Q} LOCALE=${LOCALE@Q} +SYSTEMD_NETWORKD=${SYSTEMD_NETWORKD@Q} +SYSTEMD_NETWORKD_INTERFACE_NAME=${SYSTEMD_NETWORKD_INTERFACE_NAME@Q} +SYSTEMD_NETWORKD_DHCP=${SYSTEMD_NETWORKD_DHCP@Q} +SYSTEMD_NETWORKD_ADDRESSES=${SYSTEMD_NETWORKD_ADDRESSES@Q} +SYSTEMD_NETWORKD_GATEWAY=${SYSTEMD_NETWORKD_GATEWAY@Q} +SYSTEMD_INITRAMFS_SSHD=${SYSTEMD_INITRAMFS_SSHD@Q} + ################################################ # Gentoo configuration @@ -1497,7 +1590,7 @@ SYSTEMD=\$([[ \$STAGE3_VARIANT == *systemd* ]] && echo "true" || echo "false") # Additional (optional) configuration ADDITIONAL_PACKAGES=(${ADDITIONAL_PACKAGES[@]@Q}) -INSTALL_SSHD=${INSTALL_SSHD@Q} +ENABLE_SSHD=${ENABLE_SSHD@Q} ROOT_SSH_AUTHORIZED_KEYS=${ROOT_SSH_AUTHORIZED_KEYS@Q} diff --git a/gentoo.conf.example b/gentoo.conf.example index e4d37e1..501170a 100644 --- a/gentoo.conf.example +++ b/gentoo.conf.example @@ -199,6 +199,28 @@ LOCALE="C.utf8" # LOCALE="de_DE.utf8" +################################################ +# Network configuration + +# The following network configuration only applies to systemd +# configurations and will otherwise be ignore. All openrc based +# configurations always just starts dhcpcd. + +# Enable systemd-networkd to configure internet +SYSTEMD_NETWORKD=true +# The interfaces to match and configure (systemd [Match] -> Name) +SYSTEMD_NETWORKD_INTERFACE_NAME="en*" +# Whether to use DHCP (systemd [Network] -> DHCP) +SYSTEMD_NETWORKD_DHCP=true +# If DHCP is disabled, assign the given list of addresses (systemd [Network] -> Address) +SYSTEMD_NETWORKD_ADDRESSES=("192.168.1.100" "fd00::1") +# If DHCP is disabled, use the given gateway +SYSTEMD_NETWORKD_GATEWAY="192.168.1.1" +# Enable sshd in initramfs to allow unlocking encrypted devices / enter emergency shell if needed. +# Requires systemd. Visit https://github.com/gsauthof/dracut-sshd for more information. +SYSTEMD_INITRAMFS_SSHD=false + + ################################################ # Gentoo configuration @@ -250,7 +272,7 @@ ADDITIONAL_PACKAGES=() # Install and configure sshd (a reasonably secure config is provided, which # only allows the use of ed25519 keys, and requires pubkey authentication) -INSTALL_SSHD=true +ENABLE_SSHD=true # An ssh key to add to the authorized_keys file for the root user. # This variable will become the content of the authorized_keys file, diff --git a/scripts/main.sh b/scripts/main.sh index 179dbf5..1d2c5b2 100644 --- a/scripts/main.sh +++ b/scripts/main.sh @@ -90,12 +90,14 @@ function configure_portage() { || die "Could not chmod 644 /etc/portage/make.conf" } -function install_sshd() { - einfo "Installing sshd" +function enable_sshd() { + einfo "Installing and enabling sshd" install -m0600 -o root -g root "$GENTOO_INSTALL_REPO_DIR/contrib/sshd_config" /etc/ssh/sshd_config \ || die "Could not install /etc/ssh/sshd_config" enable_service sshd +} +function install_authorized_keys() { mkdir_or_die 0700 "/root/" mkdir_or_die 0700 "/root/.ssh" @@ -128,20 +130,31 @@ function generate_initramfs() { || die "Could not figure out kernel version from /usr/src/linux symlink." kver="${kver#linux-}" + dracut_opts=() + if [[ $SYSTEMD == "true" && $SYSTEMD_INITRAMFS_SSHD == "true" ]]; then + try git clone https://github.com/gsauthof/dracut-sshd + try cp -r dracut-sshd/46sshd /usr/lib/dracut/modules.d + sed -e 's/^Type=notify/Type=simple/' \ + -e 's@^\(ExecStart=/usr/sbin/sshd\) -D@\1 -e -D@' \ + -i /usr/lib/dracut/modules.d/46sshd/sshd.service \ + || die "Could not replace sshd options in service file" + dracut_opts+=("--install" "/etc/systemd/network/20-wired.network") + modules+=("systemd-networkd") + fi + # Generate initramfs - # TODO --conf "/dev/null" \ - # TODO --confdir "/dev/null" \ + # TODO --conf "/dev/null" \ + # TODO --confdir "/dev/null" \ try dracut \ --kver "$kver" \ --zstd \ --no-hostonly \ --ro-mnt \ --add "bash ${modules[*]}" \ + "${dracut_opts[@]}" \ --force \ "$output" - # TODO --conf "/dev/null" \\ - # TODO --confdir "/dev/null" \\ # Create script to repeat initramfs generation cat > "$(dirname "$output")/generate_initramfs.sh" < /etc/systemd/network/20-wired-dhcp.network \ - || die "Could not write dhcp network config to '/etc/systemd/network/20-wired-dhcp.network'" - chown root:systemd-network /etc/systemd/network/20-wired-dhcp.network \ - || die "Could not change owner of '/etc/systemd/network/20-wired-dhcp.network'" - chmod 640 /etc/systemd/network/20-wired-dhcp.network \ - || die "Could not change permissions of '/etc/systemd/network/20-wired-dhcp.network'" + if [[ $SYSTEMD_NETWORKD == "true" ]]; then + # Enable systemd networking and dhcp + enable_service systemd-networkd + enable_service systemd-resolved + if [[ $SYSTEMD_NETWORKD_DHCP == "true" ]]; then + echo -en "[Match]\nName=${SYSTEMD_NETWORKD_INTERFACE_NAME}\n\n[Network]\nDHCP=yes" > /etc/systemd/network/20-wired.network \ + || die "Could not write dhcp network config to '/etc/systemd/network/20-wired.network'" + else + addresses="" + for addr in "${SYSTEMD_NETWORKD_ADDRESSES[@]}"; do + addresses="Address=$addr\n" + done + echo -en "[Match]\nName=${SYSTEMD_NETWORKD_INTERFACE_NAME}\n\n[Network]\n${addresses}Gateway=$SYSTEMD_NETWORKD_GATEWAY" > /etc/systemd/network/20-wired.network \ + || die "Could not write dhcp network config to '/etc/systemd/network/20-wired.network'" + fi + chown root:systemd-network /etc/systemd/network/20-wired.network \ + || die "Could not change owner of '/etc/systemd/network/20-wired.network'" + chmod 640 /etc/systemd/network/20-wired.network \ + || die "Could not change permissions of '/etc/systemd/network/20-wired.network'" + fi else # Install and enable dhcpcd einfo "Installing dhcpcd" @@ -408,6 +430,10 @@ EOF enable_service dhcpcd fi + if [[ $ENABLE_SSHD == "true" ]]; then + enable_sshd + fi + # Install additional packages, if any. if [[ ${#ADDITIONAL_PACKAGES[@]} -gt 0 ]]; then einfo "Installing additional packages"