From e596091daf51443248a0cb427832be62552eaf27 Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Mon, 28 Oct 2013 19:50:41 +0100 Subject: Reorganization. Move preseed-related stuff in ./preseed/, and vm-related stuff in ./virtualenv/. --- src/fripost-postinst-udeb/debian/changelog | 5 + src/fripost-postinst-udeb/debian/compat | 1 + src/fripost-postinst-udeb/debian/control | 11 + src/fripost-postinst-udeb/debian/copyright | 7 + src/fripost-postinst-udeb/debian/install | 2 + src/fripost-postinst-udeb/debian/rules | 3 + src/fripost-postinst-udeb/debian/templates | 93 +++++++ .../finish-install.d/07fripost | 275 +++++++++++++++++++++ src/fripost-postinst-udeb/sshd_config | 40 +++ 9 files changed, 437 insertions(+) create mode 100644 src/fripost-postinst-udeb/debian/changelog create mode 100644 src/fripost-postinst-udeb/debian/compat create mode 100644 src/fripost-postinst-udeb/debian/control create mode 100644 src/fripost-postinst-udeb/debian/copyright create mode 100644 src/fripost-postinst-udeb/debian/install create mode 100755 src/fripost-postinst-udeb/debian/rules create mode 100644 src/fripost-postinst-udeb/debian/templates create mode 100755 src/fripost-postinst-udeb/finish-install.d/07fripost create mode 100644 src/fripost-postinst-udeb/sshd_config (limited to 'src/fripost-postinst-udeb') diff --git a/src/fripost-postinst-udeb/debian/changelog b/src/fripost-postinst-udeb/debian/changelog new file mode 100644 index 0000000..c1ea4fd --- /dev/null +++ b/src/fripost-postinst-udeb/debian/changelog @@ -0,0 +1,5 @@ +fripost-postinst (0.0.0) unstable; urgency=low + + * Tests + + -- Guilhem Moulin Wed, 17 Oct 2013 04:32:31 +0200 diff --git a/src/fripost-postinst-udeb/debian/compat b/src/fripost-postinst-udeb/debian/compat new file mode 100644 index 0000000..7f8f011 --- /dev/null +++ b/src/fripost-postinst-udeb/debian/compat @@ -0,0 +1 @@ +7 diff --git a/src/fripost-postinst-udeb/debian/control b/src/fripost-postinst-udeb/debian/control new file mode 100644 index 0000000..e173159 --- /dev/null +++ b/src/fripost-postinst-udeb/debian/control @@ -0,0 +1,11 @@ +Source: fripost-postinst +Section: debian-installer +Priority: optional +Maintainer: Guilhem Moulin +Build-Depends: debhelper (>= 7) + +Package: fripost-postinst +XC-Package-Type: udeb +Architecture: all +Depends: fripost-partman, ${misc:Depends} +Description: Post-install scripts (e.g., install dropbear in the initramfs) diff --git a/src/fripost-postinst-udeb/debian/copyright b/src/fripost-postinst-udeb/debian/copyright new file mode 100644 index 0000000..4e26ce2 --- /dev/null +++ b/src/fripost-postinst-udeb/debian/copyright @@ -0,0 +1,7 @@ +Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Source: native package + +Files: * +Copyright: © 2013 Guilhem Moulin +License: GPL-3+ + diff --git a/src/fripost-postinst-udeb/debian/install b/src/fripost-postinst-udeb/debian/install new file mode 100644 index 0000000..5426071 --- /dev/null +++ b/src/fripost-postinst-udeb/debian/install @@ -0,0 +1,2 @@ +finish-install.d/* /usr/lib/finish-install.d +sshd_config /var/lib/fripost diff --git a/src/fripost-postinst-udeb/debian/rules b/src/fripost-postinst-udeb/debian/rules new file mode 100755 index 0000000..cbe925d --- /dev/null +++ b/src/fripost-postinst-udeb/debian/rules @@ -0,0 +1,3 @@ +#!/usr/bin/make -f +%: + dh $@ diff --git a/src/fripost-postinst-udeb/debian/templates b/src/fripost-postinst-udeb/debian/templates new file mode 100644 index 0000000..5385ce9 --- /dev/null +++ b/src/fripost-postinst-udeb/debian/templates @@ -0,0 +1,93 @@ +Template: base-installer/progress/fripost +Type: text +Description: ${WHAT} + +Template: fripost/initrd-ssh-port +Type: string +Default: 22 +Description: On which [address:]port should dropbear listen? +Extended_description: If port is a range (e.g., 1024-65535), a random + port in that range is chosen. Leaving the question empty is equivalent + to specifying the range of registered port 1024-49151. This is only + used for remote (SSH) unlocking of encrypted disks. + +Template: fripost/dropbear-use-openssh-key +Type: boolean +Default: false +Description: Use the same key for dropbear and OpenSSH? +Extended_description: If False, generate a dedicated key for dropbear. + +Template: fripost/activate-selinux +Type: boolean +Default: true +Description: Install and activate (in enforcing mode) SELinux? +Extended_description: Note that activating SELinux requires a dummy + reboot to label all files. So if you have full-disk encryption, you'll + have to send the password twice to dropbear. + +Template: fripost/keep-media-directory +Type: boolean +Default: false +Description: Keep /media and its kids' entries in the fstab? +Extended_description: /media (and its related entries in the fstab) + can safely be removed on a headless server. + +Template: fripost/sshd-fprs_title +Type: text +Description: Reboot in progress + +Template: fripost/sshd-fprs_text +Type: note +Description: Press 'continue' to reboot on the new system + We are done! After rebooting you should be able to log in into your + new machine: + . + ssh ${USER}@${IPv4} + . + To defeat MiTM-attacks, please ensure (for instance by trying to log in + right now, although it won't be successful before the next reboot) that + the server's public key has the following fingerprint + . + ${SSHFPR_SERVER} + . + To unlock the encrypted disk, you need to send the key to the SSH + daemon living in in the initrd: + . + ssh -p ${PORT} -T root@${IPv4} < /path/to/key + . + An attacker successfully mounting a MiTM-attack could get hold of the + encryption key! It is crucial that you match this (single purpose) + server's fingerprint against + . + ${SSHFPR_INITRD} + . + Key(s) that are granted access to these two servers have the following + fingerprint: + . + ${SSHFPR_AUTHORIZED} + +Template: fripost/sshd-fprs-nodropbear_text +Type: note +Description: Press 'continue' to reboot on the new system + We are done! After rebooting you should be able to log in into your new + machine: + . + ssh ${USER}@${IPv4} + . + To defeat MiTM-attacks, please ensure (for instance by trying to log in + right now, although it won't be successful before the next reboot) that + the server's public key has the following fingerprint + . + ${SSHFPR_SERVER} + . + Key(s) that are granted access to the server have the following + fingerprint: + . + ${SSHFPR_AUTHORIZED} + +Template: fripost/final-notice +Type: boolean +Default: true +Description: Display the final notice before rebooting? +Extended_description: It's good to show SSH fingerprints, because it + defeats MiTM-attacks. diff --git a/src/fripost-postinst-udeb/finish-install.d/07fripost b/src/fripost-postinst-udeb/finish-install.d/07fripost new file mode 100755 index 0000000..55d292b --- /dev/null +++ b/src/fripost-postinst-udeb/finish-install.d/07fripost @@ -0,0 +1,275 @@ +#! /bin/sh +# +# Fripost's postinstall scripts. Should be run after setting up the +# users (06), and ideally before updating the initramfs (10). +# +# Copyright 2013 Guilhem Moulin +# +# Licensed under the GNU GPL version 3 or higher. + +# TODO: blacklist firewire-related modules, to defeat DMA-based attacks. + +set -ue + +. /lib/fripost-partman/base.sh +import=/cdrom/include + +# Update the information below the progress bar. Also, log the argument. +progress() { + log "$1" + db_subst base-installer/progress/fripost WHAT "$1" + db_progress INFO base-installer/progress/fripost +} + + +####################################################################### +# Ensure OpenSSH is installed, and generate a new key, longer than +# default. + +progress "Installing packages" +/bin/apt-install debconf initramfs-tools openssh-server +sshHostKey=/target/etc/ssh/ssh_host_rsa_key +rm -f "${sshHostKey}" "${sshHostKey}.pub" +progress "Generating public/private rsa key pair (OpenSSH)" +/bin/in-target /usr/bin/ssh-keygen -b 4096 -t rsa -N '' \ + -C "${sshHostKey#/target}" -f "${sshHostKey#/target}" + + +####################################################################### +# Put dropbear in the initrd if full disk encryption is desired. + +# Get username of the first user +db_get passwd/username +user="$RET" + +db_get fripost/encrypt +encrypt=$RET +if [ "$encrypt" = true ]; then + # Put dropbear in the initrd + progress "Installing dropbear" + /bin/apt-install dropbear + + cat /var/lib/fripost/initrd-modules >> /target/etc/initramfs-tools/modules + + rm -rf /target/etc/dropbear \ + /target/etc/initramfs-tools/etc/dropbear/dropbear_rsa_host_key + + # The default is not to copy the keys from the OpenSSH server to the + # initrd, because it's trivial for an attacker with physical access + # to the box to uncompress it and get hold of the private keys. + + db_get fripost/dropbear-use-openssh-key + if [ "$RET" = true ]; then + progress "Converting OpenSSH rsa key to dropbear format" + /bin/in-target /usr/lib/dropbear/dropbearconvert openssh dropbear \ + ${sshHostKey#/target} \ + /etc/initramfs-tools/etc/dropbear/dropbear_rsa_host_key + else + progress "Generating public/private rsa key pair (dropbear)" + /bin/in-target /usr/bin/dropbearkey -t rsa -s 4096 \ + -f /etc/initramfs-tools/etc/dropbear/dropbear_rsa_host_key + fi + + progress "Copying authorized_keys to the initrd" + rm -rf /target/etc/initramfs-tools/root/.ssh + mkdir -pm0700 /target/etc/initramfs-tools/root/.ssh + copy_authorized_keys $import/authorized_keys /target/etc/initramfs-tools/root/.ssh/authorized_keys \ + 'no-port-forwarding,no-agent-forwarding,no-X11-forwarding,no-pty,command="/bin/cat >/lib/cryptsetup/passfifo"' + + # Get the [address:]port to make dropbear listen to + db_get fripost/initrd-ssh-port + port="${RET:-1024-49151}" + min=${port%-*} + max=${port#*-} + if [ $port = "$min-$max" -a $min -le $max ]; then + # Pick a random port in the given range + port=$(/target/usr/bin/od -An -N2 -i /dev/urandom) + port=$(( $port % ($max + 1 - $min) + $min )) + fi + # See dropbear(8) for the list of options. Failure to read a keyfile + # makes dropbear disable the corresponding algorithm (including + # key-based authentication), in our case DSS/DSA. + log "Changing dropbear's options; port $port" + sed -i "s@^\s*/sbin/dropbear\$@& -d '' -sgjk -p $port@" \ + /target/usr/share/initramfs-tools/scripts/init-premount/dropbear + + # Sadly /usr/lib/finish-install.d/10update-initramfs only updates + # the ramdisk if both cryptsetup *and* console-setup are installed. + # (Cf. #694156 and #696773.) So we perform the update manually here. + progress "Generating new initramfs image" + /bin/in-target /usr/sbin/update-initramfs -u -t +fi + + +####################################################################### + +progress "Updating OpenSSH's server configuration" +rm -f /target/etc/ssh/ssh_host_dsa_key /target/etc/ssh/ssh_host_dsa_key.pub +cp /var/lib/fripost/sshd_config /target/etc/ssh/sshd_config + + +####################################################################### +# Install and activate SELinux +# TODO: would be better to have our own policy instead of amending the +# default one. + +db_get fripost/activate-selinux +if [ "$RET" = true ]; then + progress "Installing SELinux" + # Recommended packages include graphical tools... + /bin/in-target /usr/bin/debconf-apt-progress --no-progress -- \ + apt-get -y install --no-install-recommends \ + selinux-basics selinux-policy-default selinux-policy-dev auditd + progress "Activating SELinux" + /bin/in-target /usr/sbin/selinux-activate + + sed -ri 's/^#?\s*(FSCKFIX)=(yes|no)\s*(\s#.*)?$/\1=yes/' \ + /target/etc/default/rcS + + progress "Running update-grub" + grep -q '^GRUB_CMDLINE_LINUX=' /target/etc/default/grub \ + || fatal "Missing definition of 'GRUB_CMDLINE_LINUX' in /etc/default/grub" + GRUB_CMDLINE="console=tty0 security=selinux enforcing=1" + # ^ TODO: we should leave (non SELinux-related) existing + # configuration options + sed -ri "s/^(GRUB_CMDLINE_LINUX)=.*/\1=\"$GRUB_CMDLINE\"/" \ + /target/etc/default/grub + /bin/in-target /usr/sbin/update-grub + + if /bin/in-target /bin/sh -c "dpkg-query -s postfix >/dev/null 2>&1"; then + progress "Running postfix-nochroot" + echo 'SYNC_CHROOT=n' >> /target/etc/default/postfix + /bin/in-target /usr/sbin/postfix-nochroot + fi + # TODO: in a crontab: check-selinux-installation +fi + + +####################################################################### +# Remove unnecessary packages + +# TODO: check for dummy packages / RCs in a weekly crontab. +dpkg_remove=$(mktemp -p /target/tmp) +cat > "$dpkg_remove" <<- EOF + acpi + dictionaries-common + eject + ispell + laptop-detect + nano + tasksel + wamerican + wbritish +EOF +#XXX: the dummy package 'module-init-tools' is a dependency for 'acpid'. +#/usr/sbin/chroot /target /usr/bin/dpkg-query \ +# --show --showformat='${binary:Package} ${binary:Summary}\n' \ +# | sed -rn 's/^(\S+)\s.*\btransitional dummy package\b.*/\1/p' \ +# >> "$dpkg_remove" +/bin/in-target /usr/bin/xargs -a"${dpkg_remove#/target}" \ + debconf-apt-progress --no-progress -- apt-get -y autoremove --purge +rm -f "$dpkg_remove" + + +####################################################################### +# Remove /media and remove its related entries from the fstab. +# It's a bit dirty to remove what we created earlier, but /media/cdrom +# is required in the target, because apt gets some packages on that +# pool. + +db_get fripost/keep-media-directory +if [ "$RET" = false ]; then + log "Removing /media and amending the fstab" + sed -nr 's@^\S+\s+(/target/media/\S+)\s.*@\1@p' /proc/mounts \ + | while read dir; do + log "Unmounting $dir" + /bin/umount "$dir" + done + sed -ri '/^[^#[:blank:]]+\s+\/media\//d' /target/etc/fstab + + for mp in /target/media/*; do + if [ -h "$mp" ]; then + rm -f "$mp" + elif [ -d "$mp" ]; then + rmdir "$mp" + elif [ -e "$mp" ]; then + fatal "Could not remove $mp" + fi + done + rmdir /target/media +fi + + +####################################################################### +# Final notice before rebooting + +if [ "$encrypt" = false ]; then + # There is no dropbear + template=fripost/sshd-fprs-nodropbear_text +else + template=fripost/sshd-fprs_text + db_subst "$template" PORT "$port" + + # Convert the key to OpenSSH format, so we can use ssh-keygen + sshHostKey2=$(mktemp) + /usr/sbin/chroot /target /usr/bin/dropbearkey -y \ + -f /etc/initramfs-tools/etc/dropbear/dropbear_rsa_host_key \ + | grep -E '^(ssh-(dss|rsa)|ecdsa-sha2-nistp(256|384|521))' > "$sshHostKey2" + db_subst "$template" SSHFPR_INITRD "$(/usr/bin/ssh-keygen -lf $sshHostKey2)" + rm -f "$sshHostKey2" +fi +db_subst "$template" USER "$user" +db_subst "$template" IPv4 "$(getIPv4)" +db_subst "$template" SSHFPR_SERVER "$(/usr/bin/ssh-keygen -lf $sshHostKey)" +db_subst "$template" SSHFPR_AUTHORIZED "$(sshfprs $import/authorized_keys ' - ')" + +db_get fripost/final-notice +if [ "$RET" = true ]; then + # Start the SSH daemon to let the user's client to recognize the server + # hence make the weak TOFU model MiTM-immune. + progress "Starting OpenSSH" + /usr/sbin/chroot /target /usr/sbin/service ssh start + + db_settitle fripost/sshd-fprs_title + db_input critical "$template" + db_go + + # Don't show the usual "reboot in progress" notice + db_set finish-install/reboot_in_progress '' + db_fset finish-install/reboot_in_progress seen true + + progress "Stopping OpenSSH" + /usr/sbin/chroot /target /usr/sbin/service ssh stop +fi + + +####################################################################### +# Allow the user to log in via SSH at the next login. + +progress "Fixing permissions on home directories" +db_get adduser/homedir-permission || true +# Workaround for #398802 +if [ "${RET:-true}" = false ]; then + # Fix permissions for existing users + . /target/etc/adduser.conf + sed -rn "s@^([^:]+:){2}([0-9]+):([^:]*:){2}(/[^:]*):.*@\2 \4@p" /target/etc/passwd \ + | while read uuid home; do + [ $uuid -ge $FIRST_UID -a $uuid -le $LAST_UID -a -d /target"$home" ] || continue + log "Fixing permissions on $home" + chmod 0700 /target"$home" + done + + # Fix permissions for future users + sed -ri 's/^(DIR_MODE)=[0-9]+/\1=0700/' /target/etc/adduser.conf +fi + +ugid="$(sed -rn "s@^$user:[^:]*:([0-9]+:[0-9]+):.*@\1@p" /target/etc/passwd)" +home="$(sed -rn "s@^$user:([^:]*:){4}(/[^:]*):.*@\2@p" /target/etc/passwd)" + +# Create ~/.ssh/authorized_keys and fix ownership. We create it *after* +# stopping the SSH daemon to ensure that users can verify the +# fingerprint but cannot log in. +progress "Copying authorized_keys to ~$user/.ssh" +[ -d /target"$home/.ssh" ] || mkdir -m0700 /target"$home/.ssh" +copy_authorized_keys $import/authorized_keys /target"$home/.ssh/authorized_keys" +chown -R "$ugid" /target"$home/.ssh" # Probably 1000:1000, but who knows diff --git a/src/fripost-postinst-udeb/sshd_config b/src/fripost-postinst-udeb/sshd_config new file mode 100644 index 0000000..e81b272 --- /dev/null +++ b/src/fripost-postinst-udeb/sshd_config @@ -0,0 +1,40 @@ +# What ports, IPs and protocols we listen for +Port 22 +# Use these options to restrict which interfaces/protocols sshd will bind to +#ListenAddress :: +#ListenAddress 0.0.0.0 +Protocol 2 +# HostKeys for protocol version 2 +HostKey /etc/ssh/ssh_host_rsa_key +#Privilege Separation is turned on for security +UsePrivilegeSeparation yes + +# Logging +SyslogFacility AUTH +LogLevel INFO + +# Authentication: +LoginGraceTime 120 +PermitRootLogin no +AllowGroups ssh +StrictModes yes + +PubkeyAuthentication yes +#AuthorizedKeysFile %h/.ssh/authorized_keys + +# Change to yes to enable challenge-response passwords (beware issues with +# some PAM modules and threads) +ChallengeResponseAuthentication no + +# Change to no to disable tunnelled clear text passwords +PasswordAuthentication no + +X11Forwarding no +PrintMotd no +PrintLastLog yes +TCPKeepAlive yes + +# Allow client to pass locale environment variables +AcceptEnv LANG LC_* + +Subsystem sftp /usr/lib/openssh/sftp-server -- cgit v1.2.3