fix for rollback_ssh_changes()

This commit is contained in:
buildplan
2025-07-02 13:48:34 +01:00
committed by GitHub
parent 305574ac4f
commit d328e296dc

View File

@@ -1,8 +1,9 @@
#!/bin/bash
# Debian 12 and Ubuntu Server Hardening Interactive Script
# Version: 0.53 | 2025-07-01
# Version: 0.54 | 2025-07-02
# Changelog:
# - v0.54: Fix for rollback_ssh_changes() - more reliable on newer Ubuntu
# - v0.53: Fix for test_backup() - was failing if run as non root sudo user
# - v0.52: Roll-back SSH config on failure to configure SSH port, confirmed SSH config support for Ubuntu 24.10
# - v0.51: corrected repo links
@@ -92,7 +93,7 @@ print_header() {
echo -e "${CYAN}╔═════════════════════════════════════════════════════════════════╗${NC}"
echo -e "${CYAN}║ ║${NC}"
echo -e "${CYAN}║ DEBIAN/UBUNTU SERVER SETUP AND HARDENING SCRIPT ║${NC}"
echo -e "${CYAN}║ v0.53 | 2025-07-01${NC}"
echo -e "${CYAN}║ v0.54 | 2025-07-02${NC}"
echo -e "${CYAN}║ ║${NC}"
echo -e "${CYAN}╚═════════════════════════════════════════════════════════════════╝${NC}"
echo
@@ -658,40 +659,178 @@ EOF
rollback_ssh_changes() {
print_info "Rolling back SSH configuration changes to port $PREVIOUS_SSH_PORT..."
rm -f /etc/systemd/system/ssh.service.d/override.conf
rm -f /etc/systemd/system/ssh.socket.d/override.conf
rm -f /etc/ssh/sshd_config.d/99-hardening.conf
if [[ -f "$SSHD_BACKUP_FILE" ]]; then
cp "$SSHD_BACKUP_FILE" /etc/ssh/sshd_config
print_info "Restored original sshd_config from $SSHD_BACKUP_FILE."
# Ensure SSH_SERVICE is set and valid
local SSH_SERVICE=${SSH_SERVICE:-"sshd.service"}
local USE_SOCKET=false
# Check if socket activation is used
if systemctl list-units --full -all --no-pager | grep -E "[[:space:]]ssh.socket[[:space:]]" >/dev/null 2>&1; then
USE_SOCKET=true
SSH_SERVICE="ssh.socket"
print_info "Detected SSH socket activation: using ssh.socket."
log "Rollback: Using ssh.socket for SSH service."
elif ! systemctl list-units --full -all --no-pager | grep -E "[[:space:]]$SSH_SERVICE[[:space:]]" >/dev/null 2>&1; then
SSH_SERVICE="ssh.service" # Fallback for Ubuntu
print_warning "SSH service $SSH_SERVICE not found, falling back to ssh.service."
log "Rollback warning: Using fallback SSH service ssh.service."
# Verify fallback service exists
if ! systemctl list-units --full -all --no-pager | grep -E "[[:space:]]ssh.service[[:space:]]" >/dev/null 2>&1; then
print_error "No valid SSH service (sshd.service or ssh.service) found."
log "Rollback failed: No valid SSH service detected."
print_info "Action: Verify SSH service with 'systemctl list-units --full -all | grep ssh' and manually configure /etc/ssh/sshd_config."
return 0
fi
fi
# Remove systemd overrides for both service and socket
local OVERRIDE_DIR="/etc/systemd/system/${SSH_SERVICE}.d"
local SOCKET_OVERRIDE_DIR="/etc/systemd/system/ssh.socket.d"
local SERVICE_OVERRIDE_DIR="/etc/systemd/system/ssh.service.d"
if ! rm -rf "$OVERRIDE_DIR" "$SOCKET_OVERRIDE_DIR" "$SERVICE_OVERRIDE_DIR" 2>/dev/null; then
print_warning "Failed to remove systemd overrides at $OVERRIDE_DIR, $SOCKET_OVERRIDE_DIR, or $SERVICE_OVERRIDE_DIR."
log "Rollback warning: Failed to remove systemd overrides."
else
print_error "Backup file not found. Could not restore sshd_config."
return 1
log "Removed systemd overrides: $OVERRIDE_DIR, $SOCKET_OVERRIDE_DIR, $SERVICE_OVERRIDE_DIR"
fi
print_info "Reloading systemd and restarting $SSH_SERVICE..."
systemctl daemon-reload
if ! systemctl restart "$SSH_SERVICE"; then
print_warning "Failed to restart $SSH_SERVICE after rollback. Attempting manual start..."
/usr/sbin/sshd || true
# Remove custom SSH configuration
if ! rm -f /etc/ssh/sshd_config.d/99-hardening.conf 2>/dev/null; then
print_warning "Failed to remove /etc/ssh/sshd_config.d/99-hardening.conf."
log "Rollback warning: Failed to remove /etc/ssh/sshd_config.d/99-hardening.conf."
else
log "Removed /etc/ssh/sshd_config.d/99-hardening.conf"
fi
# Restore original sshd_config
if [[ -f "$SSHD_BACKUP_FILE" ]]; then
if ! cp "$SSHD_BACKUP_FILE" /etc/ssh/sshd_config 2>/dev/null; then
print_error "Failed to restore sshd_config from $SSHD_BACKUP_FILE."
log "Rollback failed: Cannot copy $SSHD_BACKUP_FILE to /etc/ssh/sshd_config."
print_info "Action: Manually restore with 'cp $SSHD_BACKUP_FILE /etc/ssh/sshd_config' and verify with 'sshd -t'."
return 0
fi
print_info "Restored original sshd_config from $SSHD_BACKUP_FILE."
log "Restored sshd_config from $SSHD_BACKUP_FILE."
else
print_error "Backup file not found at $SSHD_BACKUP_FILE."
log "Rollback failed: $SSHD_BACKUP_FILE not found."
print_info "Action: Manually configure /etc/ssh/sshd_config to use port $PREVIOUS_SSH_PORT and verify with 'sshd -t'."
return 0
fi
# Validate restored sshd_config
if ! /usr/sbin/sshd -t >/tmp/sshd_config_test.log 2>&1; then
print_error "Restored sshd_config is invalid. Check /tmp/sshd_config_test.log for details."
log "Rollback failed: Invalid sshd_config after restoration. See /tmp/sshd_config_test.log."
print_info "Action: Fix /etc/ssh/sshd_config manually and test with 'sshd -t', then restart with 'systemctl restart ssh.service'."
return 0
fi
# Reload systemd
print_info "Reloading systemd..."
if ! systemctl daemon-reload 2>/dev/null; then
print_warning "Failed to reload systemd. Continuing with restart attempt..."
log "Rollback warning: Failed to reload systemd."
fi
# Handle socket activation or direct service restart
if [[ "$USE_SOCKET" == true ]]; then
# Stop ssh.socket to avoid conflicts
if systemctl is-active --quiet ssh.socket; then
if ! systemctl stop ssh.socket 2>/tmp/ssh_socket_stop.log; then
print_warning "Failed to stop ssh.socket. May affect port binding."
log "Rollback warning: Failed to stop ssh.socket. See /tmp/ssh_socket_stop.log."
else
log "Stopped ssh.socket to ensure correct port binding."
fi
fi
# Restart ssh.service to ensure sshd starts
print_info "Restarting ssh.service..."
if ! systemctl restart ssh.service 2>/tmp/sshd_restart.log; then
print_warning "Failed to restart ssh.service. Attempting manual start..."
log "Rollback warning: Failed to restart ssh.service. See /tmp/sshd_restart.log."
# Ensure no other sshd processes are running
pkill -f "sshd:.*" 2>/dev/null || true
# Manual start in foreground to verify
timeout 5 /usr/sbin/sshd -D -f /etc/ssh/sshd_config >/tmp/sshd_manual_start.log 2>&1
local TIMEOUT_EXIT=$?
if [[ $TIMEOUT_EXIT -eq 0 || $TIMEOUT_EXIT -eq 124 ]]; then
log "Manual SSH start succeeded (exit code $TIMEOUT_EXIT)."
# Restart ssh.service to ensure systemd management
if ! systemctl restart ssh.service 2>/tmp/sshd_restart_manual.log; then
print_error "Failed to restart ssh.service after manual start."
log "Rollback failed: Failed to restart ssh.service after manual start. See /tmp/sshd_restart_manual.log."
print_info "Action: Check service status with 'systemctl status ssh.service' and logs with 'journalctl -u ssh.service'."
return 0
fi
else
print_error "Manual SSH start failed (exit code $TIMEOUT_EXIT). Check /tmp/sshd_manual_start.log."
log "Rollback failed: Manual SSH start failed (exit code $TIMEOUT_EXIT). See /tmp/sshd_manual_start.log."
print_info "Action: Check service status with 'systemctl status ssh.service' and logs with 'journalctl -u ssh.service'."
return 0
fi
fi
# Restart ssh.socket to re-enable socket activation
print_info "Restarting ssh.socket..."
if ! systemctl restart ssh.socket 2>/tmp/ssh_socket_restart.log; then
print_warning "Failed to restart ssh.socket. SSH service may still be running."
log "Rollback warning: Failed to restart ssh.socket. See /tmp/ssh_socket_restart.log."
else
log "Restarted ssh.socket for socket activation."
fi
else
# Direct service restart for non-socket systems
print_info "Restarting $SSH_SERVICE..."
if ! systemctl restart "$SSH_SERVICE" 2>/tmp/sshd_restart.log; then
print_warning "Failed to restart $SSH_SERVICE. Attempting manual start..."
log "Rollback warning: Failed to restart $SSH_SERVICE. See /tmp/sshd_restart.log."
# Ensure no other sshd processes are running
pkill -f "sshd:.*" 2>/dev/null || true
# Manual start in foreground to verify
timeout 5 /usr/sbin/sshd -D -f /etc/ssh/sshd_config >/tmp/sshd_manual_start.log 2>&1
local TIMEOUT_EXIT=$?
if [[ $TIMEOUT_EXIT -eq 0 || $TIMEOUT_EXIT -eq 124 ]]; then
log "Manual SSH start succeeded (exit code $TIMEOUT_EXIT)."
# Restart service to ensure systemd management
if ! systemctl restart "$SSH_SERVICE" 2>/tmp/sshd_restart_manual.log; then
print_error "Failed to restart $SSH_SERVICE after manual start."
log "Rollback failed: Failed to restart $SSH_SERVICE after manual start. See /tmp/sshd_restart_manual.log."
print_info "Action: Check service status with 'systemctl status $SSH_SERVICE' and logs with 'journalctl -u $SSH_SERVICE'."
return 0
fi
else
print_error "Manual SSH start failed (exit code $TIMEOUT_EXIT). Check /tmp/sshd_manual_start.log."
log "Rollback failed: Manual SSH start failed (exit code $TIMEOUT_EXIT). See /tmp/sshd_manual_start.log."
print_info "Action: Check service status with 'systemctl status $SSH_SERVICE' and logs with 'journalctl -u $SSH_SERVICE'."
return 0
fi
fi
fi
# Verify rollback with retries
local rollback_verified=false
print_info "Verifying SSH rollback to port $PREVIOUS_SSH_PORT..."
for ((i=1; i<=10; i++)); do
if ss -tuln | grep -q ":$PREVIOUS_SSH_PORT"; then
print_success "Rollback successful. SSH is now listening on port $PREVIOUS_SSH_PORT."
if ss -tuln | grep -q ":$PREVIOUS_SSH_PORT "; then
rollback_verified=true
break
fi
sleep 1
log "Rollback verification attempt $i/10: SSH not listening on port $PREVIOUS_SSH_PORT."
sleep 3
done
if [[ $rollback_verified == false ]]; then
if [[ $rollback_verified == true ]]; then
print_success "Rollback successful. SSH is now listening on port $PREVIOUS_SSH_PORT."
log "Rollback successful: SSH listening on port $PREVIOUS_SSH_PORT."
else
print_error "Rollback failed. SSH service is not listening on port $PREVIOUS_SSH_PORT."
print_info "Please check service status manually with 'systemctl status $SSH_SERVICE' and 'journalctl -u $SSH_SERVICE'."
return 1
log "Rollback failed: SSH not listening on port $PREVIOUS_SSH_PORT. See /tmp/sshd_config_test.log, /tmp/sshd_restart.log, /tmp/sshd_manual_start.log, /tmp/ssh_socket_restart.log."
print_info "Action: Check service status with 'systemctl status ssh.service' or 'systemctl status ssh.socket', logs with 'journalctl -u ssh.service' or 'journalctl -u ssh.socket', and test config with 'sshd -t'."
print_info "Manually verify port with 'ss -tuln | grep :$PREVIOUS_SSH_PORT'."
print_info "Try starting SSH with 'sudo systemctl start ssh.service'."
fi
return 0
}
configure_firewall() {