provisioning/taskservs/desktop/default/ssh-setup.sh
2025-09-22 23:11:41 +01:00

344 lines
8.8 KiB
Bash
Executable File

#!/usr/bin/env bash
# SSH Server Setup and Hardening Script
set -euo pipefail
# Load environment variables
source /tmp/env-desktop
log() {
echo "[$(date +'%Y-%m-%d %H:%M:%S')] SSH: $1"
}
error() {
echo "[$(date +'%Y-%m-%d %H:%M:%S')] SSH ERROR: $1" >&2
exit 1
}
# Detect OS
detect_os() {
if [[ -f /etc/os-release ]]; then
. /etc/os-release
OS=$ID
VERSION=$VERSION_ID
else
error "Cannot detect OS"
fi
log "Detected OS: $OS $VERSION"
}
# Install SSH server
install_ssh_server() {
log "Installing SSH server..."
case $OS in
ubuntu|debian)
apt-get update
apt-get install -y openssh-server openssh-client
;;
centos|rhel|fedora)
if command -v dnf >/dev/null 2>&1; then
dnf install -y openssh-server openssh-clients
else
yum install -y openssh-server openssh-clients
fi
;;
*)
error "Unsupported OS for SSH installation: $OS"
;;
esac
log "SSH server installed"
}
# Configure SSH server
configure_ssh_server() {
log "Configuring SSH server..."
local ssh_port="${SSH_PORT:-22}"
local password_auth="${SSH_PASSWORD_AUTH:-yes}"
local key_auth="${SSH_KEY_AUTH:-yes}"
local root_login="${SSH_ROOT_LOGIN:-prohibit-password}"
local max_auth_tries="${SSH_MAX_AUTH_TRIES:-3}"
local client_alive_interval="${SSH_CLIENT_ALIVE_INTERVAL:-300}"
local client_alive_count_max="${SSH_CLIENT_ALIVE_COUNT_MAX:-2}"
# Backup original config
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.backup.$(date +%Y%m%d_%H%M%S)
# Create new SSH configuration
cat > /etc/ssh/sshd_config << EOF
# SSH Configuration for Desktop Environment
# Generated by provisioning system
# Connection settings
Port $ssh_port
AddressFamily any
ListenAddress 0.0.0.0
ListenAddress ::
# Host keys
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
# Ciphers and keying
RekeyLimit default none
# Logging
SyslogFacility AUTH
LogLevel INFO
# Authentication
LoginGraceTime 2m
PermitRootLogin $root_login
StrictModes yes
MaxAuthTries $max_auth_tries
MaxSessions 10
PubkeyAuthentication $key_auth
AuthorizedKeysFile .ssh/authorized_keys .ssh/authorized_keys2
# Password authentication
PasswordAuthentication $password_auth
PermitEmptyPasswords no
ChallengeResponseAuthentication no
# Kerberos and GSSAPI (disabled for security)
KerberosAuthentication no
GSSAPIAuthentication no
# Connection timeouts
ClientAliveInterval $client_alive_interval
ClientAliveCountMax $client_alive_count_max
TCPKeepAlive yes
# Compression
Compression delayed
# Environment
AcceptEnv LANG LC_*
AcceptEnv XMODIFIERS
# X11 forwarding (enabled for desktop environment)
X11Forwarding yes
X11DisplayOffset 10
X11UseLocalhost yes
# Agent forwarding (be careful with security)
AllowAgentForwarding yes
# TCP forwarding
AllowTcpForwarding yes
GatewayPorts no
# Tunnel device forwarding
PermitTunnel no
# chroot directory
ChrootDirectory none
# Banner
Banner none
# Subsystem
Subsystem sftp /usr/lib/openssh/sftp-server
# User/Group restrictions
EOF
# Add user restrictions if specified
if [[ -n "${SSH_ALLOWED_USERS:-}" ]]; then
echo "AllowUsers $SSH_ALLOWED_USERS" >> /etc/ssh/sshd_config
log "SSH access restricted to users: $SSH_ALLOWED_USERS"
fi
if [[ -n "${SSH_DENIED_USERS:-}" ]]; then
echo "DenyUsers $SSH_DENIED_USERS" >> /etc/ssh/sshd_config
log "SSH access denied for users: $SSH_DENIED_USERS"
fi
# Fix sftp-server path for different distributions
case $OS in
ubuntu|debian)
sed -i 's|/usr/lib/openssh/sftp-server|/usr/lib/openssh/sftp-server|' /etc/ssh/sshd_config
;;
centos|rhel|fedora)
sed -i 's|/usr/lib/openssh/sftp-server|/usr/libexec/openssh/sftp-server|' /etc/ssh/sshd_config
;;
esac
# Test SSH configuration
sshd -t || error "SSH configuration is invalid"
log "SSH server configured"
}
# Setup SSH keys for desktop user
setup_ssh_keys() {
local desktop_user="${DESKTOP_USER:-desktop}"
local desktop_home="${DESKTOP_HOME:-/home/$desktop_user}"
log "Setting up SSH keys for user $desktop_user"
# Create user if not exists
if ! id "$desktop_user" &>/dev/null; then
useradd -m -s /bin/bash "$desktop_user"
log "Created user $desktop_user"
fi
# Create .ssh directory
sudo -u "$desktop_user" mkdir -p "$desktop_home/.ssh"
chmod 700 "$desktop_home/.ssh"
# Generate SSH key pair if not exists
if [[ ! -f "$desktop_home/.ssh/id_rsa" ]]; then
log "Generating SSH key pair for $desktop_user"
sudo -u "$desktop_user" ssh-keygen -t rsa -b 4096 -f "$desktop_home/.ssh/id_rsa" -N "" -C "$desktop_user@$(hostname)"
log "SSH key pair generated"
fi
# Create authorized_keys file
sudo -u "$desktop_user" touch "$desktop_home/.ssh/authorized_keys"
chmod 600 "$desktop_home/.ssh/authorized_keys"
# Set proper ownership
chown -R "$desktop_user:$desktop_user" "$desktop_home/.ssh"
log "SSH keys setup completed for $desktop_user"
}
# Setup fail2ban for SSH protection
setup_fail2ban() {
log "Setting up fail2ban for SSH protection..."
case $OS in
ubuntu|debian)
apt-get install -y fail2ban
;;
centos|rhel|fedora)
if command -v dnf >/dev/null 2>&1; then
dnf install -y fail2ban
else
yum install -y fail2ban
fi
;;
esac
# Create fail2ban configuration for SSH
cat > /etc/fail2ban/jail.local << EOF
[DEFAULT]
# Ban time in seconds (10 minutes)
bantime = 600
# Find time window (10 minutes)
findtime = 600
# Max retry attempts
maxretry = 3
[sshd]
enabled = true
port = ${SSH_PORT:-22}
filter = sshd
logpath = /var/log/auth.log
maxretry = ${SSH_MAX_AUTH_TRIES:-3}
bantime = 3600
EOF
# Start and enable fail2ban
systemctl enable fail2ban
systemctl start fail2ban
log "fail2ban configured and started"
}
# Setup firewall rules for SSH
setup_firewall() {
log "Setting up firewall rules for SSH"
local ssh_port="${SSH_PORT:-22}"
# Try different firewall tools
if command -v ufw >/dev/null 2>&1; then
ufw allow "$ssh_port/tcp" comment "SSH"
log "UFW rule added for SSH port $ssh_port"
elif command -v firewall-cmd >/dev/null 2>&1; then
if [[ "$ssh_port" != "22" ]]; then
firewall-cmd --permanent --add-port="$ssh_port/tcp"
else
firewall-cmd --permanent --add-service=ssh
fi
firewall-cmd --reload
log "FirewallD rule added for SSH port $ssh_port"
else
log "WARNING: No supported firewall tool found. Manual firewall configuration may be needed."
fi
}
# Start and enable SSH service
start_ssh_service() {
log "Starting SSH service..."
# Enable and start SSH service
systemctl enable ssh sshd 2>/dev/null || systemctl enable sshd
systemctl restart ssh sshd 2>/dev/null || systemctl restart sshd
# Check service status
if systemctl is-active --quiet ssh || systemctl is-active --quiet sshd; then
log "SSH service is running"
else
error "Failed to start SSH service"
fi
log "SSH service started and enabled"
}
# Display connection information
display_connection_info() {
local desktop_user="${DESKTOP_USER:-desktop}"
local ssh_port="${SSH_PORT:-22}"
local server_ip=$(ip route get 1.1.1.1 | grep -oP 'src \K\S+' 2>/dev/null || echo "$(hostname -I | awk '{print $1}')")
log "SSH setup completed!"
log ""
log "SSH Connection Information:"
log " Server IP: $server_ip"
log " SSH Port: $ssh_port"
log " Desktop User: $desktop_user"
log ""
log "Connect via SSH:"
log " ssh $desktop_user@$server_ip -p $ssh_port"
log ""
log "Public key location (for key-based auth):"
log " /home/$desktop_user/.ssh/id_rsa.pub"
log ""
log "To copy your public key to another machine:"
log " ssh-copy-id -i /home/$desktop_user/.ssh/id_rsa.pub user@remote-host"
}
# Main installation function
main() {
if [[ "${SSH_ENABLED:-true}" != "true" ]]; then
log "SSH is disabled, skipping installation"
return 0
fi
log "Starting SSH server installation and configuration..."
detect_os
install_ssh_server
configure_ssh_server
setup_ssh_keys
setup_fail2ban
setup_firewall
start_ssh_service
display_connection_info
log "SSH setup completed successfully!"
}
# Run main function if script is executed directly
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
main "$@"
fi