diff --git a/README.md b/README.md index dfd48fc..7a440c8 100644 --- a/README.md +++ b/README.md @@ -193,10 +193,6 @@ Non-root user to create. Ignored if `ENABLE_USER`=false ##### `ENABLE_ROOT`=false Set root user password so root login will be enabled -##### `ENABLE_ROOT_SSH`=true -Enable password root login via SSH. May be a security risk with default -password, use only in trusted environments. - ##### `ENABLE_HARDNET`=false Enable IPv4/IPv6 network stack hardening settings. @@ -212,6 +208,28 @@ Create an initramfs that that will be loaded during the Linux startup process. ` ##### `ENABLE_IFNAMES`=true Enable automatic assignment of predictable, stable network interface names for all local Ethernet, WLAN interfaces. This might create complex and long interface names. This parameter is only supported if the Debian release `stretch` is used. +#### SSH settings +##### `SSH_ENABLE_ROOT`=false +Enable password root login via SSH. This may be a security risk with default password, use only in trusted environments. `ENABLE_ROOT` must be set to `true`. + +##### `SSH_DISABLE_PASSWORD_AUTH`=false +Disable password based SSH authentication. Only public key based SSH (v2) authentication will be supported. + +##### `SSH_LIMIT_USERS`=false +Limit the users that are allowed to login via SSH. Only allow user `USER_NAME`=pi and root if `SSH_ENABLE_ROOT`=true to login. + +##### `SSH_ROOT_AUTHORIZED_KEYS`="" +Add specified SSH `authorized_keys2` file that contains keys for public key based SSH (v2) authentication of user `root`. SSH protocol version 1 is not supported. `ENABLE_ROOT` **and** `SSH_ENABLE_ROOT` must be set to `true`. + +##### `SSH_ROOT_PUB_KEY`="" +Add specified SSH (v2) public key file to `authorized_keys2` file to enable public key based SSH (v2) authentication of user `root`. SSH protocol version 1 is not supported. `ENABLE_ROOT` **and** `SSH_ENABLE_ROOT` must be set to `true`. + +##### `SSH_USER_AUTHORIZED_KEYS`="" +Add specified SSH `authorized_keys2` file that contains keys for public key based SSH (v2) authentication of user `USER_NAME`=pi. SSH protocol version 1 is not supported. + +##### `SSH_USER_PUB_KEY`="" +Add specified SSH (v2) public key file to `authorized_keys2` file to enable public key based SSH (v2) authentication of user `USER_NAME`=pi. SSH protocol version 1 is not supported. + #### Kernel compilation: ##### `BUILD_KERNEL`=false Build and install the latest RPi2/3 Linux kernel. Currently only the default RPi2/3 kernel configuration is used. `BUILD_KERNEL`=true will automatically be set if the Raspberry Pi model `3` is used. @@ -306,6 +324,7 @@ The functions of this script that are required for the different stages of the b | `21-firewall.sh` | Setup Firewall | | `30-security.sh` | Setup Users and Security settings | | `31-logging.sh` | Setup Logging | +| `32-sshd.sh` | Setup SSH and public keys | | `41-uboot.sh` | Build and Setup U-Boot | | `42-fbturbo.sh` | Build and Setup fbturbo Xorg driver | | `50-firstboot.sh` | First boot actions | diff --git a/bootstrap.d/13-kernel.sh b/bootstrap.d/13-kernel.sh index 4922348..ddfed3d 100644 --- a/bootstrap.d/13-kernel.sh +++ b/bootstrap.d/13-kernel.sh @@ -233,7 +233,7 @@ fi # Disable RPi3 Bluetooth and restore ttyAMA0 serial device if [ "$RPI_MODEL" = 3 ] ; then - if [ "$ENABLE_CONSOLE" = true ] && [ "$ENABLE_UBOOT" = false ]; then + if [ "$ENABLE_CONSOLE" = true ] && [ "$ENABLE_UBOOT" = false ] ; then echo "dtoverlay=pi3-disable-bt" >> "${BOOT_DIR}/config.txt" echo "enable_uart=1" >> "${BOOT_DIR}/config.txt" fi diff --git a/bootstrap.d/30-security.sh b/bootstrap.d/30-security.sh index 19773ee..8b0e464 100644 --- a/bootstrap.d/30-security.sh +++ b/bootstrap.d/30-security.sh @@ -11,18 +11,13 @@ ENCRYPTED_USER_PASSWORD=`mkpasswd -m sha-512 "${USER_PASSWORD}"` # Setup default user if [ "$ENABLE_USER" = true ] ; then - chroot_exec adduser --gecos $USER_NAME --add_extra_groups \ - --disabled-password $USER_NAME + chroot_exec adduser --gecos $USER_NAME --add_extra_groups --disabled-password $USER_NAME chroot_exec usermod -a -G sudo -p "${ENCRYPTED_USER_PASSWORD}" $USER_NAME fi # Setup root password or not if [ "$ENABLE_ROOT" = true ] ; then chroot_exec usermod -p "${ENCRYPTED_PASSWORD}" root - - if [ "$ENABLE_ROOT_SSH" = true ] ; then - sed -i "s|[#]*PermitRootLogin.*|PermitRootLogin yes|g" "${ETC_DIR}/ssh/sshd_config" - fi else # Set no root password to disable root login chroot_exec usermod -p \'!\' root diff --git a/bootstrap.d/32-sshd.sh b/bootstrap.d/32-sshd.sh new file mode 100644 index 0000000..7b700b4 --- /dev/null +++ b/bootstrap.d/32-sshd.sh @@ -0,0 +1,90 @@ +# +# Setup SSH settings and public keys +# + +# Load utility functions +. ./functions.sh + +if [ "$ENABLE_SSHD" = true ] ; then + if [ "$SSH_ENABLE_ROOT" = false ] ; then + # User root is not allowed to log in + sed -i "s|[#]*PermitRootLogin.*|PermitRootLogin no|g" "${ETC_DIR}/ssh/sshd_config" + fi + + if [ "$ENABLE_ROOT" = true ] && [ "$SSH_ENABLE_ROOT" = true ] ; then + # Permit SSH root login + sed -i "s|[#]*PermitRootLogin.*|PermitRootLogin yes|g" "${ETC_DIR}/ssh/sshd_config" + + # Create root SSH config directory + mkdir -p "${R}/root/.ssh" + + # Set permissions of root SSH config directory + chroot_exec chmod 700 "/root/.ssh" + chroot_exec chown root:root "/root/.ssh" + + # Install SSH (v2) authorized keys file for user root + if [ ! -z "$SSH_ROOT_AUTHORIZED_KEYS" ] ; then + install_readonly "$SSH_ROOT_AUTHORIZED_KEYS" "${R}/root/.ssh/authorized_keys2" + fi + + # Add SSH (v2) public key for user root + if [ ! -z "$SSH_ROOT_PUB_KEY" ] ; then + cat "$SSH_ROOT_PUB_KEY" >> "${R}/root/.ssh/authorized_keys2" + fi + + # Set permissions of root SSH authorized keys file + if [ -f "${R}/root/.ssh/authorized_keys2" ] ; then + chroot_exec chmod 600 "/root/.ssh/authorized_keys2" + chroot_exec chown root:root "/root/.ssh/authorized_keys2" + + # Allow SSH public key authentication + sed -i "s|[#]*PubkeyAuthentication.*|PubkeyAuthentication yes|g" "${ETC_DIR}/ssh/sshd_config" + fi + fi + + # Create $USER_NAME SSH config directory + mkdir -p "${R}/home/${USER_NAME}/.ssh" + + # Set permissions of $USER_NAME SSH config directory + chroot_exec chmod 700 "/home/${USER_NAME}/.ssh" + chroot_exec chown ${USER_NAME}:${USER_NAME} "/home/${USER_NAME}/.ssh" + + # Install SSH (v2) authorized keys file for user $USER_NAME + if [ ! -z "$SSH_USER_AUTHORIZED_KEYS" ] ; then + install_readonly "$SSH_USER_AUTHORIZED_KEYS" "${R}/home/${USER_NAME}/.ssh/authorized_keys2" + fi + + # Add SSH (v2) public key for user $USER_NAME + if [ ! -z "$SSH_USER_PUB_KEY" ] ; then + cat "$SSH_USER_PUB_KEY" >> "${R}/home/${USER_NAME}/.ssh/authorized_keys2" + fi + + # Set permissions of $USER_NAME SSH authorized keys file + if [ -f "${R}/home/${USER_NAME}/.ssh/authorized_keys2" ] ; then + chroot_exec chmod 600 "/home/${USER_NAME}/.ssh/authorized_keys2" + chroot_exec chown ${USER_NAME}:${USER_NAME} "/home/${USER_NAME}/.ssh/authorized_keys2" + + # Allow SSH public key authentication + sed -i "s|[#]*PubkeyAuthentication.*|PubkeyAuthentication yes|g" "${ETC_DIR}/ssh/sshd_config" + fi + + # Limit the users that are allowed to login via SSH + if [ "$SSH_LIMIT_USERS" = true ] ; then + if [ "$ENABLE_ROOT" = true ] && [ "$SSH_ENABLE_ROOT" = true ] ; then + echo "AllowUsers root ${USER_NAME}" >> "${ETC_DIR}/ssh/sshd_config" + else + echo "AllowUsers ${USER_NAME}" >> "${ETC_DIR}/ssh/sshd_config" + fi + fi + + # Disable password-based authentication + if [ "$SSH_DISABLE_PASSWORD_AUTH" = true ] ; then + if [ "$ENABLE_ROOT" = true ] && [ "$SSH_ENABLE_ROOT" = true ] ; then + sed -i "s|[#]*PermitRootLogin.*|PermitRootLogin without-password|g" "${ETC_DIR}/ssh/sshd_config" + fi + + sed -i "s|[#]*PasswordAuthentication.*|PasswordAuthentication no|g" "${ETC_DIR}/ssh/sshd_config" + sed -i "s|[#]*ChallengeResponseAuthentication no.*|ChallengeResponseAuthentication no|g" "${ETC_DIR}/ssh/sshd_config" + sed -i "s|[#]*UsePAM.*|UsePAM no|g" "${ETC_DIR}/ssh/sshd_config" + fi +fi diff --git a/rpi23-gen-image.sh b/rpi23-gen-image.sh index 5cb9d23..9fad608 100755 --- a/rpi23-gen-image.sh +++ b/rpi23-gen-image.sh @@ -1,7 +1,7 @@ #!/bin/sh ######################################################################## -# rpi23-gen-image.sh 2015-2016 +# rpi23-gen-image.sh 2015-2017 # # Advanced Debian "jessie" and "stretch" bootstrap script for RPi2/3 # @@ -126,7 +126,15 @@ ENABLE_RSYSLOG=${ENABLE_RSYSLOG:=true} ENABLE_USER=${ENABLE_USER:=true} USER_NAME=${USER_NAME:="pi"} ENABLE_ROOT=${ENABLE_ROOT:=false} -ENABLE_ROOT_SSH=${ENABLE_ROOT_SSH:=false} + +# SSH settings +SSH_ENABLE_ROOT=${SSH_ENABLE_ROOT:=false} +SSH_DISABLE_PASSWORD_AUTH=${SSH_DISABLE_PASSWORD_AUTH:=false} +SSH_LIMIT_USERS=${SSH_LIMIT_USERS:=false} +SSH_ROOT_AUTHORIZED_KEYS=${SSH_ROOT_AUTHORIZED_KEYS:=""} +SSH_USER_AUTHORIZED_KEYS=${SSH_USER_AUTHORIZED_KEYS:=""} +SSH_ROOT_PUB_KEY=${SSH_ROOT_PUB_KEY:=""} +SSH_USER_PUB_KEY=${SSH_USER_PUB_KEY:=""} # Advanced settings ENABLE_MINBASE=${ENABLE_MINBASE:=false} @@ -253,6 +261,38 @@ if [ "$ENABLE_UBOOT" = true ] ; then APT_INCLUDES="${APT_INCLUDES},device-tree-compiler" fi +# Check if root SSH (v2) authorized keys file exists +if [ ! -z "$SSH_ROOT_AUTHORIZED_KEYS" ] ; then + if [ ! -f "$SSH_ROOT_AUTHORIZED_KEYS" ] ; then + echo "error: '$SSH_ROOT_AUTHORIZED_KEYS' specified SSH authorized keys file not found (SSH_ROOT_AUTHORIZED_KEYS)!" + exit 1 + fi +fi + +# Check if $USER_NAME SSH (v2) authorized keys file exists +if [ ! -z "$SSH_USER_AUTHORIZED_KEYS" ] ; then + if [ ! -f "$SSH_USER_AUTHORIZED_KEYS" ] ; then + echo "error: '$SSH_USER_AUTHORIZED_KEYS' specified SSH authorized keys file not found (SSH_USER_AUTHORIZED_KEYS)!" + exit 1 + fi +fi + +# Check if root SSH (v2) public key file exists +if [ ! -z "$SSH_ROOT_PUB_KEY" ] ; then + if [ ! -f "$SSH_ROOT_PUB_KEY" ] ; then + echo "error: '$SSH_ROOT_PUB_KEY' specified SSH public key file not found (SSH_ROOT_PUB_KEY)!" + exit 1 + fi +fi + +# Check if $USER_NAME SSH (v2) public key file exists +if [ ! -z "$SSH_USER_PUB_KEY" ] ; then + if [ ! -f "$SSH_USER_PUB_KEY" ] ; then + echo "error: '$SSH_USER_PUB_KEY' specified SSH public key file not found (SSH_USER_PUB_KEY)!" + exit 1 + fi +fi + # Check if all required packages are installed on the build system for package in $REQUIRED_PACKAGES ; do if [ "`dpkg-query -W -f='${Status}' $package`" != "install ok installed" ] ; then @@ -489,37 +529,37 @@ DATE="$(date +%Y-%m-%d)" # Prepare image file if [ "$ENABLE_SPLITFS" = true ] ; then - dd if=/dev/zero of="$BASEDIR/${DATE}-debian-${RELEASE}-frmw.img" bs=512 count=${TABLE_SECTORS} - dd if=/dev/zero of="$BASEDIR/${DATE}-debian-${RELEASE}-frmw.img" bs=512 count=0 seek=${FRMW_SECTORS} - dd if=/dev/zero of="$BASEDIR/${DATE}-debian-${RELEASE}-root.img" bs=512 count=${TABLE_SECTORS} - dd if=/dev/zero of="$BASEDIR/${DATE}-debian-${RELEASE}-root.img" bs=512 count=0 seek=${ROOT_SECTORS} + dd if=/dev/zero of="$BASEDIR/${DATE}-rpi${RPI_MODEL}-${RELEASE}-frmw.img" bs=512 count=${TABLE_SECTORS} + dd if=/dev/zero of="$BASEDIR/${DATE}-rpi${RPI_MODEL}-${RELEASE}-frmw.img" bs=512 count=0 seek=${FRMW_SECTORS} + dd if=/dev/zero of="$BASEDIR/${DATE}-rpi${RPI_MODEL}-${RELEASE}-root.img" bs=512 count=${TABLE_SECTORS} + dd if=/dev/zero of="$BASEDIR/${DATE}-rpi${RPI_MODEL}-${RELEASE}-root.img" bs=512 count=0 seek=${ROOT_SECTORS} # Write firmware/boot partition tables - sfdisk -q -L -uS -f "$BASEDIR/${DATE}-debian-${RELEASE}-frmw.img" 2> /dev/null < /dev/null < /dev/null < /dev/null < /dev/null < /dev/null <