Run the following script to verify local interactive user dot files
- Don't include .forward, .rhost, or .netrc files
- Are mode 0644 or more restrictive
- Are owned by the local interactive user
- Are group owned by the user's primary group
- .bash_history is mode 0600 or more restrictive
Note: If a .netrc file is required, and follows local site policy, it should be mode 0600 or more restrictive.
#!/usr/bin/env bash{a_output2=();a_output3=()l_maxsize="1000"# Maximum number of local interactive users before warning (Default 1,000)l_valid_shells="^($(awk-F\/'$NF != "nologin" {print}'/etc/shells|sed-rn'/^\//{s,/,\\\\/,g;p}'|paste-s-d'|'-))$"a_user_and_home=()# Create array with local users and their home directorieswhileread-rl_local_userl_local_user_home;do# Populate array with users and user home location[[-n"$l_local_user"&&-n"$l_local_user_home"]]&&a_user_and_home+=("$l_local_user:$l_local_user_home")done<<<"$(awk-vpat="$l_valid_shells"-F:'$(NF) ~ pat { print $1 " " $(NF-1) }'/etc/passwd)"l_asize="${#a_user_and_home[@]}"# Here if we want to look at number of users before proceeding["${#a_user_and_home[@]}"-gt"$l_maxsize"]&&printf'%s\n'""" ** INFO **"\"-\"$l_asize\"Localinteractiveusersfoundonthesystem" \" - This may be a long running check"""file_access_chk(){a_access_out=()l_max="$(printf'%o'$((0777&~$l_mask)))"if[$(($l_mode&$l_mask))-gt0];thena_access_out+=(" - File: \"$l_hdfile\" is mode: \"$l_mode\" and should be mode: \"$l_max\" or more restrictive")fiif[[!"$l_owner"=~($l_user)]];thena_access_out+=(" - File: \"$l_hdfile\" owned by: \"$l_owner\" and should be owned by \"${l_user//|/ or }\"")fiif[[!"$l_gowner"=~($l_group)]];thena_access_out+=(" - File: \"$l_hdfile\" group owned by: \"$l_gowner\" and should be group owned by \"${l_group//|/ or }\"")fi}whileIFS=:read-rl_userl_home;doa_dot_file=();a_netrc=();a_netrc_warn=();a_bhout=();a_hdirout=()if[-d"$l_home"];thenl_group="$(id-gn"$l_user"|xargs)";l_group="${l_group// /|}"whileIFS=read-r-d$'\0'l_hdfile;dowhileread-rl_model_ownerl_gowner;docase"$(basename"$l_hdfile")"in.forward|.rhost)a_dot_file+=(" - File: \"$l_hdfile\" exists");;.netrc)l_mask='0177';file_access_chk
if["${#a_access_out[@]}"-gt0];thena_netrc+=("${a_access_out[@]}")elsea_netrc_warn+=("- File: \"$l_hdfile\" exists")fi;;.bash_history)l_mask='0177';file_access_chk
["${#a_access_out[@]}"-gt0]&&a_bhout+=("${a_access_out[@]}");;*)l_mask='0133';file_access_chk
["${#a_access_out[@]}"-gt0]&&a_hdirout+=("${a_access_out[@]}");;esacdone<<(stat-Lc'%#a %U %G'"$l_hdfile")done<<(find"$l_home"-xdev-typef-name'.*'-print0)fiif[["${#a_dot_file[@]}"-gt0||"${#a_netrc[@]}"-gt0||"${#a_bhout[@]}"-gt0||"${#a_hdirout[@]}"-gt0]];thena_output2+=(" - User: \"$l_user\" Home Directory: \"$l_home\"""${a_dot_file[@]}""${a_netrc[@]}""${a_bhout[@]}""${a_hdirout[@]}")fi["${#a_netrc_warn[@]}"-gt0]&&a_output3+=(" - User: \"$l_user\" Home Directory: \"$l_home\"""${a_netrc_warn[@]}")done<<<"$(printf'%s\n'"${a_user_and_home[@]}")"if["${#a_output2[@]}"-le0];then# If l_output2 is empty, we pass["${#a_output3[@]}"-gt0]&&printf'%s\n'" ** WARNING **""${a_output3[@]}"printf'%s\n'"- Audit Result:"" ** PASS **"elseprintf'%s\n'"- Audit Result:"" ** FAIL **"" - * Reasons for audit failure * :""${a_output2[@]}"""["${#a_output3[@]}"-gt0]&&printf'%s\n'" ** WARNING **""${a_output3[@]}"fi}
Making global modifications to users' files without alerting the user community can result in unexpected outages and unhappy users. Therefore, it is recommended that a monitoring policy be established to report user dot file permissions and determine the action to be taken in accordance with site policy.
The following script will:
- remove excessive permissions on dot files within interactive users' home directories
- change ownership of dot files within interactive users' home directories to the user
- change group ownership of dot files within interactive users' home directories to the user's primary group
- list .forward and .rhost files to be investigated and manually deleted
#!/usr/bin/env bash{a_output2=();a_output3=()l_maxsize="1000"# Maximum number of local interactive users before warning (Default 1,000)l_valid_shells="^($(awk-F\/'$NF != "nologin" {print}'/etc/shells|sed-rn'/^\//{s,/,\\\\/,g;p}'|paste-s-d'|'-))$"a_user_and_home=()# Create array with local users and their home directorieswhileread-rl_local_userl_local_user_home;do# Populate array with users and user home location[[-n"$l_local_user"&&-n"$l_local_user_home"]]&&a_user_and_home+=("$l_local_user:$l_local_user_home")done<<<"$(awk-vpat="$l_valid_shells"-F:'$(NF) ~ pat { print $1 " " $(NF-1) }'/etc/passwd)"l_asize="${#a_user_and_home[@]}"# Here if we want to look at number of users before proceeding["${#a_user_and_home[@]}"-gt"$l_maxsize"]&&printf'%s\n'""" ** INFO **"\"-\"$l_asize\"Localinteractiveusersfoundonthesystem" \" - This may be a long running check"""file_access_fix(){a_access_out=()l_max="$(printf'%o'$((0777&~$l_mask)))"if[$(($l_mode&$l_mask))-gt0];thenprintf'%s\n'""" - File: \"$l_hdfile\" is mode: \"$l_mode\" and should be mode: \"$l_max\" or more restrictive"\"Updatingfile:\"$l_hdfile\"tobemode:\"$l_max\"ormorerestrictive"chmod "$l_change" "$l_hdfile"fiif [[ ! "$l_owner" =~ ($l_user) ]]; thenprintf '%s\n' "" "-File:\"$l_hdfile\"ownedby:\"$l_owner\"andshouldbeownedby\"${l_user//|/ or }\"" \"Updating file: \"$l_hdfile\" to be owned by \"${l_user//|/ or }\""chown"$l_user""$l_hdfile"fiif[[!"$l_gowner"=~($l_group)]];thenprintf'%s\n'""" - File: \"$l_hdfile\" group owned by: \"$l_gowner\" and should be group owned by \"${l_group//|/ or }\""\"Updatingfile:\"$l_hdfile\"tobegroupownedby\"${l_group//|/ or }\""chgrp "$l_group" "$l_hdfile"fi}while IFS=: read -r l_user l_home; doa_dot_file=(); a_netrc=(); a_netrc_warn=(); a_bhout=(); a_hdirout=()if [ -d "$l_home" ]; thenl_group="$(id-gn"$l_user"|xargs)";l_group="${l_group// /|}"while IFS= read -r -d $'\0' l_hdfile; dowhile read -r l_mode l_owner l_gowner; docase "$(basename"$l_hdfile")" in .forward | .rhost )a_dot_file+=("-File:\"$l_hdfile\"exists" "Pleasereviewandmanuallydeletethisfile") ;; .netrc )l_mask='0177'; l_change="u-x,go-rwx"; file_access_fixa_netrc_warn+=("-File:\"$l_hdfile\"exists") ;; .bash_history )l_mask='0177'; l_change="u-x,go-rwx"; file_access_fix ;; * )l_mask='0133'; l_change="u-x,go-wx"; file_access_fix ;;esacdone < <(stat -Lc '%#a %U %G' "$l_hdfile")done < <(find "$l_home" -xdev -type f -name '.*' -print0)fi[ "${#a_dot_file[@]}" -gt 0 ] && a_output2+=("-User:\"$l_user\"HomeDirectory:\"$l_home\"" "${a_dot_file[@]}")[ "${#a_netrc_warn[@]}" -gt 0 ] && a_output3+=("-User:\"$l_user\"HomeDirectory:\"$l_home\"" "${a_netrc_warn[@]}")done <<< "$(printf'%s\n'"${a_user_and_home[@]}")"[ "${#a_output3[@]}" -gt 0 ] && printf '%s\n' "" "**WARNING**" "${a_output3[@]}" ""[ "${#a_output2[@]}" -gt 0 ] && printf '%s\n' "" "${a_output2[@]}"}