Compare commits

..

1 Commits

Author SHA1 Message Date
Nick Heppler
2b420c119e Sets the system timezone based on geolocation or user input. 2024-12-28 11:22:28 -05:00

345
setup.sh
View File

@ -1,23 +1,28 @@
#!/bin/bash #!/bin/bash
#
# Script to update a RHEL-based Linux system, set the timezone, change the hostname, # Script to perform system maintenance on a RHEL-based Linux system.
# add a limited user account, modify sshd_config settings, and optionally install Docker CE #
# This script:
# - Updates package manager and installed packages
# - Sets the system timezone based on geolocation or user input
# - Changes the system hostname and updates /etc/hosts
# - Creates a limited user account and modifies SSH settings
# - Optionally installs Docker CE
#
# Prerequisites:
# - The script must be run as root or with sudo privileges
#
# Usage:
# - Run the script directly on the system or via SSH.
# - Respond to prompts as required during the script execution.
# Variables # Variables
timezone="America/New_York"
sshd_config="/etc/ssh/sshd_config" sshd_config="/etc/ssh/sshd_config"
docker_installed=false docker_installed=false
# Function to prompt for hostname with validation # Function to prompt for hostname
prompt_for_hostname() { prompt_for_hostname() {
while true; do read -p "Please enter the desired hostname: " hostname
read -p "Please enter the desired hostname: " hostname
if [[ -z "$hostname" ]]; then
echo "Hostname cannot be empty. Please try again."
else
break
fi
done
} }
# Function to add hostname and IP to /etc/hosts # Function to add hostname and IP to /etc/hosts
@ -25,7 +30,7 @@ update_hosts_file() {
local ip_address local ip_address
ip_address=$(hostname -I | awk '{print $1}') ip_address=$(hostname -I | awk '{print $1}')
echo "Updating /etc/hosts with IP $ip_address and hostname $hostname..." echo "Updating /etc/hosts with IP $ip_address and hostname $hostname..."
# Check if the entry already exists # Check if the entry already exists
if grep -q "$ip_address" /etc/hosts; then if grep -q "$ip_address" /etc/hosts; then
echo "Entry for $ip_address already exists in /etc/hosts." echo "Entry for $ip_address already exists in /etc/hosts."
@ -36,33 +41,22 @@ update_hosts_file() {
fi fi
} }
# Function to prompt for Docker installation with validation # Function to prompt for Docker installation
prompt_for_docker_install() { prompt_for_docker_install() {
while true; do read -p "Would you like to install Docker CE? (y/n): " install_docker
read -p "Would you like to install Docker CE? (y/n): " install_docker if [[ "$install_docker" =~ ^[Yy]$ ]]; then
case "$install_docker" in install_docker
[Yy]*) install_docker ;; else
[Nn]*) echo "Skipping Docker installation."; break ;; echo "Skipping Docker installation."
*) echo "Invalid input. Please enter 'y' or 'n'." ;; fi
esac
done
} }
# Function to install Docker # Function to install Docker
install_docker() { install_docker() {
echo "Installing Docker CE..." echo "Installing Docker CE..."
curl -fsSL https://get.docker.com -o get-docker.sh curl -fsSL https://get.docker.com -o get-docker.sh
if [ $? -ne 0 ]; then
echo "Error downloading Docker installation script."
exit 1
fi
sh get-docker.sh sh get-docker.sh
if [ $? -ne 0 ]; then
echo "Error installing Docker."
exit 1
fi
# Start and enable Docker service # Start and enable Docker service
systemctl start docker systemctl start docker
systemctl enable docker systemctl enable docker
@ -70,21 +64,23 @@ install_docker() {
usermod -aG docker "$username" usermod -aG docker "$username"
echo "User $username added to the docker group." echo "User $username added to the docker group."
# Clean up get-docker.sh
rm -f get-docker.sh
} }
# Function to create a limited user account with validation # Function to create a limited user account
create_user_account() { create_user_account() {
while true; do read -p "Please enter the username for the new user account: " username
read -p "Please enter the username for the new user account: " username
if [[ -z "$username" ]]; then
echo "Username cannot be empty. Please try again."
else
break
fi
done
read -sp "Please enter the password for the new user account: " password read -sp "Please enter the password for the new user account: " password
echo echo
read -sp "Please confirm the password: " password_confirm
echo
if [ "$password" != "$password_confirm" ]; then
echo "Passwords do not match. Exiting."
exit 1
fi
# Create the user and add to the wheel group # Create the user and add to the wheel group
if id "$username" &>/dev/null; then if id "$username" &>/dev/null; then
@ -96,116 +92,177 @@ create_user_account() {
fi fi
} }
# Function to check if running as root # Check if the script is run as root
check_root() { if [ "$(id -u)" -ne 0 ]; then
if [ "$(id -u)" -ne 0 ]; then echo "This script must be run as root. Please use sudo or switch to root."
echo "This script must be run as root. Please use sudo or switch to root." exit 1
exit 1 fi
fi
# Update the package manager
echo "Updating package manager..."
if command -v dnf &> /dev/null; then
dnf -y makecache
elif command -v yum &> /dev/null; then
yum -y makecache
else
echo "Neither dnf nor yum found. This script only works on RHEL-based distributions."
exit 1
fi
# Upgrade installed packages
echo "Upgrading installed packages..."
if command -v dnf &> /dev/null; then
dnf -y upgrade
elif command -v yum &> /dev/null; then
yum -y update
fi
# Change the timezone
# Function to set the timezone to UTC in case of an error
set_utc_timezone() {
echo "Error occurred while determining the timezone. Falling back to UTC."
timedatectl set-timezone UTC
} }
# Function to update package manager cache # Function to get the timezone from the ipinfo.io API
update_package_manager() { get_timezone_from_api() {
echo "Updating package manager..." # Fetch geolocation information using the ipinfo.io API
if command -v dnf &> /dev/null; then response=$(curl -s https://ipinfo.io)
dnf -y makecache
elif command -v yum &> /dev/null; then # Check if the curl command succeeded and the response contains the 'timezone' field
yum -y makecache if [ $? -eq 0 ] && echo "$response" | grep -q "timezone"; then
else # Extract the timezone directly from the JSON response
echo "Neither dnf nor yum found. This script only works on RHEL-based distributions." timezone=$(echo "$response" | jq -r '.timezone')
exit 1
fi echo "Detected timezone: $timezone"
return 0
else
set_utc_timezone
return 1
fi
} }
# Function to upgrade installed packages # Function to prompt the user to choose a timezone
upgrade_packages() { prompt_for_timezone() {
echo "Upgrading installed packages..." echo ""
if command -v dnf &> /dev/null; then echo "Choose a timezone option:"
dnf -y upgrade echo "1) Use the detected timezone ($1)"
elif command -v yum &> /dev/null; then echo "2) Use UTC"
yum -y update echo "3) Enter a custom timezone"
fi
# Read user choice
read -p "Enter the number corresponding to your choice: " choice
case "$choice" in
1)
echo "You chose to use the detected timezone: $1"
timedatectl set-timezone "$1"
;;
2)
echo "You chose to use UTC."
timedatectl set-timezone UTC
;;
3)
# Ask for a custom timezone
read -p "Enter your preferred timezone (e.g., Europe/London, America/New_York): " custom_timezone
if timedatectl list-timezones | grep -q "$custom_timezone"; then
timedatectl set-timezone "$custom_timezone"
else
echo "Invalid timezone. Falling back to UTC."
timedatectl set-timezone UTC
fi
;;
*)
echo "Invalid choice. Falling back to UTC."
timedatectl set-timezone UTC
;;
esac
} }
# Function to change the timezone # Main script execution starts here
set_timezone() { echo "Attempting to detect and set the timezone..."
echo "Setting timezone to $timezone..."
timedatectl set-timezone "$timezone"
}
# Function to change the hostname # Try to get the detected timezone from the API
set_hostname() { if get_timezone_from_api; then
prompt_for_hostname # If the timezone was successfully detected, prompt the user for their choice
echo "Setting hostname to $hostname..." prompt_for_timezone "$timezone"
hostnamectl set-hostname "$hostname" else
} # If no timezone was detected, ask the user to fall back to UTC
echo "Unable to detect timezone. Falling back to UTC."
timedatectl set-timezone UTC
fi
# Function to modify sshd_config # Change the hostname
modify_sshd_config() { prompt_for_hostname
echo "Modifying SSH configuration..." echo "Setting hostname to $hostname..."
if [ -f "$sshd_config" ]; then hostnamectl set-hostname "$hostname"
# Set PermitRootLogin to no
sed -i 's/^PermitRootLogin .*/PermitRootLogin no/' "$sshd_config" || echo "PermitRootLogin no" >> "$sshd_config"
# Set PasswordAuthentication to no # Update /etc/hosts
if grep -q '^#PasswordAuthentication' "$sshd_config"; then
sed -i 's/^#PasswordAuthentication.*/PasswordAuthentication no/' "$sshd_config"
else
sed -i 's/^PasswordAuthentication .*/PasswordAuthentication no/' "$sshd_config" || echo "PasswordAuthentication no" >> "$sshd_config"
fi
# Ensure AddressFamily inet is set
if grep -q '^#AddressFamily' "$sshd_config"; then
sed -i 's/^#AddressFamily.*/AddressFamily inet/' "$sshd_config"
else
sed -i 's/^AddressFamily .*/AddressFamily inet/' "$sshd_config" || echo "AddressFamily inet" >> "$sshd_config"
fi
else
echo "sshd_config file not found. Exiting."
exit 1
fi
}
# Function to restart SSH service
restart_ssh() {
echo "Restarting SSH service..."
systemctl restart sshd
}
# Function to wait for SSH key copy
wait_for_key_copy() {
echo "Waiting for your public key to be copied..."
while true; do
if [ -s "/home/$username/.ssh/authorized_keys" ]; then
echo "Public key has been successfully copied."
break
fi
sleep 2
done
}
# Function to clean up unused packages
cleanup() {
echo "Cleaning up..."
if command -v dnf &> /dev/null; then
dnf -y autoremove
elif command -v yum &> /dev/null; then
yum -y autoremove
fi
}
# Main execution
check_root
update_package_manager
upgrade_packages
set_timezone
set_hostname
update_hosts_file update_hosts_file
create_user_account
modify_sshd_config
restart_ssh
wait_for_key_copy
prompt_for_docker_install
cleanup
echo "System update complete! Timezone set to $timezone, hostname set to $hostname, limited user created, sshd_config modified, and Docker installation completed if selected." # Create a limited user account
create_user_account
# Modify sshd_config
echo "Modifying SSH configuration..."
if [ -f "$sshd_config" ]; then
# Set PermitRootLogin to no
if ! grep -q "^PermitRootLogin" "$sshd_config"; then
echo "PermitRootLogin no" >> "$sshd_config"
else
sed -i 's/^PermitRootLogin.*/PermitRootLogin no/' "$sshd_config"
fi
# Set PasswordAuthentication to no
if grep -q '^#PasswordAuthentication' "$sshd_config"; then
sed -i 's/^#PasswordAuthentication.*/PasswordAuthentication no/' "$sshd_config"
else
sed -i 's/^PasswordAuthentication .*/PasswordAuthentication no/' "$sshd_config" || echo "PasswordAuthentication no" >> "$sshd_config"
fi
# Ensure AddressFamily inet is set
if grep -q '^#AddressFamily' "$sshd_config"; then
sed -i 's/^#AddressFamily.*/AddressFamily inet/' "$sshd_config"
else
sed -i 's/^AddressFamily .*/AddressFamily inet/' "$sshd_config" || echo "AddressFamily inet" >> "$sshd_config"
fi
else
echo "sshd_config file not found. Exiting."
exit 1
fi
# Get the IP address of the machine
ip_address=$(hostname -I | awk '{print $1}')
# Prompt the user to copy their public key
echo "Please copy your public SSH key to the server using the following command:"
echo "ssh-copy-id $username@$ip_address"
# Wait until the authorized_keys file is no longer empty
echo "Waiting for your public key to be copied..."
while true; do
if [ -s "/home/$username/.ssh/authorized_keys" ]; then
echo "Public key has been successfully copied."
break
fi
sleep 2
done
# Restart SSH service to apply changes
echo "Restarting SSH service..."
systemctl restart sshd
# Prompt for Docker installation
prompt_for_docker_install
# Clean up
echo "Cleaning up..."
if command -v dnf &> /dev/null; then
dnf -y autoremove
elif command -v yum &> /dev/null; then
yum -y autoremove
fi
echo "System update complete! Timezone set to ${timezone:-UTC}, hostname set to $hostname, limited user created, sshd_config modified, and Docker installation completed if selected."