diff --git a/build_image.sh b/build_image.sh index cd8c26da1225..5c5407b6a725 100755 --- a/build_image.sh +++ b/build_image.sh @@ -133,6 +133,7 @@ elif [ "$IMAGE_TYPE" = "aboot" ]; then sed -i -e "s/%%IMAGE_VERSION%%/$IMAGE_VERSION/g" files/Aboot/boot0 pushd files/Aboot && zip -g $OLDPWD/$OUTPUT_ABOOT_IMAGE boot0; popd pushd files/Aboot && zip -g $OLDPWD/$ABOOT_BOOT_IMAGE boot0; popd + pushd files/image_config/secureboot && zip -g $OLDPWD/$OUTPUT_ABOOT_IMAGE allowlist_paths.conf; popd echo "$IMAGE_VERSION" >> .imagehash zip -g $OUTPUT_ABOOT_IMAGE .imagehash zip -g $ABOOT_BOOT_IMAGE .imagehash diff --git a/files/Aboot/boot0.j2 b/files/Aboot/boot0.j2 index 6460db61c8e3..49d6a96594d9 100644 --- a/files/Aboot/boot0.j2 +++ b/files/Aboot/boot0.j2 @@ -395,6 +395,9 @@ write_boot_configs() { fi fi + # setting secure_boot_enable=y when secure boot enabled + [ -f /bin/securebootctl ] && securebootctl secureboot -display | grep -i "Secure Boot enable" -q && echo "secure_boot_enable=y" >> /tmp/append + mkdir -p "$image_path" cat /tmp/append > $cmdline_image [ -s ${target_path}/machine.conf ] || write_machine_config diff --git a/files/image_config/secureboot/allowlist_paths.conf b/files/image_config/secureboot/allowlist_paths.conf new file mode 100644 index 000000000000..fe5b890e0678 --- /dev/null +++ b/files/image_config/secureboot/allowlist_paths.conf @@ -0,0 +1,35 @@ +home/.* +var/core/.* +var/log/.* +etc/adjtime +etc/default/ntp +etc/dhcp/dhclient.conf +etc/ebtables.filter +etc/group +etc/gshadow +etc/hostname +etc/hosts +etc/machine-id +etc/network/interfaces +etc/nsswitch.conf +etc/ntp.conf +etc/pam.d/common-auth-sonic +etc/pam.d/sshd +etc/pam.d/login +etc/pam.d/sshd.old +etc/passwd +etc/rsyslog.conf +etc/shadow +etc/sonic/acl.json +etc/sonic/config_db.json +etc/sonic/minigraph.xml +etc/sonic/old_config/.* +etc/sonic/snmp.yml +etc/sonic/updategraph.conf +etc/ssh/ssh_host_rsa_key.pub +etc/ssh/ssh_host_rsa_key +etc/subgid +etc/subuid +etc/tacplus_nss.conf +etc/tacplus_user +lib/systemd/system/serial-getty@.service diff --git a/files/image_config/secureboot/allowlist_paths.md b/files/image_config/secureboot/allowlist_paths.md new file mode 100644 index 000000000000..7ce86b9bc90c --- /dev/null +++ b/files/image_config/secureboot/allowlist_paths.md @@ -0,0 +1,11 @@ +# Configuration Guide +It is the patterns of the relative paths in /host/image-{{hash}}/rw folder. +The patterns will not be used if the Sonic Secure Boot feature is not enabled. +The files that are not in the allowlist will be removed when the Sonic System cold reboot. + +### Example config to add all the files in a folder to allowlist +home/.* + +### Example config to add a file to allowlist +etc/nsswitch.conf + diff --git a/files/initramfs-tools/union-mount.j2 b/files/initramfs-tools/union-mount.j2 index 5e33e1760874..8c8bb926444d 100644 --- a/files/initramfs-tools/union-mount.j2 +++ b/files/initramfs-tools/union-mount.j2 @@ -39,10 +39,43 @@ set_tmpfs_log_partition_size() [ $maxsize -le $varlogsize ] && varlogsize=$maxsize } +remove_not_in_allowlist_files() +{ + image_dir=$1 + allowlist_file=${rootmnt}/host/$image_dir/allowlist_paths.conf + + # Return if the secure_boot_enable option is not set + if ! (cat /proc/cmdline | grep -i -q "secure_boot_enable=[y1]"); then + return + fi + + # Return if the allowlist file does not exist + if ! test -f "${allowlist_file}"; then + echo "The file ${allowlist_file} is missing, failed to mount rw folder." 1>&2 + exit 1 + fi + + rw_dir=${rootmnt}/host/$image_dir/rw + + # Set the grep pattern file, remove the blank line in config file + allowlist_pattern_file=${rootmnt}/host/$image_dir/allowlist_paths.pattern + awk -v rw_dir="$rw_dir" 'NF {print rw_dir"/"$0"$"}' ${allowlist_file} > $allowlist_pattern_file + + # Find the files in the rw folder, and remove the files not in the allowlist + find ${rw_dir} -type f | grep -v -f $allowlist_pattern_file | xargs /bin/rm -f + rm -f $allowlist_pattern_file +} + ## Mount the overlay file system: rw layer over squashfs image_dir=$(cat /proc/cmdline | sed -e 's/.*loop=\(\S*\)\/.*/\1/') mkdir -p ${rootmnt}/host/$image_dir/rw mkdir -p ${rootmnt}/host/$image_dir/work +## Remove the files not in allowlist in the rw folder +remove_not_in_allowlist_files "$image_dir" +## Remove the executable permission for all the files in rw folder except home folder +rw_dir=${rootmnt}/host/$image_dir/rw +find ${rw_dir} -type f -not -path ${rw_dir}/home -exec chmod a-x {} + + mount -n -o lowerdir=${rootmnt},upperdir=${rootmnt}/host/$image_dir/rw,workdir=${rootmnt}/host/$image_dir/work -t overlay root-overlay ${rootmnt} ## Check if the root block device is still there [ -b ${ROOT} ] || mdev -s