diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c6f92cf --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +.DS_Store +info/ +rootfs/ +.veid +config +logfile +*.tar.zst diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..f41071a --- /dev/null +++ b/Makefile @@ -0,0 +1,154 @@ +EXECUTABLES = curl git dab sed +K := $(foreach exec,$(EXECUTABLES),\ + $(if $(shell which $(exec)),some string,$(error "No $(exec) in PATH"))) + +BASEDIR:=$(shell dab basedir) +TEMPLATE_DIR=./templates + +global: info/init_ok sysinst installzsh createsysuser createclonescript hardenssh removepkg + + +info/init_ok: dab.conf + dab init + touch $@ + + +sysinst: + # ============================ + # Sys Install + # ============================ + # + # Create a minimal debootstrap + @dab bootstrap --minimal + + # Generate and set the default locale + @dab install locales + @sed -e 's/^# en_US.UTF-8/en_US.UTF-8/' -i $(BASEDIR)/etc/locale.gen + @dab exec dpkg-reconfigure locales + @echo "LANG=en_US.UTF-8" > $(BASEDIR)/etc/default/locale + + # Set the default keyboard layout + @sed -e 's/^XKBLAYOUT="us"/XKBLAYOUT="de"/' -i $(BASEDIR)/etc/default/keyboard + + # Set timezone to Europe/Berlin + @echo "Europe/Berlin" > $(BASEDIR)/etc/timezone + @dab exec rm -f /etc/localtime + @dab exec ln -s /usr/share/zoneinfo/Europe/Berlin /etc/localtime + + +installzsh: + # + # + # ============================ + # Install ZSH + # ============================ + # + # Install zsh & oh-my-zsh + @dab install git + @dab install zsh + @curl -o /tmp/oh-my-zhs-install.sh https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh + @chmod +x /tmp/oh-my-zhs-install.sh + ZSH='$(BASEDIR)/usr/share/oh-my-zsh' /tmp/oh-my-zhs-install.sh --unattended + + # Install 'dracula' theme + @dab exec mkdir -p /usr/share/oh-my-zsh/themes/lib + @curl -o $(BASEDIR)/usr/share/oh-my-zsh/themes/dracula.zsh-theme https://raw.githubusercontent.com/dracula/zsh/master/dracula.zsh-theme + @curl -o $(BASEDIR)/usr/share/oh-my-zsh/themes/lib/async.zsh https://raw.githubusercontent.com/dracula/zsh/master/lib/async.zsh + + # Customize .zshrc template in /etc/skel + @dab exec cp /usr/share/oh-my-zsh/templates/zshrc.zsh-template /etc/skel/.zshrc + @dab exec sed -i 's|export ZSH=.*|export ZSH=/usr/share/oh-my-zsh|' /etc/skel/.zshrc + @dab exec sed -i 's|ZSH_THEME=.*|ZSH_THEME="dracula"|' /etc/skel/.zshrc + @dab exec sed -i '/source.*/i ZSH_CACHE_DIR=$$HOME\/.cache\/oh-my-zsh\nif [[ ! -d $$ZSH_CACHE_DIR ]]; then\n mkdir -p $$ZSH_CACHE_DIR\nfi\n' /etc/skel/.zshrc + @dab exec sed -i '/source.*/i ZSH_COMPDUMP=$${ZSH_CACHE_DIR}\/.zcomdump-$${ZSH_VERSION}\n' /etc/skel/.zshrc + @dab exec sed -i '/# User configuration/a \\nif [ -d "\$${HOME}/.local/bin" ] ; then\n PATH="\$${HOME}/.local/bin:\$${PATH}\nfi' /etc/skel/.zshrc + @dab exec sed -i '/# User configuration/a \\nif [ -d "\$${HOME}/bin" ] ; then\n PATH="\$${HOME}/bin:\$${PATH}\nfi' /etc/skel/.zshrc + + # Remove bash templates from /etc/skel + @dab exec rm -f /etc/skel/.bash_logout + @dab exec rm -f /etc/skel/.bashrc + @dab exec rm -f /etc/skel/.profile + + # Make zsh the default shell for new users + @dab exec sed -i "s|#DSHELL=.*|DSHELL=/bin/zsh|" /etc/adduser.conf + + # Convert the root user + @dab exec chsh -s /bin/zsh root + @dab exec rm -f /root/.bash_logout + @dab exec rm -f /root/.bashrc + @dab exec rm -f /root/.profile + @dab exec cp /etc/skel/.zshrc /root + + +createsysuser: + # + # + # ============================ + # Creating the management user + # ============================ + # + # Install zsh & oh-my-zsh + @dab exec adduser --quiet --disabled-password --comment "System Operator" sysop + @dab exec sudo adduser sysop sudo + @dab exec sh -c "echo sysop:sysop | sudo chpasswd" + + +createclonescript: + # + # + # ============================ + # Create the cloning service + # ============================ + @cp $(TEMPLATE_DIR)/clone-credentials.sh $(BASEDIR)/usr/local/bin + @chmod 0744 $(BASEDIR)/usr/local/bin/clone-credentials.sh + @cp $(TEMPLATE_DIR)/clone-credentials.service $(BASEDIR)/etc/systemd/system + @dab exec ln -s /usr/lib/systemd/system/clone-credentials.service /etc/systemd/system/sysinit.target.wants/clone-credentials.service + + +hardenssh: + # + # + # ============================ + # Harden the ssh service + # ============================ + @cp $(TEMPLATE_DIR)/sshd_config $(BASEDIR)/etc/ssh/ + awk '$$5 >= 3071' $(BASEDIR)/etc/ssh/moduli > $(BASEDIR)/etc/ssh/moduli.tmp + mv $(BASEDIR)/etc/ssh/moduli.tmp $(BASEDIR)/etc/ssh/moduli + + +removepkg: + # + # + # ============================ + # Remove system packages + # ============================ + @dab exec apt --purge -q -y remove postfix + + +package: + # + # + # ============================ + # Create dist archive + # ============================ + dab finalize --compressor zstd-max + + +.PHONY: clean +clean: + dab clean + + +.PHONY: dist-clean +dist-clean: + dab dist-clean + + +all: global + # + # + # ============================ + # If no errors reported + # you can run "make package" + # to create dist archive + # ============================ diff --git a/dab.conf b/dab.conf new file mode 100644 index 0000000..94bc72f --- /dev/null +++ b/dab.conf @@ -0,0 +1,10 @@ +Suite: noble +CacheDir: ../cache +Architecture: amd64 +Name: ubuntu-24.04-rethinc +Version: 24.04-1 +Section: rethinc +Maintainer: Tim Kettler +Infopage: https://pve.proxmox.com/wiki/Linux_Container#pct_supported_distributions +Description: Ubuntu 24.04 Noble (Rethinc Edition) + A small Ubuntu 24.04 Noble Numbat system including all standard packages. diff --git a/templates/clone-credentials.service b/templates/clone-credentials.service new file mode 100644 index 0000000..193c2bd --- /dev/null +++ b/templates/clone-credentials.service @@ -0,0 +1,8 @@ +[Service] +Description=Copy the root credentials to the management user +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/local/bin/clone-credentials.sh + +[Install] +WantedBy=rescue.target diff --git a/templates/clone-credentials.sh b/templates/clone-credentials.sh new file mode 100755 index 0000000..638733b --- /dev/null +++ b/templates/clone-credentials.sh @@ -0,0 +1,61 @@ +#!/bin/sh + +# is_root() +# +# Returns 0 if the current user is root. Otherwise returns 1. +is_root () +{ + [ "$(id -u)" -eq 0 ] +} + +# contains(string, substring) +# +# Returns 0 if the specified string contains the specified substring, +# otherwise returns 1. +contains() { + string="$1" + substring="$2" + if [ "${string#*"$substring"}" != "$string" ]; then + return 0 # $substring is in $string + else + return 1 # $substring is not in $string + fi +} + +is_lxc() { + contains $(systemd-detect-virt) 'lxc' + return $? +} + +is_pve() { + contains $(uname -r) 'pve' + return $? +} + +ROOTPW='*' +get_root_pw() { + ROOTPW="$(grep root /etc/shadow | awk -F: '{print $2}')" +} + +if ! is_root; then + echo 'Script must be run as root' + exit 1 +fi + +get_root_pw +if [ "$ROOTPW" != '*' ]; then + usermod -p "${ROOTPW}" sysop + usermod -p "*" root +fi + +if [ -f /root/.ssh/authorized_keys ]; then + mkdir -m 0700 /home/sysop/.ssh + cp /root/.ssh/authorized_keys /home/sysop/.ssh + chown sysop:sysop /home/sysop/.ssh + chown sysop:sysop /home/sysop/.ssh/authorized_keys + rm -rf /root/.ssh +fi + +systemctl disable clone-credentials.service +rm /etc/systemd/system/clone-credentials.service +rm /usr/local/bin/clone-credentials.sh diff --git a/templates/sshd_config b/templates/sshd_config new file mode 100644 index 0000000..17e8957 --- /dev/null +++ b/templates/sshd_config @@ -0,0 +1,27 @@ +# Supported HostKey algorithms by order of preference. +HostKey /etc/ssh/ssh_host_ed25519_key +HostKey /etc/ssh/ssh_host_rsa_key +HostKey /etc/ssh/ssh_host_ecdsa_key + +KexAlgorithms curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256 + +Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr + +MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,umac-128@openssh.com + +# Password based logins are disabled - only public key based logins are allowed. +AuthenticationMethods publickey + +# LogLevel VERBOSE logs user's key fingerprint on login. Needed to have a clear audit track of which key was using to log in. +LogLevel VERBOSE + +# Log sftp level file access (read/write/etc.) that would not be easily logged otherwise. +Subsystem sftp /usr/lib/ssh/sftp-server -f AUTHPRIV -l INFO + +# Root login is not allowed for auditing reasons. This is because it's difficult to track which process belongs to which root user: +# +# On Linux, user sessions are tracking using a kernel-side session id, however, this session id is not recorded by OpenSSH. +# Additionally, only tools such as systemd and auditd record the process session id. +# On other OSes, the user session id is not necessarily recorded at all kernel-side. +# Using regular users in combination with /bin/su or /usr/bin/sudo ensure a clear audit track. +PermitRootLogin No