149 lines
3.4 KiB
Bash
149 lines
3.4 KiB
Bash
#!/bin/bash
|
||
set -euo pipefail
|
||
|
||
# Logging
|
||
exec > >(tee /var/log/cloud-init-custom.log) 2>&1
|
||
echo "=== Cloud-init started at $(date) ==="
|
||
|
||
# System updates
|
||
apt update
|
||
DEBIAN_FRONTEND=noninteractive apt upgrade -y
|
||
|
||
# Install essentials
|
||
DEBIAN_FRONTEND=noninteractive apt install -y \
|
||
curl \
|
||
git \
|
||
htop \
|
||
ufw \
|
||
unattended-upgrades \
|
||
apt-listchanges
|
||
|
||
# Create non-root user
|
||
#if ! id "$USERNAME" &>/dev/null; then
|
||
# useradd -m -s /bin/bash -G sudo "$USERNAME"
|
||
# echo "$USERNAME ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/$USERNAME
|
||
# chmod 0440 /etc/sudoers.d/$USERNAME
|
||
#fi
|
||
|
||
## SSH key for user
|
||
#USER_HOME="/home/$USERNAME"
|
||
#mkdir -p "$USER_HOME/.ssh"
|
||
#echo "$SSH_PUBLIC_KEY" > "$USER_HOME/.ssh/authorized_keys"
|
||
#chmod 700 "$USER_HOME/.ssh"
|
||
#chmod 600 "$USER_HOME/.ssh/authorized_keys"
|
||
#chown -R "$USERNAME:$USERNAME" "$USER_HOME/.ssh"
|
||
|
||
# SSH hardening
|
||
cat > /etc/ssh/sshd_config.d/hardening.conf << 'EOF'
|
||
# Disable password authentication
|
||
PasswordAuthentication no
|
||
ChallengeResponseAuthentication no
|
||
UsePAM yes
|
||
|
||
## Disable root login
|
||
#PermitRootLogin no
|
||
|
||
# Key-based auth only
|
||
PubkeyAuthentication yes
|
||
AuthorizedKeysFile .ssh/authorized_keys
|
||
|
||
# Timeouts and limits
|
||
ClientAliveInterval 300
|
||
ClientAliveCountMax 2
|
||
MaxAuthTries 3
|
||
MaxSessions 3
|
||
LoginGraceTime 30
|
||
|
||
# Disable unused auth methods
|
||
HostbasedAuthentication no
|
||
PermitEmptyPasswords no
|
||
KerberosAuthentication no
|
||
GSSAPIAuthentication no
|
||
|
||
# Logging
|
||
LogLevel VERBOSE
|
||
EOF
|
||
|
||
# Restart SSH
|
||
systemctl restart ssh
|
||
|
||
## fail2ban configuration
|
||
#cat > /etc/fail2ban/jail.local << 'EOF'
|
||
#[DEFAULT]
|
||
#bantime = 1h
|
||
#findtime = 10m
|
||
#maxretry = 5
|
||
#banaction = ufw
|
||
|
||
[sshd]
|
||
enabled = true
|
||
port = ssh
|
||
logpath = /var/log/auth.log
|
||
maxretry = 3
|
||
bantime = 24h
|
||
EOF
|
||
|
||
#systemctl enable fail2ban
|
||
#systemctl restart fail2ban
|
||
#
|
||
# UFW firewall
|
||
ufw default deny incoming
|
||
ufw default allow outgoing
|
||
ufw allow ssh
|
||
ufw --force enable
|
||
|
||
# Unattended upgrades – security patches only
|
||
cat > /etc/apt/apt.conf.d/50unattended-upgrades << 'EOF'
|
||
Unattended-Upgrade::Allowed-Origins {
|
||
"${distro_id}:${distro_codename}-security";
|
||
};
|
||
Unattended-Upgrade::AutoFixInterruptedDpkg "true";
|
||
Unattended-Upgrade::MinimalSteps "true";
|
||
Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
|
||
Unattended-Upgrade::Remove-Unused-Dependencies "true";
|
||
Unattended-Upgrade::Automatic-Reboot "false";
|
||
EOF
|
||
|
||
cat > /etc/apt/apt.conf.d/20auto-upgrades << 'EOF'
|
||
APT::Periodic::Update-Package-Lists "1";
|
||
APT::Periodic::Unattended-Upgrade "1";
|
||
APT::Periodic::AutocleanInterval "7";
|
||
EOF
|
||
|
||
systemctl enable unattended-upgrades
|
||
|
||
# Kernel hardening via sysctl
|
||
cat > /etc/sysctl.d/99-security.conf << 'EOF'
|
||
# IP Spoofing protection
|
||
net.ipv4.conf.all.rp_filter = 1
|
||
net.ipv4.conf.default.rp_filter = 1
|
||
|
||
# Ignore ICMP redirects
|
||
net.ipv4.conf.all.accept_redirects = 0
|
||
net.ipv6.conf.all.accept_redirects = 0
|
||
net.ipv4.conf.all.send_redirects = 0
|
||
|
||
# Ignore source routed packets
|
||
net.ipv4.conf.all.accept_source_route = 0
|
||
net.ipv6.conf.all.accept_source_route = 0
|
||
|
||
# Log Martian packets
|
||
net.ipv4.conf.all.log_martians = 1
|
||
|
||
# Ignore broadcast pings
|
||
net.ipv4.icmp_echo_ignore_broadcasts = 1
|
||
|
||
# Disable IPv6 if not needed (optional)
|
||
# net.ipv6.conf.all.disable_ipv6 = 1
|
||
EOF
|
||
|
||
sysctl -p /etc/sysctl.d/99-security.conf
|
||
|
||
## Tailscale (optional)
|
||
#if [ -n "$TAILSCALE_AUTH_KEY" ]; then
|
||
# curl -fsSL https://tailscale.com/install.sh | sh
|
||
# tailscale up --authkey="$TAILSCALE_AUTH_KEY" --ssh
|
||
# echo "Tailscale installed and connected"
|
||
#fi
|
||
|
||
echo "=== Cloud-init completed at $(date) ===" |