Actualiser miscellaneous/secure_ssh.sh
This commit is contained in:
@@ -1,101 +1,232 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Warning: Before running this script, make sure you have created a user and an SSH key in the authorized_keys file.
|
# This script configures the SSH server according to Mozilla's best security practices.
|
||||||
|
# It backs up the original SSH configuration file, generates a new secure configuration file,
|
||||||
# This script is designed to configure the SSH server on a Linux system according to Mozilla's security best practices.
|
# and then restarts the SSH service to apply the changes.
|
||||||
# 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:
|
# Usage:
|
||||||
# To run this script, save it as "secure_ssh.sh" and make it executable by running the command: `chmod +x secure_ssh.sh`.
|
# 1. Save this script as "secure_ssh.sh".
|
||||||
# After that, execute it with root privileges using: `sudo ./secure_ssh.sh`.
|
# 2. Make it executable with: `chmod +x secure_ssh.sh`.
|
||||||
# The script will automatically apply the recommended configuration changes and restart the SSH service.
|
# 3. Run it with root privileges using: `sudo ./secure_ssh.sh`.
|
||||||
|
|
||||||
# Check if the script is run as root
|
|
||||||
if [[ "$EUID" -ne 0 ]]; then
|
|
||||||
echo "This script must be run as root. Please use sudo to execute it."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Variables
|
# Variables
|
||||||
SSHD_CONFIG="/etc/ssh/sshd_config"
|
SSHD_CONFIG="/etc/ssh/sshd_config"
|
||||||
BACKUP_FILE="${SSHD_CONFIG}_$(date +'%Y%m%d_%H%M%S').bak" # Backup with date and time
|
BACKUP_DIR="/etc/ssh/backup_sshd_config"
|
||||||
|
DATE_STR=$(date +"%Y%m%d_%H%M%S")
|
||||||
|
SSHD_SERVICE=""
|
||||||
|
|
||||||
# Backup the old configuration with a timestamp
|
# Function to validate an IP address
|
||||||
cp "$SSHD_CONFIG" "$BACKUP_FILE"
|
validate_ip() {
|
||||||
|
local ip=$1
|
||||||
|
local stat=1
|
||||||
|
|
||||||
# Ask user if they want to restrict SSH access to a single IP
|
if [[ $ip =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
|
||||||
read -p "Do you want to restrict SSH access to a single IP? (yes/no): " restrict_ip
|
OIFS=$IFS
|
||||||
|
IFS='.'
|
||||||
|
ip=($ip)
|
||||||
|
IFS=$OIFS
|
||||||
|
if [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]; then
|
||||||
|
stat=0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ "$restrict_ip" == "yes" ]]; then
|
return $stat
|
||||||
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
|
|
||||||
|
|
||||||
# Ask user if they want to change the SSH port
|
# Function to validate the SSH port
|
||||||
read -p "Do you want to change the SSH port? (yes/no): " change_port
|
validate_ssh_port() {
|
||||||
if [[ "$change_port" == "yes" ]]; then
|
local port=$1
|
||||||
read -p "Enter the new SSH port: " new_port
|
local stat=1
|
||||||
port_setting="Port $new_port"
|
|
||||||
else
|
|
||||||
port_setting="# Port configuration not changed"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Ask user if they want to use password or key-based authentication
|
if [[ "$port" =~ ^[0-9]+$ ]] && [[ "$port" -gt 0 && "$port" -le 65535 ]]; then
|
||||||
read -p "Do you want to use password or key-based authentication? (password/key): " auth_method
|
stat=0
|
||||||
if [[ "$auth_method" == "password" ]]; then
|
fi
|
||||||
password_auth="PasswordAuthentication yes"
|
|
||||||
key_auth="# PasswordAuthentication no"
|
|
||||||
else
|
|
||||||
password_auth="# PasswordAuthentication no"
|
|
||||||
key_auth="PubkeyAuthentication yes"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Modify the sshd_config file
|
return $stat
|
||||||
cat <<EOL > "$SSHD_CONFIG"
|
}
|
||||||
# Mozilla SSH Security Recommendations
|
|
||||||
|
# Detect the name of the SSH service
|
||||||
|
detect_sshd_service() {
|
||||||
|
if systemctl list-units --type=service | grep -q 'sshd'; then
|
||||||
|
echo "sshd"
|
||||||
|
elif systemctl list-units --type=service | grep -q 'ssh'; then
|
||||||
|
echo "ssh"
|
||||||
|
else
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to restart the SSH service
|
||||||
|
restart_sshd() {
|
||||||
|
local service=$1
|
||||||
|
systemctl restart "$service"
|
||||||
|
return $?
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create a backup of the SSH configuration file
|
||||||
|
backup_sshd_config() {
|
||||||
|
mkdir -p "$BACKUP_DIR"
|
||||||
|
BACKUP_FILE="${BACKUP_DIR}/sshd_config.${DATE_STR}.bak"
|
||||||
|
cp "$SSHD_CONFIG" "$BACKUP_FILE"
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
|
echo "Error creating backup of the SSH configuration file."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "SSH configuration backup created: $BACKUP_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Prompt for the SSH port
|
||||||
|
prompt_ssh_port() {
|
||||||
|
while true; do
|
||||||
|
read -p "Please enter the SSH port (default 22): " SSH_PORT
|
||||||
|
SSH_PORT=${SSH_PORT:-22}
|
||||||
|
if validate_ssh_port "$SSH_PORT"; then
|
||||||
|
echo "SSH port used: $SSH_PORT"
|
||||||
|
break
|
||||||
|
else
|
||||||
|
echo "Invalid port. The port must be an integer between 1 and 65535."
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# Prompt to restrict SSH access to specific IP addresses
|
||||||
|
prompt_allowed_ips() {
|
||||||
|
read -p "Do you want to restrict SSH access to specific IP addresses? (yes/no): " RESTRICT_ACCESS
|
||||||
|
ALLOWED_IPS=""
|
||||||
|
if [[ "$RESTRICT_ACCESS" =~ ^([oO]ui|[yY]es)$ ]]; then
|
||||||
|
while true; do
|
||||||
|
read -p "Enter a comma-separated list of allowed IP addresses (e.g. 192.168.1.1,10.0.0.1): " ALLOWED_IPS_INPUT
|
||||||
|
IFS=',' read -ra IP_ARRAY <<< "$ALLOWED_IPS_INPUT"
|
||||||
|
VALID=true
|
||||||
|
ALLOWED_IPS_CLEAN=""
|
||||||
|
for ip in "${IP_ARRAY[@]}"; do
|
||||||
|
ip=$(echo "$ip" | xargs) # Remove spaces
|
||||||
|
if ! validate_ip "$ip"; then
|
||||||
|
echo "Invalid IP address: $ip"
|
||||||
|
VALID=false
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
ALLOWED_IPS_CLEAN+="$ip "
|
||||||
|
done
|
||||||
|
if $VALID; then
|
||||||
|
ALLOWED_IPS="${ALLOWED_IPS_CLEAN% }" # Remove trailing space
|
||||||
|
echo "SSH access allowed from: $ALLOWED_IPS"
|
||||||
|
break
|
||||||
|
else
|
||||||
|
echo "Please enter valid IP addresses."
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
else
|
||||||
|
echo "SSH access allowed from all IP addresses."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Generate a new SSH configuration file
|
||||||
|
generate_new_sshd_config() {
|
||||||
|
cat <<EOL > "$SSHD_CONFIG"
|
||||||
|
# Secure SSH configuration according to Mozilla's recommendations
|
||||||
|
|
||||||
|
# Protocol version
|
||||||
Protocol 2
|
Protocol 2
|
||||||
# Enable only secure ciphers
|
|
||||||
|
# Secure ciphers
|
||||||
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
|
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
|
||||||
# Enable only secure key exchange algorithms
|
|
||||||
|
# Secure key exchange algorithms
|
||||||
KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256
|
KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256
|
||||||
# Enable only secure MAC algorithms
|
|
||||||
|
# Secure MAC algorithms
|
||||||
MACs hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha2-512
|
MACs hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha2-512
|
||||||
|
|
||||||
# Authentication method based on user input
|
# Disable password authentication
|
||||||
$password_auth
|
PasswordAuthentication no
|
||||||
$key_auth
|
|
||||||
|
|
||||||
# Disable old host keys
|
# Secure host keys (make sure they exist)
|
||||||
HostKey /etc/ssh/ssh_host_ed25519_key
|
HostKey /etc/ssh/ssh_host_ed25519_key
|
||||||
HostKey /etc/ssh/ssh_host_rsa_key
|
HostKey /etc/ssh/ssh_host_rsa_key
|
||||||
|
|
||||||
# Restrict root access
|
# Restrict root access
|
||||||
PermitRootLogin no
|
PermitRootLogin no
|
||||||
|
|
||||||
# Strict connection policy
|
# Strict login policy
|
||||||
MaxAuthTries 3
|
MaxAuthTries 3
|
||||||
LoginGraceTime 30
|
LoginGraceTime 30
|
||||||
|
|
||||||
# Additional security recommendations
|
# Specified SSH port
|
||||||
|
Port $SSH_PORT
|
||||||
|
|
||||||
|
# Other recommended configurations
|
||||||
|
PermitEmptyPasswords no
|
||||||
|
ChallengeResponseAuthentication no
|
||||||
|
UsePAM yes
|
||||||
AllowTcpForwarding no
|
AllowTcpForwarding no
|
||||||
MaxSessions 2
|
X11Forwarding no
|
||||||
LogLevel VERBOSE
|
|
||||||
ClientAliveInterval 300
|
|
||||||
ClientAliveCountMax 2
|
|
||||||
|
|
||||||
# IP restriction based on user input
|
# IP address access restrictions (if specified)
|
||||||
$allow_users
|
|
||||||
|
|
||||||
# SSH port based on user input
|
|
||||||
$port_setting
|
|
||||||
EOL
|
EOL
|
||||||
|
|
||||||
# Restart the SSH service
|
if [[ -n "$ALLOWED_IPS" ]]; then
|
||||||
systemctl restart sshd
|
echo "" >> "$SSHD_CONFIG"
|
||||||
|
echo "# IP address access restriction" >> "$SSHD_CONFIG"
|
||||||
|
echo "Match Address $(echo "$ALLOWED_IPS" | tr ' ' ',')" >> "$SSHD_CONFIG"
|
||||||
|
echo " AllowUsers *" >> "$SSHD_CONFIG"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
echo "SSH configuration has been updated and backed up to $BACKUP_FILE according to Mozilla's security recommendations."
|
# Test the syntax of the new SSH configuration
|
||||||
|
test_sshd_config() {
|
||||||
|
sshd -t
|
||||||
|
return $?
|
||||||
|
}
|
||||||
|
|
||||||
|
# Detect the SSH service in use
|
||||||
|
detect_service() {
|
||||||
|
SSHD_SERVICE=$(detect_sshd_service)
|
||||||
|
if [[ -z "$SSHD_SERVICE" ]]; then
|
||||||
|
echo "Error: Unable to detect the SSH service (sshd or ssh)."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main process
|
||||||
|
main() {
|
||||||
|
# Detect the SSH service
|
||||||
|
detect_service
|
||||||
|
|
||||||
|
# Backup current configuration
|
||||||
|
backup_sshd_config
|
||||||
|
|
||||||
|
# Prompt for the SSH port
|
||||||
|
prompt_ssh_port
|
||||||
|
|
||||||
|
# Prompt for allowed IP addresses
|
||||||
|
prompt_allowed_ips
|
||||||
|
|
||||||
|
# Generate the new configuration file
|
||||||
|
generate_new_sshd_config
|
||||||
|
echo "New SSH configuration file generated."
|
||||||
|
|
||||||
|
# Test the syntax of the new configuration
|
||||||
|
if test_sshd_config; then
|
||||||
|
echo "The new SSH configuration is valid."
|
||||||
|
else
|
||||||
|
echo "Error: The new SSH configuration contains errors. Restoring original configuration."
|
||||||
|
cp "$BACKUP_FILE" "$SSHD_CONFIG"
|
||||||
|
restart_sshd "$SSHD_SERVICE"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Restart the SSH service
|
||||||
|
if restart_sshd "$SSHD_SERVICE"; then
|
||||||
|
echo "The SSH service has been restarted successfully."
|
||||||
|
echo "The SSH configuration has been updated according to Mozilla's security recommendations."
|
||||||
|
else
|
||||||
|
echo "Error: Failed to restart the SSH service. Restoring original configuration."
|
||||||
|
cp "$BACKUP_FILE" "$SSHD_CONFIG"
|
||||||
|
restart_sshd "$SSHD_SERVICE"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Execute the main process
|
||||||
|
main
|
||||||
Reference in New Issue
Block a user