Added Console logs

This commit is contained in:
Pratik
2018-12-07 03:06:32 +05:30
parent 3d0b2eaed5
commit 04e3daedf1

View File

@@ -1,10 +1,11 @@
#!/etc/bin/env bash #!/etc/bin/env bash
# Accept user name as a script argument
# Add the user to "sudo" # If no username provided
# Display the private-key on the screen and ask the user 2times to copy it # generate a random username - all lowercase
# Install sudo curl screen # Something important fails
# Restart systemctl restart ssh # Revert everything back to how it was
# Redirect every output to a logfile
# Ask the user to NOT logout yet # Ask the user to NOT logout yet
# Ask him to report back if he can login using the new user -with the ssh-private key # Ask him to report back if he can login using the new user -with the ssh-private key
# If not # If not
@@ -16,21 +17,142 @@
# User SSH-Private Key # User SSH-Private Key
# User SSH-Public key # User SSH-Public key
# Display the root-user's new password on screen # Display the root-user's new password on screen
# Something important fails
# Revert everything back to how it was
# Accept user name as a script argument
# If no username provided
# generate a random username - all lowercase
# What to do if making .bkp file fails? # What to do if making .bkp file fails?
##############################################################
# Basic checks before starting
##############################################################
# No root - no good
[ "$(id -u)" != "0" ] && {
echo "Error: You must be root to run this script, please login as root and execute the script again."
exit 1
}
# Check supported OSes
if [[ $(sed 's/\..*//' /etc/debian_version) -eq 8 ]]; then
DEB_VER_STR="jessie"
elif [[ $(sed 's/\..*//' /etc/debian_version) -eq 9 ]]; then
DEB_VER_STR="stretch"
else
printf "This version of Debian is NOT supported.\\n"
exit 1
fi
##############################################################
# Display what the script does
##############################################################
# What to do if something fails
# Catastophic failure
# Ignorable failure
# Where to find the log file
##############################################################
# Gather info
##############################################################
# Change root user's password
# Choose a user name
clear
echo "Do you want to change root password ? (y/n)"
echo "(You might want to do this if you received it as an email from your host.)"
while [[ $RESET_ROOT_PWD != "y" && $RESET_ROOT_PWD != "n" ]]; do
read -rp "Select an option [1-2]: " RESET_ROOT_PWD
done
# Ask for a user name
echo ""
echo "A new non-root user will be created for you."
read -rp "Please provide a user name - " NORM_USER_NAME
# If the user exists - ask for a different username
while [[ ! "$NORM_USER_NAME" ]] && [[ $(getent passwd "$NORM_USER_NAME" | wc -l) -gt 0 ]]; do
echo "User name either already exists or you provided an invalid username."
read -rp "Please provide a user name - " NORM_USER_NAME
done
##############################################################
# Log
##############################################################
CSI='\033['
CEND="${CSI}0m"
CRED="${CSI}1;31m"
CGREEN="${CSI}1;32m"
CVERTICAL="|"
CHORIZONTAL="_"
SCRIPT_NAME=server_harden
SCRIPT_VERSION=0.2
LOGFILE=/tmp/"$SCRIPT_NAME"_v"$SCRIPT_VERSION".log
function horizontal_fill() {
local char=$1
declare -i rep=$2
for ((x = 0; x < "$rep"; x++)); do
printf %s "$char"
done
}
function line_fill() {
horizontal_fill "$1" "$2"
printf "\\n"
}
function recap (){
local purpose=$1
local value=$2
if [[ $value ]]; then
value="[${CGREEN}${value}${CEND}]"
else
value="${CRED}-FAILED-${CEND}"
fi
horizontal_fill "$CVERTICAL" 1
printf "%20s:%5s%-33s" "$purpose" " " "$(echo -e "$value")"
line_fill "$CVERTICAL" 1
}
function finally(){
#local what_failed=$1
line_fill "$CHORIZONTAL" 60
recap "New root Password" "$PASS_ROOT"
recap "User Name" "$NORM_USER_NAME"
recap "User's Password" "$USER_PASS"
recap "User's SSH Private Key Location" "$KEY_PASS"
recap "User's SSH Public Key Location" "$KEY_PASS"
recap "User's SSH Key Passphrase" "$KEY_PASS"
line_fill "$CHORIZONTAL" 60
}
function log() {
local EVENT=$1
local RESULT=$2
if [ "$RESULT" = "SUCCESSFUL" ]
then
printf "%30s %7s [${CGREEN}${RESULT}${CEND}]\\n" "$EVENT" " "
echo "$(date '+%Y-%m-%d %H:%M:%S')" - "$EVENT" - "$RESULT" >> "$LOGFILE"
elif [ "$RESULT" = "FAILED" ]
then
printf "%30s %7s [${CRED}${RESULT}${CEND}]\\n" "$EVENT" " "
printf "\\n\\nPlease look at %s\\n\\n" "$LOGFILE"
echo "$(date '+%Y-%m-%d %H:%M:%S')" - "$EVENT" - "$RESULT" >> "$LOGFILE"
else
printf "%30s %7s [${CRED}..${CEND}]\\r" "$EVENT" " "
echo "$(date '+%Y-%m-%d %H:%M:%S')" - "$EVENT" - "begin..." >> "$LOGFILE"
fi
}
declare SESSION_TYPE="" declare SESSION_TYPE=""
##############################################################
# Change root's password
##############################################################
# Check if the user connected through SSH # Check if the user connected through SSH
if [ -n "$SSH_CLIENT" ] || [ -n "$SSH_TTY" ]; then if [[ -n "$SSH_CLIENT" ]] || [[ -n "$SSH_TTY" ]]; then
SESSION_TYPE=remote/ssh SESSION_TYPE=remote/ssh
else else
case $(ps -o comm= -p $PPID) in case $(ps -o comm= -p $PPID) in
@@ -39,82 +161,34 @@ else
esac esac
fi fi
if [ $SESSION_TYPE == "remote/ssh" ]; then if [[ $SESSION_TYPE == "remote/ssh" ]]; then
printf "You are currently connected to an SSH session.\n" printf "You are currently connected to an SSH session.\\n"
else else
printf "You are currently connected using password authentication.\n" printf "You are currently connected using password authentication.\\n"
fi fi
{
##############################################################
# Change root's password
##############################################################
if [[ $RESET_ROOT_PWD == 'y' ]]; then
{
log "Changing root password"
# Generate a 15 character random password # Generate a 15 character random password
PASS_ROOT="$(< /dev/urandom tr -cd "[:alnum:]" | head -c 15)" || exit 1 PASS_ROOT="$(< /dev/urandom tr -cd "[:alnum:]" | head -c 15)" || exit 1
# Change root's password # Change root's password
echo -e "${PASS_ROOT}\n${PASS_ROOT}" | passwd > /dev/null echo -e "${PASS_ROOT}\\n${PASS_ROOT}" | passwd > /dev/null
} }
if [[ $? -eq 0 ]]; then if [[ $? -eq 0 ]]; then
printf "Successully changed root password.\n" log "Changing root password" "SUCCESSFUL"
else else
printf "Could not reset root password.\n" # Low priority - since we are disabling root login anyways
exit 1 log "Changing root password" "FAILED"
fi fi
##############################################################
# Change default source-list
##############################################################
if [[ $(sed 's/\..*//' /etc/debian_version) -eq 8 ]]; then
DEB_VER_STR="jessie"
elif [[ $(sed 's/\..*//' /etc/debian_version) -eq 9 ]]; then
DEB_VER_STR="stretch"
else
printf "This version of Debian is NOT supported.\n"
exit 1
fi
mv /etc/apt/sources.list /etc/apt/sources.list.bak
sed -i "1,$(wc -l < /etc/apt/sources.list.bak) s/^/#/" /etc/apt/sources.list.bak
# Find any additional sources listed by the provider and comment them out
if [[ $(ls -fL /etc/apt/source*/*.list | wc -l ) -gt 0 ]]; then
for file in /etc/apt/source*/*.list;
do
mv "$file" "$file".bak
sed -i "1,$(wc -l < "$file") s/^/#/" "$file" >&2 /dev/null
done
fi
# Default sources list for debian
cat <<TAG > /etc/apt/sources.list || exit 1
deb https://deb.debian.org/debian ${DEB_VER_STR} main
deb-src https://deb.debian.org/debian ${DEB_VER_STR} main
## Major bug fix updates produced after the final release of the
## distribution.
deb http://security.debian.org ${DEB_VER_STR}/updates main
deb-src http://security.debian.org ${DEB_VER_STR}/updates main
deb https://deb.debian.org/debian ${DEB_VER_STR}-updates main
deb-src https://deb.debian.org/debian ${DEB_VER_STR}-updates main
deb https://deb.debian.org/debian ${DEB_VER_STR}-backports main
deb-src https://deb.debian.org/debian ${DEB_VER_STR}-backports main
TAG
# Comment out cloud-init generated templates for sources
if [[ $(ls -fL /etc/cloud/templates*/*.tmpl | wc -l ) -gt 0 ]]; then
for file in /etc/cloud/templates*/*.tmpl;
do
mv "$file" "$file".bak
sed -i "1,$(wc -l < "$file") s/^/#/" "$file" >&2 /dev/null
done
fi
if [[ $? -eq 0 ]]; then
printf "Successfully updated the source list.\n"
else
printf "Updating source list failed.\n"
fi fi
@@ -122,39 +196,38 @@ fi
# Create a normal user # Create a normal user
############################################################## ##############################################################
{ {
clear log "Creating new user"
# Ask for a user name
read -rp "Please provide a user name - " NORM_USER_NAME
# If the user exists - ask for a different username
while [ $(getent passwd "$NORM_USER_NAME" | wc -l) -gt 0 ]; do
echo "${NORM_USER_NAME} already exists."
read -rp "Please provide another user name - " NORM_USER_NAME
done
# Generate a 15 character random password # Generate a 15 character random password
USER_PASS="$(< /dev/urandom tr -cd "[:alnum:]" | head -c 15)" || exit 1 USER_PASS="$(< /dev/urandom tr -cd "[:alnum:]" | head -c 15)" || exit 1
# Create the user and assign the above password # Create the user and assign the above password
echo -e "${USER_PASS}\n${USER_PASS}" | adduser "$NORM_USER_NAME" -q --gecos "First Last,RoomNumber,WorkPhone,HomePhone" 2> /dev/null echo -e "${USER_PASS}\\n${USER_PASS}" | adduser "$NORM_USER_NAME" -q --gecos "First Last,RoomNumber,WorkPhone,HomePhone" 2> /dev/null
# Give root privilages to the above user # Give root privilages to the above user
usermod -aG sudo "$NORM_USER_NAME" || exit 1 usermod -aG sudo "$NORM_USER_NAME" || exit 1
} }
if [[ $? -eq 0 ]]; then if [[ $? -eq 0 ]]; then
printf "Successfully created new user %s.\n" "$NORM_USER_NAME" log "Creating new user" "SUCCESSFUL"
else else
printf "Creating new user failed.\n" log "Creating new user" "FAILED"
finally "CNU"
exit 1; exit 1;
fi fi
############################################################## ##############################################################
# Create SSH Key for the new user created # Create SSH Key for the new user
############################################################## ##############################################################
{ {
log "Creating SSH Key for new user"
shopt -s nullglob
KEY_FILES=("$SSH_DIR"/"$NORM_USER_NAME".pem*)
# Create key file only if it does NOT exist
if [[ ! ${KEY_FILES[0]} ]]; then
SSH_DIR=/home/"$NORM_USER_NAME"/.ssh SSH_DIR=/home/"$NORM_USER_NAME"/.ssh
mkdir "$SSH_DIR" || exit 1 mkdir "$SSH_DIR" || exit 1
@@ -164,8 +237,41 @@ fi
# Create a OpenSSH-compliant ed25519-type key # Create a OpenSSH-compliant ed25519-type key
ssh-keygen -a 1000 -o -t ed25519 -N "$KEY_PASS" -C "$NORM_USER_NAME" -f "$SSH_DIR"/"$NORM_USER_NAME".pem -q || exit 1 ssh-keygen -a 1000 -o -t ed25519 -N "$KEY_PASS" -C "$NORM_USER_NAME" -f "$SSH_DIR"/"$NORM_USER_NAME".pem -q || exit 1
KEY_FILES=("$SSH_DIR"/"$NORM_USER_NAME".pem*)
fi
}
if [[ $? -eq 0 ]]; then
log "Creating SSH Key for new user" "SUCCESSFUL"
else
log "Creating SSH Key for new user" "FAILED"
finally "CSK"
exit 1;
fi
##############################################################
# Add generated key to authorized_keys file
##############################################################
{
log "Adding SSH Key to 'authorized_keys' file"
# Insert the public key into "authoried_keys" file # Insert the public key into "authoried_keys" file
cat "$SSH_DIR"/"$NORM_USER_NAME".pem.pub >> "$SSH_DIR"/authorized_keys || exit 1 cat "${KEY_FILES[1]}" >> "$SSH_DIR"/authorized_keys || exit 1
}
if [[ $? -eq 0 ]]; then
log "Adding SSH Key to 'authorized_keys' file" "SUCCESSFUL"
else
log "Adding SSH Key to 'authorized_keys' file" "FAILED"
finally "ATAF"
exit 1;
fi
##############################################################
# Secure authorized_keys file
##############################################################
{
log "Securing 'authorized_keys' file"
# Set appropriate permissions for ".ssh" dir and "authorized_key" file # Set appropriate permissions for ".ssh" dir and "authorized_key" file
chown -R "$NORM_USER_NAME" "$SSH_DIR" && \ chown -R "$NORM_USER_NAME" "$SSH_DIR" && \
@@ -175,10 +281,9 @@ fi
chattr +i "$SSH_DIR"/authorized_keys chattr +i "$SSH_DIR"/authorized_keys
} }
if [[ $? -eq 0 ]]; then if [[ $? -eq 0 ]]; then
printf "Successfully created SSH keys.\n%s" "${SSH_DIR}/${NORM_USER_NAME}".pem log "Securing 'authorized_keys' file" "SUCCESSFUL"
else else
printf "Creating SSH key failed.\n" log "Securing 'authorized_keys' file" "FAILED"
exit 1;
fi fi
@@ -186,9 +291,6 @@ fi
# Enable SSH-only login # Enable SSH-only login
############################################################## ##############################################################
# Backup the sshd_config file
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak || exit 1
function config_search_regex(){ function config_search_regex(){
local search_key=$1 local search_key=$1
declare -i isCommented=$2 declare -i isCommented=$2
@@ -213,7 +315,6 @@ function config_search_regex(){
fi fi
} }
function set_config_key(){ function set_config_key(){
local file_location=$1 local file_location=$1
local key=$2 local key=$2
@@ -266,19 +367,94 @@ function set_config_key(){
fi fi
} }
# Remove root login {
set_config_key "/etc/ssh/sshd_config" "PermitRootLogin" "no" log "Enabling SSH-only login"
# Disable password login # Backup the sshd_config file
set_config_key "/etc/ssh/sshd_config" "PasswordAuthentication" "no" cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak || exit 1
# Set SSH Authorization-Keys path # Remove root login
set_config_key "/etc/ssh/sshd_config" "AuthorizedKeysFile" '%h\/\.ssh\/authorized_keys' set_config_key "/etc/ssh/sshd_config" "PermitRootLogin" "no"
# Disable password login
set_config_key "/etc/ssh/sshd_config" "PasswordAuthentication" "no"
# Set SSH Authorization-Keys path
set_config_key "/etc/ssh/sshd_config" "AuthorizedKeysFile" '%h\/\.ssh\/authorized_keys'
systemctl restart sshd
}
if [[ $? -eq 0 ]]; then
log "Enabling SSH-only login" "SUCCESSFUL"
else
log "Enabling SSH-only login" "FAILED"
finally "ESOL"
exit 1;
fi
############################################################## ##############################################################
# Enable SSH-only login # Change default source-list
############################################################## ##############################################################
systemctl restart sshd # Low priority - But what to do if it fails???
log "Changing urls in sources.list to defaults"
mv /etc/apt/sources.list /etc/apt/sources.list.bak
sed -i "1,$(wc -l < /etc/apt/sources.list.bak) s/^/#/" /etc/apt/sources.list.bak
# Default sources list for debian
cat <<TAG > /etc/apt/sources.list || exit 1
deb https://deb.debian.org/debian ${DEB_VER_STR} main
deb-src https://deb.debian.org/debian ${DEB_VER_STR} main
## Major bug fix updates produced after the final release of the
## distribution.
deb http://security.debian.org ${DEB_VER_STR}/updates main
deb-src http://security.debian.org ${DEB_VER_STR}/updates main
deb https://deb.debian.org/debian ${DEB_VER_STR}-updates main
deb-src https://deb.debian.org/debian ${DEB_VER_STR}-updates main
deb https://deb.debian.org/debian ${DEB_VER_STR}-backports main
deb-src https://deb.debian.org/debian ${DEB_VER_STR}-backports main
TAG
# Find any additional sources listed by the provider and comment them out
SOURCE_FILES=(/etc/apt/source*/*.list)
if [[ ${#SOURCE_FILES[@]} -gt 0 ]]; then
for file in "${SOURCE_FILES[@]}";
do
mv "$file" "$file".bak
sed -i "1,$(wc -l < "$file") s/^/#/" "$file" >&2 /dev/null
done
fi
# Comment out cloud-init generated templates for sources
CLOUD_INIT_FILES=(/etc/cloud/templates*/*.tmpl)
if [[ ${#CLOUD_INIT_FILES[@]} -gt 0 ]]; then
for file in "${CLOUD_INIT_FILES[@]}";
do
mv "$file" "$file".bak
sed -i "1,$(wc -l < "$file") s/^/#/" "$file" >&2 /dev/null
done
fi
if [[ $? -eq 0 ]]; then
log "Changing urls in sources.list to defaults" "FAILED"
else
log "Changing urls in sources.list to defaults" "FAILED"
fi
##############################################################
# Install required softwares
##############################################################
apt-get update && apt-get upgrade -y && apt-get install -y sudo curl screen
##############################################################
# Recap
##############################################################
finally