mirror of
https://github.com/buildplan/du_setup.git
synced 2025-12-29 16:14:59 +00:00
option to run Lynis and debsecan, updated to ufw, tailscale and summary
This commit is contained in:
61
README.md
61
README.md
@@ -1,6 +1,6 @@
|
|||||||
# Debian & Ubuntu Server Setup & Hardening Script
|
# Debian & Ubuntu Server Setup & Hardening Script
|
||||||
|
|
||||||
**Version:** 4.1
|
**Version:** 4.2
|
||||||
|
|
||||||
**Last Updated:** 2025-06-29
|
**Last Updated:** 2025-06-29
|
||||||
|
|
||||||
@@ -22,7 +22,9 @@ This script automates the initial setup and security hardening of a fresh Debian
|
|||||||
- **Automated Security Updates**: Enables `unattended-upgrades` for automatic security patches.
|
- **Automated Security Updates**: Enables `unattended-upgrades` for automatic security patches.
|
||||||
- **System Stability**: Configures NTP time synchronization with `chrony` and optional swap file setup for low-RAM systems.
|
- **System Stability**: Configures NTP time synchronization with `chrony` and optional swap file setup for low-RAM systems.
|
||||||
- **Remote rsync Backups**: Configures automated `rsync` backups over SSH to any compatible server (e.g., Hetzner Storage Box), with SSH key automation (`sshpass` or manual), cron scheduling, ntfy/Discord notifications, and a customizable exclude file.
|
- **Remote rsync Backups**: Configures automated `rsync` backups over SSH to any compatible server (e.g., Hetzner Storage Box), with SSH key automation (`sshpass` or manual), cron scheduling, ntfy/Discord notifications, and a customizable exclude file.
|
||||||
|
- **Backup Testing**: Includes an optional test backup to verify the rsync configuration before scheduling.
|
||||||
- **Tailscale VPN**: Installs Tailscale and connects to the standard Tailscale network (pre-auth key required) or a custom server (URL and key required). Configures optional flags (`--ssh`, `--advertise-exit-node`, `--accept-dns`, `--accept-routes`).
|
- **Tailscale VPN**: Installs Tailscale and connects to the standard Tailscale network (pre-auth key required) or a custom server (URL and key required). Configures optional flags (`--ssh`, `--advertise-exit-node`, `--accept-dns`, `--accept-routes`).
|
||||||
|
- **Security Auditing**: Optionally runs **Lynis** for system hardening audits and **debsecan** for package vulnerability checks, with results logged for review.
|
||||||
- **Safety First**: Backs up critical configuration files before modification, stored in `/root/setup_harden_backup_*`.
|
- **Safety First**: Backs up critical configuration files before modification, stored in `/root/setup_harden_backup_*`.
|
||||||
- **Optional Software**: Offers interactive installation of:
|
- **Optional Software**: Offers interactive installation of:
|
||||||
- Docker & Docker Compose
|
- Docker & Docker Compose
|
||||||
@@ -37,25 +39,26 @@ This script automates the initial setup and security hardening of a fresh Debian
|
|||||||
- Fresh installation of a compatible OS.
|
- Fresh installation of a compatible OS.
|
||||||
- Root or `sudo` privileges.
|
- Root or `sudo` privileges.
|
||||||
- Internet access for package downloads.
|
- Internet access for package downloads.
|
||||||
- For remote backups: An SSH-accessible server (e.g., Hetzner Storage Box) with credentials or SSH key access.
|
- Minimum 2GB disk space for swap file creation and temporary files.
|
||||||
|
- For remote backups: An SSH-accessible server (e.g., Hetzner Storage Box) with credentials or SSH key access. For Hetzner, SSH (port 23) is used for rsync.
|
||||||
- For Tailscale: A pre-auth key from https://login.tailscale.com/admin (standard, starts with `tskey-auth-`) or from a custom server (e.g., `https://ts.mydomain.cloud`).
|
- For Tailscale: A pre-auth key from https://login.tailscale.com/admin (standard, starts with `tskey-auth-`) or from a custom server (e.g., `https://ts.mydomain.cloud`).
|
||||||
|
|
||||||
### 1. Download the Script
|
### 1. Download the Script
|
||||||
|
|
||||||
```
|
```bash
|
||||||
wget https://raw.githubusercontent.com/buildplan/setup_harden_server/refs/heads/main/setup_harden_debian_ubuntu.sh
|
wget https://raw.githubusercontent.com/buildplan/setup_harden_server/refs/heads/main/setup_harden_debian_ubuntu.sh
|
||||||
chmod +x setup_harden_debian_ubuntu.sh
|
chmod +x setup_harden_debian_ubuntu.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. Run Interactively (Recommended)
|
### 2. Run Interactively (Recommended)
|
||||||
|
|
||||||
```
|
```bash
|
||||||
sudo ./setup_harden_debian_ubuntu.sh
|
sudo ./setup_harden_debian_ubuntu.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3. Run in Quiet Mode (for Automation)
|
### 3. Run in Quiet Mode (for Automation)
|
||||||
|
|
||||||
```
|
```bash
|
||||||
sudo ./setup_harden_debian_ubuntu.sh --quiet
|
sudo ./setup_harden_debian_ubuntu.sh --quiet
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -68,11 +71,13 @@ sudo ./setup_harden_debian_ubuntu.sh --quiet
|
|||||||
| Task | Description |
|
| Task | Description |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| **System Checks** | Verifies OS compatibility, root privileges, and internet connectivity. |
|
| **System Checks** | Verifies OS compatibility, root privileges, and internet connectivity. |
|
||||||
| **Package Management** | Updates packages and installs tools (`ufw`, `fail2ban`, `chrony`, `rsync`, etc.). |
|
| **Package Management** | Updates packages and installs tools (`ufw`, `fail2ban`, `chrony`, `rsync`, `lynis`, `debsecan`, etc.). |
|
||||||
| **Admin User Creation** | Creates a `sudo` user with a password and/or SSH public key. |
|
| **Admin User Creation** | Creates a `sudo` user with a password and/or SSH public key. |
|
||||||
| **SSH Hardening** | Disables root login, enforces key-based auth, and sets a custom port. |
|
| **SSH Hardening** | Disables root login, enforces key-based auth, and sets a custom port. |
|
||||||
| **Firewall Setup** | Configures UFW to deny incoming traffic by default, allowing specific ports. |
|
| **Firewall Setup** | Configures UFW to deny incoming traffic by default, allowing specific ports. |
|
||||||
| **Remote Backup Setup** | Configures `rsync` backups to an SSH server (e.g., `u457300-sub4@u457300.your-storagebox.de:23`). Creates `/root/run_backup.sh`, `/root/rsync_exclude.txt`, and schedules a cron job. Supports ntfy/Discord notifications. |
|
| **Remote Backup Setup** | Configures `rsync` backups to an SSH server (e.g., `u457300-sub4@u457300.your-storagebox.de:23`). Creates `/root/run_backup.sh`, `/root/rsync_exclude.txt`, and schedules a cron job. Supports ntfy/Discord notifications. |
|
||||||
|
| **Backup Testing** | Performs an optional test backup to verify rsync configuration, logging results to `/var/log/backup_rsync.log`. |
|
||||||
|
| **Security Auditing** | Runs optional **Lynis** and **debsecan** audits, logging results to `/var/log/setup_harden_security_audit_*.log`. |
|
||||||
| **Tailscale Setup** | Installs Tailscale and connects to the standard Tailscale network (pre-auth key starting with `tskey-auth-`) or a custom server (any valid key). Configures optional flags (`--ssh`, `--advertise-exit-node`, `--accept-dns`, `--accept-routes`). |
|
| **Tailscale Setup** | Installs Tailscale and connects to the standard Tailscale network (pre-auth key starting with `tskey-auth-`) or a custom server (any valid key). Configures optional flags (`--ssh`, `--advertise-exit-node`, `--accept-dns`, `--accept-routes`). |
|
||||||
| **System Backups** | Saves timestamped configuration backups in `/root/setup_harden_backup_*`. |
|
| **System Backups** | Saves timestamped configuration backups in `/root/setup_harden_backup_*`. |
|
||||||
| **Swap File Setup** | Creates an optional swap file (e.g., 2G) with tuned settings. |
|
| **Swap File Setup** | Creates an optional swap file (e.g., 2G) with tuned settings. |
|
||||||
@@ -84,6 +89,7 @@ sudo ./setup_harden_debian_ubuntu.sh --quiet
|
|||||||
|
|
||||||
- **Log Files**: `/var/log/setup_harden_debian_ubuntu_*.log`
|
- **Log Files**: `/var/log/setup_harden_debian_ubuntu_*.log`
|
||||||
- **Backup Logs**: `/var/log/backup_rsync.log` (for remote backup operations)
|
- **Backup Logs**: `/var/log/backup_rsync.log` (for remote backup operations)
|
||||||
|
- **Audit Logs**: `/var/log/setup_harden_security_audit_*.log` (for Lynis and debsecan results)
|
||||||
- **Configuration Backups**: `/root/setup_harden_backup_*`
|
- **Configuration Backups**: `/root/setup_harden_backup_*`
|
||||||
|
|
||||||
## Post-Reboot Verification
|
## Post-Reboot Verification
|
||||||
@@ -108,24 +114,28 @@ After rebooting, verify the setup:
|
|||||||
- Copy key (if not done): `ssh-copy-id -p <backup_port> -s <backup_user@backup_host>`
|
- Copy key (if not done): `ssh-copy-id -p <backup_port> -s <backup_user@backup_host>`
|
||||||
- Test backup: `sudo /root/run_backup.sh`
|
- Test backup: `sudo /root/run_backup.sh`
|
||||||
- Check logs: `sudo less /var/log/backup_rsync.log`
|
- Check logs: `sudo less /var/log/backup_rsync.log`
|
||||||
- Verify cron job: `sudo crontab -l` (e.g., `3 3 * * * /root/run_backup.sh`)
|
- Verify cron job: `sudo crontab -l` (e.g., `5 3 * * * /root/run_backup.sh`)
|
||||||
|
- **Security Audit** (if run):
|
||||||
|
- Check results: `sudo less /var/log/setup_harden_security_audit_*.log`
|
||||||
|
- Review Lynis hardening index and debsecan vulnerabilities in the script’s summary output
|
||||||
|
|
||||||
## Tested On
|
## Tested On
|
||||||
|
|
||||||
- Debian 12
|
- Debian 12
|
||||||
- Ubuntu 22.04, 24.04, 24.10 (experimental)
|
- Ubuntu 22.04, 24.04, 24.10 (experimental)
|
||||||
- Cloud providers: DigitalOcean, Oracle Cloud, Hetzner, Netcup
|
- Cloud providers: DigitalOcean, Oracle Cloud, Hetzner, Netcup
|
||||||
- Backup destinations: Hetzner Storage Box, custom SSH servers
|
- Backup destinations: Hetzner Storage Box (SSH, port 23), custom SSH servers
|
||||||
- Tailscale: Standard network, custom self-hosted servers
|
- Tailscale: Standard network, custom self-hosted servers
|
||||||
|
|
||||||
## Important Notes
|
## Important Notes
|
||||||
|
|
||||||
- **Run on a fresh system**: Designed for initial provisioning.
|
- **Run on a fresh system**: Designed for initial provisioning with at least 2GB free disk space.
|
||||||
- **Reboot required**: Ensures kernel and service changes apply cleanly.
|
- **Reboot required**: Ensures kernel and service changes apply cleanly.
|
||||||
- Test in a non-production environment (e.g., staging VM) first.
|
- Test in a non-production environment (e.g., staging VM) first.
|
||||||
- Maintain out-of-band console access in case of SSH lockout.
|
- Maintain out-of-band console access in case of SSH lockout.
|
||||||
- For Hetzner Storage Box, ensure `~/.ssh/` exists on the remote server: `ssh -p 23 <backup_user@backup_host> "mkdir -p ~/.ssh && chmod 700 ~/.ssh"`.
|
- For Hetzner Storage Box, ensure `~/.ssh/` exists on the remote server: `ssh -p 23 <backup_user@backup_host> "mkdir -p ~/.ssh && chmod 700 ~/.ssh"`. Backups use SSH (port 23) for rsync, not SFTP.
|
||||||
- For Tailscale, generate a pre-auth key from https://login.tailscale.com/admin (standard, must start with `tskey-auth-`) or your custom server (any valid key). Ensure UDP 41641 is open for Tailscale traffic.
|
- For Tailscale, generate a pre-auth key from https://login.tailscale.com/admin (standard, must start with `tskey-auth-`) or your custom server (any valid key). Ensure UDP 41641 is open for Tailscale traffic.
|
||||||
|
- For security audits, review `/var/log/setup_harden_security_audit_*.log` for Lynis and debsecan recommendations.
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
@@ -134,18 +144,18 @@ After rebooting, verify the setup:
|
|||||||
If locked out, use your provider’s console:
|
If locked out, use your provider’s console:
|
||||||
|
|
||||||
1. **Remove Hardened Configuration**:
|
1. **Remove Hardened Configuration**:
|
||||||
```
|
```bash
|
||||||
rm /etc/ssh/sshd_config.d/99-hardening.conf
|
rm /etc/ssh/sshd_config.d/99-hardening.conf
|
||||||
```
|
```
|
||||||
|
|
||||||
2. **Restore Original `sshd_config`**:
|
2. **Restore Original `sshd_config`**:
|
||||||
```
|
```bash
|
||||||
LATEST_BACKUP=$(ls -td /root/setup_harden_backup_* | head -1)
|
LATEST_BACKUP=$(ls -td /root/setup_harden_backup_* | head -1)
|
||||||
cp "$LATEST_BACKUP"/sshd_config.backup_* /etc/ssh/sshd_config
|
cp "$LATEST_BACKUP"/sshd_config.backup_* /etc/ssh/sshd_config
|
||||||
```
|
```
|
||||||
|
|
||||||
3. **Restart SSH**:
|
3. **Restart SSH**:
|
||||||
```
|
```bash
|
||||||
systemctl restart ssh
|
systemctl restart ssh
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -164,14 +174,14 @@ If backups fail:
|
|||||||
- If automated key copy fails: `cat /tmp/ssh-copy-id.log`
|
- If automated key copy fails: `cat /tmp/ssh-copy-id.log`
|
||||||
|
|
||||||
3. **Test Backup Manually**:
|
3. **Test Backup Manually**:
|
||||||
```
|
```bash
|
||||||
sudo /root/run_backup.sh
|
sudo /root/run_backup.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
4. **Verify Cron Job**:
|
4. **Verify Cron Job**:
|
||||||
- Check: `sudo crontab -l`
|
- Check: `sudo crontab -l`
|
||||||
- Ensure: `3 3 * * * /root/run_backup.sh #-*- managed by setup_harden script -*-`
|
- Ensure: `5 3 * * * /root/run_backup.sh #-*- managed by setup_harden script -*-`
|
||||||
- Test cron permissions: `echo "3 3 * * * /root/run_backup.sh" | crontab -u root -`
|
- Test cron permissions: `echo "5 3 * * * /root/run_backup.sh" | crontab -u root -`
|
||||||
- Check permissions: `ls -l /var/spool/cron/crontabs/root` (expect `-rw------- root:crontab`)
|
- Check permissions: `ls -l /var/spool/cron/crontabs/root` (expect `-rw------- root:crontab`)
|
||||||
|
|
||||||
5. **Network Issues**:
|
5. **Network Issues**:
|
||||||
@@ -181,6 +191,23 @@ If backups fail:
|
|||||||
6. **Summary Errors**:
|
6. **Summary Errors**:
|
||||||
- If summary shows `Remote Backup: Not configured`, verify: `ls -l /root/run_backup.sh`
|
- If summary shows `Remote Backup: Not configured`, verify: `ls -l /root/run_backup.sh`
|
||||||
|
|
||||||
|
### Security Audit Issues
|
||||||
|
|
||||||
|
If audits fail:
|
||||||
|
|
||||||
|
1. **Check Audit Log**:
|
||||||
|
- Review: `sudo less /var/log/setup_harden_security_audit_*.log`
|
||||||
|
- Look for Lynis errors or debsecan CVE reports
|
||||||
|
|
||||||
|
2. **Verify Installation**:
|
||||||
|
- Lynis: `command -v lynis`
|
||||||
|
- Debsecan: `command -v debsecan`
|
||||||
|
- Reinstall if needed: `sudo apt-get install lynis debsecan`
|
||||||
|
|
||||||
|
3. **Run Manually**:
|
||||||
|
- Lynis: `sudo lynis audit system --quick`
|
||||||
|
- Debsecan: `sudo debsecan --suite $(source /etc/os-release && echo $VERSION_CODENAME)`
|
||||||
|
|
||||||
### Tailscale Issues
|
### Tailscale Issues
|
||||||
|
|
||||||
If Tailscale fails to connect:
|
If Tailscale fails to connect:
|
||||||
@@ -210,4 +237,4 @@ If Tailscale fails to connect:
|
|||||||
|
|
||||||
## [MIT](https://github.com/buildplan/setup_harden_server/blob/main/LICENSE) License
|
## [MIT](https://github.com/buildplan/setup_harden_server/blob/main/LICENSE) License
|
||||||
|
|
||||||
This script is open-source and provided "as is" without warranty. Use at your own risk.
|
This script is open-source and provided "as is" without warranty. Use at your own risk.
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Debian 12 and Ubuntu Server Hardening Interactive Script
|
# Debian 12 and Ubuntu Server Hardening Interactive Script
|
||||||
# Version: 4.1 | 2025-06-29
|
# Version: 4.2 | 2025-06-29
|
||||||
# Changelog:
|
# Changelog:
|
||||||
|
# - v4.2: Added Security Audit Tools (Integrating Lynis and Optionally Debsecan) & option to do Backup Testing
|
||||||
|
# Fixed debsecan compatibility (Debian-only), added global BACKUP_LOG, added backup testing
|
||||||
# - v4.1: Added tailscale config to connect to tailscale or headscale server
|
# - v4.1: Added tailscale config to connect to tailscale or headscale server
|
||||||
# - v4.0: Added automated backup config. Mainly for Hetzner Storage Box but can be used for any rsync/SSH enabled remote solution.
|
# - v4.0: Added automated backup config. Mainly for Hetzner Storage Box but can be used for any rsync/SSH enabled remote solution.
|
||||||
# - v3.*: Improvements to script flow and fixed bugs which were found in tests at Oracle Cloud
|
# - v3.*: Improvements to script flow and fixed bugs which were found in tests at Oracle Cloud
|
||||||
@@ -56,6 +58,7 @@ NC='\033[0m' # No Color
|
|||||||
# Script variables
|
# Script variables
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
LOG_FILE="/var/log/setup_harden_debian_ubuntu_$(date +%Y%m%d_%H%M%S).log"
|
LOG_FILE="/var/log/setup_harden_debian_ubuntu_$(date +%Y%m%d_%H%M%S).log"
|
||||||
|
BACKUP_LOG="/var/log/backup_rsync.log"
|
||||||
VERBOSE=true
|
VERBOSE=true
|
||||||
BACKUP_DIR="/root/setup_harden_backup_$(date +%Y%m%d_%H%M%S)"
|
BACKUP_DIR="/root/setup_harden_backup_$(date +%Y%m%d_%H%M%S)"
|
||||||
IS_CONTAINER=false
|
IS_CONTAINER=false
|
||||||
@@ -63,6 +66,7 @@ SSHD_BACKUP_FILE=""
|
|||||||
LOCAL_KEY_ADDED=false
|
LOCAL_KEY_ADDED=false
|
||||||
SSH_SERVICE=""
|
SSH_SERVICE=""
|
||||||
ID="" # This will be populated from /etc/os-release
|
ID="" # This will be populated from /etc/os-release
|
||||||
|
FAILED_SERVICES=()
|
||||||
|
|
||||||
# --- PARSE ARGUMENTS ---
|
# --- PARSE ARGUMENTS ---
|
||||||
while [[ $# -gt 0 ]]; do
|
while [[ $# -gt 0 ]]; do
|
||||||
@@ -83,7 +87,7 @@ print_header() {
|
|||||||
echo -e "${CYAN}╔═════════════════════════════════════════════════════════════════╗${NC}"
|
echo -e "${CYAN}╔═════════════════════════════════════════════════════════════════╗${NC}"
|
||||||
echo -e "${CYAN}║ ║${NC}"
|
echo -e "${CYAN}║ ║${NC}"
|
||||||
echo -e "${CYAN}║ DEBIAN/UBUNTU SERVER SETUP AND HARDENING SCRIPT ║${NC}"
|
echo -e "${CYAN}║ DEBIAN/UBUNTU SERVER SETUP AND HARDENING SCRIPT ║${NC}"
|
||||||
echo -e "${CYAN}║ v4.1 | 2025-06-29 ║${NC}"
|
echo -e "${CYAN}║ v4.2 | 2025-06-29 ║${NC}"
|
||||||
echo -e "${CYAN}║ ║${NC}"
|
echo -e "${CYAN}║ ║${NC}"
|
||||||
echo -e "${CYAN}╚═════════════════════════════════════════════════════════════════╝${NC}"
|
echo -e "${CYAN}╚═════════════════════════════════════════════════════════════════╝${NC}"
|
||||||
echo
|
echo
|
||||||
@@ -730,6 +734,15 @@ configure_firewall() {
|
|||||||
print_info "HTTPS rule already exists."
|
print_info "HTTPS rule already exists."
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
if confirm "Allow Tailscale traffic (UDP 41641)?"; then
|
||||||
|
if ! ufw status | grep -qw "41641/udp"; then
|
||||||
|
ufw allow 41641/udp comment 'Tailscale VPN'
|
||||||
|
print_success "Tailscale traffic (UDP 41641) allowed."
|
||||||
|
log "Added UFW rule for Tailscale (41641/udp)."
|
||||||
|
else
|
||||||
|
print_info "Tailscale rule (UDP 41641) already exists."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
if confirm "Add additional custom ports (e.g., 8080/tcp, 123/udp)?"; then
|
if confirm "Add additional custom ports (e.g., 8080/tcp, 123/udp)?"; then
|
||||||
while true; do
|
while true; do
|
||||||
local CUSTOM_PORTS # Make variable local to the loop
|
local CUSTOM_PORTS # Make variable local to the loop
|
||||||
@@ -751,9 +764,16 @@ configure_firewall() {
|
|||||||
if ufw status | grep -qw "$port"; then
|
if ufw status | grep -qw "$port"; then
|
||||||
print_info "Rule for $port already exists."
|
print_info "Rule for $port already exists."
|
||||||
else
|
else
|
||||||
ufw allow "$port" comment "Custom port $port"
|
local CUSTOM_COMMENT
|
||||||
print_success "Added rule for $port."
|
read -rp "$(echo -e "${CYAN}Enter comment for $port (e.g., 'My App Port'): ${NC}")" CUSTOM_COMMENT
|
||||||
log "Added UFW rule for $port."
|
if [[ -z "$CUSTOM_COMMENT" ]]; then
|
||||||
|
CUSTOM_COMMENT="Custom port $port"
|
||||||
|
fi
|
||||||
|
# Sanitize comment to avoid breaking UFW command
|
||||||
|
CUSTOM_COMMENT=$(echo "$CUSTOM_COMMENT" | tr -d "'\"\\")
|
||||||
|
ufw allow "$port" comment "$CUSTOM_COMMENT"
|
||||||
|
print_success "Added rule for $port with comment '$CUSTOM_COMMENT'."
|
||||||
|
log "Added UFW rule for $port with comment '$CUSTOM_COMMENT'."
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
break
|
break
|
||||||
@@ -773,7 +793,7 @@ configure_firewall() {
|
|||||||
print_error "UFW failed to activate. Check 'journalctl -u ufw' for details."
|
print_error "UFW failed to activate. Check 'journalctl -u ufw' for details."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
print_warning "ACTION REQUIRED: Check your VPS provider's edge firewall to allow opened ports (e.g., $SSH_PORT/tcp)."
|
print_warning "ACTION REQUIRED: Check your VPS provider's edge firewall to allow opened ports (e.g., $SSH_PORT/tcp, 41641/udp for Tailscale)."
|
||||||
ufw status verbose | tee -a "$LOG_FILE"
|
ufw status verbose | tee -a "$LOG_FILE"
|
||||||
log "Firewall configuration completed."
|
log "Firewall configuration completed."
|
||||||
}
|
}
|
||||||
@@ -831,6 +851,10 @@ configure_auto_updates() {
|
|||||||
print_error "unattended-upgrades package is not installed."
|
print_error "unattended-upgrades package is not installed."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
# Check for existing unattended-upgrades configuration
|
||||||
|
if [[ -f /etc/apt/apt.conf.d/50unattended-upgrades ]] && grep -q "Unattended-Upgrade::Allowed-Origins" /etc/apt/apt.conf.d/50unattended-upgrades; then
|
||||||
|
print_info "Existing unattended-upgrades configuration found. Verify with 'cat /etc/apt/apt.conf.d/50unattended-upgrades'."
|
||||||
|
fi
|
||||||
print_info "Configuring unattended upgrades..."
|
print_info "Configuring unattended upgrades..."
|
||||||
echo "unattended-upgrades unattended-upgrades/enable_auto_updates boolean true" | debconf-set-selections
|
echo "unattended-upgrades unattended-upgrades/enable_auto_updates boolean true" | debconf-set-selections
|
||||||
DEBIAN_FRONTEND=noninteractive dpkg-reconfigure -f noninteractive unattended-upgrades
|
DEBIAN_FRONTEND=noninteractive dpkg-reconfigure -f noninteractive unattended-upgrades
|
||||||
@@ -911,8 +935,12 @@ install_tailscale() {
|
|||||||
print_section "Tailscale VPN Installation and Configuration"
|
print_section "Tailscale VPN Installation and Configuration"
|
||||||
if command -v tailscale >/dev/null 2>&1; then
|
if command -v tailscale >/dev/null 2>&1; then
|
||||||
print_info "Tailscale already installed."
|
print_info "Tailscale already installed."
|
||||||
if systemctl is-active --quiet tailscaled && tailscale status >/dev/null 2>&1; then
|
if systemctl is-active --quiet tailscaled && tailscale ip >/dev/null 2>&1; then
|
||||||
print_success "Tailscale service is active and connected."
|
local TS_IPS TS_IPV4
|
||||||
|
TS_IPS=$(tailscale ip 2>/dev/null || echo "Unknown")
|
||||||
|
TS_IPV4=$(echo "$TS_IPS" | grep -E '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' | head -1 || echo "Unknown")
|
||||||
|
print_success "Tailscale service is active and connected. Node IPv4 in tailnet: $TS_IPV4"
|
||||||
|
echo "$TS_IPS" > /tmp/tailscale_ips.txt
|
||||||
return 0
|
return 0
|
||||||
else
|
else
|
||||||
print_warning "Tailscale installed but service is not active or not connected."
|
print_warning "Tailscale installed but service is not active or not connected."
|
||||||
@@ -939,8 +967,12 @@ install_tailscale() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# --- Configure Tailscale Connection ---
|
# --- Configure Tailscale Connection ---
|
||||||
if systemctl is-active --quiet tailscaled && tailscale status >/dev/null 2>&1 && tailscale status | grep -q "^[^ ]* \+${SERVER_NAME} \+"; then
|
if systemctl is-active --quiet tailscaled && tailscale ip >/dev/null 2>&1; then
|
||||||
print_info "Tailscale is already connected (hostname: $SERVER_NAME)."
|
local TS_IPS TS_IPV4
|
||||||
|
TS_IPS=$(tailscale ip 2>/dev/null || echo "Unknown")
|
||||||
|
TS_IPV4=$(echo "$TS_IPS" | grep -E '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' | head -1 || echo "Unknown")
|
||||||
|
print_info "Tailscale is already connected. Node IPv4 in tailnet: $TS_IPV4"
|
||||||
|
echo "$TS_IPS" > /tmp/tailscale_ips.txt
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
print_info "Configuring Tailscale connection..."
|
print_info "Configuring Tailscale connection..."
|
||||||
@@ -982,23 +1014,29 @@ install_tailscale() {
|
|||||||
local RETRIES=3
|
local RETRIES=3
|
||||||
local DELAY=5
|
local DELAY=5
|
||||||
local CONNECTED=false
|
local CONNECTED=false
|
||||||
|
local TS_IPS TS_IPV4
|
||||||
for ((i=1; i<=RETRIES; i++)); do
|
for ((i=1; i<=RETRIES; i++)); do
|
||||||
if tailscale status 2>/dev/null | grep -q "^[^ ]* \+${SERVER_NAME} \+.*[^offline]$"; then
|
if tailscale ip >/dev/null 2>&1; then
|
||||||
CONNECTED=true
|
TS_IPS=$(tailscale ip 2>/dev/null || echo "Unknown")
|
||||||
break
|
TS_IPV4=$(echo "$TS_IPS" | grep -E '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' | head -1 || echo "Unknown")
|
||||||
|
if [[ -n "$TS_IPV4" && "$TS_IPV4" != "Unknown" ]]; then
|
||||||
|
CONNECTED=true
|
||||||
|
break
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
print_info "Waiting for Tailscale to connect ($i/$RETRIES)..."
|
print_info "Waiting for Tailscale to connect ($i/$RETRIES)..."
|
||||||
sleep $DELAY
|
sleep $DELAY
|
||||||
done
|
done
|
||||||
if $CONNECTED; then
|
if $CONNECTED; then
|
||||||
print_success "Tailscale connected successfully (hostname: $SERVER_NAME)."
|
print_success "Tailscale connected successfully. Node IPv4 in tailnet: $TS_IPV4"
|
||||||
log "Tailscale connected: $TS_COMMAND"
|
log "Tailscale connected: $TS_COMMAND"
|
||||||
# Store connection details for summary
|
# Store connection details for summary
|
||||||
echo "${LOGIN_SERVER:-https://controlplane.tailscale.com}" > /tmp/tailscale_server
|
echo "${LOGIN_SERVER:-https://controlplane.tailscale.com}" > /tmp/tailscale_server
|
||||||
|
echo "$TS_IPS" > /tmp/tailscale_ips.txt
|
||||||
echo "None" > /tmp/tailscale_flags
|
echo "None" > /tmp/tailscale_flags
|
||||||
else
|
else
|
||||||
print_warning "Tailscale connection attempt succeeded, but hostname ($SERVER_NAME) not found in 'tailscale status'."
|
print_warning "Tailscale connection attempt succeeded, but no IPs assigned."
|
||||||
print_info "Please verify with 'tailscale status' and run the following command manually if needed:"
|
print_info "Please verify with 'tailscale ip' and run the following command manually if needed:"
|
||||||
echo -e "${CYAN} $TS_COMMAND${NC}"
|
echo -e "${CYAN} $TS_COMMAND${NC}"
|
||||||
log "Tailscale connection not verified: $TS_COMMAND"
|
log "Tailscale connection not verified: $TS_COMMAND"
|
||||||
tailscale status > /tmp/tailscale_status.txt 2>&1
|
tailscale status > /tmp/tailscale_status.txt 2>&1
|
||||||
@@ -1045,22 +1083,28 @@ install_tailscale() {
|
|||||||
local RETRIES=3
|
local RETRIES=3
|
||||||
local DELAY=5
|
local DELAY=5
|
||||||
local CONNECTED=false
|
local CONNECTED=false
|
||||||
|
local TS_IPS TS_IPV4
|
||||||
for ((i=1; i<=RETRIES; i++)); do
|
for ((i=1; i<=RETRIES; i++)); do
|
||||||
if tailscale status 2>/dev/null | grep -q "^[^ ]* \+${SERVER_NAME} \+.*[^offline]$"; then
|
if tailscale ip >/dev/null 2>&1; then
|
||||||
CONNECTED=true
|
TS_IPS=$(tailscale ip 2>/dev/null || echo "Unknown")
|
||||||
break
|
TS_IPV4=$(echo "$TS_IPS" | grep -E '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' | head -1 || echo "Unknown")
|
||||||
|
if [[ -n "$TS_IPV4" && "$TS_IPV4" != "Unknown" ]]; then
|
||||||
|
CONNECTED=true
|
||||||
|
break
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
print_info "Waiting for Tailscale to connect ($i/$RETRIES)..."
|
print_info "Waiting for Tailscale to connect ($i/$RETRIES)..."
|
||||||
sleep $DELAY
|
sleep $DELAY
|
||||||
done
|
done
|
||||||
if $CONNECTED; then
|
if $CONNECTED; then
|
||||||
print_success "Tailscale reconfigured with additional options."
|
print_success "Tailscale reconfigured with additional options. Node IPv4 in tailnet: $TS_IPV4"
|
||||||
log "Tailscale reconfigured: $TS_COMMAND"
|
log "Tailscale reconfigured: $TS_COMMAND"
|
||||||
# Store flags for summary
|
# Store flags and IPs for summary
|
||||||
echo "${TS_FLAGS// --/}" > /tmp/tailscale_flags
|
echo "${TS_FLAGS// --/}" > /tmp/tailscale_flags
|
||||||
|
echo "$TS_IPS" > /tmp/tailscale_ips.txt
|
||||||
else
|
else
|
||||||
print_warning "Tailscale reconfiguration attempt succeeded, but hostname ($SERVER_NAME) not found in 'tailscale status'."
|
print_warning "Tailscale reconfiguration attempt succeeded, but no IPs assigned."
|
||||||
print_info "Please verify with 'tailscale status' and run the following command manually if needed:"
|
print_info "Please verify with 'tailscale ip' and run the following command manually if needed:"
|
||||||
echo -e "${CYAN} $TS_COMMAND${NC}"
|
echo -e "${CYAN} $TS_COMMAND${NC}"
|
||||||
log "Tailscale reconfiguration not verified: $TS_COMMAND"
|
log "Tailscale reconfiguration not verified: $TS_COMMAND"
|
||||||
tailscale status > /tmp/tailscale_status.txt 2>&1
|
tailscale status > /tmp/tailscale_status.txt 2>&1
|
||||||
@@ -1076,7 +1120,7 @@ install_tailscale() {
|
|||||||
log "No additional Tailscale options applied."
|
log "No additional Tailscale options applied."
|
||||||
fi
|
fi
|
||||||
print_success "Tailscale setup complete."
|
print_success "Tailscale setup complete."
|
||||||
print_info "Verify status: tailscale status"
|
print_info "Verify status: tailscale ip"
|
||||||
log "Tailscale setup completed."
|
log "Tailscale setup completed."
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1326,6 +1370,9 @@ EOF
|
|||||||
fi
|
fi
|
||||||
print_success "Backup script created."
|
print_success "Backup script created."
|
||||||
|
|
||||||
|
# --- Backup test ---
|
||||||
|
test_backup
|
||||||
|
|
||||||
# --- Configure Cron Job ---
|
# --- Configure Cron Job ---
|
||||||
print_info "Configuring root cron job..."
|
print_info "Configuring root cron job..."
|
||||||
# Ensure crontab is writable
|
# Ensure crontab is writable
|
||||||
@@ -1363,12 +1410,73 @@ EOF
|
|||||||
log "Backup configuration completed."
|
log "Backup configuration completed."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test_backup() {
|
||||||
|
print_section "Backup Configuration Test"
|
||||||
|
if [[ ! -f /root/run_backup.sh ]]; then
|
||||||
|
print_error "Backup script not found. Cannot run test."
|
||||||
|
log "Backup test failed: /root/run_backup.sh not found."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! confirm "Run a test backup to verify configuration?"; then
|
||||||
|
print_info "Skipping backup test."
|
||||||
|
log "Backup test skipped by user."
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
local BACKUP_DEST=$(grep "^REMOTE_DEST=" /root/run_backup.sh | cut -d'"' -f2 || echo "unknown")
|
||||||
|
local BACKUP_PORT=$(grep "^SSH_PORT=" /root/run_backup.sh | cut -d'"' -f2 || echo "22")
|
||||||
|
local REMOTE_BACKUP_PATH=$(grep "^REMOTE_PATH=" /root/run_backup.sh | cut -d'"' -f2 || echo "unknown")
|
||||||
|
local BACKUP_LOG="/var/log/backup_rsync.log"
|
||||||
|
|
||||||
|
if [[ "$BACKUP_DEST" == "unknown" || "$REMOTE_BACKUP_PATH" == "unknown" ]]; then
|
||||||
|
print_error "Invalid backup configuration in /root/run_backup.sh."
|
||||||
|
log "Backup test failed: Invalid configuration in /root/run_backup.sh."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create a temporary test file
|
||||||
|
local TEST_DIR="/root/test_backup_$(date +%Y%m%d_%H%M%S)"
|
||||||
|
mkdir -p "$TEST_DIR"
|
||||||
|
echo "Test file for backup verification" > "$TEST_DIR/test.txt"
|
||||||
|
chmod 600 "$TEST_DIR/test.txt"
|
||||||
|
|
||||||
|
print_info "Running test backup to $BACKUP_DEST:$REMOTE_BACKUP_PATH..."
|
||||||
|
local RSYNC_OUTPUT
|
||||||
|
RSYNC_OUTPUT=$(rsync -avz --delete -e "ssh -p $BACKUP_PORT" "$TEST_DIR/" "${BACKUP_DEST}:${REMOTE_BACKUP_PATH}test_backup/" 2>&1)
|
||||||
|
local RSYNC_EXIT_CODE=$?
|
||||||
|
echo "--- Test Backup at $(date) ---" >> "$BACKUP_LOG"
|
||||||
|
echo "$RSYNC_OUTPUT" >> "$BACKUP_LOG"
|
||||||
|
|
||||||
|
if [[ $RSYNC_EXIT_CODE -eq 0 ]]; then
|
||||||
|
echo "Test backup successful" >> "$BACKUP_LOG"
|
||||||
|
print_success "Test backup successful! Check $BACKUP_LOG for details."
|
||||||
|
log "Test backup successful."
|
||||||
|
else
|
||||||
|
print_error "Test backup failed (exit code: $RSYNC_EXIT_CODE). Check $BACKUP_LOG for details."
|
||||||
|
print_info "Troubleshooting steps:"
|
||||||
|
print_info " - Verify SSH key: cat /root/.ssh/id_ed25519.pub"
|
||||||
|
print_info " - Copy key: ssh-copy-id -p \"$BACKUP_PORT\" -i /root/.ssh/id_ed25519.pub \"$BACKUP_DEST\""
|
||||||
|
print_info " - Test SSH: ssh -p \"$BACKUP_PORT\" \"$BACKUP_DEST\" true"
|
||||||
|
log "Test backup failed with exit code $RSYNC_EXIT_CODE."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Clean up test directory
|
||||||
|
rm -rf "$TEST_DIR"
|
||||||
|
print_success "Backup test completed."
|
||||||
|
log "Backup test completed."
|
||||||
|
}
|
||||||
|
|
||||||
configure_swap() {
|
configure_swap() {
|
||||||
if [[ $IS_CONTAINER == true ]]; then
|
if [[ $IS_CONTAINER == true ]]; then
|
||||||
print_info "Swap configuration skipped in container."
|
print_info "Swap configuration skipped in container."
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
print_section "Swap Configuration"
|
print_section "Swap Configuration"
|
||||||
|
# Check for existing swap partition
|
||||||
|
if lsblk -r | grep -q '\[SWAP\]'; then
|
||||||
|
print_warning "Existing swap partition found. Verify with 'lsblk -f'. Proceed with caution."
|
||||||
|
fi
|
||||||
local existing_swap
|
local existing_swap
|
||||||
existing_swap=$(swapon --show --noheadings | awk '{print $1}' || true)
|
existing_swap=$(swapon --show --noheadings | awk '{print $1}' || true)
|
||||||
if [[ -n "$existing_swap" ]]; then
|
if [[ -n "$existing_swap" ]]; then
|
||||||
@@ -1522,6 +1630,79 @@ configure_time_sync() {
|
|||||||
log "Time synchronization completed."
|
log "Time synchronization completed."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
configure_security_audit() {
|
||||||
|
print_section "Security Audit Configuration"
|
||||||
|
if ! confirm "Run a security audit with Lynis (and optionally debsecan on Debian)?"; then
|
||||||
|
print_info "Security audit skipped."
|
||||||
|
log "Security audit skipped by user."
|
||||||
|
AUDIT_RAN=false
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
AUDIT_LOG="/var/log/setup_harden_security_audit_$(date +%Y%m%d_%H%M%S).log"
|
||||||
|
touch "$AUDIT_LOG" && chmod 600 "$AUDIT_LOG"
|
||||||
|
AUDIT_RAN=true
|
||||||
|
HARDENING_INDEX=""
|
||||||
|
DEBSECAN_VULNS="Not run"
|
||||||
|
|
||||||
|
# Install and run Lynis
|
||||||
|
print_info "Installing Lynis..."
|
||||||
|
if ! apt-get update -qq; then
|
||||||
|
print_error "Failed to update package lists. Cannot install Lynis."
|
||||||
|
log "apt-get update failed for Lynis installation."
|
||||||
|
return 1
|
||||||
|
elif ! apt-get install -y -qq lynis; then
|
||||||
|
print_warning "Failed to install Lynis. Skipping Lynis audit."
|
||||||
|
log "Lynis installation failed."
|
||||||
|
else
|
||||||
|
print_info "Running Lynis audit (non-interactive mode)..."
|
||||||
|
if lynis audit system --quick >> "$AUDIT_LOG" 2>&1; then
|
||||||
|
print_success "Lynis audit completed. Check $AUDIT_LOG for details."
|
||||||
|
log "Lynis audit completed successfully."
|
||||||
|
# Extract hardening index
|
||||||
|
HARDENING_INDEX=$(grep -oP "Hardening index : \K\d+" "$AUDIT_LOG" || echo "Unknown")
|
||||||
|
# Append Lynis system log for persistence
|
||||||
|
cat /var/log/lynis.log >> "$AUDIT_LOG" 2>/dev/null
|
||||||
|
else
|
||||||
|
print_error "Lynis audit failed. Check $AUDIT_LOG for details."
|
||||||
|
log "Lynis audit failed."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if system is Debian before running debsecan
|
||||||
|
source /etc/os-release
|
||||||
|
if [[ "$ID" == "debian" ]]; then
|
||||||
|
if confirm "Also run debsecan to check for package vulnerabilities?"; then
|
||||||
|
print_info "Installing debsecan..."
|
||||||
|
if ! apt-get install -y -qq debsecan; then
|
||||||
|
print_warning "Failed to install debsecan. Skipping debsecan audit."
|
||||||
|
log "debsecan installation failed."
|
||||||
|
else
|
||||||
|
print_info "Running debsecan audit..."
|
||||||
|
if debsecan --suite "$VERSION_CODENAME" >> "$AUDIT_LOG" 2>&1; then
|
||||||
|
DEBSECAN_VULNS=$(grep -c "CVE-" "$AUDIT_LOG" || echo "0")
|
||||||
|
print_success "debsecan audit completed. Found $DEBSECAN_VULNS vulnerabilities."
|
||||||
|
log "debsecan audit completed with $DEBSECAN_VULNS vulnerabilities."
|
||||||
|
else
|
||||||
|
print_error "debsecan audit failed. Check $AUDIT_LOG for details."
|
||||||
|
log "debsecan audit failed."
|
||||||
|
DEBSECAN_VULNS="Failed"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
print_info "debsecan audit skipped."
|
||||||
|
log "debsecan audit skipped by user."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
print_info "debsecan is not supported on Ubuntu. Skipping debsecan audit."
|
||||||
|
log "debsecan audit skipped (Ubuntu detected)."
|
||||||
|
DEBSECAN_VULNS="Not supported on Ubuntu"
|
||||||
|
fi
|
||||||
|
|
||||||
|
print_warning "Review audit results in $AUDIT_LOG for security recommendations."
|
||||||
|
log "Security audit configuration completed."
|
||||||
|
}
|
||||||
|
|
||||||
final_cleanup() {
|
final_cleanup() {
|
||||||
print_section "Final System Cleanup"
|
print_section "Final System Cleanup"
|
||||||
print_info "Running final system update and cleanup..."
|
print_info "Running final system update and cleanup..."
|
||||||
@@ -1544,34 +1725,43 @@ generate_summary() {
|
|||||||
print_success "Service $service is active."
|
print_success "Service $service is active."
|
||||||
else
|
else
|
||||||
print_error "Service $service is NOT active."
|
print_error "Service $service is NOT active."
|
||||||
|
FAILED_SERVICES+=("$service")
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
if ufw status | grep -q "Status: active"; then
|
if ufw status | grep -q "Status: active"; then
|
||||||
print_success "Service ufw is active."
|
print_success "Service ufw is active."
|
||||||
else
|
else
|
||||||
print_error "Service ufw is NOT active."
|
print_error "Service ufw is NOT active."
|
||||||
|
FAILED_SERVICES+=("ufw")
|
||||||
fi
|
fi
|
||||||
if command -v docker >/dev/null 2>&1; then
|
if command -v docker >/dev/null 2>&1; then
|
||||||
if systemctl is-active --quiet docker; then
|
if systemctl is-active --quiet docker; then
|
||||||
print_success "Service docker is active."
|
print_success "Service docker is active."
|
||||||
else
|
else
|
||||||
print_error "Service docker is NOT active."
|
print_error "Service docker is NOT active."
|
||||||
|
FAILED_SERVICES+=("docker")
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
local TS_COMMAND=""
|
local TS_COMMAND=""
|
||||||
if command -v tailscale >/dev/null 2>&1; then
|
if command -v tailscale >/dev/null 2>&1; then
|
||||||
if systemctl is-active --quiet tailscaled && tailscale status >/dev/null 2>&1 && tailscale status | grep -q "^[^ ]* \+${SERVER_NAME} \+.*[^offline]$"; then
|
if systemctl is-active --quiet tailscaled && tailscale ip >/dev/null 2>&1; then
|
||||||
print_success "Service tailscaled is active and connected."
|
local TS_IPS TS_IPV4
|
||||||
local TS_SERVER=$(cat /tmp/tailscale_server 2>/dev/null || echo "https://controlplane.tailscale.com")
|
TS_IPS=$(tailscale ip 2>/dev/null || echo "Unknown")
|
||||||
local TS_FLAGS=$(cat /tmp/tailscale_flags 2>/dev/null || echo "None")
|
TS_IPV4=$(echo "$TS_IPS" | grep -E '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' | head -1 || echo "Unknown")
|
||||||
|
print_success "Service tailscaled is active and connected. Node IPv4 in tailnet: $TS_IPV4"
|
||||||
|
echo "$TS_IPS" > /tmp/tailscale_ips.txt
|
||||||
else
|
else
|
||||||
print_error "Service tailscaled is NOT active or not connected."
|
print_error "Service tailscaled is NOT active or not connected."
|
||||||
local TS_SERVER="Not connected"
|
FAILED_SERVICES+=("tailscaled")
|
||||||
local TS_FLAGS="None"
|
|
||||||
TS_COMMAND=$(grep "Tailscale connection failed: tailscale up" "$LOG_FILE" | tail -1 | sed 's/.*Tailscale connection failed: //')
|
TS_COMMAND=$(grep "Tailscale connection failed: tailscale up" "$LOG_FILE" | tail -1 | sed 's/.*Tailscale connection failed: //')
|
||||||
TS_COMMAND=${TS_COMMAND:-"tailscale up --operator=$USERNAME"}
|
TS_COMMAND=${TS_COMMAND:-"tailscale up --operator=$USERNAME"}
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
if [[ "$AUDIT_RAN" == true ]]; then
|
||||||
|
print_success "Security audit performed."
|
||||||
|
else
|
||||||
|
print_info "Security audit not performed."
|
||||||
|
fi
|
||||||
echo -e "\n${GREEN}Server setup and hardening script has finished successfully.${NC}\n"
|
echo -e "\n${GREEN}Server setup and hardening script has finished successfully.${NC}\n"
|
||||||
echo -e "${YELLOW}Configuration Summary:${NC}"
|
echo -e "${YELLOW}Configuration Summary:${NC}"
|
||||||
printf " %-16s%s\n" "Admin User:" "$USERNAME"
|
printf " %-16s%s\n" "Admin User:" "$USERNAME"
|
||||||
@@ -1596,16 +1786,35 @@ generate_summary() {
|
|||||||
printf " %-16s%s\n" "- Remote Path:" "$REMOTE_BACKUP_PATH"
|
printf " %-16s%s\n" "- Remote Path:" "$REMOTE_BACKUP_PATH"
|
||||||
printf " %-16s%s\n" "- Cron Schedule:" "$CRON_SCHEDULE"
|
printf " %-16s%s\n" "- Cron Schedule:" "$CRON_SCHEDULE"
|
||||||
printf " %-16s%s\n" "- Notifications:" "$NOTIFICATION_STATUS"
|
printf " %-16s%s\n" "- Notifications:" "$NOTIFICATION_STATUS"
|
||||||
|
if [[ -f "$BACKUP_LOG" ]] && grep -q "Test backup successful" "$BACKUP_LOG" 2>/dev/null; then
|
||||||
|
printf " %-16s%s\n" "- Test Status:" "Successful"
|
||||||
|
elif [[ -f "$BACKUP_LOG" ]]; then
|
||||||
|
printf " %-16s%s\n" "- Test Status:" "Failed (check $BACKUP_LOG)"
|
||||||
|
else
|
||||||
|
printf " %-16s%s\n" "- Test Status:" "Not run"
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
echo -e " Remote Backup: ${RED}Not configured${NC}"
|
echo -e " Remote Backup: ${RED}Not configured${NC}"
|
||||||
fi
|
fi
|
||||||
if command -v tailscale >/dev/null 2>&1; then
|
if command -v tailscale >/dev/null 2>&1; then
|
||||||
|
local TS_SERVER=$(cat /tmp/tailscale_server 2>/dev/null || echo "https://controlplane.tailscale.com")
|
||||||
|
local TS_IPS=$(cat /tmp/tailscale_ips.txt 2>/dev/null || echo "Not connected")
|
||||||
|
local TS_FLAGS=$(cat /tmp/tailscale_flags 2>/dev/null || echo "None")
|
||||||
echo -e " Tailscale: ${GREEN}Enabled${NC}"
|
echo -e " Tailscale: ${GREEN}Enabled${NC}"
|
||||||
printf " %-16s%s\n" "- Server:" "$TS_SERVER"
|
printf " %-16s%s\n" "- Server:" "$TS_SERVER"
|
||||||
|
printf " %-16s%s\n" "- Tailscale IPs:" "$TS_IPS"
|
||||||
printf " %-16s%s\n" "- Flags:" "$TS_FLAGS"
|
printf " %-16s%s\n" "- Flags:" "$TS_FLAGS"
|
||||||
else
|
else
|
||||||
echo -e " Tailscale: ${RED}Not configured${NC}"
|
echo -e " Tailscale: ${RED}Not configured${NC}"
|
||||||
fi
|
fi
|
||||||
|
if [[ "$AUDIT_RAN" == true ]]; then
|
||||||
|
echo -e " Security Audit: ${GREEN}Performed${NC}"
|
||||||
|
printf " %-16s%s\n" "- Audit Log:" "$AUDIT_LOG"
|
||||||
|
printf " %-16s%s\n" "- Hardening Index:" "${HARDENING_INDEX:-Unknown}"
|
||||||
|
printf " %-16s%s\n" "- Vulnerabilities:" "$DEBSECAN_VULNS"
|
||||||
|
else
|
||||||
|
echo -e " Security Audit: ${RED}Not run${NC}"
|
||||||
|
fi
|
||||||
echo
|
echo
|
||||||
printf "${PURPLE}%-16s%s${NC}\n" "Log File:" "$LOG_FILE"
|
printf "${PURPLE}%-16s%s${NC}\n" "Log File:" "$LOG_FILE"
|
||||||
printf "${PURPLE}%-16s%s${NC}\n" "Backups:" "$BACKUP_DIR"
|
printf "${PURPLE}%-16s%s${NC}\n" "Backups:" "$BACKUP_DIR"
|
||||||
@@ -1622,21 +1831,29 @@ generate_summary() {
|
|||||||
fi
|
fi
|
||||||
if command -v tailscale >/dev/null 2>&1; then
|
if command -v tailscale >/dev/null 2>&1; then
|
||||||
printf " %-20s${CYAN}%s${NC}\n" "- Tailscale status:" "tailscale status"
|
printf " %-20s${CYAN}%s${NC}\n" "- Tailscale status:" "tailscale status"
|
||||||
if [[ "$TS_SERVER" == "Not connected" && -n "$TS_COMMAND" ]]; then
|
|
||||||
printf " %-20s${CYAN}%s${NC}\n" "- Tailscale connect:" "$TS_COMMAND"
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
if [[ -f /root/run_backup.sh ]]; then
|
if [[ -f /root/run_backup.sh ]]; then
|
||||||
echo -e " Remote Backup:"
|
echo -e " Remote Backup:"
|
||||||
printf " %-18s${CYAN}%s${NC}\n" "- Verify SSH key:" "cat /root/.ssh/id_ed25519.pub"
|
printf " %-18s${CYAN}%s${NC}\n" "- Verify SSH key:" "cat /root/.ssh/id_ed25519.pub"
|
||||||
printf " %-18s${CYAN}%s${NC}\n" "- Copy key if needed:" "ssh-copy-id -p $BACKUP_PORT -s $BACKUP_DEST"
|
printf " %-18s${CYAN}%s${NC}\n" "- Copy key if needed:" "ssh-copy-id -p $BACKUP_PORT -s $BACKUP_DEST"
|
||||||
printf " %-18s${CYAN}%s${NC}\n" "- Test backup:" "sudo /root/run_backup.sh"
|
printf " %-18s${CYAN}%s${NC}\n" "- Test backup:" "sudo /root/run_backup.sh"
|
||||||
printf " %-18s${CYAN}%s${NC}\n" "- Check logs:" "sudo less /var/log/backup_rsync.log"
|
printf " %-18s${CYAN}%s${NC}\n" "- Check logs:" "sudo less $BACKUP_LOG"
|
||||||
|
fi
|
||||||
|
if [[ "$AUDIT_RAN" == true ]]; then
|
||||||
|
echo -e " Security Audit:"
|
||||||
|
printf " %-18s${CYAN}%s${NC}\n" "- Check results:" "sudo less $AUDIT_LOG"
|
||||||
|
fi
|
||||||
|
if [[ ${#FAILED_SERVICES[@]} -gt 0 ]]; then
|
||||||
|
print_warning "ACTION REQUIRED: The following services failed: ${FAILED_SERVICES[*]}. Verify with 'systemctl status <service>'."
|
||||||
fi
|
fi
|
||||||
print_warning "\nACTION REQUIRED: If remote backup is enabled, ensure the root SSH key is copied to the destination server."
|
|
||||||
if [[ -n "$TS_COMMAND" ]]; then
|
if [[ -n "$TS_COMMAND" ]]; then
|
||||||
print_warning "ACTION REQUIRED: Tailscale connection failed. Run the command above to connect manually."
|
print_warning "ACTION REQUIRED: Tailscale connection failed. Run the following command to connect manually:"
|
||||||
|
echo -e "${CYAN} $TS_COMMAND${NC}"
|
||||||
fi
|
fi
|
||||||
|
if [[ -f /root/run_backup.sh && "$KEY_COPY_CHOICE" == "2" ]]; then
|
||||||
|
print_warning "ACTION REQUIRED: Ensure the root SSH key (/root/.ssh/id_ed25519.pub) is copied to $BACKUP_DEST."
|
||||||
|
fi
|
||||||
|
print_warning "ACTION REQUIRED: If remote backup is enabled, ensure the root SSH key is copied to the destination server."
|
||||||
print_warning "A reboot is required to apply all changes cleanly."
|
print_warning "A reboot is required to apply all changes cleanly."
|
||||||
if [[ $VERBOSE == true ]]; then
|
if [[ $VERBOSE == true ]]; then
|
||||||
if confirm "Reboot now?" "y"; then
|
if confirm "Reboot now?" "y"; then
|
||||||
@@ -1682,6 +1899,7 @@ main() {
|
|||||||
install_tailscale
|
install_tailscale
|
||||||
setup_backup
|
setup_backup
|
||||||
configure_swap
|
configure_swap
|
||||||
|
configure_security_audit
|
||||||
final_cleanup
|
final_cleanup
|
||||||
generate_summary
|
generate_summary
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user