From bfd6ce582589293f28edabc2887ab23b216a79ca Mon Sep 17 00:00:00 2001 From: solidc0re <140627847+solidc0re@users.noreply.github.com> Date: Sun, 10 Sep 2023 07:10:17 +0100 Subject: [PATCH 1/7] UX improvements --- solidcore-firstboot.sh | 60 ++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 31 deletions(-) diff --git a/solidcore-firstboot.sh b/solidcore-firstboot.sh index 192f6ce..06be606 100644 --- a/solidcore-firstboot.sh +++ b/solidcore-firstboot.sh @@ -167,9 +167,9 @@ while true; do space_1 short_msg "Numbers and special characters are permitted, but not required." space_1 - short_msg "${bold}Password length is more important than complexity.${normal}" + short_msg "${bold}Password length is more important than character complexity.${normal}" space_1 - short_msg "For example, ${italics}TwoClownsWalkedintoaBar${normal} is better than ${italics}dVc78#!_sjdRa${normal}." + short_msg "For example, ${bold}${italics}Two-Clowns-Walked-into-a-Bar${normal} is better than ${bold}${italics}dVc78#!_sjdRa${normal}." sleep 1 space_1 short_msg "Enter your new password below." @@ -205,13 +205,12 @@ if [ "$num_users" -gt 0 ]; then chage -E 0 "$username" done space_1 - short_msg "${bold}Passwords for other human users have now expired.${normal}" - short_msg "They will be prompted to update their password on the next login." + short_msg "${bold}Passwords for other users have now expired.${normal}" + short_msg "They will be prompted to update their password on next login." sleep 1 fi space_2 -space_1 # === GRUB === @@ -297,7 +296,7 @@ function prompt_for_multiselect { cursor_blink_off() { printf "$ESC[?25l"; } cursor_to() { printf "$ESC[$1;${2:-1}H"; } print_inactive() { printf "$2 $1 "; } - print_active() { printf "$2 $ESC[7m $1 $ESC[27m"; } + print_active() { printf "$2 $ESC[7m $1 $normal"; } get_cursor_row() { IFS=';' read -sdR -p $'\E[6n' ROW COL; echo ${ROW#*[}; } key_input() { local key @@ -354,7 +353,7 @@ function prompt_for_multiselect { for option in "${options[@]}"; do local prefix="[ ]" if [[ ${selected[idx]} == true ]]; then - prefix="[x]" + prefix="[${green}${bold}✓${normal}]" fi cursor_to $(($startrow + $idx)) @@ -395,14 +394,14 @@ thunderbolt_response="N" usb_response="N" # Define the options for the menu -options_1=("Printer" "Webcam (non-USB)") -options_2=("Bluetooth" "Wi-Fi") -options_3=("FireWire" "Thunderbolt" "USB") +options_1=("Printer" "Webcam (non-USB)" "None of the above") +options_2=("Bluetooth" "Wi-Fi" "None of the above") +options_3=("FireWire" "Thunderbolt" "USB" "None of the above") # Define the defaults (which options are initially selected) -defaults_1=("N" "N") -defaults_2=("N" "N") -defaults_3=("N" "N" "N") +defaults_1=("N" "N" "N") +defaults_2=("N" "N" "N") +defaults_3=("N" "N" "N" "N") # User interaction clear @@ -410,17 +409,14 @@ space_2 short_msg "You will now be given a series of questions to select what devices, wireless connections and ports you use on your device." sleep 1 space_1 -short_msg "Use the up and down arrows to cycle through the options, and use the space bar to select and de-select your choices." -space_1 -short_msg "Once you have selected your choices you can press enter to continue to the next question." -space_1 short_msg "Let's begin..." sleep 2 space_1 -short_msg "${bold}[1 of 3] Do you use any of the following devices?${normal}" +short_msg "${bold}[1 of 3]${normal} Do you use any of the following devices?" +short_msg "Use ${bold}▲ up${normal}and ${bold}▼ down${normal} to navigate, ${bold}${normal} to select, ${bold}${normal} to submit." echo -prompt_for_multiselect user_input "$(IFS=';'; echo "${options_1[*]}")" "$(IFS=';'; echo "${defaults_1[*]}")" +prompt_for_multiselect user_input "$(IFS=';'; echo "> ${options_1[*]}")" "$(IFS=';'; echo "${defaults_1[*]}")" for i in "${!user_input[@]}"; do case $i in @@ -430,10 +426,10 @@ for i in "${!user_input[@]}"; do done echo -short_msg "${bold}[2 of 3] Do you use any of the following wireless connections on this device?${normal}" +short_msg "${bold}[2 of 3]${normal} Do you use any of the following wireless connections on this device?" echo -prompt_for_multiselect user_input "$(IFS=';'; echo "${options_2[*]}")" "$(IFS=';'; echo "${defaults_2[*]}")" +prompt_for_multiselect user_input "$(IFS=';'; echo "> ${options_2[*]}")" "$(IFS=';'; echo "${defaults_2[*]}")" for i in "${!user_input[@]}"; do case $i in @@ -443,10 +439,10 @@ for i in "${!user_input[@]}"; do done echo -short_msg "${bold}[3 of 3] Which of the following ports do you use on this device?${normal}" +short_msg "${bold}[3 of 3]${normal} Which of the following ports do you use on this device?" echo -prompt_for_multiselect user_input "$(IFS=';'; echo "${options_3[*]}")" "$(IFS=';'; echo "${defaults_3[*]}")" +prompt_for_multiselect user_input "$(IFS=';'; echo "> ${options_3[*]}")" "$(IFS=';'; echo "${defaults_3[*]}")" for i in "${!user_input[@]}"; do case $i in @@ -457,9 +453,11 @@ for i in "${!user_input[@]}"; do done echo +space_2 + while true; do - - read -rp "> ${bold}Question: Do you use any hardware security keys?${normal} (y/n): " token_response + + read -rp "${bold}[USB]${normal} Do you use any hardware security keys? (y/n): " token_response case $token_response in [Yy] ) token_response="Y"; @@ -528,7 +526,7 @@ if [[ "$token_response" =~ ^[Yy]$ ]]; then done fi -short_msg "Thank you for your responses." +short_msg "Thank you for your input." sleep 1 space_1 @@ -662,7 +660,7 @@ if [[ "$usb_response" =~ ^[Yy]$ ]]; then script_path="/etc/solidcore/solidcore-secondboot.sh" # Write secondboot.sh script -cat > "$script_path" << EOF +cat > "$script_path" << OF #!/bin/bash ## Solidcore Hardening Scripts for Fedora's rpm-ostree Operating Systems @@ -861,7 +859,7 @@ if [ -x "$(command -v minisign)" ]; then fi else - short_msg "${bold}[WARN]${normal} minisign is not installed, downloaded file signature could not be verified." + short_msg "${bold}[NOTE]${normal} minisign is not installed, downloaded file signature could not be verified." space_1 fi @@ -1156,7 +1154,7 @@ sleep 2 space_2 # Check the current SELinux status and enable enforcing if required -short_msg "[1 of 3] Checking SELinux..." +short_msg "${bold}[1 of 3]${normal} Checking SELinux..." space_1 sleep 1 current_status=$(sestatus | awk '/Current mode:/ {print $3}') @@ -1171,7 +1169,7 @@ fi space_2 # HTTP check for the repos -short_msg "[2 of 3] Checking insecure URLs in the repo directory..." +short_msg "${bold}[2 of 3]${normal} Checking insecure URLs in the repo directory..." space_1 sleep 1 patterns=("^baseurl=http:" "^metalink=http:") @@ -1190,7 +1188,7 @@ done space_2 # CPU vulnerability check -short_msg "[3 of 3] Checking CPU Vulnerabilities..." +short_msg "${bold}[3 of 3]${normal} Checking CPU Vulnerabilities..." space_1 sleep 1 From 6ebb5565c91a2e2ed7418de666cda37fbdf1e0a7 Mon Sep 17 00:00:00 2001 From: solidc0re <140627847+solidc0re@users.noreply.github.com> Date: Sun, 10 Sep 2023 07:39:11 +0100 Subject: [PATCH 2/7] UX updates --- solidcore-firstboot.sh | 87 ++++++++++++++++++------------------------ 1 file changed, 38 insertions(+), 49 deletions(-) diff --git a/solidcore-firstboot.sh b/solidcore-firstboot.sh index 06be606..c7271cb 100644 --- a/solidcore-firstboot.sh +++ b/solidcore-firstboot.sh @@ -154,23 +154,24 @@ fi short_msg "As part of solidcore's hardening, new password policies were implemented." sleep 1 space_1 +short_msg "${bold}You are now required to set a new password.${normal}" +sleep 1 +space_1 +short_msg "The new password requirements are:" +short_msg " • 12 character minimum" +short_msg " • at least 1 UPPER case character" +short_msg " • at least 1 lower case character" +short_msg " • the same character can not be repeated 3+ times in a row" +short_msg " • the password must pass a dictionary test" +space_1 +short_msg "Numbers and special characters are permitted, but not required." +space_1 +short_msg "${bold}Password length is more important than character complexity.${normal}" +space_1 +short_msg "For example, ${bold}${italics}Two-Clowns-Walked-into-a-Bar${normal} is better than ${bold}${italics}dVc78#!_sjdRa${normal}." +sleep 3 + while true; do - short_msg "${bold}You are now required to set a new password.${normal}" - sleep 1 - space_1 - short_msg "The new password requirements are:" - short_msg " • 12 character minimum" - short_msg " • at least 1 UPPER case character" - short_msg " • at least 1 lower case character" - short_msg " • the same character can not be repeated 3+ times in a row" - short_msg " • the password must pass a dictionary test" - space_1 - short_msg "Numbers and special characters are permitted, but not required." - space_1 - short_msg "${bold}Password length is more important than character complexity.${normal}" - space_1 - short_msg "For example, ${bold}${italics}Two-Clowns-Walked-into-a-Bar${normal} is better than ${bold}${italics}dVc78#!_sjdRa${normal}." - sleep 1 space_1 short_msg "Enter your new password below." space_1 @@ -186,7 +187,6 @@ while true; do space_1 fi done -conf_msg "Password updated" # Expire passwords of all other users short_msg "Expiring all user passwords except for user..." @@ -219,7 +219,7 @@ space_2 short_msg "Setting a GRUB password prevents an attacker from accessing the bootloader configuration menus and terminal." space_1 while true; do -read -rp "${bold}Question: Do you want to set a GRUB password [recommended]?${normal} (y/n): " grub_response +read -rp "${bold}[Question]${normal} Do you want to set a GRUB password [recommended]? (y/n): " grub_response case $grub_response in [Yy] ) grub_response="Y"; break;; @@ -256,7 +256,7 @@ space_1 # Ask the user if they want to set a new generic hostname while true; do -read -rp "${bold}Question: Do you want to set a generic hostname [recommended]?${normal}`echo $'\n> Examples include 'hostname', 'host', 'computer', etc. (y/n) : '`" hostname_response +read -rp "${bold}[Question]${normal} Do you want to set a generic hostname [recommended]?`echo $'\n> Examples include 'hostname', 'host', 'computer', etc. (y/n) : '`" hostname_response case $hostname_response in [Yy] ) hostname_response="Y"; break;; @@ -413,10 +413,9 @@ short_msg "Let's begin..." sleep 2 space_1 short_msg "${bold}[1 of 3]${normal} Do you use any of the following devices?" -short_msg "Use ${bold}▲ up${normal}and ${bold}▼ down${normal} to navigate, ${bold}${normal} to select, ${bold}${normal} to submit." - -echo -prompt_for_multiselect user_input "$(IFS=';'; echo "> ${options_1[*]}")" "$(IFS=';'; echo "${defaults_1[*]}")" +short_msg "${bold}▲ up${normal} / ${bold}▼ down${normal} to navigate, ${bold}${normal} to select, ${bold}${normal} to submit." +echo "" +prompt_for_multiselect user_input "$(IFS=';'; echo "${options_1[*]}")" "$(IFS=';'; echo "${defaults_1[*]}")" for i in "${!user_input[@]}"; do case $i in @@ -424,12 +423,12 @@ for i in "${!user_input[@]}"; do 1) [ "${user_input[i]}" == "true" ] && webcam_response="Y" || webcam_response="N" ;; esac done -echo +echo "" short_msg "${bold}[2 of 3]${normal} Do you use any of the following wireless connections on this device?" -echo -prompt_for_multiselect user_input "$(IFS=';'; echo "> ${options_2[*]}")" "$(IFS=';'; echo "${defaults_2[*]}")" +echo "" +prompt_for_multiselect user_input "$(IFS=';'; echo "${options_2[*]}")" "$(IFS=';'; echo "${defaults_2[*]}")" for i in "${!user_input[@]}"; do case $i in @@ -437,12 +436,12 @@ for i in "${!user_input[@]}"; do 1) [ "${user_input[i]}" == "true" ] && wifi_response="Y" || wifi_response="N" ;; esac done -echo +echo "" short_msg "${bold}[3 of 3]${normal} Which of the following ports do you use on this device?" -echo -prompt_for_multiselect user_input "$(IFS=';'; echo "> ${options_3[*]}")" "$(IFS=';'; echo "${defaults_3[*]}")" +echo "" +prompt_for_multiselect user_input "$(IFS=';'; echo "${options_3[*]}")" "$(IFS=';'; echo "${defaults_3[*]}")" for i in "${!user_input[@]}"; do case $i in @@ -451,9 +450,9 @@ for i in "${!user_input[@]}"; do 2) [ "${user_input[i]}" == "true" ] && usb_response="Y" || usb_response="N" ;; esac done -echo +echo "" -space_2 +space_1 while true; do @@ -471,7 +470,7 @@ done if [[ "$token_response" =~ ^[Yy]$ ]]; then # User prompt for security key type - PS3="Select your security key type: " + PS3="Select your security key type (1 - 5): " options=("Google Titan Security Key" "Yubico's YubiKey" "Nitrokey" "OnlyKey" "Other") select opt in "${options[@]}" do @@ -515,7 +514,6 @@ if [[ "$token_response" =~ ^[Yy]$ ]]; then break ;; "Other") - space_1 short_msg "Other hardware tokens are not currently supported by this script." short_msg "Please check with your hardware security key supplier for instructions on how to implement the required udev rules." sleep 3 @@ -550,7 +548,6 @@ else systemctl disable cups > /dev/null 2>&1 systemctl --now mask cups > /dev/null 2>&1 systemctl daemon-reload - space_1 conf_msg "Printer service (CUPS) has been stopped and disabled" fi @@ -559,12 +556,10 @@ fi # Enable or disable the webcam based on user response if [[ "$webcam_response" =~ ^[Yy]$ ]]; then - space_1 conf_msg "Webcam remains enabled" else rmmod uvcvideo > /dev/null 2>&1 echo "install uvcvideo /bin/true" | tee -a "$block_file" > /dev/null - space_1 conf_msg "Webcam has been disabled and added to the kernel module blacklist" fi @@ -660,7 +655,7 @@ if [[ "$usb_response" =~ ^[Yy]$ ]]; then script_path="/etc/solidcore/solidcore-secondboot.sh" # Write secondboot.sh script -cat > "$script_path" << OF +cat > "$script_path" << EOF #!/bin/bash ## Solidcore Hardening Scripts for Fedora's rpm-ostree Operating Systems @@ -860,7 +855,6 @@ if [ -x "$(command -v minisign)" ]; then else short_msg "${bold}[NOTE]${normal} minisign is not installed, downloaded file signature could not be verified." - space_1 fi tar xz -C "$workdir" -f "$workdir/$download_file" "${PLATFORM}-${CPU_ARCH}/dnscrypt-proxy" "${PLATFORM}-${CPU_ARCH}/example-dnscrypt-proxy.toml" @@ -1189,20 +1183,17 @@ space_2 # CPU vulnerability check short_msg "${bold}[3 of 3]${normal} Checking CPU Vulnerabilities..." -space_1 -sleep 1 +echo +sleep 1 grep . /sys/devices/system/cpu/vulnerabilities/* - sleep 1 -space_1 -short_msg "${bold}Please take a note of any vulnerability that affects your CPU with no mitigation (Migitation: None).{$normal}" -sleep 2 -space_1 -short_msg "... And raise this vulnerability as an issue on the solidcore-script Github page:" -short_msg "https://github.com/solidc0re/solidcore-scripts" +echo + +short_msg "${bold}Please check that all known CPU vulnerabilities either don't affect this device, or have some mitigation applied.{$normal}" sleep 3 + # === TiDY UP & FINISH === # Reboot if USB Guard installed, otherwise farewell @@ -1211,7 +1202,6 @@ if [[ "$usb_response" =~ ^[Yy]$ ]]; then space_1 short_msg "Another script will guide you through whitelisting your USB devices." sleep 2 - space_2 read -n 1 -s -r -p "Press any key to continue..." space_1 for i in {5..1}; do @@ -1227,7 +1217,6 @@ if [[ "$usb_response" =~ ^[Yy]$ ]]; then else # Remove first boot autostart rm /etc/xdg/autostart/solidcore-welcome.desktop > /dev/null 2>&1 - sleep 1 # End short_msg "${bold}Thank you for running the solidcore script.${normal}" space_1 From 2ebd5c724a704d5510d630488f39468e68e82916 Mon Sep 17 00:00:00 2001 From: solidc0re <140627847+solidc0re@users.noreply.github.com> Date: Sun, 10 Sep 2023 08:10:33 +0100 Subject: [PATCH 3/7] fix user expiry bugs --- solidcore-firstboot.sh | 52 +++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/solidcore-firstboot.sh b/solidcore-firstboot.sh index c7271cb..4ebb1fe 100644 --- a/solidcore-firstboot.sh +++ b/solidcore-firstboot.sh @@ -172,8 +172,6 @@ short_msg "For example, ${bold}${italics}Two-Clowns-Walked-into-a-Bar${normal} i sleep 3 while true; do - space_1 - short_msg "Enter your new password below." space_1 echo passwd > /dev/null @@ -191,16 +189,16 @@ done # Expire passwords of all other users short_msg "Expiring all user passwords except for user..." -# Get the UID of the current user -current_user_uid=$(id -u) +current_user=$(whoami) +excluded_user="nfsnobody" # Count the number of non-root human users on the system -num_users=$(getent passwd | awk -F: '$3 >= 1000 && $3 != '$current_user_uid' {print $1}' | wc -l) +num_users=$(getent passwd | awk -F: '$3 >= 1000 && $1 != "'$current_user'" && $1 != "'$excluded_user'" {print $1}' | wc -l) -# Check if there are other human users besides the current user +# Check if there are other human users besides the current user and excluded user if [ "$num_users" -gt 0 ]; then - # Loop through all user accounts and exclude the current user - getent passwd | awk -F: '$3 >= 1000 && $3 != '$current_user_uid' {print $1}' | while read -r username; do + # Loop through all user accounts and exclude the current user and excluded user + getent passwd | awk -F: '$3 >= 1000 && $1 != "'$current_user'" && $1 != "'$excluded_user'" {print $1}' | while read -r username; do short_msg "Expiring password for user: $username" chage -E 0 "$username" done @@ -266,7 +264,6 @@ case $hostname_response in echo ">"; esac done -space_2 if [[ "$hostname_response" =~ ^[Yy]$ ]]; then # Create backup @@ -381,6 +378,12 @@ function prompt_for_multiselect { printf "\n" cursor_blink_on + # Remove highlighting + for ((idx=0; idx<${#options[@]}; idx++)); do + cursor_to $(($startrow + $idx)) + print_inactive "${options[idx]}" "[ ]" + done + eval $retval='("${selected[@]}")' } @@ -454,19 +457,21 @@ echo "" space_1 -while true; do +if [[ "$usb_response" =~ ^[Yy]$ ]]; then + while true; do - read -rp "${bold}[USB]${normal} Do you use any hardware security keys? (y/n): " token_response + read -rp "${bold}[USB]${normal} Do you use any hardware security keys? (y/n): " token_response - case $token_response in - [Yy] ) token_response="Y"; - break;; - [Nn] ) - break;; - * ) short_msg "Invalid response. Please retry with 'y' or 'n'." - echo ">"; - esac -done + case $token_response in + [Yy] ) token_response="Y"; + break;; + [Nn] ) + break;; + * ) short_msg "Invalid response. Please retry with 'y' or 'n'." + echo ">"; + esac + done +fi if [[ "$token_response" =~ ^[Yy]$ ]]; then # User prompt for security key type @@ -810,7 +815,6 @@ else rmmod usbcore usb_storage > /dev/null 2>&1 echo "install usb_storage /bin/true" | tee -a "$block_file" > /dev/null echo "install usbcore /bin/true" | tee -a "$block_file" > /dev/null - space_1 conf_msg "USB has been disabled and added to the kernel module blacklist" fi @@ -1190,9 +1194,9 @@ grep . /sys/devices/system/cpu/vulnerabilities/* sleep 1 echo -short_msg "${bold}Please check that all known CPU vulnerabilities either don't affect this device, or have some mitigation applied.{$normal}" -sleep 3 - +short_msg "${bold}Please check that all known CPU vulnerabilities either don't affect this device, or have some mitigation applied.${normal}" +sleep 5 +space_1 # === TiDY UP & FINISH === From 428b920856ef69853e2171bdbd093607e27356d8 Mon Sep 17 00:00:00 2001 From: solidc0re <140627847+solidc0re@users.noreply.github.com> Date: Sun, 10 Sep 2023 08:34:11 +0100 Subject: [PATCH 4/7] user interaction added for pwd resets --- solidcore-firstboot.sh | 279 +++++++++++++++++++++++------------------ 1 file changed, 158 insertions(+), 121 deletions(-) diff --git a/solidcore-firstboot.sh b/solidcore-firstboot.sh index 4ebb1fe..35b3650 100644 --- a/solidcore-firstboot.sh +++ b/solidcore-firstboot.sh @@ -110,6 +110,110 @@ space_1() { > " } +# Thanks to stackoverflow for the multiselect function +# https://stackoverflow.com/questions/45382472/bash-select-multiple-answers-at-once + +function prompt_for_multiselect { + + # little helpers for terminal print control and key input + ESC=$( printf "\033") + cursor_blink_on() { printf "$ESC[?25h"; } + cursor_blink_off() { printf "$ESC[?25l"; } + cursor_to() { printf "$ESC[$1;${2:-1}H"; } + print_inactive() { printf "$2 $1 "; } + print_active() { printf "$2 $ESC[7m $1 $normal"; } + get_cursor_row() { IFS=';' read -sdR -p $'\E[6n' ROW COL; echo ${ROW#*[}; } + key_input() { + local key + IFS= read -rsn1 key 2>/dev/null >&2 + if [[ $key = "" ]]; then echo enter; fi; + if [[ $key = $'\x20' ]]; then echo space; fi; + if [[ $key = $'\x1b' ]]; then + read -rsn2 key + if [[ $key = [A ]]; then echo up; fi; + if [[ $key = [B ]]; then echo down; fi; + fi + } + toggle_option() { + local arr_name=$1 + eval "local arr=(\"\${${arr_name}[@]}\")" + local option=$2 + if [[ ${arr[option]} == true ]]; then + arr[option]= + else + arr[option]=true + fi + eval $arr_name='("${arr[@]}")' + } + + local retval=$1 + local options + local defaults + + IFS=';' read -r -a options <<< "$2" + if [[ -z $3 ]]; then + defaults=() + else + IFS=';' read -r -a defaults <<< "$3" + fi + local selected=() + + for ((i=0; i<${#options[@]}; i++)); do + selected+=("${defaults[i]}") + printf "\n" + done + + # determine current screen position for overwriting the options + local lastrow=`get_cursor_row` + local startrow=$(($lastrow - ${#options[@]})) + + # ensure cursor and input echoing back on upon a ctrl+c during read -s + trap "cursor_blink_on; stty echo; printf '\n'; exit" 2 + cursor_blink_off + + local active=0 + while true; do + # print options by overwriting the last lines + local idx=0 + for option in "${options[@]}"; do + local prefix="[ ]" + if [[ ${selected[idx]} == true ]]; then + prefix="[${green}${bold}✓${normal}]" + fi + + cursor_to $(($startrow + $idx)) + if [ $idx -eq $active ]; then + print_active "$option" "$prefix" + else + print_inactive "$option" "$prefix" + fi + ((idx++)) + done + + # user key control + case `key_input` in + space) toggle_option selected $active;; + enter) break;; + up) ((active--)); + if [ $active -lt 0 ]; then active=$((${#options[@]} - 1)); fi;; + down) ((active++)); + if [ $active -ge ${#options[@]} ]; then active=0; fi;; + esac + done + + # cursor position back to normal + cursor_to $lastrow + printf "\n" + cursor_blink_on + + # Remove highlighting + for ((idx=0; idx<${#options[@]}; idx++)); do + cursor_to $(($startrow + $idx)) + print_inactive "${options[idx]}" "[ ]" + done + + eval $retval='("${selected[@]}")' +} # === FLAGS === @@ -186,28 +290,66 @@ while true; do fi done -# Expire passwords of all other users -short_msg "Expiring all user passwords except for user..." - +# OLD CODE - EXPIRED CURRENT USER, NOT WORKING +## Expire passwords of all other users +#short_msg "Expiring all user passwords except for user..." +# +#current_user=$(whoami) +#excluded_user="nfsnobody" +# +## Count the number of non-root human users on the system +#num_users=$(getent passwd | awk -F: '$3 >= 1000 && $1 != "'$current_user'" && $1 != "'$excluded_user'" {print $1}' | wc -l) +# +## Check if there are other human users besides the current user and excluded user +#if [ "$num_users" -gt 0 ]; then +# # Loop through all user accounts and exclude the current user and excluded user +# getent passwd | awk -F: '$3 >= 1000 && $1 != "'$current_user'" && $1 != "'$excluded_user'" {print $1}' | while read -r username; do +# short_msg "Expiring password for user: $username" +# chage -E 0 "$username" +# done +# space_1 +# short_msg "${bold}Passwords for other users have now expired.${normal}" +# short_msg "They will be prompted to update their password on next login." +# sleep 1 +#fi + +# Expire passwords based on user interaction current_user=$(whoami) excluded_user="nfsnobody" -# Count the number of non-root human users on the system -num_users=$(getent passwd | awk -F: '$3 >= 1000 && $1 != "'$current_user'" && $1 != "'$excluded_user'" {print $1}' | wc -l) +# Get a list of eligible users (UID >= 1000) excluding the current user and excluded user +eligible_users=($(getent passwd | awk -F: '$3 >= 1000 && $1 != "'$current_user'" && $1 != "'$excluded_user'" {print $1}')) -# Check if there are other human users besides the current user and excluded user -if [ "$num_users" -gt 0 ]; then - # Loop through all user accounts and exclude the current user and excluded user - getent passwd | awk -F: '$3 >= 1000 && $1 != "'$current_user'" && $1 != "'$excluded_user'" {print $1}' | while read -r username; do - short_msg "Expiring password for user: $username" - chage -E 0 "$username" - done - space_1 - short_msg "${bold}Passwords for other users have now expired.${normal}" - short_msg "They will be prompted to update their password on next login." - sleep 1 +if [ ${#eligible_users[@]} -eq 0 ]; then + short_msg "No user passwords to expire..." +else + # Define the options for the menu, including "None of the above" + options_user=("${eligible_users[@]}" "None of the above") + selected_users=() + + # User interaction + short_msg "Select the users whose passwords you want to expire." + short_msg "Use ${bold}▲ up${normal} and ${bold}▼ down${normal} to navigate, ${bold}${normal} to select, ${bold}${normal} to submit." + + prompt_for_multiselect selected_users "$(IFS=';'; echo "${options_user[*]}")" + + # Check if "None of the above" was selected or if no users were selected + if [ "${#selected_users[@]}" -eq 0 ] || [ "${selected_users[0]}" == "None of the above" ]; then + space_1 + short_msg "No users selected. Passwords remain unchanged." + else + # Loop through selected users and expire their passwords + for username in "${selected_users[@]}"; do + short_msg "Expiring password for user: $username" + chage -E 0 "$username" + done + space_1 + short_msg "${bold}Passwords for selected users have now expired.${normal}" + short_msg "They will be prompted to update their password on next login." + fi fi +sleep 2 space_2 @@ -282,111 +424,6 @@ sleep 1 # === USER INPUT FOR PORTS/DEVICES/WIRELESS === -# Thanks to stackoverflow for the multiselect function -# https://stackoverflow.com/questions/45382472/bash-select-multiple-answers-at-once - -function prompt_for_multiselect { - - # little helpers for terminal print control and key input - ESC=$( printf "\033") - cursor_blink_on() { printf "$ESC[?25h"; } - cursor_blink_off() { printf "$ESC[?25l"; } - cursor_to() { printf "$ESC[$1;${2:-1}H"; } - print_inactive() { printf "$2 $1 "; } - print_active() { printf "$2 $ESC[7m $1 $normal"; } - get_cursor_row() { IFS=';' read -sdR -p $'\E[6n' ROW COL; echo ${ROW#*[}; } - key_input() { - local key - IFS= read -rsn1 key 2>/dev/null >&2 - if [[ $key = "" ]]; then echo enter; fi; - if [[ $key = $'\x20' ]]; then echo space; fi; - if [[ $key = $'\x1b' ]]; then - read -rsn2 key - if [[ $key = [A ]]; then echo up; fi; - if [[ $key = [B ]]; then echo down; fi; - fi - } - toggle_option() { - local arr_name=$1 - eval "local arr=(\"\${${arr_name}[@]}\")" - local option=$2 - if [[ ${arr[option]} == true ]]; then - arr[option]= - else - arr[option]=true - fi - eval $arr_name='("${arr[@]}")' - } - - local retval=$1 - local options - local defaults - - IFS=';' read -r -a options <<< "$2" - if [[ -z $3 ]]; then - defaults=() - else - IFS=';' read -r -a defaults <<< "$3" - fi - local selected=() - - for ((i=0; i<${#options[@]}; i++)); do - selected+=("${defaults[i]}") - printf "\n" - done - - # determine current screen position for overwriting the options - local lastrow=`get_cursor_row` - local startrow=$(($lastrow - ${#options[@]})) - - # ensure cursor and input echoing back on upon a ctrl+c during read -s - trap "cursor_blink_on; stty echo; printf '\n'; exit" 2 - cursor_blink_off - - local active=0 - while true; do - # print options by overwriting the last lines - local idx=0 - for option in "${options[@]}"; do - local prefix="[ ]" - if [[ ${selected[idx]} == true ]]; then - prefix="[${green}${bold}✓${normal}]" - fi - - cursor_to $(($startrow + $idx)) - if [ $idx -eq $active ]; then - print_active "$option" "$prefix" - else - print_inactive "$option" "$prefix" - fi - ((idx++)) - done - - # user key control - case `key_input` in - space) toggle_option selected $active;; - enter) break;; - up) ((active--)); - if [ $active -lt 0 ]; then active=$((${#options[@]} - 1)); fi;; - down) ((active++)); - if [ $active -ge ${#options[@]} ]; then active=0; fi;; - esac - done - - # cursor position back to normal - cursor_to $lastrow - printf "\n" - cursor_blink_on - - # Remove highlighting - for ((idx=0; idx<${#options[@]}; idx++)); do - cursor_to $(($startrow + $idx)) - print_inactive "${options[idx]}" "[ ]" - done - - eval $retval='("${selected[@]}")' -} - # Initialize variables printer_response="N" webcam_response="N" From 6ea3123f4682cda0330d0fb2e15e47a782030eb0 Mon Sep 17 00:00:00 2001 From: solidc0re <140627847+solidc0re@users.noreply.github.com> Date: Sun, 10 Sep 2023 08:53:09 +0100 Subject: [PATCH 5/7] removed pwd reset for other users (not working) --- solidcore-firstboot.sh | 41 ++--------------------------------------- 1 file changed, 2 insertions(+), 39 deletions(-) diff --git a/solidcore-firstboot.sh b/solidcore-firstboot.sh index 35b3650..c124aac 100644 --- a/solidcore-firstboot.sh +++ b/solidcore-firstboot.sh @@ -290,7 +290,7 @@ while true; do fi done -# OLD CODE - EXPIRED CURRENT USER, NOT WORKING +# OLD CODE - EXPIRED CURRENT USER, NOT WORKING (expires current user pwd locking them out) ## Expire passwords of all other users #short_msg "Expiring all user passwords except for user..." # @@ -312,44 +312,7 @@ done # short_msg "They will be prompted to update their password on next login." # sleep 1 #fi - -# Expire passwords based on user interaction -current_user=$(whoami) -excluded_user="nfsnobody" - -# Get a list of eligible users (UID >= 1000) excluding the current user and excluded user -eligible_users=($(getent passwd | awk -F: '$3 >= 1000 && $1 != "'$current_user'" && $1 != "'$excluded_user'" {print $1}')) - -if [ ${#eligible_users[@]} -eq 0 ]; then - short_msg "No user passwords to expire..." -else - # Define the options for the menu, including "None of the above" - options_user=("${eligible_users[@]}" "None of the above") - selected_users=() - - # User interaction - short_msg "Select the users whose passwords you want to expire." - short_msg "Use ${bold}▲ up${normal} and ${bold}▼ down${normal} to navigate, ${bold}${normal} to select, ${bold}${normal} to submit." - - prompt_for_multiselect selected_users "$(IFS=';'; echo "${options_user[*]}")" - - # Check if "None of the above" was selected or if no users were selected - if [ "${#selected_users[@]}" -eq 0 ] || [ "${selected_users[0]}" == "None of the above" ]; then - space_1 - short_msg "No users selected. Passwords remain unchanged." - else - # Loop through selected users and expire their passwords - for username in "${selected_users[@]}"; do - short_msg "Expiring password for user: $username" - chage -E 0 "$username" - done - space_1 - short_msg "${bold}Passwords for selected users have now expired.${normal}" - short_msg "They will be prompted to update their password on next login." - fi -fi - -sleep 2 +#sleep 2 space_2 From 83b5d6b9d420994b0e0d547901e44657dd884773 Mon Sep 17 00:00:00 2001 From: solidc0re <140627847+solidc0re@users.noreply.github.com> Date: Sun, 10 Sep 2023 09:36:19 +0100 Subject: [PATCH 6/7] v0.2.6 --- solidcore-firstboot.sh | 4 ++-- solidcore-install.sh | 4 ++-- solidcore-uninstall.sh | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/solidcore-firstboot.sh b/solidcore-firstboot.sh index c124aac..3255cba 100644 --- a/solidcore-firstboot.sh +++ b/solidcore-firstboot.sh @@ -1,7 +1,7 @@ #!/bin/bash ## Solidcore Hardening Scripts for Fedora's rpm-ostree Operating Systems -## Version 0.2.5 +## Version 0.2.6 ## ## Copyright (C) 2023 solidc0re (https://github.com/solidc0re) ## @@ -664,7 +664,7 @@ cat > "$script_path" << EOF #!/bin/bash ## Solidcore Hardening Scripts for Fedora's rpm-ostree Operating Systems -## Version 0.2.5 +## Version 0.2.6 ## ## Copyright (C) 2023 solidc0re (https://github.com/solidc0re) ## diff --git a/solidcore-install.sh b/solidcore-install.sh index e1b3072..96b7a3d 100644 --- a/solidcore-install.sh +++ b/solidcore-install.sh @@ -1,7 +1,7 @@ #!/bin/bash ## Solidcore Hardening Scripts for Fedora's rpm-ostree Operating Systems -## Version 0.2.5 +## Version 0.2.6 ## ## Copyright (C) 2023 solidc0re (https://github.com/solidc0re) ## @@ -924,7 +924,7 @@ mv -f "solidcore-firstboot.sh" "/etc/solidcore/" cat > /etc/solidcore/solidcore-welcome.sh << EOF #!/bin/bash ## Solidcore Hardening Scripts for Fedora's rpm-ostree Operating Systems -## Version 0.2.5 +## Version 0.2.6 ## ## Copyright (C) 2023 solidc0re (https://github.com/solidc0re) ## diff --git a/solidcore-uninstall.sh b/solidcore-uninstall.sh index 6e39fee..e4f1d99 100644 --- a/solidcore-uninstall.sh +++ b/solidcore-uninstall.sh @@ -1,7 +1,7 @@ #!/bin/bash ## Solidcore Hardening Scripts for Fedora's rpm-ostree Operating Systems -## Version 0.2.5 +## Version 0.2.6 ## ## Copyright (C) 2023 solidc0re (https://github.com/solidc0re) ## @@ -399,7 +399,7 @@ if [[ "$uninstall_response" =~ ^[Yy]$ ]]; then cat > /etc/solidcore/solidcore-farewell.sh << EOF #!/bin/bash ## Solidcore Hardening Scripts for Fedora's rpm-ostree Operating Systems -## Version 0.2.5 +## Version 0.2.6 ## ## Copyright (C) 2023 solidc0re (https://github.com/solidc0re) ## @@ -445,7 +445,7 @@ cat > /etc/solidcore/solidcore-uninstall2.sh << EOF #!/bin/bash ## Solidcore Hardening Scripts for Fedora's rpm-ostree Operating Systems -## Version 0.2.5 +## Version 0.2.6 ## ## Copyright (C) 2023 solidc0re (https://github.com/solidc0re) ## From 0a294bd5775fb8f0b6eec2c990915bdb67dc43e8 Mon Sep 17 00:00:00 2001 From: solidc0re <140627847+solidc0re@users.noreply.github.com> Date: Sun, 10 Sep 2023 10:18:09 +0100 Subject: [PATCH 7/7] removed gnome software service --- solidcore-install.sh | 9 +++++++-- solidcore-uninstall.sh | 7 ++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/solidcore-install.sh b/solidcore-install.sh index 96b7a3d..1e7ed39 100644 --- a/solidcore-install.sh +++ b/solidcore-install.sh @@ -198,7 +198,7 @@ long_msg " > > 1. Kernel and physical hardening to reduce attack surface > 2. Drop all incoming connections, prevent IP spoofing and protect against various forms of attack -> 3. Hide sensitive kernel and file information from potential attackers +> 3. More secure DNS lookups and added blocklists > 4. Stengthen password policies > 5. Enable automatic updates for rpm-ostree and flatpaks" @@ -208,7 +208,7 @@ long_msg " > > This script is open source (GPLv3) and has been tested on Silverblue 38 by the author. > -> Hardening MAY reduce your experience of your device and is not suited for everyone." +> Hardening MAY reduce your experience of your device and is not suitable for everyone." sleep 2 space_2 @@ -322,6 +322,7 @@ files_to_backup=( "/etc/sysconfig/chronyd" "/etc/systemd/coredump.conf" "/etc/systemd/system/rpm-ostreed-automatic.timer.d/override.conf" + "/etc/xdg/autostart/org.gnome.Software.desktop" "/var/lib/dbus/machine-id" ) @@ -335,6 +336,10 @@ for source_file in "${files_to_backup[@]}"; do cp "$source_file" "$backup_file" fi done + +# Remove Gnome Software update service +rm -f /etc/xdg/autostart/org.gnome.Software.desktop + conf_msg "All backups created" fi # End of -server flag if statement diff --git a/solidcore-uninstall.sh b/solidcore-uninstall.sh index e4f1d99..35ff152 100644 --- a/solidcore-uninstall.sh +++ b/solidcore-uninstall.sh @@ -191,6 +191,7 @@ if [[ "$uninstall_response" =~ ^[Yy]$ ]]; then "/etc/sysconfig/chronyd" "/etc/systemd/coredump.conf" "/etc/systemd/system/rpm-ostreed-automatic.timer.d/override.conf" + "/etc/xdg/autostart/org.gnome.Software.desktop" "/var/lib/dbus/machine-id" ) @@ -208,7 +209,7 @@ if [[ "$uninstall_response" =~ ^[Yy]$ ]]; then conf_msg "Machine ID restored" else # Restore the backup file - cp "$backup_file" "$source_file" + cp -f "$backup_file" "$source_file" conf_msg "Backup restored for: $source_file" # Remove the backup file rm "$backup_file" @@ -556,8 +557,8 @@ for service in "${services[@]}"; do done systemctl daemon-reload -# Re-insert Firewire, USB & webcam modules -insmod dv1394 firewire-core firewire_core firewire-ohci firewire_ohci firewire-sbp2 firewire_sbp2 ohci1394 sbp2 raw1394 video1394 usbcore usb_storage uvcvideo +# Re-insert bluetooth, Firewire, USB & webcam modules +modprobe bluetooth btusb dv1394 firewire-core firewire_core firewire-ohci firewire_ohci firewire-sbp2 firewire_sbp2 ohci1394 sbp2 raw1394 video1394 usbcore usb_storage uvcvideo # Unblock Thunderbolt disabled_domains=$(boltctl list | awk '/authorized: no/ {print $1}')