home · contact · privacy
Add basic Bullseye server setup.
authorChristian Heller <c.heller@plomlompom.de>
Thu, 7 Oct 2021 21:01:59 +0000 (23:01 +0200)
committerChristian Heller <c.heller@plomlompom.de>
Thu, 7 Oct 2021 21:01:59 +0000 (23:01 +0200)
bullseye/apt-mark/all [new file with mode: 0644]
bullseye/apt-mark/server [new file with mode: 0644]
bullseye/setup_scripts/copy_dirtree.sh [new file with mode: 0755]
bullseye/setup_scripts/init_user_and_keybased_login.sh
bullseye/setup_scripts/install_for_target.sh [new file with mode: 0755]
bullseye/setup_scripts/purge_nonrequireds.sh [new file with mode: 0755]
bullseye/setup_scripts/set_hostname_and_fqdn.sh [new file with mode: 0755]
bullseye/setup_scripts/setup.sh [new file with mode: 0755]
bullseye/setup_scripts/setup_server.sh [new file with mode: 0755]

diff --git a/bullseye/apt-mark/all b/bullseye/apt-mark/all
new file mode 100644 (file)
index 0000000..4b760bc
--- /dev/null
@@ -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 (file)
index 0000000..2ab22d2
--- /dev/null
@@ -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 (executable)
index 0000000..c0cb9bf
--- /dev/null
@@ -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
index 2ff2896e9cff65a9d625dc2727e32fd73d321f05..f237a84de33a85e6fe5635e6ff89eb98f76b2651 100755 (executable)
@@ -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 (executable)
index 0000000..6f42b56
--- /dev/null
@@ -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 (executable)
index 0000000..135196b
--- /dev/null
@@ -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 (executable)
index 0000000..a3b9f9a
--- /dev/null
@@ -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
+# <https://www.debian.org/doc/manuals/debian-reference/ch05.en.html>
+# (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
+# <https://unix.stackexchange.com/a/13087>.
+#
+# 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 (executable)
index 0000000..aadfc25
--- /dev/null
@@ -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 (executable)
index 0000000..a05db18
--- /dev/null
@@ -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