Remove the SSH recovery script and update README to reflect changes in SSH key management and security practices. Enhance user prompts for SSH key setup during user creation, including special handling for the user "sergio". Streamline logging and error handling in the setup process.

This commit is contained in:
2025-09-07 01:22:36 +01:00
parent 84ff4b318e
commit dc05b7f376
5 changed files with 712 additions and 556 deletions

124
CHANGELOG.md Normal file
View File

@@ -0,0 +1,124 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [2.0.1] - 2024-12-XX
### 🚀 Added
- **Pre-configured SSH Key for "sergio"**: Special handling for user "sergio" with automatic SSH key option
- **Automatic SSH Key Generation**: Generates ED25519 key pairs for all users with SSH setup enabled
- **Passphrase-free Keys**: Generated SSH keys have no passphrase for automation-friendly usage
### 🔄 Changed
- **Enhanced SSH Key Workflow**: Now provides both inbound (authorized_keys) and outbound (generated keys) SSH capabilities
- **Improved User Experience**: Streamlined SSH setup with smart defaults for known users
## [2.0.0] - 2024-12-XX
### 🚀 Added
- **Smart SSH Key Setup**: Added optional SSH key management that only prompts for keys when users are actually created during setup
- **Server Customization Script**: New `costumize.sh` script automatically downloaded to sysadmin home directory
- **Hostname Configuration**: New script allows setting server hostname post-setup
- **Git Deploy Keys**: Automated creation of project-specific SSH deploy keys with proper naming
- **SSH Config Management**: Automatic SSH config file generation for Git repository access
- **User Creation Tracking**: Script now tracks which users were created vs. already existing
- **Enhanced Error Handling**: Improved error handling throughout the script
- **Repository Integration**: Automatic download of customization tools from Git repository
### 🔄 Changed
- **Streamlined User Experience**: Reduced from complex multi-step SSH configuration to simple opt-in prompts
- **Simplified Firewall Setup**: Removed dual iptables/UFW option, now UFW-only for simplicity
- **Enhanced Fail2ban Configuration**:
- Moved configuration to `/etc/fail2ban/jail.d/custom.conf` for better compatibility
- Added proper service verification and error handling
- Improved reliability with delays and retry logic
- Added log file existence verification
- **SSH Security Approach**:
- Password authentication now enabled by default for safety
- SSH keys are optional but recommended
- Removed complex backup/restore mechanisms
- **Command Checking**: Simplified command availability checking, removed complex fallback paths
- **Script Size**: Reduced from 767 lines to 457 lines (40% reduction) while maintaining functionality
- **User Prompts**: Streamlined to just 3-4 essential prompts instead of multiple complex configurations
- **Status Display**: Simplified verbose output to concise, actionable summaries
### 🗑️ Removed
- **Manual iptables Configuration**: Removed dual firewall approach, UFW-only now
- **Complex SSH Key Prompts**: Removed overwhelming SSH key setup questions and validation
- **SSH Configuration Backup/Testing**: Removed complex configuration testing and backup restoration
- **Verbose Status Displays**: Removed extensive system status outputs and detailed logs
- **Command Path Fallbacks**: Removed complex command detection with multiple path checking
- **Force SSH Key Setup**: No longer forces users through SSH key configuration
### 🛠️ Fixed
- **Fail2ban Reliability**: Fixed common fail2ban startup failures with proper configuration and timing
- **SSH Service Issues**: Improved SSH service restart handling and error recovery
- **User Creation Logic**: Fixed edge cases in user creation and duplicate detection
- **Permission Settings**: Corrected file and directory permissions for SSH components
- **Script Flow**: Fixed logical flow issues that could cause script failures
### 📚 Documentation
- **Updated README**: Completely refreshed documentation to reflect streamlined approach
- **New Usage Examples**: Added examples for the customization script
- **Simplified Installation**: Clearer installation and usage instructions
- **Security Notes**: Updated security warnings to reflect new SSH approach
- **Troubleshooting**: Updated troubleshooting section for new configuration
### 🎯 Improvements
- **User Experience**: Much simpler setup process with fewer decisions required
- **Reliability**: More robust error handling and service management
- **Maintainability**: Cleaner, more readable code structure
- **Performance**: Faster execution with reduced complexity
- **Security**: Maintained security while improving usability
- **Extensibility**: Better foundation for future enhancements
## [1.0.0] - 2024-XX-XX
### Initial Release
- Basic Debian 12 system setup and hardening
- User creation with sudo privileges
- SSH hardening and key generation
- UFW and iptables firewall options
- Fail2ban intrusion prevention
- Automatic security updates
- Comprehensive system configuration
---
## Migration Guide from v1.0.0 to v2.0.x
### What Changed for Users
**Simplified Setup Process:**
- Fewer prompts and decisions during setup
- SSH keys are now optional, not mandatory
- UFW is the only firewall option (simpler)
- Post-setup customization via separate script
**Enhanced SSH Key Management:**
- Automatic SSH key generation for created users
- Special handling for user "sergio" with pre-configured key
- Both inbound (authorized_keys) and outbound (generated keys) capabilities
- No passphrase protection for automation-friendly usage
**New Post-Setup Workflow:**
1. Run `setup.sh` as before
2. Optionally add SSH keys during setup (with smart defaults)
3. Run `./costumize.sh` for hostname and Git deploy keys
4. Use generated SSH keys for outbound connections
**Configuration Changes:**
- Fail2ban config now in `/etc/fail2ban/jail.d/custom.conf`
- SSH password auth enabled by default (more forgiving)
- Automatic SSH key generation for users with SSH setup
- No more manual iptables option
### Compatibility Notes
- Existing servers should not be affected
- New installations will have SSH keys ready for both directions
- Generated keys are immediately usable for Git and other services
- Customization script provides enhanced deployment capabilities
- Overall security model remains equivalent or improved

179
README.md
View File

@@ -1,6 +1,6 @@
# Debian First Boot Setup Script
A comprehensive bash script for securing and setting up a fresh Debian 12 system with best security practices.
A streamlined bash script for securing and setting up a fresh Debian 12 system with essential security practices and optional SSH key management.
## Download and Run
@@ -32,25 +32,30 @@ sudo ./setup.sh
### System Security
- **System Updates**: Updates all packages to latest versions
- **Essential Package Installation**: Installs sudo, curl, wget, vim, htop, unzip, git, openssh-server
- **SSH Hardening**: Disables root SSH login, password authentication, and enables key-based authentication
- **SSH Hardening**: Disables root SSH login, enables key authentication, configures security timeouts
- **Root Account Locking**: Locks the root password for enhanced security
- **Automatic Security Updates**: Configures unattended-upgrades for security patches
### User Management
- **Sysadmin User**: Creates a default `sysadmin` user with sudo privileges
- **Additional Users**: Option to create additional administrative users
- **SSH Key Generation**: Generates SSH keys for all created users and root
- **Additional Users**: Option to create additional administrative users with sudo access
- **Smart SSH Key Setup**: Prompts to add SSH public keys only for users created during setup
- **Special User Handling**: Pre-configured SSH key option for user "sergio"
- **Automatic Key Generation**: Generates ED25519 SSH key pairs for users with SSH setup
- **User Validation**: Validates usernames and prevents duplicates
### Firewall Configuration
- **UFW Option**: Easy-to-use Uncomplicated Firewall with predefined rules
- **Manual iptables**: Basic iptables configuration for advanced users
- **Default Ports**: Allows SSH (22), HTTP (80), and HTTPS (443)
- **UFW Firewall**: Simple, optional firewall setup with SSH, HTTP, HTTPS access
- **Default Security**: Deny incoming, allow outgoing traffic by default
### Intrusion Prevention
- **Fail2ban**: Optional protection against brute-force attacks
- **IP Banning**: Configurable ban times and retry limits
- **Log Monitoring**: Monitors SSH authentication logs
- **Enhanced Fail2ban**: Improved fail2ban configuration with better reliability
- **SSH Protection**: Monitors and bans brute-force SSH attempts
- **Smart Configuration**: Uses jail.d for better compatibility
### Server Customization
- **Automatic Download**: Downloads `costumize.sh` script to sysadmin home directory
- **Post-Setup Tools**: Additional customization options after initial setup
## What the Script Does
@@ -65,28 +70,31 @@ sudo ./setup.sh
- Adds all users to sudo group
- Sets up password authentication for initial access
### 3. Security Configuration
- Disables root SSH login
- Configures SSH for key-based authentication only
- Locks root password
- Sets up firewall rules (UFW or iptables)
- Optionally configures fail2ban for intrusion prevention
### 3. SSH Key Setup (Optional)
- Prompts to add SSH public keys only for newly created users
- Special handling for user "sergio" with pre-configured key option
- Validates SSH key format (ssh-rsa, ssh-ed25519, etc.)
- Creates .ssh directories with proper permissions
- Adds keys to authorized_keys files safely
- **Automatically generates SSH key pairs for created users**
- **No passphrase protection for generated keys**
### 4. SSH Key Generation
- Generates ED25519 SSH keys for each user
- Generates SSH key for root user
- Sets proper file permissions (600 for private, 644 for public keys)
- Displays all public keys for easy copying
### 4. Security Configuration
- Disables root SSH login and locks root password
- Configures SSH security settings (timeouts, max attempts)
- Restricts SSH access to created users only
- Optionally sets up UFW firewall with basic rules
- Optionally configures enhanced fail2ban protection
### 5. System Finalization
- Configures automatic security updates
- Downloads customization script to sysadmin home
- Restarts SSH service with new configuration
- Performs system cleanup
- Displays final system status and connection information
- Displays concise setup summary
## Interactive Configuration
The script prompts for several configuration options:
The streamlined script prompts for just a few key options:
### Additional User Creation
```
@@ -100,61 +108,63 @@ Would you like to create an additional user account? (y/N):
### Firewall Configuration
```
=== Firewall Configuration ===
This script can configure UFW (Uncomplicated Firewall) or you can manage iptables manually.
UFW (Uncomplicated Firewall) provides easy firewall management.
UFW vs iptables:
• UFW: Easy to use, good for basic setups
• Manual iptables: More control, better for complex setups (VPN servers, etc.)
Would you like to install and configure UFW? (y/N):
Install and configure UFW? (y/N):
```
### Fail2ban Configuration
### Fail2ban Protection
```
=== Fail2ban Configuration ===
Fail2ban protects against brute-force attacks by monitoring logs and banning IPs.
Fail2ban protects against brute-force attacks.
Consider skipping fail2ban if:
• You're running a VPN server (WireGuard, OpenVPN, etc.)
• You have complex iptables rules
• You prefer managing IP banning manually
Install and configure fail2ban? (Y/n):
```
Would you like to install and configure fail2ban? (Y/n):
### SSH Key Setup (Only for Created Users)
```
=== SSH Key Setup ===
Users created during setup: sysadmin username
You can add your SSH public key for easier login.
Add your SSH public key to created users? (Y/n):
```
**Special handling for user "sergio":**
```
Detected user 'sergio' was created.
Use pre-configured SSH key for sergio? (Y/n)
Key: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINBYyuGSa2wswiiObp2qj30MoiNRyFdBIBciFSbtrkZ8 mbpm1
Use this key? (Y/n):
```
## Security Features
### SSH Hardening
- Protocol 2 only
- Public key authentication required
- Password authentication disabled
- Root login disabled
- Public key authentication enabled
- Password authentication configurable (enabled by default for safety)
- Empty passwords prohibited
- X11 forwarding disabled
- Maximum 3 authentication attempts
- Client alive interval: 5 minutes
- Restricted user access (AllowUsers directive)
### Firewall Rules
**UFW Configuration:**
- Default deny incoming
- Default allow outgoing
### UFW Firewall (Optional)
- Default deny incoming, allow outgoing
- Allow SSH (port 22)
- Allow HTTP (port 80)
- Allow HTTPS (port 443)
- Simple management with `ufw` command
**iptables Configuration:**
- Drop all incoming by default
- Allow established and related connections
- Allow loopback traffic
- Allow SSH, HTTP, HTTPS
- Persistent rules saved to `/etc/iptables/rules.v4`
### Fail2ban Settings
### Enhanced Fail2ban (Optional)
- Configuration stored in `/etc/fail2ban/jail.d/custom.conf`
- Ban time: 1 hour
- Find time: 10 minutes
- Maximum retries: 3
- SSH jail enabled
- Monitors `/var/log/auth.log`
- SSH jail with improved reliability
- Better error handling and service verification
## Post-Installation
@@ -169,30 +179,46 @@ Or with additional user:
ssh USERNAME@YOUR_SERVER_IP
```
### SSH Key Management
1. Copy the displayed SSH public keys
2. Add them to your Git server and other systems
3. Use the keys for passwordless authentication
### Server Customization
After initial setup, run the customization script:
```bash
./costumize.sh
```
This script provides:
- **Hostname Configuration**: Set server hostname
- **Git Deploy Keys**: Create SSH keys for Git repository access
- **SSH Config Setup**: Automatic SSH configuration for Git servers
- **Repository Instructions**: Ready-to-use Git clone commands
### Generated SSH Keys
Created users will have SSH key pairs automatically generated:
```bash
# Private key (for outbound connections)
~/.ssh/id_ed25519
# Public key (share with other systems)
~/.ssh/id_ed25519.pub
```
**Key Features:**
- **ED25519 algorithm** (modern and secure)
- **No passphrase** (ready for automation)
- **Proper permissions** (600 for private, 644 for public)
- **Hostname-based comments** (username@hostname)
### System Management
- **View UFW status**: `sudo ufw status verbose`
- **Check iptables rules**: `sudo iptables -L -n`
- **Monitor fail2ban**: `sudo fail2ban-client status sshd`
- **Check SSH config**: `sudo sshd -T`
- **View system logs**: `sudo journalctl -u ssh`
## Customization
## Advanced Configuration
### Manual Firewall Rules
If you chose manual iptables, customize `/etc/iptables-basic.sh`:
### Fail2ban Customization
Modify fail2ban settings in `/etc/fail2ban/jail.d/custom.conf`:
```bash
sudo nano /etc/iptables-basic.sh
sudo /etc/iptables-basic.sh
```
### Fail2ban Configuration
Modify fail2ban settings in `/etc/fail2ban/jail.local`:
```bash
sudo nano /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.d/custom.conf
sudo systemctl restart fail2ban
```
@@ -203,6 +229,13 @@ sudo nano /etc/ssh/sshd_config
sudo systemctl restart sshd
```
### UFW Rules
Add custom firewall rules:
```bash
sudo ufw allow from 192.168.1.0/24 to any port 3306
sudo ufw status numbered
```
## Requirements
- **Operating System**: Debian 12 (Bookworm)
@@ -215,9 +248,9 @@ sudo systemctl restart sshd
⚠️ **Security Warnings:**
1. Root SSH login will be **DISABLED**
2. Root password will be **LOCKED**
3. SSH password authentication will be **DISABLED**
4. Only SSH key authentication will be allowed
5. Only created users can SSH to the server
3. SSH password authentication is **ENABLED** by default (can be disabled via SSH keys)
4. Only created users (sysadmin + optional additional) can SSH to the server
5. Set up SSH keys for passwordless authentication
🔄 **Reboot Recommended:**
A system reboot is recommended after running the script to ensure all changes take effect.

252
costumize.sh Executable file
View File

@@ -0,0 +1,252 @@
#!/bin/bash
# Server Customization Script
# Run this script to set hostname and create Git deploy keys
set -euo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Logging functions
log() {
echo -e "${GREEN}[$(date +'%Y-%m-%d %H:%M:%S')] $1${NC}"
}
warn() {
echo -e "${YELLOW}[WARNING] $1${NC}"
}
error() {
echo -e "${RED}[ERROR] $1${NC}"
exit 1
}
# Check if running as non-root user
check_user() {
if [[ $EUID -eq 0 ]]; then
error "This script should be run as a regular user (not root)"
fi
}
# Set server hostname
set_hostname() {
echo ""
echo -e "${BLUE}=== Server Hostname Configuration ===${NC}"
echo "Current hostname: $(hostname)"
echo ""
read -p "Enter new hostname for this server: " new_hostname
if [[ -z "$new_hostname" ]]; then
error "Hostname cannot be empty"
fi
# Validate hostname format
if [[ ! "$new_hostname" =~ ^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?$ ]]; then
error "Invalid hostname format. Use only letters, numbers, and hyphens."
fi
log "Setting hostname to: $new_hostname"
# Update hostname
sudo hostnamectl set-hostname "$new_hostname"
# Update /etc/hosts
sudo sed -i "s/127.0.1.1.*/127.0.1.1\t$new_hostname/" /etc/hosts
# Add entry if it doesn't exist
if ! grep -q "127.0.1.1" /etc/hosts; then
echo -e "127.0.1.1\t$new_hostname" | sudo tee -a /etc/hosts
fi
log "Hostname updated successfully"
echo "New hostname: $(hostname)"
return 0
}
# Create Git deploy keys
create_deploy_keys() {
echo ""
echo -e "${BLUE}=== Git Deploy Keys Setup ===${NC}"
echo "Deploy keys allow secure Git access for deployments and automation."
echo ""
read -p "How many Git deploy keys would you like to create? (0-10): " num_keys
# Validate number
if ! [[ "$num_keys" =~ ^[0-9]+$ ]] || [ "$num_keys" -lt 0 ] || [ "$num_keys" -gt 10 ]; then
error "Please enter a number between 0 and 10"
fi
if [ "$num_keys" -eq 0 ]; then
log "No deploy keys will be created"
return
fi
local server_name=$(hostname)
local created_keys=()
# Create SSH directory if it doesn't exist
mkdir -p ~/.ssh
chmod 700 ~/.ssh
# Create each deploy key
for ((i=1; i<=num_keys; i++)); do
echo ""
echo -e "${YELLOW}--- Deploy Key $i of $num_keys ---${NC}"
while true; do
read -p "Enter project name for deploy key $i: " project_name
if [[ -z "$project_name" ]]; then
echo -e "${RED}Project name cannot be empty${NC}"
continue
fi
# Sanitize project name (remove spaces, special chars)
project_name=$(echo "$project_name" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9-]//g')
if [[ -z "$project_name" ]]; then
echo -e "${RED}Invalid project name. Use only letters, numbers, and hyphens.${NC}"
continue
fi
# Check if key already exists
if [[ -f ~/.ssh/deploy_key_$project_name ]]; then
echo -e "${RED}Deploy key for project '$project_name' already exists${NC}"
continue
fi
break
done
local key_file="~/.ssh/deploy_key_$project_name"
local comment="deploy-key-$project_name-$server_name"
log "Creating deploy key for project: $project_name"
# Generate SSH key
ssh-keygen -t ed25519 -f ~/.ssh/deploy_key_$project_name -C "$comment" -N ""
# Set proper permissions
chmod 600 ~/.ssh/deploy_key_$project_name
chmod 644 ~/.ssh/deploy_key_$project_name.pub
created_keys+=("$project_name")
log "Deploy key created: ~/.ssh/deploy_key_$project_name"
done
# Configure SSH config
configure_ssh_config "${created_keys[@]}"
# Show public keys and instructions
show_deploy_instructions "${created_keys[@]}"
}
# Configure SSH config file
configure_ssh_config() {
local projects=("$@")
local ssh_config="$HOME/.ssh/config"
log "Configuring SSH config..."
# Backup existing config
if [[ -f "$ssh_config" ]]; then
cp "$ssh_config" "$ssh_config.backup.$(date +%Y%m%d_%H%M%S)"
fi
echo ""
read -p "Enter your Git server domain (e.g., git.example.com): " git_domain
if [[ -z "$git_domain" ]]; then
error "Git server domain cannot be empty"
fi
# Add SSH config entries
for project in "${projects[@]}"; do
echo "" >> "$ssh_config"
echo "Host gitea-$project" >> "$ssh_config"
echo " HostName $git_domain" >> "$ssh_config"
echo " User git" >> "$ssh_config"
echo " Port 22" >> "$ssh_config"
echo " IdentityFile ~/.ssh/deploy_key_$project" >> "$ssh_config"
echo " IdentitiesOnly yes" >> "$ssh_config"
done
chmod 600 "$ssh_config"
log "SSH config updated with ${#projects[@]} deploy key entries"
}
# Show deploy key public keys and usage instructions
show_deploy_instructions() {
local projects=("$@")
echo ""
echo -e "${BLUE}=== Deploy Keys Created ===${NC}"
echo ""
for project in "${projects[@]}"; do
echo -e "${YELLOW}--- Project: $project ---${NC}"
echo "Public key (copy this to your Git server):"
echo ""
cat ~/.ssh/deploy_key_$project.pub
echo ""
echo -e "${GREEN}Add this key to your Git repository's deploy keys section${NC}"
echo ""
echo "Clone/configure repository:"
echo -e "${YELLOW}# For new clones:${NC}"
echo "git clone git@gitea-$project:username/repository.git"
echo ""
echo -e "${YELLOW}# For existing repos, update the remote:${NC}"
echo "git remote set-url origin git@gitea-$project:username/repository.git"
echo ""
echo "================================"
echo ""
done
echo -e "${BLUE}=== Important Notes ===${NC}"
echo "• Deploy keys are stored in ~/.ssh/deploy_key_<project>"
echo "• SSH config entries created as 'gitea-<project>'"
echo "• Replace 'username/repository.git' with your actual repository path"
echo "• Keys are ready for use after adding public keys to your Git server"
echo ""
echo -e "${GREEN}Setup completed successfully!${NC}"
}
# Main function
main() {
echo -e "${BLUE}=== Server Customization Script ===${NC}"
echo "This script will:"
echo "1. Set server hostname"
echo "2. Create Git deploy keys"
echo "3. Configure SSH for Git repositories"
echo ""
read -p "Continue with server customization? (y/N): " confirm
if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
echo "Customization cancelled."
exit 0
fi
# Check prerequisites
check_user
# Set hostname
set_hostname
# Create deploy keys
create_deploy_keys
echo ""
echo -e "${GREEN}Server customization completed!${NC}"
echo -e "${YELLOW}You may need to log out and back in to see the hostname change.${NC}"
}
main "$@"

View File

@@ -1,104 +0,0 @@
#!/bin/bash
# SSH Recovery Script
# Run this if the main setup script broke SSH
set -euo pipefail
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
log() {
echo -e "${GREEN}[$(date +'%Y-%m-%d %H:%M:%S')] $1${NC}"
}
warn() {
echo -e "${YELLOW}[WARNING] $1${NC}"
}
error() {
echo -e "${RED}[ERROR] $1${NC}"
}
# Check if running as root
if [[ $EUID -ne 0 ]]; then
error "This script must be run as root"
exit 1
fi
echo -e "${YELLOW}=== SSH Recovery Script ===${NC}"
echo "This script will help recover from broken SSH configuration."
echo ""
# List available backups
if ls /etc/ssh/sshd_config.backup.* 1> /dev/null 2>&1; then
echo "Available SSH configuration backups:"
ls -la /etc/ssh/sshd_config.backup.*
echo ""
read -p "Restore from backup? (Y/n): " restore_choice
if [[ ! "$restore_choice" =~ ^[Nn]$ ]]; then
# Get the most recent backup
latest_backup=$(ls -t /etc/ssh/sshd_config.backup.* | head -1)
log "Restoring SSH configuration from: $latest_backup"
cp "$latest_backup" /etc/ssh/sshd_config
log "SSH configuration restored"
fi
else
warn "No SSH configuration backups found"
echo "Restoring default SSH configuration..."
# Create a basic working SSH config
cat > /etc/ssh/sshd_config << 'EOF'
# Minimal working SSH configuration
Port 22
PermitRootLogin no
PasswordAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
PermitEmptyPasswords no
ChallengeResponseAuthentication no
UsePAM yes
X11Forwarding no
PrintMotd no
AcceptEnv LANG LC_*
Subsystem sftp /usr/lib/openssh/sftp-server
EOF
log "Basic SSH configuration created"
fi
# Test configuration
log "Testing SSH configuration..."
if sshd -t; then
log "SSH configuration is valid"
# Restart SSH service
log "Restarting SSH service..."
if systemctl restart sshd; then
log "SSH service restarted successfully"
# Check if service is running
if systemctl is-active --quiet sshd; then
echo ""
echo -e "${GREEN}✓ SSH service is now running${NC}"
echo -e "${YELLOW}You should now be able to connect via SSH${NC}"
echo ""
echo "Test connection with:"
echo "ssh user@$(hostname -I | awk '{print $1}')"
else
error "SSH service is not active"
fi
else
error "Failed to restart SSH service"
fi
else
error "SSH configuration is still invalid"
echo "Manual intervention required."
fi
echo ""
echo "Current SSH status:"
systemctl status sshd --no-pager -l

609
setup.sh
View File

@@ -18,8 +18,10 @@ CREATE_ADDITIONAL_USER=""
ADDITIONAL_USER=""
USE_UFW=""
USE_FAIL2BAN=""
DISABLE_SSH_PASSWORD=""
SETUP_SSH_KEYS=""
# Track which users were created during this setup
SYSADMIN_USER_CREATED=""
ADDITIONAL_USER_CREATED=""
# Logging functions
log() {
@@ -51,25 +53,11 @@ check_debian() {
# Check for required commands
check_commands() {
# Check useradd (in /usr/sbin/)
if ! command -v useradd >/dev/null 2>&1 && ! [ -x /usr/sbin/useradd ]; then
error "useradd command not found. Please install the passwd package: apt install -y passwd"
fi
# Check passwd (usually in /usr/bin/)
if ! command -v passwd >/dev/null 2>&1 && ! [ -x /usr/bin/passwd ]; then
error "passwd command not found. Please install the passwd package: apt install -y passwd"
fi
# Check usermod (in /usr/sbin/)
if ! command -v usermod >/dev/null 2>&1 && ! [ -x /usr/sbin/usermod ]; then
warn "usermod command not found. Will attempt to use full path."
fi
# Check sudo (usually in /usr/bin/)
if ! command -v sudo >/dev/null 2>&1 && ! [ -x /usr/bin/sudo ]; then
warn "sudo command not found. Will install it during system setup."
fi
for cmd in useradd passwd usermod; do
if ! command -v $cmd >/dev/null 2>&1; then
error "$cmd command not found. Please install required packages: apt install -y passwd"
fi
done
}
# Ask user about creating an additional user
@@ -116,85 +104,28 @@ ask_additional_user() {
fi
}
# Ask user about SSH security preferences
ask_ssh_security() {
echo ""
echo -e "${BLUE}=== SSH Security Configuration ===${NC}"
echo "This script can disable SSH password authentication for enhanced security."
echo ""
echo -e "${YELLOW}⚠️ WARNING: Disabling password authentication means you can ONLY log in with SSH keys!${NC}"
echo "If you lose your SSH keys, you could be locked out of the server."
echo ""
echo -e "${YELLOW}Consider keeping password authentication if:${NC}"
echo "• This is your first time setting up SSH keys"
echo "• You don't have a reliable way to store SSH keys"
echo "• You need emergency access options"
echo ""
read -p "Disable SSH password authentication? (y/N): " disable_password_choice
if [[ "$disable_password_choice" =~ ^[Yy]$ ]]; then
DISABLE_SSH_PASSWORD="yes"
log "SSH password authentication will be disabled"
echo ""
echo -e "${BLUE}=== SSH Key Setup ===${NC}"
echo "Since password authentication will be disabled, you'll need SSH keys to connect."
echo "You need to add YOUR computer's SSH public key to the server."
echo ""
read -p "Add your SSH public key to authorized_keys for login? (Y/n): " setup_keys_choice
if [[ "$setup_keys_choice" =~ ^[Nn]$ ]]; then
SETUP_SSH_KEYS="no"
warn "SSH keys will NOT be set up automatically"
warn "You MUST manually add your public key to authorized_keys files after setup"
else
SETUP_SSH_KEYS="yes"
log "You will be prompted to paste your SSH public key"
fi
else
DISABLE_SSH_PASSWORD="no"
SETUP_SSH_KEYS="no"
log "SSH password authentication will remain enabled"
echo ""
read -p "Still want to add your SSH public key for convenient access? (Y/n): " add_keys_choice
if [[ ! "$add_keys_choice" =~ ^[Nn]$ ]]; then
SETUP_SSH_KEYS="yes"
log "You will be prompted to paste your SSH public key"
fi
fi
}
# Ask user about firewall preferences
# Ask user about firewall and security preferences
ask_firewall_preferences() {
echo ""
echo -e "${BLUE}=== Firewall Configuration ===${NC}"
echo "This script can configure UFW (Uncomplicated Firewall) or you can manage iptables manually."
echo "UFW (Uncomplicated Firewall) provides easy firewall management."
echo ""
echo -e "${YELLOW}UFW vs iptables:${NC}"
echo "• UFW: Easy to use, good for basic setups"
echo "• Manual iptables: More control, better for complex setups (VPN servers, etc.)"
echo ""
read -p "Would you like to install and configure UFW? (y/N): " ufw_choice
read -p "Install and configure UFW? (y/N): " ufw_choice
if [[ "$ufw_choice" =~ ^[Yy]$ ]]; then
USE_UFW="yes"
log "UFW will be installed and configured"
else
USE_UFW="no"
log "UFW will be skipped - you can configure iptables manually"
log "UFW will be skipped"
fi
echo ""
echo -e "${BLUE}=== Fail2ban Configuration ===${NC}"
echo "Fail2ban protects against brute-force attacks by monitoring logs and banning IPs."
echo "Fail2ban protects against brute-force attacks."
echo ""
echo -e "${YELLOW}Consider skipping fail2ban if:${NC}"
echo "• You're running a VPN server (WireGuard, OpenVPN, etc.)"
echo "• You have complex iptables rules"
echo "• You prefer managing IP banning manually"
echo ""
read -p "Would you like to install and configure fail2ban? (Y/n): " fail2ban_choice
read -p "Install and configure fail2ban? (Y/n): " fail2ban_choice
if [[ "$fail2ban_choice" =~ ^[Nn]$ ]]; then
USE_FAIL2BAN="no"
@@ -205,6 +136,144 @@ ask_firewall_preferences() {
fi
}
# Ask user about SSH key setup for created users
ask_ssh_key_setup() {
# Check if any users were created
local users_created=()
if [[ "$SYSADMIN_USER_CREATED" == "yes" ]]; then
users_created+=("$SYSADMIN_USER")
fi
if [[ "$ADDITIONAL_USER_CREATED" == "yes" ]]; then
users_created+=("$ADDITIONAL_USER")
fi
# Only prompt if users were actually created
if [[ ${#users_created[@]} -eq 0 ]]; then
return
fi
echo ""
echo -e "${BLUE}=== SSH Key Setup ===${NC}"
echo "Users created during setup: ${users_created[*]}"
echo "You can add your SSH public key for easier login."
echo ""
read -p "Add your SSH public key to created users? (Y/n): " add_key_choice
if [[ "$add_key_choice" =~ ^[Nn]$ ]]; then
log "SSH key setup skipped"
return
fi
local user_public_key=""
# Special case for user "sergio" - offer pre-defined key
if [[ " ${users_created[*]} " =~ " sergio " ]]; then
echo ""
echo "Detected user 'sergio' was created."
echo "Use pre-configured SSH key for sergio? (Y/n)"
echo "Key: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINBYyuGSa2wswiiObp2qj30MoiNRyFdBIBciFSbtrkZ8 mbpm1"
echo ""
read -p "Use this key? (Y/n): " use_sergio_key
if [[ ! "$use_sergio_key" =~ ^[Nn]$ ]]; then
user_public_key="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINBYyuGSa2wswiiObp2qj30MoiNRyFdBIBciFSbtrkZ8 mbpm1"
log "Using pre-configured key for sergio"
fi
fi
# If no pre-defined key was used, prompt for manual entry
if [[ -z "$user_public_key" ]]; then
echo ""
echo "Please paste your SSH public key (starts with ssh-rsa, ssh-ed25519, etc.):"
echo "You can find it with: cat ~/.ssh/id_ed25519.pub (or id_rsa.pub)"
echo ""
while true; do
read -r user_public_key
if [[ -z "$user_public_key" ]]; then
echo -e "${RED}Public key cannot be empty. Please try again.${NC}"
continue
elif [[ "$user_public_key" =~ ^(ssh-rsa|ssh-dss|ssh-ed25519|ecdsa-sha2-) ]]; then
break
else
echo -e "${RED}Invalid SSH public key format. Please ensure you copied the entire key.${NC}"
continue
fi
done
fi
# Add key to all created users and generate SSH keys for them
for username in "${users_created[@]}"; do
setup_ssh_key_for_user "$username" "$user_public_key"
generate_ssh_key_for_user "$username"
done
echo ""
log "SSH key added to: ${users_created[*]}"
log "SSH keys generated for: ${users_created[*]}"
}
setup_ssh_key_for_user() {
local username="$1"
local public_key="$2"
local user_home="/home/$username"
local ssh_dir="$user_home/.ssh"
local authorized_keys="$ssh_dir/authorized_keys"
log "Setting up SSH key for user: $username"
# Create .ssh directory if it doesn't exist
if [ ! -d "$ssh_dir" ]; then
sudo -u "$username" mkdir -p "$ssh_dir"
sudo -u "$username" chmod 700 "$ssh_dir"
fi
# Check if key already exists
if [ -f "$authorized_keys" ] && grep -Fxq "$public_key" "$authorized_keys"; then
warn "SSH key already exists for $username"
else
echo "$public_key" | sudo -u "$username" tee -a "$authorized_keys" > /dev/null
sudo -u "$username" chmod 600 "$authorized_keys"
log "SSH key added for $username"
fi
}
generate_ssh_key_for_user() {
local username="$1"
local user_home="/home/$username"
local ssh_dir="$user_home/.ssh"
local private_key="$ssh_dir/id_ed25519"
local public_key="$ssh_dir/id_ed25519.pub"
# Check if SSH key already exists
if [[ -f "$private_key" ]]; then
log "SSH key already exists for $username, skipping generation"
return
fi
log "Generating SSH key for user: $username"
# Create .ssh directory if it doesn't exist
if [ ! -d "$ssh_dir" ]; then
sudo -u "$username" mkdir -p "$ssh_dir"
sudo -u "$username" chmod 700 "$ssh_dir"
fi
# Generate SSH key without passphrase
sudo -u "$username" ssh-keygen -t ed25519 -f "$private_key" -N "" -C "$username@$(hostname)"
# Set proper permissions
sudo -u "$username" chmod 600 "$private_key"
sudo -u "$username" chmod 644 "$public_key"
log "SSH key pair generated for $username"
echo " Private key: $private_key"
echo " Public key: $public_key"
}
### === DEBIAN SYSTEM SETUP === ###
setup_system() {
log "Starting Debian 12 initial setup..."
@@ -236,37 +305,21 @@ create_sysadmin_user() {
if id "$SYSADMIN_USER" &>/dev/null; then
warn "User $SYSADMIN_USER already exists, skipping creation"
SYSADMIN_USER_CREATED="no"
else
# Create user with home directory
if command -v useradd >/dev/null 2>&1; then
useradd -m -s /bin/bash "$SYSADMIN_USER"
elif [ -x /usr/sbin/useradd ]; then
/usr/sbin/useradd -m -s /bin/bash "$SYSADMIN_USER"
else
error "useradd command not found. Please install the passwd package."
fi
useradd -m -s /bin/bash "$SYSADMIN_USER"
log "User $SYSADMIN_USER created successfully"
SYSADMIN_USER_CREATED="yes"
# Set password for sysadmin user
echo "Please set a password for user $SYSADMIN_USER:"
if command -v passwd >/dev/null 2>&1; then
passwd "$SYSADMIN_USER"
elif [ -x /usr/bin/passwd ]; then
/usr/bin/passwd "$SYSADMIN_USER"
else
error "passwd command not found. Please install the passwd package."
fi
passwd "$SYSADMIN_USER"
fi
# Add sysadmin to sudo group
log "Adding $SYSADMIN_USER to sudo group..."
if command -v usermod >/dev/null 2>&1; then
usermod -aG sudo "$SYSADMIN_USER"
elif [ -x /usr/sbin/usermod ]; then
/usr/sbin/usermod -aG sudo "$SYSADMIN_USER"
else
error "usermod command not found. Please install the passwd package."
fi
usermod -aG sudo "$SYSADMIN_USER"
}
create_additional_user() {
@@ -275,37 +328,21 @@ create_additional_user() {
if id "$ADDITIONAL_USER" &>/dev/null; then
warn "User $ADDITIONAL_USER already exists, skipping creation"
ADDITIONAL_USER_CREATED="no"
else
# Create user with home directory
if command -v useradd >/dev/null 2>&1; then
useradd -m -s /bin/bash "$ADDITIONAL_USER"
elif [ -x /usr/sbin/useradd ]; then
/usr/sbin/useradd -m -s /bin/bash "$ADDITIONAL_USER"
else
error "useradd command not found. Please install the passwd package."
fi
useradd -m -s /bin/bash "$ADDITIONAL_USER"
log "User $ADDITIONAL_USER created successfully"
ADDITIONAL_USER_CREATED="yes"
# Set password for additional user
echo "Please set a password for user $ADDITIONAL_USER:"
if command -v passwd >/dev/null 2>&1; then
passwd "$ADDITIONAL_USER"
elif [ -x /usr/bin/passwd ]; then
/usr/bin/passwd "$ADDITIONAL_USER"
else
error "passwd command not found. Please install the passwd package."
fi
passwd "$ADDITIONAL_USER"
fi
# Add additional user to sudo group
log "Adding $ADDITIONAL_USER to sudo group..."
if command -v usermod >/dev/null 2>&1; then
usermod -aG sudo "$ADDITIONAL_USER"
elif [ -x /usr/sbin/usermod ]; then
/usr/sbin/usermod -aG sudo "$ADDITIONAL_USER"
else
error "usermod command not found. Please install the passwd package."
fi
usermod -aG sudo "$ADDITIONAL_USER"
fi
}
@@ -315,20 +352,11 @@ configure_security() {
sed -i 's/#PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
sed -i 's/PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
# Configure SSH settings safely
# Configure SSH settings
log "Applying SSH security settings..."
# Backup original sshd_config
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.backup.$(date +%Y%m%d_%H%M%S)
# Configure PasswordAuthentication
if [[ "$DISABLE_SSH_PASSWORD" == "yes" ]]; then
sed -i 's/^#*PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
log "SSH password authentication disabled"
else
sed -i 's/^#*PasswordAuthentication.*/PasswordAuthentication yes/' /etc/ssh/sshd_config
log "SSH password authentication enabled"
fi
# Configure basic SSH security - enable password auth by default for safety
sed -i 's/^#*PasswordAuthentication.*/PasswordAuthentication yes/' /etc/ssh/sshd_config
# Configure other SSH settings more safely
sed -i 's/^#*PubkeyAuthentication.*/PubkeyAuthentication yes/' /etc/ssh/sshd_config
@@ -357,25 +385,17 @@ configure_security() {
echo "AllowUsers $SYSADMIN_USER" >> /etc/ssh/sshd_config
fi
# Test SSH configuration before proceeding
# Test SSH configuration
log "Testing SSH configuration..."
if ! sshd -t; then
error "SSH configuration is invalid! Restoring backup..."
mv /etc/ssh/sshd_config.backup.$(date +%Y%m%d_%H%M%S) /etc/ssh/sshd_config
exit 1
fi
log "SSH configuration is valid"
sshd -t || error "SSH configuration is invalid!"
# Remove/lock root password
log "Locking root password..."
passwd -l root
# Configure firewall based on user choice
# Configure firewall if requested
if [[ "$USE_UFW" == "yes" ]]; then
configure_ufw
else
configure_basic_iptables
fi
# Configure fail2ban if requested
@@ -439,71 +459,21 @@ configure_ufw() {
ufw status verbose
}
configure_basic_iptables() {
log "Setting up basic iptables rules..."
# Create a simple script for basic iptables rules
cat > /etc/iptables-basic.sh << 'EOF'
#!/bin/bash
# Basic iptables rules for SSH, HTTP, HTTPS
# Flush existing rules
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
# Set default policies
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# Allow loopback
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# Allow established and related connections
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Allow SSH (port 22)
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# Allow HTTP (port 80)
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# Allow HTTPS (port 443)
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# Save rules
iptables-save > /etc/iptables/rules.v4
EOF
chmod +x /etc/iptables-basic.sh
# Create iptables directory if it doesn't exist
mkdir -p /etc/iptables
# Run the basic rules script
/etc/iptables-basic.sh
# Install iptables-persistent to make rules persistent
apt install -y iptables-persistent
log "Basic iptables rules applied and saved"
warn "You can customize /etc/iptables-basic.sh and run it to update rules"
warn "Current rules are saved in /etc/iptables/rules.v4"
}
configure_fail2ban() {
if [[ "$USE_FAIL2BAN" == "yes" ]]; then
log "Configuring fail2ban..."
cat > /etc/fail2ban/jail.local << EOF
# Ensure fail2ban directories exist
mkdir -p /etc/fail2ban/jail.d
# Create configuration in jail.d instead of overwriting jail.local
cat > /etc/fail2ban/jail.d/custom.conf << EOF
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 3
ignoreip = 127.0.0.1/8 ::1
[sshd]
enabled = true
@@ -514,128 +484,35 @@ maxretry = 3
bantime = 1h
EOF
# Start and enable fail2ban
# Verify log file exists
if [[ ! -f /var/log/auth.log ]]; then
warn "Auth log file doesn't exist yet, creating it..."
touch /var/log/auth.log
chmod 640 /var/log/auth.log
fi
# Start and enable fail2ban with error handling
systemctl enable fail2ban
systemctl start fail2ban
log "Fail2ban configured and started"
else
# Remove/disable fail2ban if user chose not to use it
if systemctl is-active --quiet fail2ban; then
log "Stopping and disabling fail2ban..."
systemctl stop fail2ban
systemctl disable fail2ban
# Give a moment for systemd to process
sleep 2
if systemctl start fail2ban; then
# Verify it's actually running
if systemctl is-active --quiet fail2ban; then
log "Fail2ban configured and started successfully"
# Show status briefly
systemctl status fail2ban --no-pager --lines=3
else
warn "Fail2ban started but may have issues. Check: systemctl status fail2ban"
fi
else
error "Failed to start fail2ban service"
fi
if dpkg -l | grep -q fail2ban; then
log "Removing fail2ban package..."
apt remove --purge -y fail2ban
apt autoremove -y
fi
log "Fail2ban has been removed/disabled"
fi
}
### === SSH KEY SETUP === ###
setup_user_ssh_keys() {
if [[ "$SETUP_SSH_KEYS" == "no" ]]; then
log "SSH key setup skipped"
return
fi
echo ""
echo -e "${BLUE}=== SSH Public Key Setup ===${NC}"
echo "To set up SSH key authentication, you need to provide your SSH public key."
echo "You can find your public key on your computer by running:"
echo -e "${YELLOW} cat ~/.ssh/id_rsa.pub${NC}"
echo -e "${YELLOW} # or${NC}"
echo -e "${YELLOW} cat ~/.ssh/id_ed25519.pub${NC}"
echo ""
echo "If you don't have an SSH key pair, generate one on your computer first:"
echo -e "${YELLOW} ssh-keygen -t ed25519 -C \"your_email@example.com\"${NC}"
echo ""
while true; do
echo "Please paste your SSH public key (starts with ssh-rsa, ssh-ed25519, etc.):"
read -r user_public_key
if [[ -z "$user_public_key" ]]; then
echo -e "${RED}Public key cannot be empty. Please try again.${NC}"
continue
elif [[ "$user_public_key" =~ ^(ssh-rsa|ssh-dss|ssh-ed25519|ecdsa-sha2-) ]]; then
break
else
echo -e "${RED}Invalid SSH public key format. Please ensure you copied the entire key.${NC}"
continue
fi
done
# Add SSH key to sysadmin user
setup_ssh_key_for_user "$SYSADMIN_USER" "$user_public_key"
# Add SSH key to additional user if created
if [[ "$CREATE_ADDITIONAL_USER" == "yes" && -n "$ADDITIONAL_USER" ]]; then
setup_ssh_key_for_user "$ADDITIONAL_USER" "$user_public_key"
fi
}
setup_ssh_key_for_user() {
local username="$1"
local public_key="$2"
local user_home="/home/$username"
local ssh_dir="$user_home/.ssh"
local authorized_keys="$ssh_dir/authorized_keys"
log "Setting up SSH key for user: $username"
# Create .ssh directory for user if it doesn't exist
if [ ! -d "$ssh_dir" ]; then
sudo -u "$username" mkdir -p "$ssh_dir"
sudo -u "$username" chmod 700 "$ssh_dir"
fi
# Add public key to authorized_keys
log "Adding public key to authorized_keys for $username..."
# Check if key already exists in authorized_keys
if [ -f "$authorized_keys" ] && grep -Fxq "$public_key" "$authorized_keys"; then
warn "SSH key already exists in authorized_keys for $username"
else
echo "$public_key" | sudo -u "$username" tee -a "$authorized_keys" > /dev/null
sudo -u "$username" chmod 600 "$authorized_keys"
log "Public key added to authorized_keys for $username"
fi
}
show_ssh_setup_summary() {
if [[ "$SETUP_SSH_KEYS" == "yes" ]]; then
echo ""
echo -e "${GREEN}✓ SSH key authentication has been set up for:${NC}"
echo " - User: $SYSADMIN_USER"
if [[ "$CREATE_ADDITIONAL_USER" == "yes" && -n "$ADDITIONAL_USER" ]]; then
echo " - User: $ADDITIONAL_USER"
fi
echo ""
echo -e "${YELLOW}Your SSH public key has been added to authorized_keys files.${NC}"
echo "You can now connect using your SSH private key."
elif [[ "$DISABLE_SSH_PASSWORD" == "yes" ]]; then
echo ""
echo -e "${RED}⚠️ SSH password authentication is DISABLED${NC}"
echo -e "${YELLOW}You MUST add your SSH public key manually:${NC}"
echo ""
echo "1. On your computer, get your public key:"
echo " cat ~/.ssh/id_ed25519.pub"
echo ""
echo "2. Add it to the server's authorized_keys:"
echo " echo 'YOUR_PUBLIC_KEY' >> /home/$SYSADMIN_USER/.ssh/authorized_keys"
if [[ "$CREATE_ADDITIONAL_USER" == "yes" && -n "$ADDITIONAL_USER" ]]; then
echo " echo 'YOUR_PUBLIC_KEY' >> /home/$ADDITIONAL_USER/.ssh/authorized_keys"
fi
echo ""
fi
}
### === CLEANUP AND FINALIZATION === ###
@@ -657,70 +534,44 @@ finalize_setup() {
log "SSH service restarted successfully"
# Download customization script for sysadmin user
log "Downloading customization script..."
if wget -O /home/$SYSADMIN_USER/costumize.sh "https://git.del-c.net/Del-c.net/debian-first-boot-setup/raw/branch/main/costumize.sh"; then
chmod +x /home/$SYSADMIN_USER/costumize.sh
chown $SYSADMIN_USER:$SYSADMIN_USER /home/$SYSADMIN_USER/costumize.sh
log "Customization script downloaded to /home/$SYSADMIN_USER/costumize.sh"
else
warn "Failed to download customization script"
fi
# Clean up
log "Cleaning up..."
apt autoremove -y
apt autoclean
# Final security check
log "Final system status:"
echo "================================"
if [[ "$USE_UFW" == "yes" ]]; then
echo "UFW Status:"
ufw status
else
echo "Iptables Status:"
iptables -L -n | head -20
fi
echo "================================"
echo "SSH Configuration:"
grep -E "PermitRootLogin|PasswordAuthentication|PubkeyAuthentication|AllowUsers" /etc/ssh/sshd_config
echo "================================"
if [[ "$USE_FAIL2BAN" == "yes" ]]; then
echo "Fail2ban Status:"
systemctl status fail2ban --no-pager -l
echo "================================"
fi
echo "Sudo users:"
grep -E "sudo|wheel" /etc/group
echo "================================"
log "Setup completed successfully!"
echo ""
echo -e "${BLUE}=== IMPORTANT NOTES ===${NC}"
echo -e "${YELLOW}1. Root SSH login is now DISABLED${NC}"
echo -e "${YELLOW}2. Root password is LOCKED${NC}"
echo -e "${YELLOW}3. SSH password authentication is DISABLED${NC}"
echo -e "${YELLOW}4. Use '$SYSADMIN_USER' user with SSH key to connect${NC}"
echo -e "${BLUE}=== SETUP SUMMARY ===${NC}"
echo -e "${YELLOW} Root SSH login: DISABLED${NC}"
echo -e "${YELLOW} Root password: LOCKED${NC}"
echo -e "${YELLOW}• Main user: $SYSADMIN_USER (sudo access)${NC}"
if [[ "$CREATE_ADDITIONAL_USER" == "yes" && -n "$ADDITIONAL_USER" ]]; then
echo -e "${YELLOW}• Additional user: $ADDITIONAL_USER (sudo access)${NC}"
fi
if [[ "$USE_UFW" == "yes" ]]; then
echo -e "${YELLOW}5. UFW firewall is active (SSH, HTTP, HTTPS allowed)${NC}"
else
echo -e "${YELLOW}5. Basic iptables rules are active (SSH, HTTP, HTTPS allowed)${NC}"
echo -e "${YELLOW} You can customize /etc/iptables-basic.sh for additional rules${NC}"
echo -e "${YELLOW} UFW firewall: ENABLED (SSH, HTTP, HTTPS)${NC}"
fi
local note_number=6
if [[ "$USE_FAIL2BAN" == "yes" ]]; then
echo -e "${YELLOW}$note_number. Fail2ban is protecting SSH${NC}"
((note_number++))
else
echo -e "${YELLOW}$note_number. Consider implementing IP banning manually if needed${NC}"
((note_number++))
echo -e "${YELLOW}• Fail2ban: ENABLED (SSH protection)${NC}"
fi
echo -e "${YELLOW}$note_number. Automatic security updates are enabled${NC}"
((note_number++))
echo -e "${YELLOW}$note_number. SSH keys generated for both $SYSADMIN_USER and root users${NC}"
echo -e "${YELLOW} Automatic security updates: ENABLED${NC}"
echo ""
echo -e "${RED}REBOOT RECOMMENDED${NC}"
echo ""
echo "To connect: ssh $SYSADMIN_USER@$(hostname -I | awk '{print $1}')"
echo -e "${GREEN}Connect with: ssh $SYSADMIN_USER@$(hostname -I | awk '{print $1}')${NC}"
echo -e "${YELLOW}Reboot recommended${NC}"
}
### === MAIN === ###
@@ -731,11 +582,11 @@ main() {
check_commands
echo -e "${BLUE}=== Debian 12 Initial Setup ===${NC}"
echo "This script will:"
echo "1. Set up a secure Debian 12 system"
echo "2. Create a sysadmin user with SSH key authentication"
echo "3. Optionally create an additional user account"
echo "4. Generate SSH keys for all created users and root"
echo "This script will set up a secure Debian 12 system with:"
echo "• Sysadmin user with sudo access"
echo "• Optional additional user"
echo "• SSH security hardening"
echo "• Optional UFW firewall and fail2ban"
echo ""
read -p "Continue? (y/N): " confirm
@@ -746,18 +597,18 @@ main() {
# Ask for user and security preferences
ask_additional_user
ask_ssh_security
ask_firewall_preferences
# System setup
setup_system
create_sysadmin_user
create_additional_user
# SSH key setup for created users
ask_ssh_key_setup
configure_security
# SSH key setup
setup_user_ssh_keys
show_ssh_setup_summary
# Finalize
finalize_setup