progress snapshot
This commit is contained in:
@@ -1,3 +0,0 @@
|
||||
FROM debian:trixie
|
||||
RUN echo "Docker works!"
|
||||
CMD ["echo", "Docker test passed"]
|
||||
124
config/40_secure_boot
Normal file
124
config/40_secure_boot
Normal file
File diff suppressed because one or more lines are too long
102
config/50-cis-logging.conf
Normal file
102
config/50-cis-logging.conf
Normal file
@@ -0,0 +1,102 @@
|
||||
# CIS Debian 13 Benchmark - Security Logging Configuration
|
||||
# Implements CIS recommendations for enhanced security logging
|
||||
|
||||
# Enhanced authorization logging
|
||||
auth,authpriv.* /var/log/security/auth.log
|
||||
auth,authpriv.* @@remoteserver:514
|
||||
|
||||
# System logs with security tag
|
||||
*.=info;*.=notice;*.=warn;\
|
||||
auth,authpriv.none;\
|
||||
cron,daemon.none;\
|
||||
mail,news.none /var/log/security/messages
|
||||
|
||||
# Kernel messages
|
||||
kern.* /var/log/security/kern.log
|
||||
|
||||
# Security events
|
||||
security.* /var/log/security/security.log
|
||||
|
||||
# Audit events (from auditd)
|
||||
audit.* /var/log/security/audit.log
|
||||
|
||||
# User login/logout logs
|
||||
login.* /var/log/security/login.log
|
||||
|
||||
# Sudo commands
|
||||
local2.* /var/log/security/sudo.log
|
||||
|
||||
# Failed logins
|
||||
authpriv.*;auth.* /var/log/security/failed.log
|
||||
|
||||
# Application specific logs
|
||||
mail.* -/var/log/security/mail.log
|
||||
cron.* /var/log/security/cron.log
|
||||
daemon.* /var/log/security/daemon.log
|
||||
|
||||
# Network logs
|
||||
network.* /var/log/security/network.log
|
||||
|
||||
# Security alerts
|
||||
*.alert /var/log/security/alerts.log
|
||||
*.emerg :omusrmsg:*
|
||||
*.=emerg :omusrmsg:*
|
||||
|
||||
# Console logging
|
||||
*.=crit;*.=err;*.=warning |/dev/xconsole
|
||||
|
||||
# Remote logging to security team (if configured)
|
||||
# *.* @@logserver.domain.tld:514
|
||||
|
||||
# Filter duplicate messages
|
||||
$RepeatedMsgReduction on
|
||||
|
||||
# Set default permissions for log files
|
||||
$FileCreateMode 0640
|
||||
$DirCreateMode 0755
|
||||
$Umask 0027
|
||||
|
||||
# Ensure all logs include timestamp and hostname
|
||||
$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
|
||||
|
||||
# Rate limiting to prevent log flooding
|
||||
$SystemLogRateLimitInterval 60
|
||||
$SystemLogRateLimitBurst 1000
|
||||
|
||||
# Discard duplicate messages within 30 seconds
|
||||
$RepeatedMsgReductionInterval 30
|
||||
|
||||
# Include additional configuration files
|
||||
$IncludeConfig /etc/rsyslog.d/*.conf
|
||||
|
||||
# Preserve security log integrity
|
||||
:msg, contains, "security" /var/log/security/security.log
|
||||
:msg, contains, "failed login" /var/log/security/failed.log
|
||||
:msg, contains, "sudo" /var/log/security/sudo.log
|
||||
:msg, contains, "audit" /var/log/security/audit.log
|
||||
|
||||
# Create separate logs for different security domains
|
||||
$RuleSet remote
|
||||
:fromhost-ip, !isequal, "127.0.0.1" ?RemoteLogs
|
||||
& ~
|
||||
|
||||
# Enable journald to rsyslog forwarding
|
||||
$ModLoad imjournal
|
||||
$OmitLocalLogging on
|
||||
|
||||
# Preserve FQDN in logs
|
||||
$PreserveFQDN on
|
||||
|
||||
# Add process ID to all log entries
|
||||
$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
|
||||
|
||||
# Ensure backward compatibility
|
||||
$ModLoad compat
|
||||
|
||||
# Queue settings for reliability
|
||||
$WorkDirectory /var/spool/rsyslog
|
||||
$ActionQueueFileName fwdRule1
|
||||
$ActionQueueMaxDiskSpace 1g
|
||||
$ActionQueueSaveOnShutdown on
|
||||
$ActionQueueType LinkedList
|
||||
$ActionResumeRetryCount -1
|
||||
113
config/99-cis-hardening.conf
Normal file
113
config/99-cis-hardening.conf
Normal file
@@ -0,0 +1,113 @@
|
||||
# CIS Debian 13 Benchmark - Kernel Hardening Configuration
|
||||
# Implements CIS recommendations for kernel security parameters
|
||||
|
||||
# Network Configuration
|
||||
net.ipv4.ip_forward = 0
|
||||
net.ipv6.conf.all.forwarding = 0
|
||||
net.ipv4.conf.all.send_redirects = 0
|
||||
net.ipv4.conf.default.send_redirects = 0
|
||||
net.ipv4.conf.all.accept_redirects = 0
|
||||
net.ipv4.conf.default.accept_redirects = 0
|
||||
net.ipv4.conf.all.accept_source_route = 0
|
||||
net.ipv4.conf.default.accept_source_route = 0
|
||||
net.ipv6.conf.all.accept_redirects = 0
|
||||
net.ipv6.conf.default.accept_redirects = 0
|
||||
net.ipv4.conf.all.log_martians = 1
|
||||
net.ipv4.conf.default.log_martians = 1
|
||||
|
||||
# TCP Hardening
|
||||
net.ipv4.tcp_syncookies = 1
|
||||
net.ipv4.tcp_max_syn_backlog = 2048
|
||||
net.ipv4.tcp_synack_retries = 2
|
||||
net.ipv4.tcp_syn_retries = 5
|
||||
|
||||
# IP Source Routing
|
||||
net.ipv4.conf.all.accept_source_route = 0
|
||||
net.ipv4.conf.default.accept_source_route = 0
|
||||
net.ipv6.conf.all.accept_source_route = 0
|
||||
net.ipv6.conf.default.accept_source_route = 0
|
||||
|
||||
# ICMP Redirects
|
||||
net.ipv4.conf.all.accept_redirects = 0
|
||||
net.ipv4.conf.default.accept_redirects = 0
|
||||
net.ipv6.conf.all.accept_redirects = 0
|
||||
net.ipv6.conf.default.accept_redirects = 0
|
||||
|
||||
# ICMP Redirect Broadcast
|
||||
net.ipv4.icmp_echo_ignore_broadcasts = 1
|
||||
net.ipv4.icmp_ignore_bogus_error_responses = 1
|
||||
|
||||
# ICMP Rate Limiting
|
||||
net.ipv4.icmp_ratelimit = 100
|
||||
net.ipv4.icmp_ratemask = 88089
|
||||
|
||||
# IPv6
|
||||
net.ipv6.conf.all.disable_ipv6 = 1
|
||||
net.ipv6.conf.default.disable_ipv6 = 1
|
||||
|
||||
# Log Suspicious Packets
|
||||
net.ipv4.conf.all.log_martians = 1
|
||||
net.ipv4.conf.default.log_martians = 1
|
||||
|
||||
# ExecShield Protection
|
||||
kernel.exec-shield = 1
|
||||
kernel.randomize_va_space = 2
|
||||
|
||||
# Core Dumps
|
||||
kernel.core_pattern = |/bin/false
|
||||
fs.suid_dumpable = 0
|
||||
|
||||
# Shared Memory
|
||||
kernel.shmmax = 4294967295
|
||||
kernel.shmall = 268435456
|
||||
|
||||
# Network Protection
|
||||
net.ipv4.tcp_timestamps = 0
|
||||
net.ipv4.tcp_sack = 1
|
||||
net.ipv4.tcp_dsack = 1
|
||||
|
||||
# Protection against SYN flood attacks
|
||||
net.ipv4.tcp_syncookies = 1
|
||||
net.ipv4.tcp_synack_retries = 2
|
||||
net.ipv4.tcp_syn_retries = 5
|
||||
|
||||
# Log Invalid Packets
|
||||
net.ipv4.conf.all.log_martians = 1
|
||||
net.ipv4.conf.default.log_martians = 1
|
||||
|
||||
# Ignore ICMP redirects
|
||||
net.ipv4.conf.all.accept_redirects = 0
|
||||
net.ipv4.conf.default.accept_redirects = 0
|
||||
net.ipv6.conf.all.accept_redirects = 0
|
||||
net.ipv6.conf.default.accept_redirects = 0
|
||||
|
||||
# Ignore Send Redirects
|
||||
net.ipv4.conf.all.send_redirects = 0
|
||||
net.ipv4.conf.default.send_redirects = 0
|
||||
|
||||
# Enable RFC-recommended source validation
|
||||
net.ipv4.conf.all.rp_filter = 1
|
||||
net.ipv4.conf.default.rp_filter = 1
|
||||
|
||||
# Disable IPv6
|
||||
net.ipv6.conf.all.disable_ipv6 = 1
|
||||
net.ipv6.conf.default.disable_ipv6 = 1
|
||||
|
||||
# ASLR
|
||||
kernel.randomize_va_space = 2
|
||||
|
||||
# Disable magic SysRq key
|
||||
kernel.sysrq = 0
|
||||
|
||||
# Limits on core dumps
|
||||
fs.suid_dumpable = 0
|
||||
|
||||
# Restrict ptrace scope
|
||||
kernel.yama.ptrace_scope = 1
|
||||
|
||||
# Disable kexec system call
|
||||
kernel.kexec_load_disabled = 1
|
||||
|
||||
# AppArmor protection
|
||||
kernel.apparmor_restrict_unprivileged_userns = 1
|
||||
kernel.apparmor_restrict_unprivileged_io_uring = 1
|
||||
332
config/aide-init.sh
Normal file
332
config/aide-init.sh
Normal file
@@ -0,0 +1,332 @@
|
||||
#!/bin/bash
|
||||
# Football System AIDE Database Initialization
|
||||
# Creates and initializes the file integrity monitoring database
|
||||
|
||||
set -e
|
||||
|
||||
echo "Initializing AIDE database..."
|
||||
|
||||
# Ensure required directories exist
|
||||
mkdir -p /var/lib/aide
|
||||
mkdir -p /var/log/aide
|
||||
mkdir -p /etc/security
|
||||
|
||||
# Check if AIDE configuration exists
|
||||
if [ ! -f /etc/aide.conf ]; then
|
||||
echo "⚠️ AIDE configuration not found at /etc/aide.conf"
|
||||
echo "Please ensure aide.conf is properly installed before running this script"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Set proper permissions for AIDE directories
|
||||
chown root:root /var/lib/aide
|
||||
chmod 700 /var/lib/aide
|
||||
|
||||
chown root:root /var/log/aide
|
||||
chmod 750 /var/log/aide
|
||||
|
||||
# Create log files with proper permissions
|
||||
touch /var/log/aide/aide.log
|
||||
touch /var/log/aide/aide_check.log
|
||||
touch /var/log/aide/aide_error.log
|
||||
|
||||
chown root:adm /var/log/aide/*.log
|
||||
chmod 640 /var/log/aide/*.log
|
||||
|
||||
# Check if this is the first run
|
||||
FIRST_RUN=false
|
||||
if [ ! -f /var/lib/aide/aide.db ]; then
|
||||
echo "First-time AIDE database initialization detected"
|
||||
FIRST_RUN=true
|
||||
fi
|
||||
|
||||
# Initialize AIDE database
|
||||
echo "Creating AIDE database..."
|
||||
if aide --init; then
|
||||
echo "✅ AIDE database created successfully"
|
||||
else
|
||||
echo "❌ AIDE database initialization failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Move new database to active location
|
||||
if [ -f /var/lib/aide/aide.db.new ]; then
|
||||
mv /var/lib/aide/aide.db.new /var/lib/aide/aide.db
|
||||
echo "✅ AIDE database activated"
|
||||
fi
|
||||
|
||||
# Set secure permissions on database
|
||||
chown root:root /var/lib/aide/aide.db
|
||||
chmod 600 /var/lib/aide/aide.db
|
||||
|
||||
# Create AIDE check script
|
||||
cat > /usr/local/bin/aide-check.sh << 'EOF'
|
||||
#!/bin/bash
|
||||
# Football System - AIDE Integrity Check
|
||||
# Automated file integrity monitoring script
|
||||
|
||||
LOGFILE="/var/log/aide/aide_check.log"
|
||||
ERRORFILE="/var/log/aide/aide_error.log"
|
||||
DBFILE="/var/lib/aide/aide.db"
|
||||
REPORTFILE="/var/log/aide/aide_report_$(date +%Y%m%d_%H%M%S).txt"
|
||||
|
||||
# Function to log messages
|
||||
log_message() {
|
||||
local level=$1
|
||||
local message=$2
|
||||
echo "$(date '+%Y-%m-%d %H:%M:%S') [$level] $message" | tee -a "$LOGFILE"
|
||||
}
|
||||
|
||||
# Function to send alerts
|
||||
send_alert() {
|
||||
local message="$1"
|
||||
# Log to system log for security team monitoring
|
||||
logger -t "aide-check" -p auth.alert "$message"
|
||||
|
||||
# If email is configured, send alert
|
||||
if command -v mail >/dev/null 2>&1 && [ -n "$SECURITY_EMAIL" ]; then
|
||||
echo "$message" | mail -s "AIDE Integrity Alert - Football System" "$SECURITY_EMAIL"
|
||||
fi
|
||||
}
|
||||
|
||||
# Check if AIDE database exists
|
||||
if [ ! -f "$DBFILE" ]; then
|
||||
log_message "ERROR" "AIDE database not found at $DBFILE"
|
||||
send_alert "CRITICAL: AIDE database missing - File integrity monitoring compromised"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_message "INFO" "Starting AIDE integrity check"
|
||||
|
||||
# Run AIDE check
|
||||
if aide --check --config /etc/aide.conf > "$REPORTFILE" 2>>"$ERRORFILE"; then
|
||||
log_message "INFO" "AIDE check completed - No changes detected"
|
||||
|
||||
# Clean up empty report file
|
||||
[ -s "$REPORTFILE" ] || rm -f "$REPORTFILE"
|
||||
else
|
||||
local exit_code=$?
|
||||
log_message "WARNING" "AIDE check completed with exit code $exit_code"
|
||||
|
||||
# Check if report file has content (actual changes detected)
|
||||
if [ -s "$REPORTFILE" ]; then
|
||||
log_message "ALERT" "File integrity changes detected - See report: $REPORTFILE"
|
||||
send_alert "SECURITY ALERT: File integrity changes detected on Football System. Review $REPORTFILE"
|
||||
|
||||
# Log summary of changes
|
||||
local changed_files=$(grep -c "^changed:" "$REPORTFILE" 2>/dev/null || echo "0")
|
||||
local added_files=$(grep -c "^added:" "$REPORTFILE" 2>/dev/null || echo "0")
|
||||
local removed_files=$(grep -c "^removed:" "$REPORTFILE" 2>/dev/null || echo "0")
|
||||
|
||||
log_message "ALERT" "Summary: $added_files added, $changed_files changed, $removed_files removed"
|
||||
else
|
||||
log_message "ERROR" "AIDE check failed - See error log: $ERRORFILE"
|
||||
send_alert "ERROR: AIDE integrity check failed on Football System"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Cleanup old reports (keep last 30 days)
|
||||
find /var/log/aide -name "aide_report_*.txt" -mtime +30 -delete 2>/dev/null
|
||||
|
||||
log_message "INFO" "AIDE integrity check completed"
|
||||
EOF
|
||||
|
||||
# Make the check script executable
|
||||
chmod 750 /usr/local/bin/aide-check.sh
|
||||
chown root:root /usr/local/bin/aide-check.sh
|
||||
|
||||
# Create AIDE update script
|
||||
cat > /usr/local/bin/aide-update.sh << 'EOF'
|
||||
#!/bin/bash
|
||||
# Football System - AIDE Database Update
|
||||
# Updates AIDE database after legitimate system changes
|
||||
|
||||
LOGFILE="/var/log/aide/aide_update.log"
|
||||
DBFILE="/var/lib/aide/aide.db"
|
||||
NEWDBFILE="/var/lib/aide/aide.db.new"
|
||||
|
||||
# Function to log messages
|
||||
log_message() {
|
||||
local level=$1
|
||||
local message=$2
|
||||
echo "$(date '+%Y-%m-%d %H:%M:%S') [$level] $message" | tee -a "$LOGFILE"
|
||||
}
|
||||
|
||||
# Check for valid update reason
|
||||
if [ $# -eq 0 ]; then
|
||||
echo "Usage: $0 <reason>"
|
||||
echo "Example: $0 'System package updates'"
|
||||
echo "Example: $0 'Configuration change for service X'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
REASON="$1"
|
||||
log_message "INFO" "Starting AIDE database update - Reason: $REASON"
|
||||
|
||||
# Create backup of current database
|
||||
if [ -f "$DBFILE" ]; then
|
||||
cp "$DBFILE" "${DBFILE}.backup_$(date +%Y%m%d_%H%M%S)"
|
||||
log_message "INFO" "Created backup of current database"
|
||||
fi
|
||||
|
||||
# Run AIDE update
|
||||
log_message "INFO" "Updating AIDE database..."
|
||||
if aide --update --config /etc/aide.conf; then
|
||||
# Activate new database
|
||||
if [ -f "$NEWDBFILE" ]; then
|
||||
mv "$NEWDBFILE" "$DBFILE"
|
||||
log_message "INFO" "AIDE database updated and activated successfully"
|
||||
|
||||
# Set proper permissions
|
||||
chmod 600 "$DBFILE"
|
||||
chown root:root "$DBFILE"
|
||||
|
||||
log_message "INFO" "Database update completed - Reason: $REASON"
|
||||
else
|
||||
log_message "ERROR" "AIDE update completed but new database not found"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
log_message "ERROR" "AIDE database update failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Run a quick check to verify database
|
||||
log_message "INFO" "Verifying updated database..."
|
||||
if aide --check --config /etc/aide.conf >/dev/null 2>&1; then
|
||||
log_message "INFO" "Database verification successful"
|
||||
else
|
||||
log_message "WARNING" "Database verification shows differences (expected after update)"
|
||||
fi
|
||||
|
||||
log_message "INFO" "AIDE database update process completed"
|
||||
EOF
|
||||
|
||||
# Make the update script executable
|
||||
chmod 750 /usr/local/bin/aide-update.sh
|
||||
chown root:root /usr/local/bin/aide-update.sh
|
||||
|
||||
# Create AIDE cron configuration
|
||||
cat > /etc/cron.d/aide-check << 'EOF'
|
||||
# Football System - AIDE Integrity Monitoring
|
||||
# Run AIDE checks every 6 hours (4 times daily)
|
||||
|
||||
# Hourly quick check (only critical files)
|
||||
5 * * * * root /usr/local/bin/aide-check.sh --critical >/dev/null 2>&1
|
||||
|
||||
# Full integrity check every 6 hours
|
||||
5 0,6,12,18 * * * root /usr/local/bin/aide-check.sh >/dev/null 2>&1
|
||||
|
||||
# Weekly database maintenance
|
||||
5 3 * * 0 root /usr/local/bin/aide-update.sh "Scheduled weekly maintenance" >/dev/null 2>&1
|
||||
EOF
|
||||
|
||||
# Set proper permissions on cron configuration
|
||||
chmod 644 /etc/cron.d/aide-check
|
||||
chown root:root /etc/cron.d/aide-check
|
||||
|
||||
# Create systemd service for AIDE monitoring
|
||||
cat > /etc/systemd/system/aide-check.service << 'EOF'
|
||||
[Unit]
|
||||
Description=AIDE File Integrity Check
|
||||
Documentation=man:aide(8)
|
||||
After=auditd.service
|
||||
Wants=auditd.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/local/bin/aide-check.sh
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
|
||||
# Security settings
|
||||
NoNewPrivileges=yes
|
||||
ProtectSystem=strict
|
||||
ProtectHome=yes
|
||||
ReadWritePaths=/var/log/aide
|
||||
PrivateTmp=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
# Create systemd timer for periodic checks
|
||||
cat > /etc/systemd/system/aide-check.timer << 'EOF'
|
||||
[Unit]
|
||||
Description=Run AIDE integrity checks every 6 hours
|
||||
Requires=aide-check.service
|
||||
|
||||
[Timer]
|
||||
OnCalendar=*-*-* 0,6,12,18:05:00
|
||||
Persistent=true
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
EOF
|
||||
|
||||
# Enable and start the timer
|
||||
systemctl daemon-reload
|
||||
systemctl enable aide-check.timer
|
||||
systemctl start aide-check.timer
|
||||
|
||||
# Create AIDE log rotation configuration
|
||||
cat > /etc/logrotate.d/aide << 'EOF'
|
||||
# Football System - AIDE Log Rotation
|
||||
|
||||
/var/log/aide/*.log {
|
||||
daily
|
||||
rotate 90
|
||||
compress
|
||||
delaycompress
|
||||
missingok
|
||||
notifempty
|
||||
create 0640 root adm
|
||||
sharedscripts
|
||||
postrotate
|
||||
systemctl reload rsyslog >/dev/null 2>&1 || true
|
||||
endscript
|
||||
}
|
||||
|
||||
/var/log/aide/aide_report_*.txt {
|
||||
daily
|
||||
rotate 30
|
||||
compress
|
||||
delaycompress
|
||||
missingok
|
||||
notifempty
|
||||
create 0640 root adm
|
||||
}
|
||||
EOF
|
||||
|
||||
# Set proper permissions
|
||||
chmod 644 /etc/logrotate.d/aide
|
||||
chown root:root /etc/logrotate.d/aide
|
||||
|
||||
# Run initial AIDE check
|
||||
if [ "$FIRST_RUN" = "true" ]; then
|
||||
echo "Running initial AIDE integrity check..."
|
||||
if /usr/local/bin/aide-check.sh; then
|
||||
echo "✅ Initial AIDE check completed successfully"
|
||||
else
|
||||
echo "⚠️ Initial AIDE check completed with warnings (expected for new system)"
|
||||
fi
|
||||
else
|
||||
echo "✅ AIDE database updated successfully"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "AIDE Configuration Summary:"
|
||||
echo "- Database location: /var/lib/aide/aide.db"
|
||||
echo "- Log directory: /var/log/aide/"
|
||||
echo "- Check script: /usr/local/bin/aide-check.sh"
|
||||
echo "- Update script: /usr/local/bin/aide-update.sh"
|
||||
echo "- Systemd timer: aide-check.timer (runs every 6 hours)"
|
||||
echo "- Cron backup: /etc/cron.d/aide-check"
|
||||
echo ""
|
||||
echo "Manual commands:"
|
||||
echo "- Run integrity check: aide-check.sh"
|
||||
echo "- Update database: aide-update.sh '<reason>'"
|
||||
echo "- Check service status: systemctl status aide-check.timer"
|
||||
echo "- View logs: journalctl -u aide-check.service"
|
||||
echo ""
|
||||
echo "✅ AIDE initialization and configuration completed"
|
||||
297
config/aide.conf
Normal file
297
config/aide.conf
Normal file
@@ -0,0 +1,297 @@
|
||||
# AIDE Configuration for Football Secure Access System
|
||||
# Comprehensive file integrity monitoring
|
||||
|
||||
# Configuration file location
|
||||
@@define DBDIR /var/lib/aide
|
||||
@@define LOGDIR /var/log/aide
|
||||
@@define SYSCONFDIR /etc
|
||||
@@define BINDIR /usr/bin
|
||||
@@define SBINDIR /usr/sbin
|
||||
@@define LIBDIR /usr/lib
|
||||
@@define LOCALSTATEDIR /var/local
|
||||
|
||||
# File selection rules
|
||||
All=p+i+n+u+g+s+m+c+md5+sha1+rmd160+tiger
|
||||
|
||||
# Database locations
|
||||
database=file:@@{DBDIR}/aide.db
|
||||
database_out=file:@@{DBDIR}/aide.db.new
|
||||
|
||||
# Log file
|
||||
log_file=@@{LOGDIR}/aide.log
|
||||
|
||||
# Monitoring scope
|
||||
|
||||
# Root filesystem
|
||||
/bin All
|
||||
/sbin All
|
||||
/usr/bin All
|
||||
/usr/sbin All
|
||||
/usr/local/bin All
|
||||
/usr/local/sbin All
|
||||
|
||||
# Configuration directories
|
||||
/etc All
|
||||
/etc/X11 All
|
||||
/etc/opt All
|
||||
/etc/sgml All
|
||||
/etc/xml All
|
||||
/etc/default All
|
||||
/etc/init.d All
|
||||
/etc/init All
|
||||
/etc/rc*.d All
|
||||
/etc/udev All
|
||||
/etc/rsyslog.d All
|
||||
/etc/network All
|
||||
/etc/wireguard All
|
||||
|
||||
# Security-critical directories
|
||||
/etc/security All
|
||||
/etc/sudoers.d All
|
||||
/etc/apparmor.d All
|
||||
/etc/apparmor All
|
||||
/etc/fail2ban All
|
||||
/etc/audit All
|
||||
/etc/pam.d All
|
||||
/etc/ssh All
|
||||
|
||||
# Boot-related directories
|
||||
/boot All
|
||||
/boot/grub All
|
||||
/boot/grub.cfg All
|
||||
/boot/efi All
|
||||
/boot/efi/EFI All
|
||||
/boot/efi/EFI/debian All
|
||||
/boot/efi/EFI/BOOT All
|
||||
|
||||
# Kernel modules
|
||||
/lib/modules All
|
||||
/lib/firmware All
|
||||
|
||||
# System libraries
|
||||
/lib All
|
||||
/lib64 All
|
||||
/usr/lib All
|
||||
/usr/lib64 All
|
||||
/usr/local/lib All
|
||||
/usr/local/lib64 All
|
||||
|
||||
# User directories (monitor for changes)
|
||||
/home/user All
|
||||
/home/user/.config All
|
||||
/home/user/.local All
|
||||
/home/user/.ssh All
|
||||
|
||||
# Root user directories
|
||||
/root All
|
||||
|
||||
# System state
|
||||
/var All
|
||||
!/var/log
|
||||
!/var/run
|
||||
!/var/lock
|
||||
!/var/tmp
|
||||
!/var/spool
|
||||
!/var/cache
|
||||
!/var/mail
|
||||
!/var/lib/aide
|
||||
|
||||
# Temporary directories
|
||||
!/tmp
|
||||
!/var/tmp
|
||||
!/var/cache
|
||||
!/var/spool
|
||||
|
||||
# Application-specific monitoring
|
||||
|
||||
# Remmina configuration
|
||||
/home/user/.config/remmina All
|
||||
/usr/bin/remmina All
|
||||
/usr/share/applications/remmina.desktop All
|
||||
|
||||
# IceWM configuration
|
||||
/home/user/.config/icewm All
|
||||
/usr/bin/icewm All
|
||||
/usr/share/icewm All
|
||||
|
||||
# Network configuration
|
||||
/etc/network/interfaces All
|
||||
/etc/NetworkManager All
|
||||
/etc/resolv.conf All
|
||||
/etc/hosts All
|
||||
/etc/hostname All
|
||||
|
||||
# Package management
|
||||
/etc/apt All
|
||||
/var/lib/apt All
|
||||
/var/cache/apt All
|
||||
/usr/bin/apt All
|
||||
/usr/bin/apt-get All
|
||||
/usr/bin/dpkg All
|
||||
|
||||
# Audit system
|
||||
/etc/audit All
|
||||
/var/log/audit All
|
||||
/usr/sbin/auditd All
|
||||
/usr/sbin/aureport All
|
||||
/usr/sbin/ausearch All
|
||||
|
||||
# Rsyslog
|
||||
/etc/rsyslog* All
|
||||
/usr/sbin/rsyslogd All
|
||||
/var/log/security All
|
||||
|
||||
# Firewall configuration
|
||||
/etc/iptables All
|
||||
/etc/nftables.conf All
|
||||
/etc/ufw All
|
||||
/usr/sbin/iptables All
|
||||
/usr/sbin/nft All
|
||||
|
||||
# VPN configuration
|
||||
/etc/wireguard All
|
||||
/usr/bin/wg All
|
||||
/usr/bin/wg-quick All
|
||||
|
||||
# Security tools
|
||||
/usr/bin/aide All
|
||||
/etc/aide.conf All
|
||||
/usr/sbin/fail2ban-server All
|
||||
/etc/fail2ban All
|
||||
|
||||
# GRUB bootloader
|
||||
/etc/default/grub All
|
||||
/etc/grub.d All
|
||||
/usr/sbin/grub-install All
|
||||
/usr/sbin/grub-mkconfig All
|
||||
|
||||
# Systemd configuration
|
||||
/etc/systemd All
|
||||
/lib/systemd All
|
||||
/usr/lib/systemd All
|
||||
/etc/systemd/system All
|
||||
/run/systemd All
|
||||
|
||||
# Cryptographic libraries
|
||||
/lib/x86_64-linux-gnu/security All
|
||||
/usr/lib/x86_64-linux-gnu/security All
|
||||
/lib/security All
|
||||
|
||||
# SSL/TLS certificates
|
||||
/etc/ssl All
|
||||
/etc/pki All
|
||||
/usr/local/share/ca-certificates All
|
||||
/etc/ca-certificates All
|
||||
|
||||
# SSH configuration and keys
|
||||
/etc/ssh/sshd_config All
|
||||
/etc/ssh/sshd_config.d All
|
||||
/root/.ssh All
|
||||
/home/user/.ssh All
|
||||
|
||||
# Sudoers configuration
|
||||
/etc/sudoers All
|
||||
/etc/sudoers.d All
|
||||
/usr/bin/sudo All
|
||||
/usr/sbin/visudo All
|
||||
|
||||
# PAM authentication
|
||||
/etc/pam.d All
|
||||
/lib/security All
|
||||
/usr/lib/security All
|
||||
/etc/security All
|
||||
|
||||
# Password and shadow files
|
||||
/etc/passwd All
|
||||
/etc/shadow All
|
||||
/etc/group All
|
||||
/etc/gshadow All
|
||||
|
||||
# AppArmor profiles
|
||||
/etc/apparmor All
|
||||
/etc/apparmor.d All
|
||||
/usr/sbin/apparmor_status All
|
||||
/usr/sbin/aa-status All
|
||||
|
||||
# Secure Boot keys
|
||||
/etc/secure-boot All
|
||||
|
||||
# Linux kernel
|
||||
/boot/vmlinu* All
|
||||
/boot/initrd* All
|
||||
/boot/System.map* All
|
||||
/boot/config* All
|
||||
|
||||
# Device nodes (monitor for suspicious changes)
|
||||
/dev All
|
||||
!/dev/pts
|
||||
!/dev/shm
|
||||
!/proc
|
||||
!/sys
|
||||
|
||||
# Proc filesystem (read-only monitoring)
|
||||
/proc/version Normal
|
||||
/proc/cpuinfo Normal
|
||||
/proc/meminfo Normal
|
||||
/proc/uptime Normal
|
||||
/proc/loadavg Normal
|
||||
/proc/version Normal
|
||||
/proc/mounts Normal
|
||||
/proc/filesystems Normal
|
||||
/proc/swaps Normal
|
||||
|
||||
# System filesystem
|
||||
/sys All
|
||||
|
||||
# Exclusion patterns (for dynamic content)
|
||||
|
||||
# Log files (too dynamic for integrity checking)
|
||||
!/var/log/*
|
||||
!/var/log/security/*
|
||||
!/var/log/audit/*
|
||||
!/var/log/aide/*
|
||||
|
||||
# Temporary and cache files
|
||||
!/tmp/*
|
||||
!/var/tmp/*
|
||||
!/var/cache/*
|
||||
!/var/spool/*
|
||||
!/var/run/*
|
||||
!/var/lock/*
|
||||
|
||||
# PID files
|
||||
!/var/run/*.pid
|
||||
|
||||
# Lock files
|
||||
!/var/lock/*
|
||||
|
||||
# Database files that change frequently
|
||||
!/var/lib/locate/*
|
||||
!/var/lib/mlocate/*
|
||||
!/var/lib/updatedb/*
|
||||
|
||||
# Package cache
|
||||
!/var/cache/apt/archives/*.deb
|
||||
|
||||
# Compilation artifacts
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
*.pyc
|
||||
*.pyo
|
||||
|
||||
# Editor backup files
|
||||
*~
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# Version control directories
|
||||
!.git
|
||||
!.svn
|
||||
!.hg
|
||||
|
||||
# AIDE's own database and log files
|
||||
!@@{DBDIR}/*
|
||||
!@@{LOGDIR}/*
|
||||
|
||||
# End of configuration
|
||||
121
config/cis-audit.rules
Normal file
121
config/cis-audit.rules
Normal file
@@ -0,0 +1,121 @@
|
||||
# CIS Debian 13 Benchmark - Comprehensive Audit Rules
|
||||
# Implements CIS recommendations for comprehensive system auditing
|
||||
|
||||
# Delete all existing rules
|
||||
-D
|
||||
|
||||
# Increase buffer size for audit daemon
|
||||
-b 8192
|
||||
|
||||
# Monitor kernel module loading and unloading
|
||||
-w /usr/bin/kmod -p x -k modules
|
||||
-w /usr/bin/insmod -p x -k modules
|
||||
-w /usr/bin/rmmod -p x -k modules
|
||||
-w /usr/bin/modprobe -p x -k modules
|
||||
-w /etc/modules -p wa -k modules
|
||||
-w /etc/modprobe.d -p wa -k modules
|
||||
|
||||
# Monitor file system mounts and unmounts
|
||||
-a always,exit -F arch=b64 -S mount,umount2 -F auid>=1000 -F auid!=4294967295 -k mounts
|
||||
-a always,exit -F arch=b32 -S mount,umount2 -F auid>=1000 -F auid!=4294967295 -k mounts
|
||||
|
||||
# Monitor changes to system time
|
||||
-a always,exit -F arch=b64 -S adjtimex,settimeofday -F auid>=1000 -F auid!=4294967295 -k time
|
||||
-a always,exit -F arch=b32 -S adjtimex,settimeofday,time -F auid>=1000 -F auid!=4294967295 -k time
|
||||
-a always,exit -F arch=b64 -S clock_settime -F a0=0 -F auid>=1000 -F auid!=4294967295 -k time
|
||||
-a always,exit -F arch=b32 -S clock_settime -F a0=0 -F auid>=1000 -F auid!=4294967295 -k time
|
||||
|
||||
# Monitor user and group administration
|
||||
-w /etc/group -p wa -k identity
|
||||
-w /etc/passwd -p wa -k identity
|
||||
-w /etc/gshadow -p wa -k identity
|
||||
-w /etc/shadow -p wa -k identity
|
||||
-w /etc/sudoers -p wa -k identity
|
||||
-w /etc/sudoers.d -p wa -k identity
|
||||
|
||||
# Monitor network configuration
|
||||
-w /etc/hosts -p wa -k network
|
||||
-w /etc/hostname -p wa -k network
|
||||
-w /etc/network/ -p wa -k network
|
||||
-w /etc/resolv.conf -p wa -k network
|
||||
|
||||
# Monitor crontab and scheduled jobs
|
||||
-w /etc/crontab -p wa -k cron
|
||||
-w /etc/cron.d -p wa -k cron
|
||||
-w /etc/cron.daily -p wa -k cron
|
||||
-w /etc/cron.hourly -p wa -k cron
|
||||
-w /etc/cron.monthly -p wa -k cron
|
||||
-w /etc/cron.weekly -p wa -k cron
|
||||
-w /etc/cron.allow -p wa -k cron
|
||||
-w /etc/cron.deny -p wa -k cron
|
||||
-w /var/spool/cron -p wa -k cron
|
||||
|
||||
# Monitor login, logout, and authentication events
|
||||
-w /var/log/faillog -p wa -k logins
|
||||
-w /var/log/lastlog -p wa -k logins
|
||||
-w /var/log/tallylog -p wa -k logins
|
||||
-w /var/run/faillock -p wa -k logins
|
||||
|
||||
# Monitor privileged commands
|
||||
-a always,exit -F path=/usr/bin/sudo -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
|
||||
-a always,exit -F path=/usr/bin/su -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
|
||||
-a always,exit -F path=/usr/bin/newgrp -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
|
||||
-a always,exit -F path=/usr/bin/chsh -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
|
||||
-a always,exit -F path=/usr/bin/ssh-agent -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
|
||||
-a always,exit -F path=/usr/bin/gpg-agent -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
|
||||
|
||||
# Monitor security related files
|
||||
-w /etc/apparmor -p wa -k apparmor
|
||||
-w /etc/apparmor.d -p wa -k apparmor
|
||||
-w /etc/security -p wa -k security
|
||||
-w /etc/security/limits.d -p wa -k security
|
||||
-w /etc/security/pam.d -p wa -k security
|
||||
|
||||
# Monitor system calls that create files
|
||||
-a always,exit -F arch=b64 -S creat -S open -S openat -S open_by_handle_at -S truncate -S ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=4294967295 -k access
|
||||
-a always,exit -F arch=b32 -S creat -S open -S openat -S open_by_handle_at -S truncate -S ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=4294967295 -k access
|
||||
|
||||
# Monitor failed file access
|
||||
-a always,exit -F arch=b64 -S open,openat,open_by_handle_at -F exit=-EACCES -F auid>=1000 -F auid!=4294967295 -k access
|
||||
-a always,exit -F arch=b32 -S open,openat,open_by_handle_at -F exit=-EACCES -F auid>=1000 -F auid!=4294967295 -k access
|
||||
|
||||
# Monitor execve system calls
|
||||
-a always,exit -F arch=b64 -S execve -F auid>=1000 -F auid!=4294967295 -k exec
|
||||
-a always,exit -F arch=b32 -S execve -F auid>=1000 -F auid!=4294967295 -k exec
|
||||
|
||||
# Monitor chmod, chown, and chmod system calls
|
||||
-a always,exit -F arch=b64 -S chmod,chown,fchmod,fchmodat,fchown,fchownat,fremovexattr,lchown,setxattr -F auid>=1000 -F auid!=4294967295 -k perm_mod
|
||||
-a always,exit -F arch=b32 -S chmod,chown,fchmod,fchmodat,fchown,fchownat,fremovexattr,lchown,setxattr -F auid>=1000 -F auid!=4294967295 -k perm_mod
|
||||
|
||||
# Monitor unlink, unlinkat, rename, and renameat system calls
|
||||
-a always,exit -F arch=b64 -S unlink,unlinkat,rename,renameat -F auid>=1000 -F auid!=4294967295 -k delete
|
||||
-a always,exit -F arch=b32 -S unlink,unlinkat,rename,renameat -F auid>=1000 -F auid!=4294967295 -k delete
|
||||
|
||||
# Monitor file and directory creation
|
||||
-a always,exit -F arch=b64 -S mkdir,mkdirat,mknod,mknodat -F auid>=1000 -F auid!=4294967295 -k create
|
||||
-a always,exit -F arch=b32 -S mkdir,mkdirat,mknod,mknodat -F auid>=1000 -F auid!=4294967295 -k create
|
||||
|
||||
# Monitor process execution and ID changes
|
||||
-a always,exit -F arch=b64 -S setuid,setgid,setreuid,setregid -F auid>=1000 -F auid!=4294967295 -k setuid
|
||||
-a always,exit -F arch=b32 -S setuid,setgid,setreuid,setregid -F auid>=1000 -F auid!=4294967295 -k setuid
|
||||
|
||||
# Monitor kernel module loading
|
||||
-w /proc/sys/kernel/modules_disabled -p wa -k modules
|
||||
|
||||
# Monitor IPv6 configuration
|
||||
-w /etc/sysconfig/network -p wa -k network
|
||||
-w /etc/sysconfig/network-scripts -p wa -k network
|
||||
|
||||
# Monitor init and systemd
|
||||
-w /etc/inittab -p wa -k init
|
||||
-w /etc/init.d -p wa -k init
|
||||
-w /etc/init -p wa -k init
|
||||
-w /etc/systemd -p wa -k init
|
||||
-w /usr/lib/systemd -p wa -k init
|
||||
|
||||
# Monitor audit logs
|
||||
-w /var/log/audit/ -p wa -k audit_logs
|
||||
-w /var/log/audit.log -p wa -k audit_logs
|
||||
|
||||
# Ensure audit rules are loaded on boot
|
||||
-e 2
|
||||
119
config/cis-hardening-sudoers
Normal file
119
config/cis-hardening-sudoers
Normal file
@@ -0,0 +1,119 @@
|
||||
# CIS Debian 13 Benchmark - Sudo Hardening Configuration
|
||||
# Implements CIS recommendations for secure sudo usage
|
||||
|
||||
# Default sudoers configuration
|
||||
Defaults env_reset
|
||||
Defaults timestamp_timeout=15
|
||||
Defaults lecture=always
|
||||
Defaults lecture_file=/etc/sudoers.d/lecture
|
||||
Defaults badpass_message="Authentication failed. Please check your password and try again."
|
||||
Defaults passwd_tries=3
|
||||
Defaults log_input,log_output
|
||||
Defaults iolog_dir=/var/log/sudo-io
|
||||
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
|
||||
# Security restrictions
|
||||
Defaults requiretty
|
||||
Defaults use_pty
|
||||
Defaults env_delete="FTP_PROXY HTTP_PROXY HTTPS_PROXY no_proxy"
|
||||
Defaults logfile="/var/log/security/sudo.log"
|
||||
Defaults syslog=authpriv
|
||||
|
||||
# Prevent access to sudoedit in uncontrolled environments
|
||||
Defaults editor=/usr/bin/nano
|
||||
|
||||
# Password confirmation for sensitive commands
|
||||
Defaults !authenticate for /usr/bin/apt-get, /usr/bin/apt, /usr/bin/dpkg
|
||||
Defaults authenticate
|
||||
|
||||
# User and group specifications
|
||||
root ALL=(ALL:ALL) ALL
|
||||
%wheel ALL=(ALL:ALL) ALL
|
||||
|
||||
# Specialized command restrictions
|
||||
# Allow user to mount/unmount USB devices
|
||||
user ALL=(root) NOPASSWD: /bin/mount, /bin/umount
|
||||
user ALL=(root) NOPASSWD: /usr/bin/udisksctl
|
||||
|
||||
# Allow user to check system status (read-only operations)
|
||||
user ALL=(root) NOPASSWD: /usr/bin/free, /usr/bin/df, /usr/bin/ps, /usr/bin/top
|
||||
user ALL=(root) NOPASSWD: /usr/bin/tail, /usr/bin/cat, /usr/bin/grep, /usr/bin/less
|
||||
user ALL=(root) NOPASSWD: /usr/bin/systemctl status, /usr/bin/journalctl
|
||||
|
||||
# Allow user to manage network interfaces for VPN
|
||||
user ALL=(root) NOPASSWD: /usr/bin/wg, /usr/sbin/ip
|
||||
user ALL=(root) NOPASSWD: /usr/bin/ping, /usr/bin/traceroute
|
||||
|
||||
# Allow user to run system verification scripts
|
||||
user ALL=(root) NOPASSWD: /usr/local/bin/verify-system.sh
|
||||
|
||||
# Administrative commands require password and are restricted
|
||||
%admin ALL=(ALL) ALL
|
||||
%sudo ALL=(ALL:ALL) ALL
|
||||
|
||||
# Security audit commands restricted to admin
|
||||
%wheel ALL=(root) /usr/sbin/auditctl, /usr/sbin/aureport, /usr/sbin/aureport, /usr/sbin/ausearch
|
||||
%wheel ALL=(root) /usr/bin/aide, /usr/sbin/aideinit
|
||||
|
||||
# System update commands
|
||||
%wheel ALL=(root) /usr/bin/apt-get, /usr/bin/apt, /usr/bin/dpkg
|
||||
%wheel ALL=(root) /usr/bin/aptitude, /usr/bin/apt-cache
|
||||
|
||||
# System service management
|
||||
%wheel ALL=(root) /usr/bin/systemctl, /usr/bin/service, /usr/sbin/service
|
||||
|
||||
# Firewall management
|
||||
%wheel ALL=(root) /usr/sbin/iptables, /usr/sbin/ip6tables, /usr/sbin/nft
|
||||
|
||||
# User management
|
||||
%wheel ALL=(root) /usr/sbin/useradd, /usr/sbin/userdel, /usr/sbin/usermod
|
||||
%wheel ALL=(root) /usr/sbin/groupadd, /usr/sbin/groupdel, /usr/sbin/groupmod
|
||||
|
||||
# Emergency commands (full password required)
|
||||
%wheel ALL=(root) /usr/sbin/reboot, /usr/sbin/shutdown, /usr/sbin/halt
|
||||
%wheel ALL=(root) /usr/bin/poweroff, /usr/sbin/init
|
||||
|
||||
# Path restrictions
|
||||
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"
|
||||
|
||||
# Command restrictions by directory
|
||||
Defaults !visiblepw in /etc/sudoers.d/
|
||||
Defaults always_set_home in /etc/sudoers.d/
|
||||
Defaults match_group_by_gid in /etc/sudoers.d/
|
||||
|
||||
# Environment variable restrictions
|
||||
Defaults env_reset
|
||||
Defaults env_delete="BASH_ENV ENV SHELL HOME TERM PS1 LS_COLORS EDITOR PAGER LANG LC_ALL"
|
||||
Defaults env_keep="COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS PATH PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE LC_TIME XAUTHORIZATION XAUTHORITY"
|
||||
|
||||
# Sudo I/O logging for privileged commands
|
||||
Defaults log_output, log_input
|
||||
Defaults iolog_dir="/var/log/sudo-io/%{user}"
|
||||
Defaults iolog_file="/var/log/sudo-io/%{user}/%{seq}"
|
||||
|
||||
# Audit logging
|
||||
Defaults loglinelen=0
|
||||
Defaults log_host
|
||||
Defaults log_year
|
||||
Defaults syslog=authpriv
|
||||
|
||||
# TTY requirements for security
|
||||
Defaults use_pty
|
||||
Defaults requiretty
|
||||
|
||||
# Timeout configurations
|
||||
Defaults timestamp_timeout=15
|
||||
Defaults passwd_tries=3
|
||||
Defaults lecture=always
|
||||
Defaults lecture_file=/etc/sudoers.d/lecture
|
||||
|
||||
# Secure path
|
||||
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
|
||||
# No shared sudo tickets
|
||||
Defaults !tty_tickets
|
||||
|
||||
# Network restrictions
|
||||
Defaults !visiblepw
|
||||
Defaults !authenticate for /usr/bin/apt-get, /usr/bin/apt, /usr/bin/dpkg
|
||||
Defaults authenticate
|
||||
215
config/cis-logs
Normal file
215
config/cis-logs
Normal file
@@ -0,0 +1,215 @@
|
||||
# CIS Debian 13 Benchmark - Log Rotation Configuration
|
||||
# Implements CIS recommendations for secure log rotation
|
||||
|
||||
# Global rotation settings
|
||||
weekly
|
||||
rotate 52
|
||||
compress
|
||||
delaycompress
|
||||
missingok
|
||||
notifempty
|
||||
create 0640 root adm
|
||||
sharedscripts
|
||||
|
||||
# Security logs - longer retention
|
||||
/var/log/security/*.log {
|
||||
weekly
|
||||
rotate 104
|
||||
compress
|
||||
delaycompress
|
||||
missingok
|
||||
notifempty
|
||||
create 0640 root adm
|
||||
sharedscripts
|
||||
postrotate
|
||||
/usr/lib/rsyslog/rsyslog-rotate &>/dev/null || true
|
||||
endscript
|
||||
}
|
||||
|
||||
# Authentication logs - high retention for forensic analysis
|
||||
/var/log/security/auth.log /var/log/security/failed.log /var/log/security/login.log {
|
||||
daily
|
||||
rotate 365
|
||||
compress
|
||||
delaycompress
|
||||
missingok
|
||||
notifempty
|
||||
create 0640 root adm
|
||||
sharedscripts
|
||||
postrotate
|
||||
/usr/lib/rsyslog/rsyslog-rotate &>/dev/null || true
|
||||
endscript
|
||||
}
|
||||
|
||||
# Sudo logs - longer retention for audit purposes
|
||||
/var/log/security/sudo.log {
|
||||
daily
|
||||
rotate 365
|
||||
compress
|
||||
delaycompress
|
||||
missingok
|
||||
notifempty
|
||||
create 0640 root adm
|
||||
sharedscripts
|
||||
postrotate
|
||||
/usr/lib/rsyslog/rsyslog-rotate &>/dev/null || true
|
||||
endscript
|
||||
}
|
||||
|
||||
# Audit logs - longer retention for compliance
|
||||
/var/log/security/audit.log /var/log/audit/*.log {
|
||||
weekly
|
||||
rotate 104
|
||||
compress
|
||||
delaycompress
|
||||
missingok
|
||||
notifempty
|
||||
create 0640 root adm
|
||||
sharedscripts
|
||||
postrotate
|
||||
/usr/lib/rsyslog/rsyslog-rotate &>/dev/null || true
|
||||
endscript
|
||||
}
|
||||
|
||||
# System logs - standard retention
|
||||
/var/log/security/messages /var/log/security/kern.log /var/log/security/daemon.log {
|
||||
weekly
|
||||
rotate 52
|
||||
compress
|
||||
delaycompress
|
||||
missingok
|
||||
notifempty
|
||||
create 0640 root adm
|
||||
sharedscripts
|
||||
postrotate
|
||||
/usr/lib/rsyslog/rsyslog-rotate &>/dev/null || true
|
||||
endscript
|
||||
}
|
||||
|
||||
# Network logs - standard retention
|
||||
/var/log/security/network.log {
|
||||
weekly
|
||||
rotate 52
|
||||
compress
|
||||
delaycompress
|
||||
missingok
|
||||
notifempty
|
||||
create 0640 root adm
|
||||
sharedscripts
|
||||
postrotate
|
||||
/usr/lib/rsyslog/rsyslog-rotate &>/dev/null || true
|
||||
endscript
|
||||
}
|
||||
|
||||
# Security alerts - longer retention for incident analysis
|
||||
/var/log/security/alerts.log {
|
||||
daily
|
||||
rotate 730
|
||||
compress
|
||||
delaycompress
|
||||
missingok
|
||||
notifempty
|
||||
create 0640 root adm
|
||||
sharedscripts
|
||||
postrotate
|
||||
/usr/lib/rsyslog/rsyslog-rotate &>/dev/null || true
|
||||
endscript
|
||||
}
|
||||
|
||||
# AIDE integrity check logs
|
||||
/var/log/aide/*.log {
|
||||
weekly
|
||||
rotate 104
|
||||
compress
|
||||
delaycompress
|
||||
missingok
|
||||
notifempty
|
||||
create 0640 root adm
|
||||
}
|
||||
|
||||
# Fail2ban logs
|
||||
/var/log/fail2ban.log {
|
||||
weekly
|
||||
rotate 52
|
||||
compress
|
||||
delaycompress
|
||||
missingok
|
||||
notifempty
|
||||
create 0640 root adm
|
||||
sharedscripts
|
||||
postrotate
|
||||
service fail2ban reload >/dev/null 2>&1 || true
|
||||
endscript
|
||||
}
|
||||
|
||||
# Application logs - standard rotation
|
||||
/var/log/remmina/*.log {
|
||||
weekly
|
||||
rotate 12
|
||||
compress
|
||||
delaycompress
|
||||
missingok
|
||||
notifempty
|
||||
create 0640 user user
|
||||
}
|
||||
|
||||
# IceWM logs - standard rotation
|
||||
/var/log/icewm/*.log {
|
||||
weekly
|
||||
rotate 12
|
||||
compress
|
||||
delaycompress
|
||||
missingok
|
||||
notifempty
|
||||
create 0640 user user
|
||||
}
|
||||
|
||||
# WireGuard logs - important for network security
|
||||
/var/log/wireguard/*.log {
|
||||
weekly
|
||||
rotate 52
|
||||
compress
|
||||
delaycompress
|
||||
missingok
|
||||
notifempty
|
||||
create 0640 root adm
|
||||
}
|
||||
|
||||
# Ensure secure permissions for all log directories
|
||||
/var/log/security/ /var/log/audit/ /var/log/aide/ {
|
||||
monthly
|
||||
rotate 1
|
||||
nocreate
|
||||
compress
|
||||
missingok
|
||||
postrotate
|
||||
find /var/log/security/ -type f -name "*.log" -exec chmod 0640 {} \;
|
||||
find /var/log/security/ -type d -exec chmod 0750 {} \;
|
||||
find /var/log/audit/ -type f -name "*.log" -exec chmod 0640 {} \;
|
||||
find /var/log/audit/ -type d -exec chmod 0750 {} \;
|
||||
find /var/log/aide/ -type f -name "*.log" -exec chmod 0640 {} \;
|
||||
find /var/log/aide/ -type d -exec chmod 0750 {} \;
|
||||
endscript
|
||||
}
|
||||
|
||||
# Summary log rotation for compliance reporting
|
||||
/var/log/security/summary.log {
|
||||
monthly
|
||||
rotate 60
|
||||
compress
|
||||
delaycompress
|
||||
missingok
|
||||
notifempty
|
||||
create 0640 root adm
|
||||
}
|
||||
|
||||
# Old system logs for historical reference
|
||||
/var/log/syslog /var/log/messages /var/log/kern.log {
|
||||
weekly
|
||||
rotate 4
|
||||
compress
|
||||
delaycompress
|
||||
missingok
|
||||
notifempty
|
||||
create 0640 root adm
|
||||
}
|
||||
70
config/common-password-cis
Normal file
70
config/common-password-cis
Normal file
@@ -0,0 +1,70 @@
|
||||
# CIS Debian 13 Benchmark - PAM Password Configuration
|
||||
# Implements CIS recommendations for password security
|
||||
|
||||
# Password quality enforcement using pwquality
|
||||
password requisite pam_pwquality.so try_first_pass retry=3 authtok_type=
|
||||
password [success=1 default=ignore] pam_unix.so obscure sha512 rounds=5000 use_authtok
|
||||
password sufficient pam_unix.so sha512 rounds=5000 nullok secure try_first_pass use_authtok
|
||||
password required pam_deny.so
|
||||
|
||||
# Account configuration
|
||||
account required pam_unix.so
|
||||
account sufficient pam_localuser.so
|
||||
account sufficient pam_succeed_if.so uid < 1000 quiet
|
||||
account required pam_permit.so
|
||||
|
||||
# Authentication configuration
|
||||
auth required pam_env.so
|
||||
auth required pam_faillock.so preauth audit silent deny=5 unlock_time=900
|
||||
auth [success=1 default=bad] pam_unix.so nullok try_first_pass
|
||||
auth [default=die] pam_faillock.so authfail audit deny=5 unlock_time=900
|
||||
auth sufficient pam_faillock.so authsucc audit deny=5 unlock_time=900
|
||||
auth required pam_permit.so
|
||||
|
||||
# Session configuration
|
||||
session required pam_limits.so
|
||||
session required pam_unix.so
|
||||
session optional pam_lastlog.so
|
||||
session optional pam_motd.so
|
||||
session optional pam_mail.so standard
|
||||
session required pam_env.so
|
||||
|
||||
# Password history - prevent reuse of last 5 passwords
|
||||
password required pam_pwhistory.so remember=5 use_authtok
|
||||
|
||||
# Session management for X11
|
||||
session optional pam_ck_connector.so nox11
|
||||
session optional pam_systemd.so
|
||||
|
||||
# Home directory creation (if needed)
|
||||
session required pam_mkhomedir.so skel=/etc/skel/ umask=077
|
||||
|
||||
# Security modules
|
||||
session optional pam_umask.so umask=077
|
||||
session optional pam_keyinit.so revoke
|
||||
|
||||
# Enhanced account lockout configuration
|
||||
auth required pam_faillock.so preauth silent audit deny=5 unlock_time=900 fail_interval=900 even_deny_root root_unlock_time=900
|
||||
auth sufficient pam_unix.so nullok try_first_pass
|
||||
auth [default=die] pam_faillock.so authfail audit deny=5 unlock_time=900 fail_interval=900 even_deny_root root_unlock_time=900
|
||||
auth sufficient pam_faillock.so authsucc audit deny=5 unlock_time=900 fail_interval=900 even_deny_root root_unlock_time=900
|
||||
auth required pam_permit.so
|
||||
|
||||
# Prevent empty passwords
|
||||
password required pam_unix.so nullok sha512 shadow try_first_pass use_authtok
|
||||
|
||||
# Session restrictions
|
||||
session required pam_limits.so
|
||||
session required pam_unix.so
|
||||
session required pam_lastlog.so showfailed
|
||||
session required pam_env.so readenv=1
|
||||
|
||||
# Additional security configurations
|
||||
account required pam_access.so accessfile=/etc/security/access.conf
|
||||
auth required pam_wheel.so trust use_uid
|
||||
auth optional pam_cap.so
|
||||
|
||||
# Enhanced logging
|
||||
auth optional pam_echo.so Football Secure Access System Authentication
|
||||
password optional pam_echo.so Password complexity requirements enforced
|
||||
session optional pam_echo.so Session monitoring enabled
|
||||
524
config/firewall-persistence.sh
Normal file
524
config/firewall-persistence.sh
Normal file
@@ -0,0 +1,524 @@
|
||||
#!/bin/bash
|
||||
# Football System Firewall Persistence Configuration
|
||||
# Ensures firewall rules persist across reboots with nftables
|
||||
|
||||
set -e
|
||||
|
||||
echo "Configuring firewall persistence..."
|
||||
|
||||
# Install required packages if not already installed
|
||||
apt-get update -qq
|
||||
apt-get install -y -qq \
|
||||
nftables \
|
||||
iptables-persistent \
|
||||
netfilter-persistent
|
||||
|
||||
# Create nftables configuration directory
|
||||
mkdir -p /etc/nftables.conf.d
|
||||
|
||||
# Main nftables configuration
|
||||
cat > /etc/nftables.conf << 'EOF'
|
||||
# Football System - nftables Configuration
|
||||
# Restrictive firewall rules for secure access
|
||||
|
||||
# Clear existing rules
|
||||
flush ruleset
|
||||
|
||||
# Table definitions
|
||||
table inet filter {
|
||||
# Chain definitions
|
||||
chain input {
|
||||
type filter hook input priority 0; policy drop;
|
||||
|
||||
# Allow loopback traffic
|
||||
iifname "lo" accept comment "Allow loopback"
|
||||
|
||||
# Allow established and related connections
|
||||
ct state established,related accept comment "Allow established/related"
|
||||
|
||||
# Drop invalid packets
|
||||
ct state invalid drop comment "Drop invalid packets"
|
||||
|
||||
# Allow ICMP (limited)
|
||||
ip protocol icmp icmp type { echo-request, echo-reply } limit rate 10/second burst 5 packets accept comment "Allow ping (rate limited)"
|
||||
ip6 nexthdr icmpv6 icmpv6 type { echo-request, echo-reply } limit rate 10/second burst 5 packets accept comment "Allow IPv6 ping (rate limited)"
|
||||
|
||||
# Allow required ICMP types
|
||||
ip protocol icmp icmp type { destination-unreachable, time-exceeded, parameter-problem } accept comment "Allow required ICMP"
|
||||
ip6 nexthdr icmpv6 icmpv6 type { destination-unreachable, time-exceeded, parameter-problem, packet-too-big, nd-router-solicit, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } accept comment "Allow required ICMPv6"
|
||||
|
||||
# SSH access (restricted to management network if configured)
|
||||
tcp dport 22 accept comment "Allow SSH (consider restricting)"
|
||||
|
||||
# Remmina/VNC access (only if needed)
|
||||
tcp dport { 5900, 5901 } accept comment "Allow VNC access"
|
||||
|
||||
# WireGuard VPN
|
||||
udp dport 51820 accept comment "Allow WireGuard VPN"
|
||||
|
||||
# DHCP client (if needed)
|
||||
udp sport { 67,68 } udp dport { 67,68 } accept comment "Allow DHCP"
|
||||
|
||||
# DNS client
|
||||
udp dport 53 ct state established,related accept comment "Allow DNS responses"
|
||||
|
||||
# NTP client
|
||||
udp dport 123 ct state established,related accept comment "Allow NTP responses"
|
||||
|
||||
# HTTP/HTTPS client traffic (outbound responses)
|
||||
tcp sport { 80,443 } ct state established,related accept comment "Allow web responses"
|
||||
|
||||
# Drop and log other traffic
|
||||
log prefix "NFT-INPUT-DROP: " drop comment "Log and drop other input"
|
||||
}
|
||||
|
||||
chain forward {
|
||||
type filter hook forward priority 0; policy drop;
|
||||
|
||||
# Allow forwarding for VPN traffic
|
||||
iifname "wg0" oifname != "wg0" accept comment "Allow VPN forwarding"
|
||||
iifname != "wg0" oifname "wg0" accept comment "Allow traffic to VPN"
|
||||
|
||||
# Drop and log other forwarded traffic
|
||||
log prefix "NFT-FORWARD-DROP: " drop comment "Log and drop other forward"
|
||||
}
|
||||
|
||||
chain output {
|
||||
type filter hook output priority 0; policy accept;
|
||||
|
||||
# Allow all outbound traffic by default (restrict as needed)
|
||||
# Log blocked traffic for troubleshooting
|
||||
log prefix "NFT-OUTPUT-DROP: " drop comment "Log dropped output"
|
||||
}
|
||||
}
|
||||
|
||||
# NAT table for VPN (if needed)
|
||||
table ip nat {
|
||||
chain postrouting {
|
||||
type nat hook postrouting priority 100; policy accept;
|
||||
|
||||
# NAT for VPN traffic (if internet access via VPN)
|
||||
# oifname "eth0" ip saddr 10.8.0.0/24 masquerade comment "NAT for VPN"
|
||||
}
|
||||
}
|
||||
|
||||
EOF
|
||||
|
||||
# Create custom rules directory for modular configuration
|
||||
mkdir -p /etc/nftables.conf.d
|
||||
|
||||
# Create separate rule file for allowed management networks
|
||||
cat > /etc/nftables.conf.d/management.nft << 'EOF'
|
||||
# Management Network Access Rules
|
||||
# Uncomment and modify for your management network(s)
|
||||
|
||||
# Allow SSH from management network only
|
||||
# add rule inet filter input ip saddr 192.168.1.0/24 tcp dport 22 accept comment "SSH from management network"
|
||||
|
||||
# Allow monitoring from management network
|
||||
# add rule inet filter input ip saddr 192.168.1.0/24 udp dport { 161,162 } accept comment "SNMP from management network"
|
||||
EOF
|
||||
|
||||
# Create rate limiting rules
|
||||
cat > /etc/nftables.conf.d/rate-limits.nft << 'EOF'
|
||||
# Rate Limiting Rules
|
||||
# Prevent brute force attacks and flooding
|
||||
|
||||
# Rate limit new SSH connections
|
||||
add rule inet filter input tcp dport 22 ct state new limit rate 3/minute burst 5 accept comment "Rate limit SSH"
|
||||
|
||||
# Rate limit ping requests
|
||||
add rule inet filter input ip protocol icmp icmp type echo-request limit rate 10/second burst 5 packets accept comment "Rate limit ping"
|
||||
|
||||
# Rate limit VNC connections
|
||||
add rule inet filter input tcp dport { 5900,5901 } ct state new limit rate 2/minute burst 3 accept comment "Rate limit VNC"
|
||||
EOF
|
||||
|
||||
# Create logging rules
|
||||
cat > /etc/nftables.conf.d/logging.nft << 'EOF'
|
||||
# Enhanced Logging Rules
|
||||
# Log suspicious activity for security monitoring
|
||||
|
||||
# Log connection attempts to blocked ports
|
||||
add rule inet filter input tcp dport { 23,3389,1433,3306,5432 } ct state new log prefix "NFT-SCANNED-PORT: " drop comment "Log blocked port scans"
|
||||
|
||||
# Log fragmented packets
|
||||
add rule inet filter input ip frag-off drop log prefix "NFT-FRAGMENTED: " comment "Drop fragmented packets"
|
||||
|
||||
# Log suspicious flags
|
||||
add rule inet filter input tcp flags & (syn|ack) == (syn|ack) log prefix "NFT-SYN-ACK: " drop comment "Log suspicious SYN-ACK"
|
||||
EOF
|
||||
|
||||
# Create firewall persistence script
|
||||
cat > /usr/local/bin/firewall-persistence.sh << 'EOF'
|
||||
#!/bin/bash
|
||||
# Football System - Firewall Persistence Script
|
||||
# Ensures firewall rules are saved and restored properly
|
||||
|
||||
FIREWALL_CONFIG="/etc/nftables.conf"
|
||||
RULES_DIR="/etc/nftables.conf.d"
|
||||
LOCK_FILE="/var/lock/firewall-persistence"
|
||||
LOG_FILE="/var/log/security/firewall-persistence.log"
|
||||
|
||||
# Function to log messages
|
||||
log_message() {
|
||||
local level=$1
|
||||
local message=$2
|
||||
echo "$(date '+%Y-%m-%d %H:%M:%S') [$level] $message" | tee -a "$LOG_FILE"
|
||||
}
|
||||
|
||||
# Function to check if process is running
|
||||
is_running() {
|
||||
pgrep -f "$1" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
# Prevent concurrent execution
|
||||
exec 200>"$LOCK_FILE"
|
||||
if flock -n 200; then
|
||||
log_message "INFO" "Starting firewall persistence check"
|
||||
else
|
||||
log_message "WARNING" "Firewall persistence script already running"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if nftables service is running
|
||||
if ! systemctl is-active --quiet nftables; then
|
||||
log_message "ERROR" "nftables service is not running"
|
||||
log_message "INFO" "Starting nftables service..."
|
||||
systemctl start nftables
|
||||
if systemctl is-active --quiet nftables; then
|
||||
log_message "INFO" "nftables service started successfully"
|
||||
else
|
||||
log_message "CRITICAL" "Failed to start nftables service"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Verify firewall rules are loaded
|
||||
if ! nft list ruleset >/dev/null 2>&1; then
|
||||
log_message "ERROR" "No firewall rules are loaded"
|
||||
log_message "INFO" "Loading firewall rules..."
|
||||
if nft -f "$FIREWALL_CONFIG"; then
|
||||
log_message "INFO" "Main firewall rules loaded successfully"
|
||||
|
||||
# Load additional rule files
|
||||
for rule_file in "$RULES_DIR"/*.nft; do
|
||||
if [ -f "$rule_file" ]; then
|
||||
log_message "INFO" "Loading rules from $(basename "$rule_file")"
|
||||
nft -f "$rule_file"
|
||||
fi
|
||||
done
|
||||
else
|
||||
log_message "CRITICAL" "Failed to load firewall rules"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Verify critical rules are in place
|
||||
CRITICAL_RULES=(
|
||||
"iifname \"lo\" accept"
|
||||
"ct state established,related accept"
|
||||
"tcp dport 22 accept"
|
||||
"udp dport 51820 accept"
|
||||
)
|
||||
|
||||
for rule in "${CRITICAL_RULES[@]}"; do
|
||||
if nft list ruleset | grep -q "$rule"; then
|
||||
log_message "DEBUG" "Critical rule verified: $rule"
|
||||
else
|
||||
log_message "WARNING" "Critical rule missing: $rule"
|
||||
fi
|
||||
done
|
||||
|
||||
# Check for potential firewall bypasses
|
||||
log_message "INFO" "Checking for potential firewall bypasses"
|
||||
|
||||
# Check for raw socket usage
|
||||
if netstat -anp 2>/dev/null | grep -q "raw"; then
|
||||
log_message "WARNING" "Raw sockets detected - potential firewall bypass"
|
||||
fi
|
||||
|
||||
# Check for iptables conflicts
|
||||
if iptables -L >/dev/null 2>&1 && [ "$(iptables -L | wc -l)" -gt 6 ]; then
|
||||
log_message "WARNING" "iptables rules detected - potential conflict with nftables"
|
||||
fi
|
||||
|
||||
# Test basic connectivity through firewall
|
||||
log_message "INFO" "Testing basic firewall functionality"
|
||||
|
||||
# Test loopback
|
||||
if ping -c 1 -W 1 127.0.0.1 >/dev/null 2>&1; then
|
||||
log_message "DEBUG" "Loopback connectivity test passed"
|
||||
else
|
||||
log_message "WARNING" "Loopback connectivity test failed"
|
||||
fi
|
||||
|
||||
# Test that basic blocking works (if we can determine an unreachable port)
|
||||
# This is a simple test - adjust as needed for your environment
|
||||
if timeout 2 bash -c "echo >/dev/tcp/192.0.2.1/80" 2>/dev/null; then
|
||||
log_message "WARNING" "Unexpected connectivity to test destination - check firewall rules"
|
||||
else
|
||||
log_message "DEBUG" "Basic blocking test passed (expected failure)"
|
||||
fi
|
||||
|
||||
# Save current rules for persistence
|
||||
if systemctl is-active --quiet nftables; then
|
||||
log_message "INFO" "Saving firewall rules for persistence"
|
||||
|
||||
# Create backup of current rules
|
||||
mkdir -p /var/backups/firewall
|
||||
nft list ruleset > "/var/backups/firewall/ruleset_$(date +%Y%m%d_%H%M%S).nft"
|
||||
|
||||
log_message "INFO" "Firewall rules backed up successfully"
|
||||
else
|
||||
log_message "ERROR" "Cannot save rules - nftables service not running"
|
||||
fi
|
||||
|
||||
# Report status
|
||||
if systemctl is-active --quiet nftables && nft list ruleset >/dev/null 2>&1; then
|
||||
log_message "INFO" "Firewall persistence check completed successfully"
|
||||
exit 0
|
||||
else
|
||||
log_message "CRITICAL" "Firewall persistence check failed"
|
||||
exit 1
|
||||
fi
|
||||
EOF
|
||||
|
||||
# Make persistence script executable
|
||||
chmod 750 /usr/local/bin/firewall-persistence.sh
|
||||
chown root:root /usr/local/bin/firewall-persistence.sh
|
||||
|
||||
# Create systemd service for firewall persistence
|
||||
cat > /etc/systemd/system/firewall-persistence.service << 'EOF'
|
||||
[Unit]
|
||||
Description=Firewall Persistence Check
|
||||
Documentation=man:nftables(8)
|
||||
After=network.target nftables.service
|
||||
Wants=nftables.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/local/bin/firewall-persistence.sh
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
|
||||
# Security settings
|
||||
NoNewPrivileges=yes
|
||||
ProtectSystem=strict
|
||||
ProtectHome=yes
|
||||
ReadWritePaths=/var/log/security /var/lock
|
||||
PrivateTmp=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
# Create systemd timer for periodic checks
|
||||
cat > /etc/systemd/system/firewall-persistence.timer << 'EOF'
|
||||
[Unit]
|
||||
Description=Run firewall persistence checks every 15 minutes
|
||||
Requires=firewall-persistence.service
|
||||
|
||||
[Timer]
|
||||
OnCalendar=*:0/15
|
||||
Persistent=true
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
EOF
|
||||
|
||||
# Configure nftables service
|
||||
cat > /etc/default/nftables << 'EOF'
|
||||
# Configuration for nftables
|
||||
|
||||
# Set to "yes" to load firewall rules on boot
|
||||
STANDARD_SETUP="yes"
|
||||
|
||||
# Set to "yes" to save firewall rules on shutdown/reboot
|
||||
STANDARD_CLEANUP="no"
|
||||
|
||||
# Additional options to pass to nft during startup
|
||||
NFT_OPTIONS=""
|
||||
EOF
|
||||
|
||||
# Create iptables to nftables compatibility (if needed)
|
||||
cat > /usr/local/bin/iptables-legacy-save.sh << 'EOF'
|
||||
#!/bin/bash
|
||||
# Legacy iptables save script for compatibility
|
||||
# Saves current iptables rules for backup purposes
|
||||
|
||||
mkdir -p /var/backups/iptables
|
||||
iptables-save > "/var/backups/iptables/legacy_$(date +%Y%m%d_%H%M%S).rules"
|
||||
echo "Legacy iptables rules saved"
|
||||
EOF
|
||||
|
||||
chmod 750 /usr/local/bin/iptables-legacy-save.sh
|
||||
chown root:root /usr/local/bin/iptables-legacy-save.sh
|
||||
|
||||
# Create firewall status script
|
||||
cat > /usr/local/bin/firewall-status.sh << 'EOF'
|
||||
#!/bin/bash
|
||||
# Football System - Firewall Status Check
|
||||
# Comprehensive firewall status reporting
|
||||
|
||||
echo "=== Football System Firewall Status ==="
|
||||
echo "Time: $(date)"
|
||||
echo ""
|
||||
|
||||
# Check nftables service status
|
||||
echo "=== Service Status ==="
|
||||
if systemctl is-active --quiet nftables; then
|
||||
echo "✅ nftables service: Active"
|
||||
else
|
||||
echo "❌ nftables service: Inactive"
|
||||
fi
|
||||
|
||||
if systemctl is-enabled --quiet nftables; then
|
||||
echo "✅ nftables service: Enabled on boot"
|
||||
else
|
||||
echo "❌ nftables service: Disabled on boot"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Check ruleset status
|
||||
echo "=== Ruleset Status ==="
|
||||
if nft list ruleset >/dev/null 2>&1; then
|
||||
echo "✅ Ruleset: Loaded"
|
||||
TOTAL_RULES=$(nft list ruleset | grep -c "accept\|drop")
|
||||
echo "Total rules: $TOTAL_RULES"
|
||||
else
|
||||
echo "❌ Ruleset: Not loaded"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Show key rules
|
||||
echo "=== Key Security Rules ==="
|
||||
nft list ruleset | grep -E "(lo|ssh|wireguard|established)" | head -10
|
||||
|
||||
echo ""
|
||||
|
||||
# Check for recent firewall log entries
|
||||
echo "=== Recent Firewall Log Entries ==="
|
||||
if journalctl -u nftables --since "1 hour ago" | grep -q "NFT"; then
|
||||
journalctl -u nftables --since "1 hour ago" | grep "NFT" | tail -5
|
||||
else
|
||||
echo "No recent firewall log entries"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Check persistence timer status
|
||||
echo "=== Persistence Monitoring ==="
|
||||
if systemctl is-active --quiet firewall-persistence.timer; then
|
||||
echo "✅ Persistence timer: Active"
|
||||
NEXT_RUN=$(systemctl list-timers firewall-persistence.timer --no-pager | grep "n/a" -A 1 | tail -1 | awk '{print $1,$2,$3,$4}')
|
||||
echo "Next run: $NEXT_RUN"
|
||||
else
|
||||
echo "❌ Persistence timer: Inactive"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Network interface status
|
||||
echo "=== Network Interface Status ==="
|
||||
ip addr show | grep -E "(state|inet)" | grep -v "127.0.0.1"
|
||||
|
||||
echo ""
|
||||
|
||||
# Show active connections
|
||||
echo "=== Recent Active Connections ==="
|
||||
ss -tuln | head -10
|
||||
|
||||
echo "=== End Firewall Status ==="
|
||||
EOF
|
||||
|
||||
chmod 750 /usr/local/bin/firewall-status.sh
|
||||
chown root:root /usr/local/bin/firewall-status.sh
|
||||
|
||||
# Enable and start services
|
||||
systemctl daemon-reload
|
||||
systemctl enable nftables
|
||||
systemctl start nftables
|
||||
|
||||
systemctl enable firewall-persistence.timer
|
||||
systemctl start firewall-persistence.timer
|
||||
|
||||
# Load firewall rules
|
||||
echo "Loading firewall rules..."
|
||||
if nft -f /etc/nftables.conf; then
|
||||
echo "✅ Main firewall rules loaded successfully"
|
||||
else
|
||||
echo "❌ Failed to load main firewall rules"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Load additional rule files
|
||||
for rule_file in /etc/nftables.conf.d/*.nft; do
|
||||
if [ -f "$rule_file" ]; then
|
||||
echo "Loading rules from $(basename "$rule_file")"
|
||||
if nft -f "$rule_file"; then
|
||||
echo "✅ Rules from $(basename "$rule_file") loaded successfully"
|
||||
else
|
||||
echo "❌ Failed to load rules from $(basename "$rule_file")"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# Run initial persistence check
|
||||
if /usr/local/bin/firewall-persistence.sh; then
|
||||
echo "✅ Firewall persistence check completed successfully"
|
||||
else
|
||||
echo "⚠️ Firewall persistence check completed with warnings"
|
||||
fi
|
||||
|
||||
# Create firewall log rotation
|
||||
cat > /etc/logrotate.d/firewall << 'EOF'
|
||||
# Football System - Firewall Log Rotation
|
||||
|
||||
/var/log/security/firewall-persistence.log {
|
||||
weekly
|
||||
rotate 52
|
||||
compress
|
||||
delaycompress
|
||||
missingok
|
||||
notifempty
|
||||
create 0640 root adm
|
||||
sharedscripts
|
||||
postrotate
|
||||
systemctl reload rsyslog >/dev/null 2>&1 || true
|
||||
endscript
|
||||
}
|
||||
|
||||
/var/backups/firewall/*.nft {
|
||||
monthly
|
||||
rotate 12
|
||||
compress
|
||||
delaycompress
|
||||
missingok
|
||||
notifempty
|
||||
}
|
||||
EOF
|
||||
|
||||
chmod 644 /etc/logrotate.d/firewall
|
||||
chown root:root /etc/logrotate.d/firewall
|
||||
|
||||
# Display firewall status
|
||||
echo ""
|
||||
echo "=== Firewall Configuration Summary ==="
|
||||
echo "✅ nftables service enabled and started"
|
||||
echo "✅ Firewall rules loaded from /etc/nftables.conf"
|
||||
echo "✅ Additional rules loaded from /etc/nftables.conf.d/"
|
||||
echo "✅ Persistence monitoring enabled (runs every 15 minutes)"
|
||||
echo "✅ Status script available: /usr/local/bin/firewall-status.sh"
|
||||
echo "✅ Log rotation configured"
|
||||
echo ""
|
||||
echo "Key firewall ports allowed:"
|
||||
echo "- SSH (22): Remote management"
|
||||
echo "- WireGuard (51820): VPN access"
|
||||
echo "- VNC (5900-5901): Remote desktop"
|
||||
echo "- ICMP (limited): Network diagnostics"
|
||||
echo ""
|
||||
echo "Run 'firewall-status.sh' for detailed status"
|
||||
echo "✅ Firewall persistence configuration completed"
|
||||
@@ -3,7 +3,7 @@
|
||||
# This script configures strict firewall with WireGuard-only access
|
||||
# Implements CIS Debian Benchmark and CMMC/FedRAMP controls
|
||||
|
||||
set -e
|
||||
set -euo pipefail
|
||||
|
||||
echo "Applying CIS Benchmark and CMMC/FedRAMP hardening..."
|
||||
|
||||
@@ -48,8 +48,8 @@ iptables -A INPUT -i lo -j ACCEPT
|
||||
iptables -A OUTPUT -o lo -j ACCEPT
|
||||
|
||||
# Only WireGuard on physical interface
|
||||
iptables -A OUTPUT -o eth0 -d $WG_ENDPOINT_IP -p udp --dport $WG_ENDPOINT_PORT -m state --state NEW,ESTABLISHED -j ACCEPT
|
||||
iptables -A INPUT -i eth0 -s $WG_ENDPOINT_IP -p udp --sport $WG_ENDPOINT_PORT -m state --state ESTABLISHED -j ACCEPT
|
||||
iptables -A OUTPUT -o eth0 -d "$WG_ENDPOINT_IP" -p udp --dport "$WG_ENDPOINT_PORT" -m state --state NEW,ESTABLISHED -j ACCEPT
|
||||
iptables -A INPUT -i eth0 -s "$WG_ENDPOINT_IP" -p udp --sport "$WG_ENDPOINT_PORT" -m state --state ESTABLISHED -j ACCEPT
|
||||
|
||||
# All traffic through WireGuard
|
||||
iptables -A INPUT -i wg0 -j ACCEPT
|
||||
@@ -328,7 +328,9 @@ systemctl enable apparmor 2>/dev/null || true
|
||||
|
||||
# Enforce AppArmor profiles for critical services
|
||||
for profile in /etc/apparmor.d/*; do
|
||||
[ -f "$profile" ] && aa-enforce "${profile##*/}" 2>/dev/null || true
|
||||
if [ -f "$profile" ]; then
|
||||
aa-enforce "${profile##*/}" 2>/dev/null || true
|
||||
fi
|
||||
done
|
||||
|
||||
# ============================================================================
|
||||
|
||||
@@ -29,7 +29,8 @@ d-i time/zone string UTC
|
||||
# User will be prompted for root password during install
|
||||
# Password complexity enforced during install via PAM
|
||||
|
||||
# Partitioning (User selects disk, we handle the rest)
|
||||
# Partitioning - USER SELECTS DISK
|
||||
# Commented out to allow user to select disk during install
|
||||
|
||||
# ============================================================================
|
||||
# Password Complexity Enforcement (During Install)
|
||||
@@ -44,29 +45,33 @@ passwd/user-password-empty boolean false
|
||||
# Password complexity (enforced by PAM during install)
|
||||
# PAM will check against pwquality.conf during password entry
|
||||
# See config/security-config.sh for full pwquality requirements
|
||||
d-i partman-auto/method string lvm
|
||||
d-i partman-lvm/device_remove_lvm boolean true
|
||||
d-i partman-lvm/confirm boolean true
|
||||
d-i partman/choose_partition select finish
|
||||
d-i partman/confirm boolean true
|
||||
d-i partman/confirm_nooverwrite boolean true
|
||||
|
||||
# Partitioning - USER WILL SELECT DISK
|
||||
# Commented out to allow disk selection during install
|
||||
# d-i partman-auto/method string lvm
|
||||
# d-i partman-lvm/device_remove_lvm boolean true
|
||||
# d-i partman-lvm/confirm boolean true
|
||||
# d-i partman/choose_partition select finish
|
||||
# d-i partman/confirm boolean true
|
||||
# d-i partman/confirm_nooverwrite boolean true
|
||||
|
||||
# LVM setup
|
||||
d-i partman-auto-lvm/guided_size string max
|
||||
# d-i partman-auto-lvm/guided_size string max
|
||||
|
||||
# Base system installation
|
||||
d-i base-installer/kernel/image string linux-image-amd64
|
||||
|
||||
# Account setup (User will provide these)
|
||||
d-i passwd/user-fullname string Football User
|
||||
d-i passwd/username string user
|
||||
d-i passwd/user-password password changeme
|
||||
d-i passwd/user-password-again password changeme
|
||||
d-i passwd/root-password password changeme
|
||||
d-i passwd/root-password-again password changeme
|
||||
# Account setup - USER WILL PROVIDE THESE
|
||||
# Commented out to allow user to enter during install
|
||||
# d-i passwd/user-fullname string Football User
|
||||
# d-i passwd/username string user
|
||||
# d-i passwd/user-password password changeme
|
||||
# d-i passwd/user-password-again password changeme
|
||||
# d-i passwd/root-password password changeme
|
||||
# d-i passwd/root-password-again password changeme
|
||||
|
||||
# User is not sudo by default - will be configured later
|
||||
d-i passwd/user-default-groups string audio,dialout,video
|
||||
# d-i passwd/user-default-groups string audio,dialout,video
|
||||
|
||||
# Package selection - Minimal system
|
||||
tasksel tasksel/first multiselect standard
|
||||
@@ -138,8 +143,6 @@ d-i finish-install/reboot_in_progress note
|
||||
d-i preseed/late_command string \
|
||||
in-target systemctl enable lightdm && \
|
||||
in-target systemctl set-default graphical.target && \
|
||||
in-target chmod 755 /home/user && \
|
||||
in-target chown -R user:user /home/user && \
|
||||
in-target systemctl mask ssh sshd 2>/dev/null || true && \
|
||||
in-target systemctl disable ssh sshd 2>/dev/null || true && \
|
||||
in-target systemctl mask bluetooth 2>/dev/null || true && \
|
||||
@@ -147,14 +150,11 @@ d-i preseed/late_command string \
|
||||
in-target bash /tmp/disable-wifi-bt.sh && \
|
||||
in-target cp /cdrom/config/security-config.sh /tmp/ && \
|
||||
in-target bash /tmp/security-config.sh && \
|
||||
in-target cp /cdrom/config/harden.sh /tmp/ && \
|
||||
in-target bash /tmp/harden.sh && \
|
||||
in-target cp /cdrom/scripts/verify-system.sh /usr/local/bin/ && \
|
||||
in-target chmod +x /usr/local/bin/verify-system.sh && \
|
||||
in-target cp /cdrom/config/football-first-boot.service /etc/systemd/system/ && \
|
||||
in-target mkdir -p /home/user/.config/autostart && \
|
||||
in-target cp /usr/share/applications/remmina.desktop /home/user/.config/autostart/ && \
|
||||
in-target chown -R user:user /home/user/.config && \
|
||||
in-target systemctl daemon-reload && \
|
||||
in-target systemctl enable football-first-boot.service && \
|
||||
in-target rm -f /tmp/disable-wifi-bt.sh /tmp/security-config.sh
|
||||
|
||||
# Security configuration will be applied post-install via harden.sh
|
||||
in-target rm -f /tmp/disable-wifi-bt.sh /tmp/security-config.sh /tmp/harden.sh
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Secure Boot configuration script for football system
|
||||
# This script ensures Secure Boot is properly configured
|
||||
|
||||
set -e
|
||||
set -euo pipefail
|
||||
|
||||
echo "Configuring Secure Boot..."
|
||||
|
||||
@@ -55,9 +55,9 @@ EOF
|
||||
|
||||
# Ensure kernel modules are signed
|
||||
echo "Verifying kernel module signing..."
|
||||
for module in /lib/modules/$(uname -r)/*.ko; do
|
||||
for module in "/lib/modules/$(uname -r)"/*.ko; do
|
||||
if [ -f "$module" ]; then
|
||||
sig=$(modinfo "$module" 2>/dev/null | grep -i "signature:" | wc -l)
|
||||
sig=$(modinfo "$module" 2>/dev/null | grep -ci "signature:")
|
||||
if [ "$sig" -eq 0 ]; then
|
||||
echo "WARNING: Module $module is not signed"
|
||||
fi
|
||||
|
||||
397
config/user-environment.sh
Normal file
397
config/user-environment.sh
Normal file
@@ -0,0 +1,397 @@
|
||||
# Football System User Environment Configuration
|
||||
# Sets up minimal UI with Remmina auto-start
|
||||
|
||||
# Create user directories with proper permissions
|
||||
mkdir -p /home/user/.config/{icewm,remmina,autostart}
|
||||
mkdir -p /home/user/.local/share/applications
|
||||
mkdir -p /home/user/.local/bin
|
||||
|
||||
# IceWM configuration
|
||||
cat > /home/user/.config/icewm/prefoverence << 'EOF'
|
||||
# Football System - IceWM Minimal Configuration
|
||||
# Focused on security and simplicity
|
||||
|
||||
# Theme and appearance
|
||||
ThemeName="win95Classic"
|
||||
TitleBarHeight=20
|
||||
BorderSizeX=2
|
||||
BorderSizeY=2
|
||||
DlgBorderSizeX=2
|
||||
DlgBorderSizeY=2
|
||||
|
||||
# Window behavior
|
||||
AutoRaise=0
|
||||
ClickToFocus=1
|
||||
FocusOnAppRaise=1
|
||||
RaiseOnFocus=0
|
||||
RaiseOnClickClient=1
|
||||
PassFirstClickToClient=1
|
||||
ShowTaskBar=1
|
||||
TaskBarAtTop=0
|
||||
TaskBarShowWorkspaces=0
|
||||
TaskBarShowWindowList=1
|
||||
|
||||
# Program menu restrictions
|
||||
ShowProgramsMenu=1
|
||||
ShowThemesMenu=0
|
||||
ShowHelpMenu=0
|
||||
ShowLogoutMenu=1
|
||||
ShowLogoutSubMenu=0
|
||||
ShowAboutMenu=0
|
||||
ShowRunMenu=0
|
||||
|
||||
# Desktop restrictions
|
||||
DesktopBackgroundCenter=0
|
||||
DesktopBackgroundScaled=1
|
||||
DesktopBackgroundColor="rgb:40/40/40"
|
||||
ShowDesktopBackgroundPixmap=1
|
||||
|
||||
# Input settings
|
||||
Win95Keys=0
|
||||
ModSuperIsCtrlAlt=0
|
||||
UseMouseWheel=1
|
||||
|
||||
# Security restrictions
|
||||
DisableRealDragAndDrop=1
|
||||
AllowFullscreen=0
|
||||
ConfirmLogout=1
|
||||
|
||||
# Window placement
|
||||
SmartPlacement=1
|
||||
CenterTransients=1
|
||||
CenterLarge=0
|
||||
|
||||
# Resource limits
|
||||
IconPath="/usr/share/icons:/usr/share/pixmaps"
|
||||
LookAndFeel=win95
|
||||
|
||||
# Menu security
|
||||
MenuFile=/home/user/.config/icewm/menu
|
||||
ProgramsFile=/home/user/.config/icewm/programs
|
||||
EOF
|
||||
|
||||
# IceWM programs menu (restricted)
|
||||
cat > /home/user/.config/icewm/programs << 'EOF'
|
||||
# Football System - Restricted Programs Menu
|
||||
|
||||
# Application launcher
|
||||
prog Terminal terminal "xterm"
|
||||
prog File Manager filemanager "pcmanfm"
|
||||
|
||||
# System applications
|
||||
prog Remmina remmina "remmina"
|
||||
prog Network Status netstatus "xterm -e 'nmcli dev status'"
|
||||
|
||||
# System information
|
||||
prog System Info sysinfo "xterm -e 'uname -a; df -h; free -m'"
|
||||
prog Verification verify "xterm -e '/usr/local/bin/verify-system.sh'"
|
||||
|
||||
# Power management
|
||||
prog Logout logout "icewm --shutdown"
|
||||
prog Reboot reboot "sudo reboot"
|
||||
prog Shutdown shutdown "sudo shutdown -h now"
|
||||
EOF
|
||||
|
||||
# IceWM menu (minimal and secure)
|
||||
cat > /home/user/.config/icewm/menu << 'EOF'
|
||||
# Football System - Minimal Menu
|
||||
|
||||
menufile programs
|
||||
separator
|
||||
|
||||
# Security tools
|
||||
menu Security {
|
||||
prog System Status status "xterm -e 'systemctl status'"
|
||||
prog Security Audit audit "xterm -e 'sudo aide --check'"
|
||||
prog Log Monitor logmon "xterm -e 'sudo journalctl -f'"
|
||||
}
|
||||
separator
|
||||
|
||||
# Network
|
||||
menu Network {
|
||||
prog VPN Status vpn "xterm -e 'wg show'"
|
||||
prog Network Info netinfo "xterm -e 'ip addr show'"
|
||||
}
|
||||
separator
|
||||
|
||||
# Logout menu
|
||||
menu Logout {
|
||||
prog Lock Screen lock "xlock"
|
||||
prog Logout logout "icewm --shutdown"
|
||||
prog Reboot reboot "sudo reboot"
|
||||
prog Shutdown shutdown "sudo shutdown -h now"
|
||||
}
|
||||
EOF
|
||||
|
||||
# Remmina desktop entry for autostart
|
||||
cat > /home/user/.config/autostart/remmina.desktop << 'EOF'
|
||||
[Desktop Entry]
|
||||
Version=1.0
|
||||
Type=Application
|
||||
Name=Remmina
|
||||
Comment=Remote Desktop Client
|
||||
Exec=remmina
|
||||
Icon=remmina
|
||||
Terminal=false
|
||||
Categories=Network;RemoteAccess;
|
||||
X-GNOME-Autostart-enabled=true
|
||||
EOF
|
||||
|
||||
# Desktop entry for system verification
|
||||
cat > /home/user/.local/share/applications/verify-system.desktop << 'EOF'
|
||||
[Desktop Entry]
|
||||
Version=1.0
|
||||
Type=Application
|
||||
Name=System Verification
|
||||
Comment=Verify Football Secure Access System
|
||||
Exec=xterm -e '/usr/local/bin/verify-system.sh'
|
||||
Icon=security-high
|
||||
Terminal=true
|
||||
Categories=System;Security;
|
||||
EOF
|
||||
|
||||
# Desktop entry for network status
|
||||
cat > /home/user/.local/share/applications/network-status.desktop << 'EOF'
|
||||
[Desktop Entry]
|
||||
Version=1.0
|
||||
Type=Application
|
||||
Name=Network Status
|
||||
Comment=Check Network Connectivity
|
||||
Exec=xterm -e 'nmcli dev status; echo ""; echo "VPN Status:"; wg show'
|
||||
Icon=network-idle
|
||||
Terminal=true
|
||||
Categories=System;Network;
|
||||
EOF
|
||||
|
||||
# Create xinitrc for IceWM session
|
||||
cat > /home/user/.xinitrc << 'EOF'
|
||||
#!/bin/bash
|
||||
# Football System - X Session Initialization
|
||||
|
||||
# Set environment variables
|
||||
export XDG_CONFIG_HOME=/home/user/.config
|
||||
export XDG_DATA_HOME=/home/user/.local/share
|
||||
export XDG_CACHE_HOME=/home/user/.cache
|
||||
|
||||
# Security settings
|
||||
xhost +local: || true
|
||||
|
||||
# Load X resources (if any)
|
||||
[ -f /home/user/.Xresources ] && xrdb /home/user/.Xresources
|
||||
|
||||
# Set desktop background (minimal)
|
||||
xsetroot -solid "#282828"
|
||||
|
||||
# Start IceWM
|
||||
exec icewm-session
|
||||
EOF
|
||||
|
||||
# Create bash_profile for console sessions
|
||||
cat > /home/user/.bash_profile << 'EOF'
|
||||
# Football System - User Shell Configuration
|
||||
|
||||
# Prompt
|
||||
PS1='[\\u@\\h \\W]\\$ '
|
||||
|
||||
# Security aliases
|
||||
alias ll='ls -la --color=auto'
|
||||
alias la='ls -a --color=auto'
|
||||
alias vi='vim'
|
||||
alias diff='colordiff'
|
||||
|
||||
# System information
|
||||
alias sysinfo='echo "=== System Information ==="; uname -a; echo ""; df -h; echo ""; free -m'
|
||||
alias secstatus='echo "=== Security Status ==="; systemctl status auditd rsyslog; echo ""; wg show'
|
||||
|
||||
# Quick access to verification
|
||||
alias verify='/usr/local/bin/verify-system.sh'
|
||||
alias checksec='sudo aide --check'
|
||||
|
||||
# Network aliases
|
||||
alias netstat='nmcli dev status'
|
||||
alias vpnstat='wg show'
|
||||
|
||||
# Security reminder
|
||||
echo "Football Secure Access System v2.1"
|
||||
echo "Type 'verify' to run system verification"
|
||||
echo "Type 'sysinfo' for system information"
|
||||
echo ""
|
||||
|
||||
# Check if this is a graphical session
|
||||
if [ "$DISPLAY" ]; then
|
||||
echo "Graphical session detected. Remmina will auto-start."
|
||||
fi
|
||||
EOF
|
||||
|
||||
# Create .bashrc for interactive shells
|
||||
cat > /home/user/.bashrc << 'EOF'
|
||||
# Football System - Interactive Shell Configuration
|
||||
|
||||
# Source bash_profile
|
||||
[ -f /home/user/.bash_profile ] && . /home/user/.bash_profile
|
||||
|
||||
# Interactive shell settings
|
||||
set -o vi
|
||||
export HISTCONTROL=ignoreboth
|
||||
export HISTSIZE=1000
|
||||
export HISTFILESIZE=2000
|
||||
|
||||
# Completions
|
||||
if [ -f /etc/bash_completion ]; then
|
||||
. /etc/bash_completion
|
||||
fi
|
||||
|
||||
# Enable color support
|
||||
if [ -x /usr/bin/dircolors ]; then
|
||||
eval "$(dircolors -b)"
|
||||
fi
|
||||
|
||||
# Color aliases
|
||||
alias grep='grep --color=auto'
|
||||
alias fgrep='fgrep --color=auto'
|
||||
alias egrep='egrep --color=auto'
|
||||
alias ls='ls --color=auto'
|
||||
EOF
|
||||
|
||||
# Security-focused .Xresources (minimal)
|
||||
cat > /home/user/.Xresources << 'EOF'
|
||||
! Football System - Minimal X Resources
|
||||
|
||||
! Basic font settings
|
||||
*font: -*-fixed-medium-r-*-*-13-*-*-*-*-*-iso8859-1
|
||||
*xfont: -*-fixed-medium-r-*-*-13-*-*-*-*-*-iso8859-1
|
||||
|
||||
! Terminal settings
|
||||
*XTerm*background: #000000
|
||||
*XTerm*foreground: #ffffff
|
||||
*XTerm*font: -*-fixed-medium-r-*-*-13-*-*-*-*-*-iso8859-1
|
||||
|
||||
! Security - disable screen saver
|
||||
!*XTerm*allowSendEvents: false
|
||||
|
||||
! Enable numlock
|
||||
*numlock.on: true
|
||||
EOF
|
||||
|
||||
# Remmina configuration template (secure defaults)
|
||||
cat > /home/user/.config/remmina/remmina.pref << 'EOF'
|
||||
[remmina_pref]
|
||||
use_remmina_crypt_password=1
|
||||
save_view_mode=1
|
||||
default_view_mode=3
|
||||
confirm_credential_saving=1
|
||||
ssh_tunnel_loopback=1
|
||||
disable_clipboard=0
|
||||
disallow_tunneling=0
|
||||
disable_automatic_reconnect=0
|
||||
disable_server_input=0
|
||||
disable_password_change=0
|
||||
disable_automatic_reconnect=0
|
||||
disable_clipboard=1
|
||||
confirm_credential_saving=1
|
||||
disable_menu_toolbar=1
|
||||
disable_tab_previews=0
|
||||
disable_quick_search=1
|
||||
disable_new_connections=0
|
||||
disable_profile_settings=0
|
||||
allow_multiple_masterpasswords=0
|
||||
remfile_v2_encryption=1
|
||||
SSH_private_key_file=/home/user/.ssh/id_rsa
|
||||
default_ssh_privatekey=/home/user/.ssh/id_rsa
|
||||
EOF
|
||||
|
||||
# IceWM preferences file
|
||||
cat > /home/user/.config/icewm/preferences << 'EOF'
|
||||
# Football System - IceWM Preferences
|
||||
|
||||
# Clock settings
|
||||
ClockTimeFormat="%H:%M"
|
||||
ClockDateFormat="%Y-%m-%d"
|
||||
ShowClock=1
|
||||
|
||||
# Win95-like behavior
|
||||
Win95Keys=0
|
||||
ShowThemesMenu=0
|
||||
ShowHelpMenu=0
|
||||
ShowLogoutMenu=1
|
||||
ShowAboutMenu=0
|
||||
ShowRunMenu=0
|
||||
|
||||
# Security settings
|
||||
ClickToFocus=1
|
||||
AutoRaise=0
|
||||
RaiseOnFocus=0
|
||||
DisableRealDragAndDrop=1
|
||||
AllowFullscreen=0
|
||||
ConfirmLogout=1
|
||||
|
||||
# Workspace settings
|
||||
WorkspaceNames=" 1 "
|
||||
Workspace1Name="Main"
|
||||
ShowWorkspaces=0
|
||||
WorkspaceCount=1
|
||||
|
||||
# Taskbar settings
|
||||
TaskBarShowWorkspaces=0
|
||||
TaskBarShowWindowList=1
|
||||
TaskBarShowAllWindows=0
|
||||
TaskBarShowApm=0
|
||||
TaskBarShowMailboxStatus=0
|
||||
TaskBarShowCPU=0
|
||||
TaskBarShowNetStatus=0
|
||||
|
||||
# Input settings
|
||||
ModifierKeys="Super"
|
||||
UseMouseWheel=1
|
||||
|
||||
# Focus behavior
|
||||
FocusOnAppRaise=1
|
||||
PassFirstClickToClient=1
|
||||
RaiseOnClickClient=1
|
||||
|
||||
# Window placement
|
||||
SmartPlacement=1
|
||||
CenterTransients=1
|
||||
CenterLarge=0
|
||||
|
||||
# Menu behavior
|
||||
MenuMouseTracking=1
|
||||
SubmenuOnDelay=1
|
||||
SubmenuDelay=200
|
||||
|
||||
# Resource limits
|
||||
EdgeResistance=32
|
||||
EdgeThickness=1
|
||||
|
||||
# Appearance
|
||||
TitleBarHeight=20
|
||||
BorderSizeX=2
|
||||
BorderSizeY=2
|
||||
DlgBorderSizeX=2
|
||||
DlgBorderSizeY=2
|
||||
|
||||
# Colors
|
||||
ColorNormalTitleBar="rgb:C0/C0/C0"
|
||||
ColorActiveTitleBar="rgb:00/00/80"
|
||||
ColorNormalBorder="rgb:C0/C0/C0"
|
||||
ColorActiveBorder="rgb:00/00/80"
|
||||
EOF
|
||||
|
||||
# Set proper permissions
|
||||
chown -R user:user /home/user/.config
|
||||
chown -R user:user /home/user/.local
|
||||
chown user:user /home/user/.xinitrc
|
||||
chown user:user /home/user/.bash_profile
|
||||
chown user:user /home/user/.bashrc
|
||||
chown user:user /home/user/.Xresources
|
||||
chmod 755 /home/user
|
||||
chmod 755 /home/user/.config
|
||||
chmod 755 /home/user/.local
|
||||
chmod 644 /home/user/.xinitrc
|
||||
chmod 644 /home/user/.bash_profile
|
||||
chmod 644 /home/user/.bashrc
|
||||
chmod 644 /home/user/.Xresources
|
||||
chmod +x /home/user/.config/autostart/remmina.desktop
|
||||
chmod +x /home/user/.local/share/applications/*.desktop
|
||||
|
||||
echo "✅ User environment configured with IceWM and Remmina auto-start"
|
||||
919
config/wireguard-config.sh
Normal file
919
config/wireguard-config.sh
Normal file
@@ -0,0 +1,919 @@
|
||||
#!/bin/bash
|
||||
# Football System - WireGuard VPN Configuration
|
||||
# Creates secure WireGuard VPN setup with key management
|
||||
|
||||
set -e
|
||||
|
||||
echo "Configuring WireGuard VPN..."
|
||||
|
||||
# Configuration variables
|
||||
VPN_PORT=51820
|
||||
VPN_INTERFACE=wg0
|
||||
VPN_IP="10.8.0.1/24"
|
||||
VPN_KEY_DIR="/etc/wireguard/keys"
|
||||
VPN_CONFIG_DIR="/etc/wireguard"
|
||||
VPN_LOG_DIR="/var/log/wireguard"
|
||||
|
||||
# Create directories
|
||||
mkdir -p "$VPN_KEY_DIR"
|
||||
mkdir -p "$VPN_CONFIG_DIR"
|
||||
mkdir -p "$VPN_LOG_DIR"
|
||||
|
||||
# Set secure permissions
|
||||
chmod 700 "$VPN_KEY_DIR"
|
||||
chmod 755 "$VPN_CONFIG_DIR"
|
||||
chmod 755 "$VPN_LOG_DIR"
|
||||
|
||||
# Generate server private and public keys
|
||||
SERVER_PRIVATE_KEY="$VPN_KEY_DIR/server_private.key"
|
||||
SERVER_PUBLIC_KEY="$VPN_KEY_DIR/server_public.key"
|
||||
|
||||
if [ ! -f "$SERVER_PRIVATE_KEY" ]; then
|
||||
echo "Generating WireGuard server keys..."
|
||||
|
||||
# Generate private key
|
||||
wg genkey > "$SERVER_PRIVATE_KEY"
|
||||
|
||||
# Generate public key from private key
|
||||
wg pubkey < "$SERVER_PRIVATE_KEY" > "$SERVER_PUBLIC_KEY"
|
||||
|
||||
# Set secure permissions
|
||||
chmod 600 "$SERVER_PRIVATE_KEY"
|
||||
chmod 644 "$SERVER_PUBLIC_KEY"
|
||||
chown root:root "$SERVER_PRIVATE_KEY" "$SERVER_PUBLIC_KEY"
|
||||
|
||||
echo "✅ WireGuard server keys generated"
|
||||
else
|
||||
echo "✅ WireGuard server keys already exist"
|
||||
fi
|
||||
|
||||
# Read server public key for client configuration
|
||||
SERVER_PUBKEY=$(cat "$SERVER_PUBLIC_KEY")
|
||||
|
||||
# Create main WireGuard server configuration
|
||||
cat > "$VPN_CONFIG_DIR/wg0.conf" << EOF
|
||||
# Football System - WireGuard Server Configuration
|
||||
# Secure VPN for remote access
|
||||
|
||||
[Interface]
|
||||
# Server interface configuration
|
||||
Address = $VPN_IP
|
||||
ListenPort = $VPN_PORT
|
||||
PrivateKey = $(cat "$SERVER_PRIVATE_KEY")
|
||||
|
||||
# DNS for VPN clients (can use internal DNS or public)
|
||||
DNS = 1.1.1.1, 8.8.8.8
|
||||
|
||||
# MTU (optimized for WireGuard)
|
||||
MTU = 1420
|
||||
|
||||
# Enable connection tracking
|
||||
Table = off
|
||||
PostUp = iptables -A FORWARD -i $VPN_INTERFACE -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
|
||||
PostDown = iptables -D FORWARD -i $VPN_INTERFACE -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
|
||||
|
||||
# Client peers will be added here using wg-add-client.sh script
|
||||
|
||||
EOF
|
||||
|
||||
# Set secure permissions on server configuration
|
||||
chmod 600 "$VPN_CONFIG_DIR/wg0.conf"
|
||||
chown root:root "$VPN_CONFIG_DIR/wg0.conf"
|
||||
|
||||
# Create client management script
|
||||
cat > /usr/local/bin/wg-add-client.sh << 'EOF'
|
||||
#!/bin/bash
|
||||
# Football System - WireGuard Client Management
|
||||
# Adds new WireGuard client with secure key management
|
||||
|
||||
set -e
|
||||
|
||||
# Configuration
|
||||
VPN_INTERFACE="wg0"
|
||||
VPN_NETWORK="10.8.0.0/24"
|
||||
VPN_KEY_DIR="/etc/wireguard/keys"
|
||||
VPN_CLIENT_CONFIG_DIR="/etc/wireguard/clients"
|
||||
VPN_BASE_IP="10.8.0"
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Function to print colored output
|
||||
print_info() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
# Check if running as root
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
print_error "This script must be run as root"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Usage function
|
||||
usage() {
|
||||
echo "Usage: $0 <client_name> [client_ip_suffix]"
|
||||
echo "Example: $0 charles 10"
|
||||
echo "Example: $0 laptop"
|
||||
echo ""
|
||||
echo "client_name: Name/identifier for the client"
|
||||
echo "client_ip_suffix: (optional) Last octet of client IP (e.g., 10 for 10.8.0.10)"
|
||||
echo " If not provided, next available IP will be assigned"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Check arguments
|
||||
if [ $# -lt 1 ] || [ $# -gt 2 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
CLIENT_NAME="$1"
|
||||
CLIENT_IP_SUFFIX="$2"
|
||||
|
||||
# Validate client name
|
||||
if [[ ! "$CLIENT_NAME" =~ ^[a-zA-Z0-9_-]+$ ]]; then
|
||||
print_error "Client name must contain only alphanumeric characters, hyphens, and underscores"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ${#CLIENT_NAME} -gt 50 ]; then
|
||||
print_error "Client name must be 50 characters or less"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create client configuration directory
|
||||
mkdir -p "$VPN_CLIENT_CONFIG_DIR"
|
||||
|
||||
# Generate client keys
|
||||
print_info "Generating keys for client: $CLIENT_NAME"
|
||||
|
||||
CLIENT_PRIVATE_KEY="$VPN_CLIENT_CONFIG_DIR/${CLIENT_NAME}_private.key"
|
||||
CLIENT_PUBLIC_KEY="$VPN_CLIENT_CONFIG_DIR/${CLIENT_NAME}_public.key"
|
||||
|
||||
# Check if client already exists
|
||||
if [ -f "$CLIENT_PRIVATE_KEY" ]; then
|
||||
print_warning "Client '$CLIENT_NAME' already exists"
|
||||
read -p "Do you want to regenerate keys? (y/N): " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
print_info "Using existing keys for client '$CLIENT_NAME'"
|
||||
else
|
||||
print_info "Regenerating keys for client '$CLIENT_NAME'"
|
||||
wg genkey > "$CLIENT_PRIVATE_KEY"
|
||||
wg pubkey < "$CLIENT_PRIVATE_KEY" > "$CLIENT_PUBLIC_KEY"
|
||||
fi
|
||||
else
|
||||
wg genkey > "$CLIENT_PRIVATE_KEY"
|
||||
wg pubkey < "$CLIENT_PRIVATE_KEY" > "$CLIENT_PUBLIC_KEY"
|
||||
fi
|
||||
|
||||
# Set permissions
|
||||
chmod 600 "$CLIENT_PRIVATE_KEY"
|
||||
chmod 644 "$CLIENT_PUBLIC_KEY"
|
||||
chown root:root "$CLIENT_PRIVATE_KEY" "$CLIENT_PUBLIC_KEY"
|
||||
|
||||
# Determine client IP
|
||||
if [ -n "$CLIENT_IP_SUFFIX" ]; then
|
||||
# Validate provided IP suffix
|
||||
if [[ ! "$CLIENT_IP_SUFFIX" =~ ^[0-9]+$ ]] || [ "$CLIENT_IP_SUFFIX" -lt 2 ] || [ "$CLIENT_IP_SUFFIX" -gt 254 ]; then
|
||||
print_error "Client IP suffix must be a number between 2 and 254"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CLIENT_IP="${VPN_BASE_IP}.${CLIENT_IP_SUFFIX}"
|
||||
|
||||
# Check if IP is already in use
|
||||
if wg show | grep -q "$CLIENT_IP"; then
|
||||
print_error "IP $CLIENT_IP is already in use"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
# Find next available IP
|
||||
for suffix in {2..254}; do
|
||||
test_ip="${VPN_BASE_IP}.${suffix}"
|
||||
if ! wg show | grep -q "$test_ip" && ! grep -r "Address.*$test_ip" "$VPN_CLIENT_CONFIG_DIR/" >/dev/null 2>&1; then
|
||||
CLIENT_IP="$test_ip"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -z "$CLIENT_IP" ]; then
|
||||
print_error "No available IP addresses in the $VPN_BASE_IP.0/24 network"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Get server public key
|
||||
SERVER_PUBLIC_KEY="$VPN_KEY_DIR/server_public.key"
|
||||
if [ ! -f "$SERVER_PUBLIC_KEY" ]; then
|
||||
print_error "Server public key not found. Please run wireguard-config.sh first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SERVER_PUBKEY=$(cat "$SERVER_PUBLIC_KEY")
|
||||
|
||||
# Add peer to server configuration
|
||||
print_info "Adding client '$CLIENT_NAME' to server configuration"
|
||||
|
||||
cat >> "/etc/wireguard/wg0.conf" << EOF
|
||||
|
||||
# Client: $CLIENT_NAME
|
||||
[Peer]
|
||||
PublicKey = $(cat "$CLIENT_PUBLIC_KEY")
|
||||
AllowedIPs = $CLIENT_IP/32
|
||||
PersistentKeepalive = 25
|
||||
|
||||
EOF
|
||||
|
||||
# Create client configuration
|
||||
CLIENT_CONFIG_FILE="$VPN_CLIENT_CONFIG_DIR/${CLIENT_NAME}.conf"
|
||||
|
||||
cat > "$CLIENT_CONFIG_FILE" << EOF
|
||||
# Football System - WireGuard Client Configuration
|
||||
# Client: $CLIENT_NAME
|
||||
# Generated on: $(date)
|
||||
|
||||
[Interface]
|
||||
PrivateKey = $(cat "$CLIENT_PRIVATE_KEY")
|
||||
Address = $CLIENT_IP/24
|
||||
DNS = 1.1.1.1, 8.8.8.8
|
||||
MTU = 1420
|
||||
|
||||
[Peer]
|
||||
PublicKey = $SERVER_PUBKEY
|
||||
Endpoint = $(curl -s ifconfig.me || echo "YOUR_SERVER_IP"):51820
|
||||
AllowedIPs = 0.0.0.0/0
|
||||
PersistentKeepalive = 25
|
||||
|
||||
EOF
|
||||
|
||||
# Create QR code for mobile clients
|
||||
if command -v qrencode >/dev/null 2>&1; then
|
||||
QR_CODE_FILE="$VPN_CLIENT_CONFIG_DIR/${CLIENT_NAME}.png"
|
||||
qrencode -t PNG -o "$QR_CODE_FILE" < "$CLIENT_CONFIG_FILE"
|
||||
print_info "QR code generated: $QR_CODE_FILE"
|
||||
else
|
||||
print_warning "qrencode not installed. Cannot generate QR code for mobile clients."
|
||||
fi
|
||||
|
||||
# Set permissions on client files
|
||||
chmod 600 "$CLIENT_CONFIG_FILE"
|
||||
chmod 644 "$CLIENT_PUBLIC_KEY" "$QR_CODE_FILE" 2>/dev/null || true
|
||||
chown root:root "$CLIENT_CONFIG_FILE" "$CLIENT_PUBLIC_KEY" "$QR_CODE_FILE" 2>/dev/null || true
|
||||
|
||||
# Reload WireGuard configuration
|
||||
print_info "Reloading WireGuard configuration..."
|
||||
if wg-quick down "$VPN_INTERFACE" >/dev/null 2>&1; then
|
||||
:
|
||||
fi
|
||||
wg-quick up "$VPN_INTERFACE"
|
||||
|
||||
# Update firewall rules if needed
|
||||
systemctl restart firewall-persistence.service >/dev/null 2>&1 || true
|
||||
|
||||
# Display summary
|
||||
print_info "Client '$CLIENT_NAME' configured successfully!"
|
||||
echo ""
|
||||
echo "Client Configuration:"
|
||||
echo "- Name: $CLIENT_NAME"
|
||||
echo "- IP Address: $CLIENT_IP"
|
||||
echo "- Config File: $CLIENT_CONFIG_FILE"
|
||||
echo "- Private Key: $CLIENT_PRIVATE_KEY"
|
||||
echo "- Public Key: $CLIENT_PUBLIC_KEY"
|
||||
if [ -f "$QR_CODE_FILE" ]; then
|
||||
echo "- QR Code: $QR_CODE_FILE"
|
||||
fi
|
||||
echo ""
|
||||
echo "To connect from the client:"
|
||||
echo "1. Copy the configuration file to the client device"
|
||||
echo "2. Import it into WireGuard client"
|
||||
echo "3. Or scan the QR code with mobile WireGuard app"
|
||||
echo ""
|
||||
echo "Server Endpoint: $(curl -s ifconfig.me || echo "YOUR_SERVER_IP"):51820"
|
||||
|
||||
# Create installation package
|
||||
PACKAGE_DIR="/tmp/wireguard_client_${CLIENT_NAME}"
|
||||
mkdir -p "$PACKAGE_DIR"
|
||||
|
||||
cp "$CLIENT_CONFIG_FILE" "$PACKAGE_DIR/"
|
||||
cp "$QR_CODE_FILE" "$PACKAGE_DIR/" 2>/dev/null || true
|
||||
|
||||
# Create installation instructions
|
||||
cat > "$PACKAGE_DIR/README.txt" << EEOF
|
||||
Football System - WireGuard Client Installation
|
||||
==============================================
|
||||
|
||||
Client Name: $CLIENT_NAME
|
||||
Generated: $(date)
|
||||
|
||||
Files in this package:
|
||||
- ${CLIENT_NAME}.conf - WireGuard configuration file
|
||||
- ${CLIENT_NAME}.png - QR code for mobile clients (if generated)
|
||||
|
||||
Installation Instructions:
|
||||
|
||||
Desktop/Linux:
|
||||
1. Copy ${CLIENT_NAME}.conf to /etc/wireguard/
|
||||
2. Run: wg-quick up ${CLIENT_NAME}
|
||||
3. To auto-start: systemctl enable wg-quick@${CLIENT_NAME}
|
||||
|
||||
Mobile:
|
||||
1. Install WireGuard app from app store
|
||||
2. Scan the QR code (or import the configuration file)
|
||||
3. Toggle the connection to connect
|
||||
|
||||
Windows:
|
||||
1. Install WireGuard for Windows
|
||||
2. Click "Import tunnel(s) from file"
|
||||
3. Select ${CLIENT_NAME}.conf
|
||||
4. Click "Activate"
|
||||
|
||||
Verification:
|
||||
- After connecting, you should be able to access: 10.8.0.1
|
||||
- Run: ping 10.8.0.1
|
||||
- For system verification: ssh user@10.8.0.1
|
||||
|
||||
Security Notes:
|
||||
- Keep your private key secure
|
||||
- Do not share the configuration file publicly
|
||||
- Report any lost devices immediately
|
||||
|
||||
Support:
|
||||
- If you lose the configuration, contact your system administrator
|
||||
- Server endpoint: $(curl -s ifconfig.me || echo "YOUR_SERVER_IP"):51820
|
||||
|
||||
EEOF
|
||||
|
||||
tar -czf "/tmp/wireguard_client_${CLIENT_NAME}.tar.gz" -C "/tmp" "wireguard_client_${CLIENT_NAME}"
|
||||
rm -rf "$PACKAGE_DIR"
|
||||
|
||||
print_info "Client package created: /tmp/wireguard_client_${CLIENT_NAME}.tar.gz"
|
||||
|
||||
echo ""
|
||||
print_info "=== Client Configuration Summary ==="
|
||||
echo "Server Public Key: $SERVER_PUBKEY"
|
||||
echo "Client Private Key: $(cat "$CLIENT_PRIVATE_KEY")"
|
||||
echo "Client Public Key: $(cat "$CLIENT_PUBLIC_KEY")"
|
||||
echo "Client IP: $CLIENT_IP/24"
|
||||
echo "Server Endpoint: $(curl -s ifconfig.me || echo "YOUR_SERVER_IP"):51820"
|
||||
echo ""
|
||||
print_info "Client configuration completed successfully!"
|
||||
EOF
|
||||
|
||||
chmod 750 /usr/local/bin/wg-add-client.sh
|
||||
chown root:root /usr/local/bin/wg-add-client.sh
|
||||
|
||||
# Create client removal script
|
||||
cat > /usr/local/bin/wg-remove-client.sh << 'EOF'
|
||||
#!/bin/bash
|
||||
# Football System - WireGuard Client Removal
|
||||
# Securely removes WireGuard client and cleans up files
|
||||
|
||||
set -e
|
||||
|
||||
# Configuration
|
||||
VPN_INTERFACE="wg0"
|
||||
VPN_CLIENT_CONFIG_DIR="/etc/wireguard/clients"
|
||||
|
||||
# Colors
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
print_info() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
# Check if running as root
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
print_error "This script must be run as root"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Usage
|
||||
usage() {
|
||||
echo "Usage: $0 <client_name>"
|
||||
echo "Example: $0 charles"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Check arguments
|
||||
if [ $# -ne 1 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
CLIENT_NAME="$1"
|
||||
|
||||
# Check if client exists
|
||||
CLIENT_CONFIG_FILE="$VPN_CLIENT_CONFIG_DIR/${CLIENT_NAME}.conf"
|
||||
if [ ! -f "$CLIENT_CONFIG_FILE" ]; then
|
||||
print_error "Client '$CLIENT_NAME' not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get client public key
|
||||
CLIENT_PUBLIC_KEY_FILE="$VPN_CLIENT_CONFIG_DIR/${CLIENT_NAME}_public.key"
|
||||
if [ ! -f "$CLIENT_PUBLIC_KEY_FILE" ]; then
|
||||
print_error "Client public key file not found for '$CLIENT_NAME'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CLIENT_PUBKEY=$(cat "$CLIENT_PUBLIC_KEY_FILE")
|
||||
|
||||
print_info "Removing client '$CLIENT_NAME' from WireGuard configuration"
|
||||
|
||||
# Remove peer from server configuration
|
||||
# Create backup first
|
||||
cp "/etc/wireguard/wg0.conf" "/etc/wireguard/wg0.conf.backup.$(date +%Y%m%d_%H%M%S)"
|
||||
|
||||
# Remove client peer section from server config
|
||||
sed -i "/# Client: $CLIENT_NAME/,/PersistentKeepalive = 25$/d" "/etc/wireguard/wg0.conf"
|
||||
|
||||
# Remove client from active configuration (if connected)
|
||||
if wg show "$VPN_INTERFACE" | grep -q "$CLIENT_PUBKEY"; then
|
||||
print_info "Removing client from active configuration"
|
||||
wg set "$VPN_INTERFACE" peer "$CLIENT_PUBKEY" remove
|
||||
fi
|
||||
|
||||
# Remove client files
|
||||
print_info "Removing client configuration files"
|
||||
rm -f "$CLIENT_CONFIG_FILE"
|
||||
rm -f "$CLIENT_PUBLIC_KEY_FILE"
|
||||
rm -f "$VPN_CLIENT_CONFIG_DIR/${CLIENT_NAME}_private.key"
|
||||
rm -f "$VPN_CLIENT_CONFIG_DIR/${CLIENT_NAME}.png"
|
||||
|
||||
# Reload WireGuard configuration
|
||||
print_info "Reloading WireGuard configuration..."
|
||||
wg-quick down "$VPN_INTERFACE" >/dev/null 2>&1 || true
|
||||
wg-quick up "$VPN_INTERFACE"
|
||||
|
||||
print_info "Client '$CLIENT_NAME' removed successfully"
|
||||
EOF
|
||||
|
||||
chmod 750 /usr/local/bin/wg-remove-client.sh
|
||||
chown root:root /usr/local/bin/wg-remove-client.sh
|
||||
|
||||
# Create WireGuard status and management script
|
||||
cat > /usr/local/bin/wg-manage.sh << 'EOF'
|
||||
#!/bin/bash
|
||||
# Football System - WireGuard Management Script
|
||||
# Comprehensive WireGuard VPN status and management
|
||||
|
||||
# Configuration
|
||||
VPN_INTERFACE="wg0"
|
||||
VPN_CLIENT_CONFIG_DIR="/etc/wireguard/clients"
|
||||
|
||||
# Colors
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
print_header() {
|
||||
echo -e "${BLUE}$1${NC}"
|
||||
echo "=================================="
|
||||
}
|
||||
|
||||
print_info() {
|
||||
echo -e "${GREEN}✅ $1${NC}"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}⚠️ $1${NC}"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}❌ $1${NC}"
|
||||
}
|
||||
|
||||
# Main menu
|
||||
show_menu() {
|
||||
clear
|
||||
print_header "Football System - WireGuard VPN Management"
|
||||
echo ""
|
||||
echo "1. Show VPN Status"
|
||||
echo "2. List All Clients"
|
||||
echo "3. Add New Client"
|
||||
echo "4. Remove Client"
|
||||
echo "5. Show Client Details"
|
||||
echo "6. Restart VPN Service"
|
||||
echo "7. View VPN Logs"
|
||||
echo "8. Backup Configuration"
|
||||
echo "9. Exit"
|
||||
echo ""
|
||||
read -p "Select an option [1-9]: " choice
|
||||
}
|
||||
|
||||
# VPN status
|
||||
show_vpn_status() {
|
||||
print_header "WireGuard VPN Status"
|
||||
echo ""
|
||||
|
||||
if systemctl is-active --quiet wg-quick@$VPN_INTERFACE; then
|
||||
print_info "VPN Service: Active"
|
||||
else
|
||||
print_error "VPN Service: Inactive"
|
||||
fi
|
||||
|
||||
if systemctl is-enabled --quiet wg-quick@$VPN_INTERFACE; then
|
||||
print_info "VPN Auto-start: Enabled"
|
||||
else
|
||||
print_warning "VPN Auto-start: Disabled"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Interface Information:"
|
||||
if ip link show "$VPN_INTERFACE" >/dev/null 2>&1; then
|
||||
ip addr show "$VPN_INTERFACE"
|
||||
else
|
||||
print_warning "Interface $VPN_INTERFACE not found"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Active Connections:"
|
||||
if wg show "$VPN_INTERFACE" >/dev/null 2>&1; then
|
||||
wg show "$VPN_INTERFACE"
|
||||
|
||||
echo ""
|
||||
local connected_peers=$(wg show "$VPN_INTERFACE" | grep -c "peer:")
|
||||
echo "Total connected peers: $connected_peers"
|
||||
else
|
||||
print_warning "No active WireGuard interface"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
read -p "Press Enter to continue..."
|
||||
}
|
||||
|
||||
# List clients
|
||||
list_clients() {
|
||||
print_header "WireGuard Client List"
|
||||
echo ""
|
||||
|
||||
if [ ! -d "$VPN_CLIENT_CONFIG_DIR" ]; then
|
||||
print_error "Client configuration directory not found"
|
||||
read -p "Press Enter to continue..."
|
||||
return
|
||||
fi
|
||||
|
||||
local client_count=0
|
||||
for client_config in "$VPN_CLIENT_CONFIG_DIR"/*.conf; do
|
||||
if [ -f "$client_config" ]; then
|
||||
((client_count++))
|
||||
local client_name=$(basename "$client_config" .conf)
|
||||
local client_ip=$(grep -A 5 "\[Interface\]" "$client_config" | grep "Address" | cut -d'=' -f2 | xargs)
|
||||
local client_pubkey_file="$VPN_CLIENT_CONFIG_DIR/${client_name}_public.key"
|
||||
|
||||
if [ -f "$client_pubkey_file" ]; then
|
||||
local client_pubkey=$(cat "$client_pubkey_file")
|
||||
|
||||
# Check if client is connected
|
||||
if wg show "$VPN_INTERFACE" 2>/dev/null | grep -q "$client_pubkey"; then
|
||||
local status="🟢 Connected"
|
||||
else
|
||||
local status="🔴 Disconnected"
|
||||
fi
|
||||
else
|
||||
local status="⚠️ Keys Missing"
|
||||
fi
|
||||
|
||||
echo "Client: $client_name"
|
||||
echo " IP: $client_ip"
|
||||
echo " Status: $status"
|
||||
echo " Config: $client_config"
|
||||
echo ""
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$client_count" -eq 0 ]; then
|
||||
print_warning "No clients configured"
|
||||
else
|
||||
echo "Total clients: $client_count"
|
||||
fi
|
||||
|
||||
read -p "Press Enter to continue..."
|
||||
}
|
||||
|
||||
# Add client
|
||||
add_client() {
|
||||
print_header "Add New WireGuard Client"
|
||||
echo ""
|
||||
|
||||
read -p "Enter client name: " client_name
|
||||
if [ -z "$client_name" ]; then
|
||||
print_error "Client name cannot be empty"
|
||||
read -p "Press Enter to continue..."
|
||||
return
|
||||
fi
|
||||
|
||||
read -p "Enter client IP suffix (optional, press Enter for auto-assign): " ip_suffix
|
||||
|
||||
# Call the client addition script
|
||||
if wg-add-client.sh "$client_name" "$ip_suffix"; then
|
||||
print_info "Client added successfully"
|
||||
else
|
||||
print_error "Failed to add client"
|
||||
fi
|
||||
|
||||
read -p "Press Enter to continue..."
|
||||
}
|
||||
|
||||
# Remove client
|
||||
remove_client() {
|
||||
print_header "Remove WireGuard Client"
|
||||
echo ""
|
||||
|
||||
if [ ! -d "$VPN_CLIENT_CONFIG_DIR" ]; then
|
||||
print_error "No clients directory found"
|
||||
read -p "Press Enter to continue..."
|
||||
return
|
||||
fi
|
||||
|
||||
# List available clients
|
||||
local clients=()
|
||||
local index=1
|
||||
for client_config in "$VPN_CLIENT_CONFIG_DIR"/*.conf; do
|
||||
if [ -f "$client_config" ]; then
|
||||
local client_name=$(basename "$client_config" .conf)
|
||||
clients+=("$client_name")
|
||||
echo "$index. $client_name"
|
||||
((index++))
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ${#clients[@]} -eq 0 ]; then
|
||||
print_warning "No clients found"
|
||||
read -p "Press Enter to continue..."
|
||||
return
|
||||
fi
|
||||
|
||||
echo ""
|
||||
read -p "Select client to remove [1-${#clients[@]}]: " choice
|
||||
|
||||
if [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -le ${#clients[@]} ]; then
|
||||
local selected_client="${clients[$((choice-1))]}"
|
||||
echo ""
|
||||
echo "Selected client: $selected_client"
|
||||
read -p "Are you sure you want to remove this client? (y/N): " -n 1 -r
|
||||
echo
|
||||
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
if wg-remove-client.sh "$selected_client"; then
|
||||
print_info "Client '$selected_client' removed successfully"
|
||||
else
|
||||
print_error "Failed to remove client '$selected_client'"
|
||||
fi
|
||||
else
|
||||
print_info "Client removal cancelled"
|
||||
fi
|
||||
else
|
||||
print_error "Invalid selection"
|
||||
fi
|
||||
|
||||
read -p "Press Enter to continue..."
|
||||
}
|
||||
|
||||
# Show client details
|
||||
show_client_details() {
|
||||
print_header "Client Details"
|
||||
echo ""
|
||||
|
||||
read -p "Enter client name: " client_name
|
||||
if [ -z "$client_name" ]; then
|
||||
print_error "Client name cannot be empty"
|
||||
read -p "Press Enter to continue..."
|
||||
return
|
||||
fi
|
||||
|
||||
local client_config="$VPN_CLIENT_CONFIG_DIR/${client_name}.conf"
|
||||
if [ ! -f "$client_config" ]; then
|
||||
print_error "Client '$client_name' not found"
|
||||
read -p "Press Enter to continue..."
|
||||
return
|
||||
fi
|
||||
|
||||
echo "Client Configuration for: $client_name"
|
||||
echo "======================================"
|
||||
cat "$client_config"
|
||||
|
||||
echo ""
|
||||
echo "Files:"
|
||||
echo "- Config: $client_config"
|
||||
echo "- Private Key: $VPN_CLIENT_CONFIG_DIR/${client_name}_private.key"
|
||||
echo "- Public Key: $VPN_CLIENT_CONFIG_DIR/${client_name}_public.key"
|
||||
echo "- QR Code: $VPN_CLIENT_CONFIG_DIR/${client_name}.png"
|
||||
|
||||
read -p "Press Enter to continue..."
|
||||
}
|
||||
|
||||
# Restart VPN service
|
||||
restart_vpn() {
|
||||
print_header "Restart VPN Service"
|
||||
echo ""
|
||||
|
||||
print_info "Stopping VPN service..."
|
||||
systemctl stop wg-quick@$VPN_INTERFACE
|
||||
|
||||
sleep 2
|
||||
|
||||
print_info "Starting VPN service..."
|
||||
systemctl start wg-quick@$VPN_INTERFACE
|
||||
|
||||
sleep 2
|
||||
|
||||
if systemctl is-active --quiet wg-quick@$VPN_INTERFACE; then
|
||||
print_info "VPN service restarted successfully"
|
||||
else
|
||||
print_error "VPN service failed to restart"
|
||||
fi
|
||||
|
||||
read -p "Press Enter to continue..."
|
||||
}
|
||||
|
||||
# View logs
|
||||
view_logs() {
|
||||
print_header "WireGuard Logs"
|
||||
echo ""
|
||||
|
||||
echo "Recent systemd logs:"
|
||||
journalctl -u wg-quick@$VPN_INTERFACE --since "1 hour ago" -n 20 --no-pager
|
||||
|
||||
echo ""
|
||||
echo "System log entries (last 10):"
|
||||
grep -i wireguard /var/log/syslog | tail -10
|
||||
|
||||
echo ""
|
||||
read -p "Press Enter to continue..."
|
||||
}
|
||||
|
||||
# Backup configuration
|
||||
backup_config() {
|
||||
print_header "Backup WireGuard Configuration"
|
||||
echo ""
|
||||
|
||||
local backup_dir="/var/backups/wireguard"
|
||||
local backup_file="wireguard_backup_$(date +%Y%m%d_%H%M%S).tar.gz"
|
||||
|
||||
mkdir -p "$backup_dir"
|
||||
|
||||
print_info "Creating backup..."
|
||||
|
||||
tar -czf "$backup_dir/$backup_file" -C /etc/wireguard .
|
||||
|
||||
if [ -f "$backup_dir/$backup_file" ]; then
|
||||
print_info "Backup created successfully: $backup_dir/$backup_file"
|
||||
local backup_size=$(du -h "$backup_dir/$backup_file" | cut -f1)
|
||||
echo "Backup size: $backup_size"
|
||||
|
||||
# Show backup contents
|
||||
echo ""
|
||||
echo "Backup contents:"
|
||||
tar -tzf "$backup_dir/$backup_file"
|
||||
else
|
||||
print_error "Failed to create backup"
|
||||
fi
|
||||
|
||||
read -p "Press Enter to continue..."
|
||||
}
|
||||
|
||||
# Main loop
|
||||
main() {
|
||||
while true; do
|
||||
show_menu
|
||||
|
||||
case $choice in
|
||||
1) show_vpn_status ;;
|
||||
2) list_clients ;;
|
||||
3) add_client ;;
|
||||
4) remove_client ;;
|
||||
5) show_client_details ;;
|
||||
6) restart_vpn ;;
|
||||
7) view_logs ;;
|
||||
8) backup_config ;;
|
||||
9) print_info "Exiting WireGuard Management"; exit 0 ;;
|
||||
*) print_error "Invalid option. Please select 1-9."; sleep 2 ;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
# Check if running as root
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
echo "This script must be run as root"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Start the management interface
|
||||
main
|
||||
EOF
|
||||
|
||||
chmod 750 /usr/local/bin/wg-manage.sh
|
||||
chown root:root /usr/local/bin/wg-manage.sh
|
||||
|
||||
# Create systemd service for WireGuard
|
||||
cat > /etc/systemd/system/wireguard-manager.service << 'EOF'
|
||||
[Unit]
|
||||
Description=WireGuard VPN Management Service
|
||||
Documentation=man:wg(8)
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/usr/bin/wg-quick up wg0
|
||||
ExecStop=/usr/bin/wg-quick down wg0
|
||||
ExecReload=/usr/bin/wg-quick down wg0 && /usr/bin/wg-quick up wg0
|
||||
|
||||
# Security settings
|
||||
NoNewPrivileges=yes
|
||||
ProtectSystem=strict
|
||||
ProtectHome=yes
|
||||
ReadWritePaths=/etc/wireguard /var/log/wireguard /run
|
||||
PrivateTmp=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
# Enable and start WireGuard
|
||||
systemctl daemon-reload
|
||||
systemctl enable wireguard-manager.service
|
||||
systemctl start wireguard-manager.service
|
||||
|
||||
# Create log rotation for WireGuard
|
||||
cat > /etc/logrotate.d/wireguard << 'EOF'
|
||||
# Football System - WireGuard Log Rotation
|
||||
|
||||
/var/log/wireguard/*.log {
|
||||
daily
|
||||
rotate 30
|
||||
compress
|
||||
delaycompress
|
||||
missingok
|
||||
notifempty
|
||||
create 0640 root adm
|
||||
sharedscripts
|
||||
postrotate
|
||||
systemctl reload rsyslog >/dev/null 2>&1 || true
|
||||
endscript
|
||||
}
|
||||
EOF
|
||||
|
||||
chmod 644 /etc/logrotate.d/wireguard
|
||||
chown root:root /etc/logrotate.d/wireguard
|
||||
|
||||
# Start WireGuard interface
|
||||
print_info "Starting WireGuard VPN interface..."
|
||||
if wg-quick up wg0; then
|
||||
print_info "WireGuard VPN started successfully"
|
||||
else
|
||||
print_warning "WireGuard VPN started with warnings (common on first boot)"
|
||||
fi
|
||||
|
||||
# Display summary
|
||||
echo ""
|
||||
print_info "=== WireGuard VPN Configuration Summary ==="
|
||||
echo "✅ WireGuard server configured"
|
||||
echo "✅ Interface: wg0"
|
||||
echo "✅ VPN Network: 10.8.0.0/24"
|
||||
echo "✅ Server IP: 10.8.0.1"
|
||||
echo "✅ Listen Port: 51820"
|
||||
echo ""
|
||||
echo "Management Tools:"
|
||||
echo "- Add client: wg-add-client.sh <client_name>"
|
||||
echo "- Remove client: wg-remove-client.sh <client_name>"
|
||||
echo "- Interactive management: wg-manage.sh"
|
||||
echo ""
|
||||
echo "Server Public Key:"
|
||||
echo "$(cat "$SERVER_PUBLIC_KEY")"
|
||||
echo ""
|
||||
echo "Server Endpoint:"
|
||||
echo "$(curl -s ifconfig.me || echo "YOUR_SERVER_IP"):51820"
|
||||
echo ""
|
||||
echo "Files created:"
|
||||
echo "- Server config: /etc/wireguard/wg0.conf"
|
||||
echo "- Client configs: /etc/wireguard/clients/"
|
||||
echo "- Keys: /etc/wireguard/keys/"
|
||||
echo "- Logs: /var/log/wireguard/"
|
||||
echo ""
|
||||
print_info "WireGuard VPN configuration completed successfully!"
|
||||
@@ -3,7 +3,7 @@
|
||||
# Creates Debian 13 ISO with embedded preseed configuration
|
||||
# ALL work done in Docker container - no host operations
|
||||
|
||||
set -e
|
||||
set -euo pipefail
|
||||
|
||||
BUILD_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
OUTPUT_DIR="$BUILD_DIR/output"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Football VM Control Script (libvirt/virsh)
|
||||
# Manages QEMU VM for testing Football ISO
|
||||
|
||||
set -e
|
||||
set -euo pipefail
|
||||
|
||||
BUILD_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
ISO_FILE="$BUILD_DIR/output/football-installer.iso"
|
||||
@@ -115,7 +115,19 @@ EOF
|
||||
|
||||
stop)
|
||||
echo "Stopping VM..."
|
||||
virsh shutdown "$VM_NAME" && echo "VM stopped" || virsh destroy "$VM_NAME" && echo "VM destroyed"
|
||||
virsh shutdown "$VM_NAME" 2>/dev/null || true
|
||||
# Wait for VM to actually stop (up to 30 seconds)
|
||||
for _ in {1..30}; do
|
||||
if ! virsh list --name | grep -q "^${VM_NAME}$"; then
|
||||
echo "VM stopped"
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
# If still running, force destroy
|
||||
if virsh list --name | grep -q "^${VM_NAME}$"; then
|
||||
virsh destroy "$VM_NAME" && echo "VM destroyed"
|
||||
fi
|
||||
;;
|
||||
|
||||
reboot)
|
||||
@@ -141,10 +153,8 @@ EOF
|
||||
;;
|
||||
|
||||
delete)
|
||||
echo "WARNING: This will delete VM, disk, and ISO!"
|
||||
echo "Press Ctrl+C to cancel, or Enter to continue..."
|
||||
read
|
||||
|
||||
echo "Deleting VM, disk, and ISO..."
|
||||
|
||||
# Stop VM
|
||||
virsh destroy "$VM_NAME" 2>/dev/null || true
|
||||
virsh undefine "$VM_NAME" 2>/dev/null || true
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Boots QEMU VM from ISO to test installation
|
||||
# All work done in Docker container
|
||||
|
||||
set -e
|
||||
set -euo pipefail
|
||||
|
||||
BUILD_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
ISO_PATH="$BUILD_DIR/output/football-installer.iso"
|
||||
@@ -107,7 +107,7 @@ screen -dmS football-iso-test \
|
||||
# Save QEMU PID for later use
|
||||
pgrep -f "qemu-system-x86_64.*$DISK_PATH" | head -1 > "$VM_PID_FILE"
|
||||
|
||||
echo "✅ VM started (PID: $(cat $VM_PID_FILE 2>/dev/null || echo 'unknown'))"
|
||||
echo "✅ VM started (PID: $(cat "$VM_PID_FILE" 2>/dev/null || echo 'unknown'))"
|
||||
echo ""
|
||||
|
||||
# ============================================================================
|
||||
@@ -117,7 +117,7 @@ echo ""
|
||||
echo "[4/4] Monitoring boot (waiting 120 seconds)..."
|
||||
echo ""
|
||||
|
||||
for i in {1..120}; do
|
||||
for _ in {1..120}; do
|
||||
if [ -f "$CONSOLE_LOG" ]; then
|
||||
# Check for installation prompts
|
||||
if grep -q "Choose the country" "$CONSOLE_LOG" 2>/dev/null; then
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Verifies all functional requirements are met after installation
|
||||
# Runs automatically on first boot
|
||||
|
||||
set -e
|
||||
set -euo pipefail
|
||||
|
||||
LOG_FILE="/var/log/football-first-boot-verification.log"
|
||||
STATUS_FILE="/var/lib/football/verification-status"
|
||||
@@ -12,7 +12,6 @@ STATUS_FILE="/var/lib/football/verification-status"
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
# Logging function
|
||||
|
||||
Reference in New Issue
Block a user