Refactor Debian setup script to enhance security and user experience. Implement sysadmin user creation with SSH key generation, configure UFW and fail2ban, and streamline repository cloning process.
This commit is contained in:
343
setup.sh
343
setup.sh
@@ -1,12 +1,184 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
# Debian 12 Initial Setup Script with Git Integration
|
||||
# Run as root: bash setup.sh
|
||||
|
||||
set -euo pipefail # Exit on error, undefined vars, pipe failures
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
### === SETTINGS === ###
|
||||
GIT_SERVER="git.del-c.net"
|
||||
USERNAME=""
|
||||
SELECTED_REPO=""
|
||||
SELECTED_DIR=""
|
||||
SYSADMIN_USER="sysadmin"
|
||||
|
||||
# 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 root
|
||||
check_root() {
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
error "This script must be run as root"
|
||||
fi
|
||||
}
|
||||
|
||||
# Check if running on Debian
|
||||
check_debian() {
|
||||
if ! grep -q "Debian" /etc/os-release; then
|
||||
error "This script is designed for Debian systems"
|
||||
fi
|
||||
}
|
||||
|
||||
### === DEBIAN SYSTEM SETUP === ###
|
||||
setup_system() {
|
||||
log "Starting Debian 12 initial setup..."
|
||||
|
||||
# Update system packages
|
||||
log "Updating system packages..."
|
||||
apt update && apt upgrade -y
|
||||
|
||||
# Install essential packages
|
||||
log "Installing essential packages..."
|
||||
apt install -y sudo ufw curl wget vim htop unzip fail2ban git openssh-server
|
||||
}
|
||||
|
||||
create_sysadmin_user() {
|
||||
log "Creating user: $SYSADMIN_USER"
|
||||
|
||||
if id "$SYSADMIN_USER" &>/dev/null; then
|
||||
warn "User $SYSADMIN_USER already exists, skipping creation"
|
||||
else
|
||||
# Create user with home directory
|
||||
useradd -m -s /bin/bash "$SYSADMIN_USER"
|
||||
log "User $SYSADMIN_USER created successfully"
|
||||
|
||||
# Set password for sysadmin user
|
||||
echo "Please set a password for user $SYSADMIN_USER:"
|
||||
passwd "$SYSADMIN_USER"
|
||||
fi
|
||||
|
||||
# Add sysadmin to sudo group
|
||||
log "Adding $SYSADMIN_USER to sudo group..."
|
||||
usermod -aG sudo "$SYSADMIN_USER"
|
||||
}
|
||||
|
||||
configure_security() {
|
||||
# Disable root SSH login
|
||||
log "Disabling root SSH login..."
|
||||
sed -i 's/#PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
|
||||
sed -i 's/PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
|
||||
|
||||
# Additional SSH hardening
|
||||
log "Applying SSH security settings..."
|
||||
{
|
||||
echo "Protocol 2"
|
||||
echo "PasswordAuthentication no"
|
||||
echo "PubkeyAuthentication yes"
|
||||
echo "PermitEmptyPasswords no"
|
||||
echo "X11Forwarding no"
|
||||
echo "MaxAuthTries 3"
|
||||
echo "ClientAliveInterval 300"
|
||||
echo "ClientAliveCountMax 2"
|
||||
echo "AllowUsers $SYSADMIN_USER"
|
||||
} >> /etc/ssh/sshd_config
|
||||
|
||||
# Remove/lock root password
|
||||
log "Locking root password..."
|
||||
passwd -l root
|
||||
|
||||
# Configure UFW (Uncomplicated Firewall)
|
||||
log "Configuring UFW firewall..."
|
||||
|
||||
# Reset UFW to defaults
|
||||
ufw --force reset
|
||||
|
||||
# Set default policies
|
||||
ufw default deny incoming
|
||||
ufw default allow outgoing
|
||||
|
||||
# Allow SSH (port 22)
|
||||
ufw allow ssh
|
||||
ufw allow 22/tcp
|
||||
|
||||
# Allow HTTP (port 80)
|
||||
ufw allow http
|
||||
ufw allow 80/tcp
|
||||
|
||||
# Allow HTTPS (port 443)
|
||||
ufw allow https
|
||||
ufw allow 443/tcp
|
||||
|
||||
# Enable UFW
|
||||
ufw --force enable
|
||||
|
||||
log "UFW status:"
|
||||
ufw status verbose
|
||||
|
||||
# Configure fail2ban for SSH protection
|
||||
log "Configuring fail2ban..."
|
||||
cat > /etc/fail2ban/jail.local << EOF
|
||||
[DEFAULT]
|
||||
bantime = 1h
|
||||
findtime = 10m
|
||||
maxretry = 3
|
||||
|
||||
[sshd]
|
||||
enabled = true
|
||||
port = ssh
|
||||
filter = sshd
|
||||
logpath = /var/log/auth.log
|
||||
maxretry = 3
|
||||
bantime = 1h
|
||||
EOF
|
||||
|
||||
# Start and enable fail2ban
|
||||
systemctl enable fail2ban
|
||||
systemctl start fail2ban
|
||||
|
||||
# Set up automatic security updates
|
||||
log "Configuring automatic security updates..."
|
||||
apt install -y unattended-upgrades apt-listchanges
|
||||
|
||||
# Configure unattended upgrades
|
||||
cat > /etc/apt/apt.conf.d/50unattended-upgrades << EOF
|
||||
Unattended-Upgrade::Allowed-Origins {
|
||||
"\${distro_id}:\${distro_codename}-security";
|
||||
"\${distro_id}ESMApps:\${distro_codename}-apps-security";
|
||||
"\${distro_id}ESM:\${distro_codename}-infra-security";
|
||||
};
|
||||
|
||||
Unattended-Upgrade::AutoFixInterruptedDpkg "true";
|
||||
Unattended-Upgrade::MinimalSteps "true";
|
||||
Unattended-Upgrade::Remove-Unused-Dependencies "true";
|
||||
Unattended-Upgrade::Automatic-Reboot "false";
|
||||
EOF
|
||||
|
||||
# Enable automatic updates
|
||||
echo 'APT::Periodic::Update-Package-Lists "1";' > /etc/apt/apt.conf.d/20auto-upgrades
|
||||
echo 'APT::Periodic::Unattended-Upgrade "1";' >> /etc/apt/apt.conf.d/20auto-upgrades
|
||||
|
||||
# Set timezone (optional)
|
||||
log "Current timezone: $(timedatectl show --property=Timezone --value)"
|
||||
echo "If you want to change timezone, run: timedatectl set-timezone Your/Timezone"
|
||||
}
|
||||
|
||||
### === GET USERNAME === ###
|
||||
get_username() {
|
||||
@@ -20,28 +192,55 @@ get_username() {
|
||||
echo
|
||||
}
|
||||
|
||||
### === CHECK FOR SSH KEY === ###
|
||||
### === SSH KEY GENERATION FOR SYSADMIN === ###
|
||||
generate_ssh_key() {
|
||||
if [ ! -f "$HOME/.ssh/id_ed25519.pub" ]; then
|
||||
echo "[+] No SSH key found. Need to generate a new SSH key..."
|
||||
echo "[+] Are you using the correct system user?"
|
||||
echo "[+] If not, please switch to the correct user and run this script again."
|
||||
echo "[+] If you are using the correct user, please enter your email for the SSH key."
|
||||
read -p "Enter your email for the SSH key: " user_email
|
||||
ssh-keygen -t ed25519 -C "$user_email" -f "$HOME/.ssh/id_ed25519" -N ""
|
||||
local sysadmin_home="/home/$SYSADMIN_USER"
|
||||
local ssh_dir="$sysadmin_home/.ssh"
|
||||
local ssh_key="$ssh_dir/id_ed25519"
|
||||
|
||||
log "Setting up SSH key for user: $SYSADMIN_USER"
|
||||
|
||||
# Create .ssh directory for sysadmin user if it doesn't exist
|
||||
if [ ! -d "$ssh_dir" ]; then
|
||||
sudo -u "$SYSADMIN_USER" mkdir -p "$ssh_dir"
|
||||
sudo -u "$SYSADMIN_USER" chmod 700 "$ssh_dir"
|
||||
fi
|
||||
|
||||
if [ ! -f "$ssh_key.pub" ]; then
|
||||
log "Generating SSH key for $SYSADMIN_USER..."
|
||||
echo "[+] Please enter your email for the SSH key:"
|
||||
read -p "Enter your email: " user_email
|
||||
|
||||
# Generate SSH key as sysadmin user
|
||||
sudo -u "$SYSADMIN_USER" ssh-keygen -t ed25519 -C "$user_email" -f "$ssh_key" -N ""
|
||||
|
||||
# Set proper permissions
|
||||
sudo -u "$SYSADMIN_USER" chmod 600 "$ssh_key"
|
||||
sudo -u "$SYSADMIN_USER" chmod 644 "$ssh_key.pub"
|
||||
|
||||
log "SSH key generated successfully for $SYSADMIN_USER"
|
||||
else
|
||||
echo "[~] SSH key already exists."
|
||||
warn "SSH key already exists for $SYSADMIN_USER"
|
||||
fi
|
||||
}
|
||||
|
||||
show_ssh_key() {
|
||||
echo "[*] Add the following public key to your GitHub account:"
|
||||
local sysadmin_home="/home/$SYSADMIN_USER"
|
||||
local ssh_key="$sysadmin_home/.ssh/id_ed25519.pub"
|
||||
|
||||
echo ""
|
||||
echo -e "${BLUE}=== SSH PUBLIC KEY ===${NC}"
|
||||
echo "Add the following public key to your Git server and any other systems:"
|
||||
echo "----------------------------------------"
|
||||
cat "$HOME/.ssh/id_ed25519.pub"
|
||||
cat "$ssh_key"
|
||||
echo "----------------------------------------"
|
||||
echo "[*] Go to your git site and add the key to your account."
|
||||
echo
|
||||
read -p "Press Enter after you've added the key..."
|
||||
echo ""
|
||||
echo -e "${YELLOW}Instructions:${NC}"
|
||||
echo "1. Copy the key above"
|
||||
echo "2. Go to your git server ($GIT_SERVER) and add it to your account"
|
||||
echo "3. Add it to any other systems you need SSH access to"
|
||||
echo ""
|
||||
read -p "Press Enter after you've added the key to continue..."
|
||||
}
|
||||
|
||||
### === LIST AVAILABLE GIT PROJECTS === ###
|
||||
@@ -218,33 +417,117 @@ select_project() {
|
||||
|
||||
### === CLONE SELECTED REPO === ###
|
||||
clone_selected_repo() {
|
||||
local sysadmin_home="/home/$SYSADMIN_USER"
|
||||
|
||||
# Update selected directory to be relative to sysadmin user's home
|
||||
if [[ "$SELECTED_DIR" == "$HOME/"* ]]; then
|
||||
SELECTED_DIR="${SELECTED_DIR/$HOME/$sysadmin_home}"
|
||||
fi
|
||||
|
||||
if [ ! -d "$SELECTED_DIR" ]; then
|
||||
echo "[+] Cloning selected repository..."
|
||||
git clone "$SELECTED_REPO" "$SELECTED_DIR"
|
||||
log "Cloning selected repository as $SYSADMIN_USER..."
|
||||
sudo -u "$SYSADMIN_USER" git clone "$SELECTED_REPO" "$SELECTED_DIR"
|
||||
else
|
||||
echo "[~] Repository already cloned. Force pulling from remote (overwriting local changes)..."
|
||||
warn "Repository already cloned. Force pulling from remote (overwriting local changes)..."
|
||||
cd "$SELECTED_DIR"
|
||||
git fetch origin
|
||||
git reset --hard origin/$(git symbolic-ref --short HEAD)
|
||||
git clean -fd
|
||||
sudo -u "$SYSADMIN_USER" git fetch origin
|
||||
sudo -u "$SYSADMIN_USER" git reset --hard origin/$(sudo -u "$SYSADMIN_USER" git symbolic-ref --short HEAD)
|
||||
sudo -u "$SYSADMIN_USER" git clean -fd
|
||||
fi
|
||||
|
||||
# Only run setup if it's the dotfiles repository
|
||||
if [[ "$SELECTED_REPO" == *"dotfiles.git" && -f "$SELECTED_DIR/setup.sh" ]]; then
|
||||
echo "[+] Launching dotfiles setup using Bash..."
|
||||
bash "$SELECTED_DIR/setup.sh"
|
||||
log "Launching dotfiles setup as $SYSADMIN_USER..."
|
||||
sudo -u "$SYSADMIN_USER" bash "$SELECTED_DIR/setup.sh"
|
||||
else
|
||||
echo "[*] Repository cloned successfully to: $SELECTED_DIR"
|
||||
log "Repository cloned successfully to: $SELECTED_DIR"
|
||||
log "Repository is owned by: $SYSADMIN_USER"
|
||||
fi
|
||||
}
|
||||
|
||||
### === CLEANUP AND FINALIZATION === ###
|
||||
finalize_setup() {
|
||||
# Restart SSH service
|
||||
log "Restarting SSH service..."
|
||||
systemctl restart sshd
|
||||
|
||||
# Clean up
|
||||
log "Cleaning up..."
|
||||
apt autoremove -y
|
||||
apt autoclean
|
||||
|
||||
# Final security check
|
||||
log "Final system status:"
|
||||
echo "================================"
|
||||
echo "UFW Status:"
|
||||
ufw status
|
||||
echo "================================"
|
||||
echo "SSH Configuration:"
|
||||
grep -E "PermitRootLogin|PasswordAuthentication|PubkeyAuthentication|AllowUsers" /etc/ssh/sshd_config
|
||||
echo "================================"
|
||||
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 "${YELLOW}5. UFW firewall is active (SSH, HTTP, HTTPS allowed)${NC}"
|
||||
echo -e "${YELLOW}6. Fail2ban is protecting SSH${NC}"
|
||||
echo -e "${YELLOW}7. Automatic security updates are enabled${NC}"
|
||||
echo ""
|
||||
echo -e "${RED}REBOOT RECOMMENDED${NC}"
|
||||
echo ""
|
||||
echo "To connect: ssh $SYSADMIN_USER@$(hostname -I | awk '{print $1}')"
|
||||
}
|
||||
|
||||
### === MAIN === ###
|
||||
main() {
|
||||
get_username
|
||||
generate_ssh_key
|
||||
show_ssh_key
|
||||
select_project
|
||||
clone_selected_repo
|
||||
# Check prerequisites
|
||||
check_root
|
||||
check_debian
|
||||
|
||||
echo -e "${BLUE}=== Debian 12 Initial Setup with Git Integration ===${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 clone a git repository"
|
||||
echo ""
|
||||
read -p "Continue? (y/N): " confirm
|
||||
|
||||
if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
|
||||
echo "Setup cancelled."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# System setup
|
||||
setup_system
|
||||
create_sysadmin_user
|
||||
configure_security
|
||||
|
||||
# SSH key setup
|
||||
generate_ssh_key
|
||||
show_ssh_key
|
||||
|
||||
# Optional git repository setup
|
||||
echo ""
|
||||
echo -e "${BLUE}=== Optional Git Repository Setup ===${NC}"
|
||||
read -p "Would you like to clone a git repository? (y/N): " git_setup
|
||||
|
||||
if [[ "$git_setup" =~ ^[Yy]$ ]]; then
|
||||
get_username
|
||||
select_project
|
||||
clone_selected_repo
|
||||
else
|
||||
log "Skipping git repository setup"
|
||||
fi
|
||||
|
||||
# Finalize
|
||||
finalize_setup
|
||||
}
|
||||
|
||||
main
|
||||
main "$@"
|
||||
|
||||
Reference in New Issue
Block a user