From 3c3d6ac607895dc89606586d658260ccde412267 2018-12-04 16:48:48 From: Unknown Date: 2018-12-04 16:48:48 Subject: [PATCH] Dropbear initramfs - Enable dropbear in initramfs with cryptfs_cropbear=true - dropbear initramfs supports static and dyn. ip - dropbear uses provided ip_config NET_* - bluetooth with serial improved - ipv6 legacy firewalling - add cleanup to videocore - improved apt-cacher-ng detection --- diff --git a/README.md b/README.md index 8257fc8..aadc3e9 100644 --- a/README.md +++ b/README.md @@ -392,6 +392,12 @@ Set cipher specification string. `aes-xts*` ciphers are strongly recommended. ##### `CRYPTFS_XTSKEYSIZE`=512 Sets key size in bits. The argument has to be a multiple of 8. +##### `CRYPTFS_DROPBEAR`=false +Enable Dropbear Initramfs support + +##### `CRYPTFS_DROPBEAR_PUBKEY`="" +Provide path to dropbear Public RSA-OpenSSH Key + --- #### Build settings: diff --git a/bootstrap.d/14-fstab.sh b/bootstrap.d/14-fstab.sh index 2f68cdf..149dcb3 100644 --- a/bootstrap.d/14-fstab.sh +++ b/bootstrap.d/14-fstab.sh @@ -29,7 +29,7 @@ if [ "$ENABLE_CRYPTFS" = true ] ; then fi # Generate initramfs file -if [ "$BUILD_KERNEL" = true ] && [ "$ENABLE_INITRAMFS" = true ] ; then +if [ "$ENABLE_INITRAMFS" = true ] ; then if [ "$ENABLE_CRYPTFS" = true ] ; then # Include initramfs scripts to auto expand encrypted root partition if [ "$EXPANDROOT" = true ] ; then @@ -38,8 +38,43 @@ if [ "$BUILD_KERNEL" = true ] && [ "$ENABLE_INITRAMFS" = true ] ; then install_exec files/initramfs/expand-tools "${ETC_DIR}/initramfs-tools/hooks/expand-tools" fi - # Disable SSHD inside initramfs - printf "#\n# DROPBEAR: [ y | n ]\n#\n\nDROPBEAR=n\n" >> "${ETC_DIR}/initramfs-tools/initramfs.conf" + if [ "$CRYPTFS_DROPBEAR" = true ]; then + if [ -n "$CRYPTFS_DROPBEAR_PUBKEY" ] && [ -f "$CRYPTFS_DROPBEAR_PUBKEY" ] ; then + install_readonly "${CRYPTFS_DROPBEAR_PUBKEY}" "${ETC_DIR}"/dropbear-initramfs/id_rsa.pub + cat "${ETC_DIR}"/dropbear-initramfs/id_rsa.pub >> "${ETC_DIR}"/dropbear-initramfs/authorized_keys + else + # Create key + chroot_exec /usr/bin/dropbearkey -t rsa -f /etc/dropbear-initramfs/id_rsa.dropbear + + # Convert dropbear key to openssh key + chroot_exec /usr/lib/dropbear/dropbearconvert dropbear openssh /etc/dropbear-initramfs/id_rsa.dropbear /etc/dropbear-initramfs/id_rsa + + # Get Public Key Part + chroot_exec /usr/bin/dropbearkey -y -f /etc/dropbear-initramfs/id_rsa.dropbear | chroot_exec tee /etc/dropbear-initramfs/id_rsa.pub + + # Delete unwanted lines + sed -i '/Public/d' "${ETC_DIR}"/dropbear-initramfs/id_rsa.pub + sed -i '/Fingerprint/d' "${ETC_DIR}"/dropbear-initramfs/id_rsa.pub + + # Trust the new key + cat "${ETC_DIR}"/dropbear-initramfs/id_rsa.pub > "${ETC_DIR}"/dropbear-initramfs/authorized_keys + + # Save Keys - convert with putty from rsa/openssh to puttkey + cp -f "${ETC_DIR}"/dropbear-initramfs/id_rsa "${BASEDIR}"/dropbear_initramfs_key.rsa + + # Get unlock script + install_exec files/initramfs/crypt_unlock.sh "${ETC_DIR}"/initramfs-tools/hooks/crypt_unlock.sh + + # Enable Dropbear inside initramfs + printf "#\n# DROPBEAR: [ y | n ]\n#\n\nDROPBEAR=y\n" >> "${ETC_DIR}/initramfs-tools/initramfs.conf" + + # Enable Dropbear inside initramfs + sed -i "54 i sleep 5" "${R}"/usr/share/initramfs-tools/scripts/init-premount/dropbear + fi + else + # Disable SSHD inside initramfs + printf "#\n# DROPBEAR: [ y | n ]\n#\n\nDROPBEAR=n\n" >> "${ETC_DIR}/initramfs-tools/initramfs.conf" + fi # Add cryptsetup modules to initramfs printf "#\n# CRYPTSETUP: [ y | n ]\n#\n\nCRYPTSETUP=y\n" >> "${ETC_DIR}/initramfs-tools/conf-hook" diff --git a/bootstrap.d/15-rpi-config.sh b/bootstrap.d/15-rpi-config.sh index eda69bd..5fe93a3 100644 --- a/bootstrap.d/15-rpi-config.sh +++ b/bootstrap.d/15-rpi-config.sh @@ -56,23 +56,38 @@ if [ "$ENABLE_CRYPTFS" = true ] ; then fi fi -#locks cpu at max frequency -if [ "$ENABLE_TURBO" = true ] ; then - echo "force_turbo=1" >> "${BOOT_DIR}/config.txt" -fi - +# Enable Kernel messages on standard output if [ "$ENABLE_PRINTK" = true ] ; then install_readonly files/sysctl.d/83-rpi-printk.conf "${ETC_DIR}/sysctl.d/83-rpi-printk.conf" fi -# Install udev rule for serial alias +# Install udev rule for serial alias - serial0 = console serial1=bluetooth install_readonly files/etc/99-com.rules "${LIB_DIR}/udev/rules.d/99-com.rules" +# Remove IPv6 networking support +if [ "$ENABLE_IPV6" = false ] ; then + CMDLINE="${CMDLINE} ipv6.disable=1" +fi + +# Automatically assign predictable network interface names +if [ "$ENABLE_IFNAMES" = false ] ; then + CMDLINE="${CMDLINE} net.ifnames=0" +else + CMDLINE="${CMDLINE} net.ifnames=1" +fi + +# Install firmware config +install_readonly files/boot/config.txt "${BOOT_DIR}/config.txt" + +# Locks CPU frequency at maximum +if [ "$ENABLE_TURBO" = true ] ; then + echo "force_turbo=1" >> "${BOOT_DIR}/config.txt" + # helps to avoid sdcard corruption when force_turbo is enabled. + echo "boot_delay=1" >> "${BOOT_DIR}/config.txt" +fi + if [ "$RPI_MODEL" = 0 ] || [ "$RPI_MODEL" = 3 ] || [ "$RPI_MODEL" = 3P ] ; then - # RPI0,3,3P Use default ttyS0 (mini-UART)as serial interface - SET_SERIAL="ttyS0" - # Bluetooth enabled if [ "$ENABLE_BLUETOOTH" = true ] ; then # Create temporary directory for Bluetooth sources @@ -94,6 +109,10 @@ if [ "$RPI_MODEL" = 0 ] || [ "$RPI_MODEL" = 3 ] || [ "$RPI_MODEL" = 3P ] ; then # Install tools install_readonly "${R}/tmp/pi-bluetooth/usr/bin/btuart" "${R}/usr/bin/btuart" install_readonly "${R}/tmp/pi-bluetooth/usr/bin/bthelper" "${R}/usr/bin/bthelper" + + # make scripts executable + chmod +x "${R}/usr/bin/bthelper" + chmod +x "${R}/usr/bin/btuart" # Install bluetooth udev rule install_readonly "${R}/tmp/pi-bluetooth/lib/udev/rules.d/90-pi-bluetooth.rules" "${LIB_DIR}/udev/rules.d/90-pi-bluetooth.rules" @@ -105,12 +124,12 @@ if [ "$RPI_MODEL" = 0 ] || [ "$RPI_MODEL" = 3 ] || [ "$RPI_MODEL" = 3P ] ; then install_readonly "${R}/tmp/pi-bluetooth/debian/pi-bluetooth.bthelper@.service" "${ETC_DIR}/systemd/system/pi-bluetooth.bthelper@.service" install_readonly "${R}/tmp/pi-bluetooth/debian/pi-bluetooth.hciuart.service" "${ETC_DIR}/systemd/system/pi-bluetooth.hciuart.service" - # Remove temporary directory + # Remove temporary directories rm -fr "${temp_dir}" + rm -fr "${R}"/tmp/pi-bluetooth # Switch Pi3 Bluetooth function to use the mini-UART (ttyS0) and restore UART0/ttyAMA0 over GPIOs 14 & 15. Slow Bluetooth and slow cpu. Use /dev/ttyS0 instead of /dev/ttyAMA0 if [ "$ENABLE_MINIUART_OVERLAY" = true ] ; then - SET_SERIAL="ttyAMA0" # set overlay to swap ttyAMA0 and ttyS0 echo "dtoverlay=pi3-miniuart-bt" >> "${BOOT_DIR}/config.txt" @@ -119,23 +138,15 @@ if [ "$RPI_MODEL" = 0 ] || [ "$RPI_MODEL" = 3 ] || [ "$RPI_MODEL" = 3P ] ; then if [ "$ENABLE_TURBO" = false ] ; then echo "core_freq=250" >> "${BOOT_DIR}/config.txt" fi - - # Activate services - chroot_exec systemctl enable pi-bluetooth.hciuart.service - #chroot_exec systemctl enable pi-bluetooth.bthelper@.service - else - chroot_exec systemctl enable pi-bluetooth.hciuart.service - #chroot_exec systemctl enable pi-bluetooth.bthelper@.service fi + + # Activate services + chroot_exec systemctl enable pi-bluetooth.hciuart.service else # if ENABLE_BLUETOOTH = false # set overlay to disable bluetooth echo "dtoverlay=pi3-disable-bt" >> "${BOOT_DIR}/config.txt" fi # ENABLE_BLUETOOTH end - -else - # RPI1,1P,2 Use default ttyAMA0 (full UART) as serial interface - SET_SERIAL="ttyAMA0" fi # may need sudo systemctl disable hciuart @@ -145,31 +156,14 @@ if [ "$ENABLE_CONSOLE" = true ] ; then CMDLINE="${CMDLINE} console=serial0,115200" # Enable serial console systemd style - chroot_exec systemctl enable serial-getty\@"$SET_SERIAL".service + chroot_exec systemctl enable serial-getty\@serial0.service else echo "enable_uart=0" >> "${BOOT_DIR}/config.txt" - # disable serial console systemd style - chroot_exec systemctl disable serial-getty\@"$SET_SERIAL".service -fi - -# Remove IPv6 networking support -if [ "$ENABLE_IPV6" = false ] ; then - CMDLINE="${CMDLINE} ipv6.disable=1" -fi - -# Automatically assign predictable network interface names -if [ "$ENABLE_IFNAMES" = false ] ; then - CMDLINE="${CMDLINE} net.ifnames=0" -else - CMDLINE="${CMDLINE} net.ifnames=1" fi # Install firmware boot cmdline echo "${CMDLINE}" > "${BOOT_DIR}/cmdline.txt" -# Install firmware config -install_readonly files/boot/config.txt "${BOOT_DIR}/config.txt" - # Setup minimal GPU memory allocation size: 16MB (no X) if [ "$ENABLE_MINGPU" = true ] ; then echo "gpu_mem=16" >> "${BOOT_DIR}/config.txt" diff --git a/bootstrap.d/20-networking.sh b/bootstrap.d/20-networking.sh index 3aca05f..4e001fe 100644 --- a/bootstrap.d/20-networking.sh +++ b/bootstrap.d/20-networking.sh @@ -57,6 +57,20 @@ else # ENABLE_DHCP=false -e "0,/NTP=\$/ s|NTP=\$|NTP=${NET_NTP_1}|"\ -e "0,/NTP=\$/ s|NTP=\$|NTP=${NET_NTP_2}|"\ "${ETC_DIR}/systemd/network/eth.network" + + if [ "$CRYPTFS_DROPBEAR" = true ] ; then + # Get cdir from NET_ADDRESS e.g. 24 + cdir=$(${NET_ADDRESS} | cut -d '/' -f2) + + # Convert cdir ro netmask e.g. 24 to 255.255.255.0 + NET_MASK=$(cdr2mask "$cdir") + + # Write static ip settings to "${ETC_DIR}"/initramfs-tools/initramfs.conf + sed -i "\$aIP=${NET_ADDRESS}::${NET_GATEWAY}:${NET_MASK}:${HOSTNAME}:" "${ETC_DIR}"/initramfs-tools/initramfs.conf + + # Regenerate initramfs + chroot_exec mkinitramfs -o "/boot/firmware/initramfs-${KERNEL_VERSION}" "${KERNEL_VERSION}" + fi fi # Remove empty settings from network configuration diff --git a/bootstrap.d/21-firewall.sh b/bootstrap.d/21-firewall.sh index e6033c4..1688be9 100644 --- a/bootstrap.d/21-firewall.sh +++ b/bootstrap.d/21-firewall.sh @@ -27,6 +27,9 @@ if [ "$ENABLE_IPTABLES" = true ] ; then chroot_exec systemctl enable iptables.service if [ "$ENABLE_IPV6" = true ] ; then + # make sure ip6tables-legacy is the used alternatives + chroot_exec update-alternatives --verbose --set ip6tables /usr/sbin/ip6tables-legacy + # Install ip6tables systemd service install_readonly files/iptables/ip6tables.service "${ETC_DIR}/systemd/system/ip6tables.service" diff --git a/bootstrap.d/30-security.sh b/bootstrap.d/30-security.sh index 8ad8275..75e3625 100644 --- a/bootstrap.d/30-security.sh +++ b/bootstrap.d/30-security.sh @@ -22,8 +22,3 @@ else # Set no root password to disable root login chroot_exec usermod -p \'!\' root fi - -# Enable serial console systemd style -if [ "$ENABLE_CONSOLE" = true ] ; then - chroot_exec systemctl enable serial-getty\@ttyAMA0.service -fi diff --git a/bootstrap.d/43-videocore.sh b/bootstrap.d/43-videocore.sh index b8ff518..344965c 100644 --- a/bootstrap.d/43-videocore.sh +++ b/bootstrap.d/43-videocore.sh @@ -50,4 +50,7 @@ if [ "$ENABLE_VIDEOCORE" = true ] ; then #back to root of scriptdir cd "${WORKDIR}" + + # Remove videocore sources + rm -fr "${R}"/tmp/userland/ fi diff --git a/files/initramfs/crypt_unlock.sh b/files/initramfs/crypt_unlock.sh new file mode 100644 index 0000000..47b6a8b --- /dev/null +++ b/files/initramfs/crypt_unlock.sh @@ -0,0 +1,45 @@ +#!/bin/sh + +PREREQ="dropbear" + +prereqs() { +echo "$PREREQ" +} + +case "$1" in +prereqs) +prereqs +exit 0 +;; +esac + +. "${CONFDIR}/initramfs.conf" +. /usr/share/initramfs-tools/hook-functions + +if [ "${DROPBEAR}" != "n" ] && [ -r "/etc/crypttab" ] ; then +cat > "${DESTDIR}/bin/unlock" << EOF +#!/bin/sh +if PATH=/lib/unlock:/bin:/sbin /scripts/local-top/cryptroot; then +kill \`ps | grep cryptroot | grep -v "grep" | awk '{print \$1}'\` +# following line kill the remote shell right after the passphrase has +# been entered. +kill -9 \`ps | grep "\-sh" | grep -v "grep" | awk '{print \$1}'\` +exit 0 +fi +exit 1 +EOF + +chmod 755 "${DESTDIR}/bin/unlock" + +mkdir -p "${DESTDIR}/lib/unlock" +cat > "${DESTDIR}/lib/unlock/plymouth" << EOF +#!/bin/sh +[ "\$1" == "--ping" ] && exit 1 +/bin/plymouth "\$@" +EOF + +chmod 755 "${DESTDIR}/lib/unlock/plymouth" + +echo To unlock root-partition run "unlock" >> ${DESTDIR}/etc/motd + +fi \ No newline at end of file diff --git a/functions.sh b/functions.sh index 74ca846..f7ce802 100644 --- a/functions.sh +++ b/functions.sh @@ -75,3 +75,12 @@ chroot_remove_cc() { COMPILER_PACKAGES="" fi } + +# https://serverfault.com/a/682849 - converts e.g. /24 to 255.255.255.0 +cdr2mask () +{ + # Number of args to shift, 255..255, first non-255 byte, zeroes + set -- $(( 5 - ($1 / 8) )) 255 255 255 255 $(( (255 << (8 - ($1 % 8))) & 255 )) 0 0 0 + [ $1 -gt 1 ] && shift $1 || shift + echo ${1-0}.${2-0}.${3-0}.${4-0} +} \ No newline at end of file diff --git a/rpi23-gen-image.sh b/rpi23-gen-image.sh index 575252a..e0f8872 100755 --- a/rpi23-gen-image.sh +++ b/rpi23-gen-image.sh @@ -185,6 +185,10 @@ CRYPTFS_PASSWORD=${CRYPTFS_PASSWORD:=""} CRYPTFS_MAPPING=${CRYPTFS_MAPPING:="secure"} CRYPTFS_CIPHER=${CRYPTFS_CIPHER:="aes-xts-plain64:sha512"} CRYPTFS_XTSKEYSIZE=${CRYPTFS_XTSKEYSIZE:=512} +#Dropbear-initramfs supports unlocking encrypted filesystem via SSH on bootup +CRYPTFS_DROPBEAR=${CRYPTFS_DROPBEAR:=false} +#Provide your own Dropbear Public RSA-OpenSSH Key otherwise it will be generated +CRYPTFS_DROPBEAR_PUBKEY=${CRYPTFS_DROPBEAR_PUBKEY:=""} # Chroot scripts directory CHROOT_SCRIPTS=${CHROOT_SCRIPTS:=""} @@ -203,11 +207,9 @@ MISSING_PACKAGES="" # Packages installed for c/c++ build environment in chroot (keep empty) COMPILER_PACKAGES="" -set +x - -#Check if apt-cacher-ng has port 3142 open and set APT_PROXY -APT_CACHER_RUNNING=$(lsof -i :3142 | grep apt-cacher-ng | cut -d ' ' -f3 | uniq) -if [ -n "${APT_CACHER_RUNNING}" ] ; then +# Check if apt-cacher-ng has port 3142 open and set APT_PROXY +APT_CACHER_RUNNING=$(lsof -i :3142 | cut -d ' ' -f3 | uniq | sed '/^\s*$/d') +if [ "${APT_CACHER_RUNNING}" = "apt-cacher-ng" ] ; then APT_PROXY=http://127.0.0.1:3142/ fi @@ -258,7 +260,7 @@ if [ -n "$SET_ARCH" ] ; then CROSS_COMPILE=${CROSS_COMPILE:=arm-linux-gnueabihf-} fi fi -#SET_ARCH not set +# SET_ARCH not set else echo "error: Please set '32' or '64' as value for SET_ARCH" exit 1 @@ -298,9 +300,12 @@ esac # Raspberry PI 0,3,3P with Bluetooth and Wifi onboard if [ "$RPI_MODEL" = 0 ] || [ "$RPI_MODEL" = 3 ] || [ "$RPI_MODEL" = 3P ] ; then # Include bluetooth packages on supported boards - if [ "$ENABLE_BLUETOOTH" = true ] && [ "$ENABLE_CONSOLE" = false ]; then + if [ "$ENABLE_BLUETOOTH" = true ] ; then APT_INCLUDES="${APT_INCLUDES},bluetooth,bluez" fi + if [ "$ENABLE_WIRELESS" = true ] ; then + APT_INCLUDES="${APT_INCLUDES},wireless-tools,crda,wireless-regdb" + fi else # Raspberry PI 1,1P,2 without Wifi and bluetooth onboard # Check if the internal wireless interface is not supported by the RPi model if [ "$ENABLE_WIRELESS" = true ] || [ "$ENABLE_BLUETOOTH" = true ]; then @@ -345,6 +350,11 @@ if [ "$ENABLE_CRYPTFS" = true ] && [ "$BUILD_KERNEL" = true ] ; then REQUIRED_PACKAGES="${REQUIRED_PACKAGES} cryptsetup" APT_INCLUDES="${APT_INCLUDES},cryptsetup,busybox,console-setup" + # If cryptfs,dropbear and initramfs are enabled include dropbear-initramfs package + if [ "$CRYPTFS_DROPBEAR" = true ] && [ "$ENABLE_INITRAMFS" = true ]; then + APT_INCLUDES="${APT_INCLUDES},dropbear-initramfs" + fi + if [ -z "$CRYPTFS_PASSWORD" ] ; then echo "error: no password defined (CRYPTFS_PASSWORD)!" exit 1 @@ -362,14 +372,6 @@ if [ "$ENABLE_UBOOT" = true ] ; then APT_INCLUDES="${APT_INCLUDES},device-tree-compiler,bison,flex,bc" fi -if [ "$ENABLE_BLUETOOTH" = true ] ; then - if [ "$RPI_MODEL" = 0 ] || [ "$RPI_MODEL" = 3 ] || [ "$RPI_MODEL" = 3P ] ; then - if [ "$ENABLE_CONSOLE" = false ] ; then - APT_INCLUDES="${APT_INCLUDES},bluetooth,bluez" - fi - fi -fi - # Check if root SSH (v2) public key file exists if [ -n "$SSH_ROOT_PUB_KEY" ] ; then if [ ! -f "$SSH_ROOT_PUB_KEY" ] ; then