diff --git a/miscellaneous/secure_ssh.sh b/miscellaneous/secure_ssh.sh index 41ecade..3e0eb6f 100644 --- a/miscellaneous/secure_ssh.sh +++ b/miscellaneous/secure_ssh.sh @@ -1,14 +1,17 @@ #!/bin/bash -# This script configures SSH server security settings following Mozilla's guidelines -# It allows choosing between SSH key and password authentication methods -# Reference: https://infosec.mozilla.org/guidelines/openssh +# Warning: Before running this script, make sure you have created a user and an SSH key in the authorized_keys file. + +# This script is designed to configure the SSH server on a Linux system according to Mozilla's security best practices. +# It enhances the security of SSH connections by enforcing modern encryption standards, disabling insecure protocols, and restricting root access. +# The script backs up the original SSH configuration file, applies a new set of secure settings, and then restarts the SSH service to apply the changes. +# These settings include disabling password authentication, limiting access to strong ciphers and key exchange methods, and enhancing brute-force protection. +# These recommendations are based on Mozilla's guidelines, which can be found here: https://infosec.mozilla.org/guidelines/openssh # Usage: -# 1. Save this script as "secure_ssh.sh" -# 2. Make it executable: chmod +x secure_ssh.sh -# 3. Run with root privileges: sudo ./secure_ssh.sh -# 4. Follow the interactive prompts to configure your SSH security settings +# To run this script, save it as "secure_ssh.sh" and make it executable by running the command: `chmod +x secure_ssh.sh`. +# After that, execute it with root privileges using: `sudo ./secure_ssh.sh`. +# The script will automatically apply the recommended configuration changes and restart the SSH service. # Check if the script is run as root if [[ "$EUID" -ne 0 ]]; then @@ -16,171 +19,83 @@ if [[ "$EUID" -ne 0 ]]; then exit 1 fi -# Define important variables +# Variables SSHD_CONFIG="/etc/ssh/sshd_config" -BACKUP_FILE="${SSHD_CONFIG}_$(date +'%Y%m%d_%H%M%S').bak" +BACKUP_FILE="${SSHD_CONFIG}_$(date +'%Y%m%d_%H%M%S').bak" # Backup with date and time -# Function to validate IP address -validate_ip() { - local ip=$1 - local stat=1 - - if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then - OIFS=$IFS - IFS='.' - ip=($ip) - IFS=$OIFS - [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]] - stat=$? - fi - return $stat -} - -# Create a backup of the current SSH configuration +# Backup the old configuration with a timestamp cp "$SSHD_CONFIG" "$BACKUP_FILE" -echo "Current SSH configuration backed up to $BACKUP_FILE" -# Configure SSH port (mandatory) -while true; do - read -p "Enter the SSH port to use (between 1024 and 65535): " new_port - if [[ "$new_port" =~ ^[0-9]+$ ]] && [ "$new_port" -ge 1024 ] && [ "$new_port" -le 65535 ]; then - port_setting="Port $new_port" - break - else - echo "Error: Please enter a valid port number between 1024 and 65535" - fi -done +# Ask user if they want to restrict SSH access to a single IP +read -p "Do you want to restrict SSH access to a single IP? (yes/no): " restrict_ip -# Configure IP whitelist (mandatory) -while true; do - read -p "Enter the IP address to whitelist for SSH access (e.g., 192.168.1.100): " allowed_ip - if validate_ip "$allowed_ip"; then - allow_users="AllowUsers *@${allowed_ip}" - break - else - echo "Error: Please enter a valid IP address" - fi -done +if [[ "$restrict_ip" == "yes" ]]; then + read -p "Enter the IP address to allow SSH access: " allowed_ip + allow_users="AllowUsers *@${allowed_ip}" +else + allow_users="# AllowUsers configuration not set" +fi -# Present authentication method options to the user -echo "Choose authentication method:" -echo "1) SSH key only (more secure)" -echo "2) Password authentication" -read -p "Enter your choice (1 or 2): " auth_choice +# Ask user if they want to change the SSH port +read -p "Do you want to change the SSH port? (yes/no): " change_port +if [[ "$change_port" == "yes" ]]; then + read -p "Enter the new SSH port: " new_port + port_setting="Port $new_port" +else + port_setting="# Port configuration not changed" +fi -# Handle authentication method selection -case $auth_choice in - 1) - # Configure SSH key authentication - auth_method="PasswordAuthentication no" - echo "SSH key authentication selected" - - # Check for existing SSH key configuration - if [ ! -f "/root/.ssh/authorized_keys" ]; then - read -p "No SSH key found. Would you like to add one now? (yes/no): " add_key - if [[ "$add_key" == "yes" ]]; then - # Create SSH directory with proper permissions - mkdir -p /root/.ssh - read -p "Paste your public SSH key: " ssh_key - echo "$ssh_key" >> /root/.ssh/authorized_keys - # Set proper permissions for SSH files - chmod 700 /root/.ssh - chmod 600 /root/.ssh/authorized_keys - else - echo "Warning: No SSH key configured. You might be locked out!" - exit 1 - fi - fi - ;; - 2) - # Configure password authentication - auth_method="PasswordAuthentication yes" - echo "Password authentication selected" - ;; - *) - echo "Invalid choice. Exiting." - exit 1 - ;; -esac +# Ask user if they want to use password or key-based authentication +read -p "Do you want to use password or key-based authentication? (password/key): " auth_method +if [[ "$auth_method" == "password" ]]; then + password_auth="PasswordAuthentication yes" + key_auth="# PasswordAuthentication no" +else + password_auth="# PasswordAuthentication no" + key_auth="PubkeyAuthentication yes" +fi -# Create new SSH configuration file with secure settings +# Modify the sshd_config file cat < "$SSHD_CONFIG" -# SSH Server Configuration -# Generated by secure_ssh.sh script -# Based on Mozilla's Modern OpenSSH server configuration -# Last modified: $(date) - -# Protocol version (only SSH protocol 2 is secure) +# Mozilla SSH Security Recommendations Protocol 2 - -# Port configuration (mandatory) -$port_setting - -# IP restriction settings (mandatory) -$allow_users - -# Authentication configuration -$auth_method - -# Cryptographic settings -# Only modern, secure ciphers are enabled +# Enable only secure ciphers Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr - -# Key exchange algorithms +# Enable only secure key exchange algorithms KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256 - -# Message Authentication Codes (MACs) +# Enable only secure MAC algorithms MACs hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha2-512 -# Host keys +# Authentication method based on user input +$password_auth +$key_auth + +# Disable old host keys HostKey /etc/ssh/ssh_host_ed25519_key HostKey /etc/ssh/ssh_host_rsa_key -# Access control settings +# Restrict root access PermitRootLogin no + +# Strict connection policy MaxAuthTries 3 LoginGraceTime 30 -# Additional security measures +# Additional security recommendations AllowTcpForwarding no MaxSessions 2 LogLevel VERBOSE ClientAliveInterval 300 ClientAliveCountMax 2 + +# IP restriction based on user input +$allow_users + +# SSH port based on user input +$port_setting EOL -# Configure UFW firewall if installed -if command -v ufw >/dev/null 2>&1; then - echo "Configuring UFW firewall..." - ufw allow from "$allowed_ip" to any port "$new_port" proto tcp - ufw status -fi - -# Restart SSH service to apply new configuration +# Restart the SSH service systemctl restart sshd -# Display completion message and configuration summary -echo " -SSH Configuration Summary: -------------------------- -Port: $new_port -Whitelisted IP: $allowed_ip -Authentication Method: ${auth_choice == 1 ? 'SSH Key' : 'Password'} -Backup File: $BACKUP_FILE - -Important notes: -1. Keep your backup file safe -2. Test your new SSH configuration in a new session before logging out -3. If you get locked out, use the backup file to restore the previous configuration -4. The following command will be needed to connect: - ssh -p $new_port user@server_ip - -Next steps: -1. Open a new terminal -2. Try to connect using the new configuration -3. Do NOT close this session until you confirm the new configuration works -" - -if [[ "$auth_choice" == "1" ]]; then - echo "WARNING: Make sure you have a valid SSH key configured before logging out!" -fi \ No newline at end of file +echo "SSH configuration has been updated and backed up to $BACKUP_FILE according to Mozilla's security recommendations." \ No newline at end of file