From: Christian Heller Date: Thu, 7 Oct 2021 21:01:59 +0000 (+0200) Subject: Add basic Bullseye server setup. X-Git-Url: https://plomlompom.com/repos/%7B%7Bdb.prefix%7D%7D/tasks?a=commitdiff_plain;h=1045df34e06701e4ddd98869baa10bf466c9c455;p=config Add basic Bullseye server setup. --- diff --git a/bullseye/apt-mark/all b/bullseye/apt-mark/all new file mode 100644 index 0000000..4b760bc --- /dev/null +++ b/bullseye/apt-mark/all @@ -0,0 +1,12 @@ +# connectivity: ifupdown seems necessary everyhwere, isc-dhcp-client +# unpredictably so +ifupdown +isc-dhcp-client +# git for the setup directory; cloning works with ca-certificates +ca-certificates +git +# to avoid constant warnings about no locale being found +locales +# extremely useful for basic network debugging; missed these more than once in an emergency +netcat +iputils-ping diff --git a/bullseye/apt-mark/server b/bullseye/apt-mark/server new file mode 100644 index 0000000..2ab22d2 --- /dev/null +++ b/bullseye/apt-mark/server @@ -0,0 +1,6 @@ +# so we can login at all … +openssh-server +# firewalling +nftables +# We want to be able to use ALL our servers as borg backup destinations. +borgbackup diff --git a/bullseye/setup_scripts/copy_dirtree.sh b/bullseye/setup_scripts/copy_dirtree.sh new file mode 100755 index 0000000..c0cb9bf --- /dev/null +++ b/bullseye/setup_scripts/copy_dirtree.sh @@ -0,0 +1,30 @@ +#!/bin/sh +# Copy files in argument-selected subdirectories of $1 to subdirectories +# of $2 (which may be an empty string), e.g. with $1 of "etc_files", $2 +# of "" and $3 of "all", copy files below etc_files/all such as +# etc_files/all/etc/foo/bar to equivalent locations below / such as +# /etc/foo/bar. Create directories as necessary. Multiple arguments after +# $3 are possible. +# +# CAUTION: This removes original files at the affected paths. +set -e + +if [ "$#" -lt 3 ]; then + echo 'Need arguments: source root, target root, modules.' + false +fi +source_root="$1" +target_root="$2" +shift 2 + +for target_module in "$@"; do + mkdir -p "${source_root}/${target_module}" + cd "${source_root}/${target_module}" + for path in $(find . -type f); do + target_path="${target_root}"$(echo "${path}" | cut -c2-) + source_path=$(realpath "${path}") + dir=$(dirname "${target_path}") + mkdir -p "${dir}" + cp "${source_path}" "${target_path}" + done +done diff --git a/bullseye/setup_scripts/init_user_and_keybased_login.sh b/bullseye/setup_scripts/init_user_and_keybased_login.sh index 2ff2896..f237a84 100755 --- a/bullseye/setup_scripts/init_user_and_keybased_login.sh +++ b/bullseye/setup_scripts/init_user_and_keybased_login.sh @@ -10,7 +10,6 @@ # Dependencies: ssh, scp, sshpass, ~/.ssh/id_rsa.pub, properly # configured sshd_config file in reach. set -e -set -x # Location of an sshd_config with "PermitRootLogin no" and # "PasswordAuthentication no". diff --git a/bullseye/setup_scripts/install_for_target.sh b/bullseye/setup_scripts/install_for_target.sh new file mode 100755 index 0000000..6f42b56 --- /dev/null +++ b/bullseye/setup_scripts/install_for_target.sh @@ -0,0 +1,20 @@ +#!/bin/sh +# Walks through the package names in the argument-selected files of +# apt-mark/ and ensures the respective packages are installed. +# +# Ignores anything in an apt-mark/ file after the last newline. +set -e + +config_tree_prefix="${HOME}/config/bullseye" +aptmark_dir="${config_tree_prefix}/apt-mark" + +for target in "$@"; do + path="${aptmark_dir}/${target}" + # TODO: continue if file at $path not found, to get rid of dummy files + cat "${path}" | while read line; do + echo "$line" + if [ ! $(echo "${line}" | cut -c1) = "#" ]; then + DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::=--force-confold install "${line}" + fi + done +done diff --git a/bullseye/setup_scripts/purge_nonrequireds.sh b/bullseye/setup_scripts/purge_nonrequireds.sh new file mode 100755 index 0000000..135196b --- /dev/null +++ b/bullseye/setup_scripts/purge_nonrequireds.sh @@ -0,0 +1,30 @@ +#!/bin/sh +# This script removes all Debian packages that are not of Priority +# "required" or not depended on by packages of priority "required" +# or not listed in the argument-selected files of apt-mark/. +set -e + +config_tree_prefix="${HOME}/config/bullseye" +aptmark_dir="${config_tree_prefix}/apt-mark" + +dpkg-query -Wf '${Package} ${Priority}\n' | grep ' required' | sed 's/ required//' > /tmp/list_white_unsorted +for target in "$@"; do + path="${aptmark_dir}/${target}" + cat "${path}" | while read line; do + if [ ! $(echo "${line}" | cut -c1) = "#" ]; then + echo "${line}" >> /tmp/list_white_unsorted + fi + done +done +sort /tmp/list_white_unsorted > /tmp/list_white +dpkg-query -Wf '${Package}\n' > /tmp/list_all_packages +sort /tmp/list_all_packages > /tmp/foo +mv /tmp/foo /tmp/list_all_packages +comm -3 /tmp/list_all_packages /tmp/list_white > /tmp/list_black +apt-mark auto `cat /tmp/list_black` +DEBIAN_FRONTEND=noninteractive apt-get -y --purge autoremove +rm /tmp/list_all_packages /tmp/list_white_unsorted /tmp/list_white /tmp/list_black + +# Somehow, auto-mounts get undone by all of this, so re-mount /etc/fstab. +# TODO: Find out why. +mount -a diff --git a/bullseye/setup_scripts/set_hostname_and_fqdn.sh b/bullseye/setup_scripts/set_hostname_and_fqdn.sh new file mode 100755 index 0000000..a3b9f9a --- /dev/null +++ b/bullseye/setup_scripts/set_hostname_and_fqdn.sh @@ -0,0 +1,50 @@ +#!/bin/sh +# Sets hostname and optionally FQDN. +# +# Calls hostname, writes to /etc/hostname and /etc/hosts. For /etc/hosts +# writing follows recommendations from Debian manual at +# +# (section "The hostname resolution") on how to map hostname and possibly +# FQDN to a permanent IP if present (we assume here any non-private IP +# and non-loopback IP returned by hostname -I to fulfill that criterion +# on our systems) or to 127.0.1.1 if not. On the reasoning for separating +# localhost and hostname mapping to different IPs, see +# . +# +# Ignores IPv6s. +set -e + +hostname="$1" +fqdn="$2" +if [ "${hostname}" = "" ]; then + echo "Need hostname as argument." + false +fi +echo "${hostname}" > /etc/hostname +hostname "${hostname}" + +final_ip="127.0.1.1" +for ip in $(hostname -I); do + if [ $(echo "${ip}" | grep ':' | wc -l) -eq 1 ]; then + continue + fi + range_1=$(echo "${ip}" | cut -d "." -f 1) + range_2=$(echo "${ip}" | cut -d "." -f 2) + if [ "${range_1}" -eq 127 ]; then + continue + elif [ "${range_1}" -eq 10 ]; then + continue + elif [ "${range_1}" -eq 172 ]; then + if [ "${range_2}" -ge 16 ] && [ "${range_2}" -le 31 ]; then + continue + fi + elif [ "${range_1}" -eq 192 ]; then + if [ "${range_2}" -eq 168 ]; then + continue + fi + fi + final_ip="${ip}" +done + +echo "127.0.0.1 localhost.localdomain localhost" > /etc/hosts +echo "${final_ip} ${fqdn} ${hostname}" >> /etc/hosts diff --git a/bullseye/setup_scripts/setup.sh b/bullseye/setup_scripts/setup.sh new file mode 100755 index 0000000..aadfc25 --- /dev/null +++ b/bullseye/setup_scripts/setup.sh @@ -0,0 +1,39 @@ +#!/bin/sh +set -e + +# Provide maximum input for set_hostname_and_fqdn.sh. +if [ "$#" -lt 2 ]; then + echo 'Need at least two arguments (hostname, FQDN).' + false +fi +hostname="$1" +fqdn="$2" +shift 2 + +config_tree_prefix="${HOME}/config/bullseye" +setup_scripts_dir="${config_tree_prefix}/setup_scripts" +cd "${setup_scripts_dir}" + +# Adapt /etc/ to our needs by copying from ./etc_files. This will set +# basic configurations affecting following steps, such as setup of APT +# and the locale selection, so needs to be right at the beginning. +./copy_dirtree.sh "${config_tree_prefix}/etc_files" "" all "$@" + +# Set hostname and FQDN. +./set_hostname_and_fqdn.sh "${hostname}" "${fqdn}" + +# Ensure package installation state as defined by what packages are +# defined as required by Debian policy and by settings in ./apt-mark/. +apt update +./install_for_target.sh all "$@" +./purge_nonrequireds.sh all "$@" + +# Ensure our desired locale is available. +locale-gen + +# Only upgrade after reducing the system to the desired minimum, so that +# we don't need to get more data than necessary. +apt -y dist-upgrade + +# Set Berlin localtime. +ln -sf /usr/share/zoneinfo/Europe/Berlin /etc/localtime diff --git a/bullseye/setup_scripts/setup_server.sh b/bullseye/setup_scripts/setup_server.sh new file mode 100755 index 0000000..a05db18 --- /dev/null +++ b/bullseye/setup_scripts/setup_server.sh @@ -0,0 +1,26 @@ +#!/bin/sh +# Next setup steps for a server whose login policy has just been set from +# the outside via ./init_user_and_keybased_login.sh. +set -e + +# Provide maximum input for set_hostname_and_fqdn.sh. +if [ "$#" -lt 2 ]; then + echo 'Need exactly two arguments (hostname, FQDN).' + false +fi +hostname="$1" +fqdn="$2" +additional_arg="$3" + +# Set up system without user environment. +config_tree_prefix="${HOME}/config/bullseye" +setup_scripts_dir="${config_tree_prefix}/setup_scripts" +cd "${setup_scripts_dir}" +./setup.sh "${hostname}" "${fqdn}" server "${additional_arg}" + +# If we have not yet set the shell for user plom, ensure it here. This +# is mostly for convenience. +usermod -s /bin/bash plom + +# Enable firewall. +systemctl enable nftables.service