large fail2ban and other security improvements

This commit is contained in:
Joby 2024-10-23 17:02:32 -06:00
parent 04be6be893
commit 11c6f69c35
5 changed files with 88 additions and 11 deletions

View file

@ -39,6 +39,14 @@ server {
server_name _;
# Apply general rate limit
limit_req zone=general burst=100 nodelay;
# Check for banned IPs
if (\$is_banned) {
return 403 "Forbidden";
}
location / {
try_files \$uri \$uri/ =404;
}

View file

@ -43,14 +43,15 @@ EOL
systemctl restart mysql
# Create MySQL fail2ban configuration
cat > /etc/fail2ban/jail.d/mysql.conf << EOL
[mysqld-auth]
enabled = true
filter = mysqld-auth
port = 3306
logpath = /var/log/mysql/error.log
maxretry = 5
bantime = 3600
tee /etc/fail2ban/jail.d/mysql.conf << 'EOL'
[mysql]
enabled = true
filter = mysql
port = 3306
logpath = /var/log/mysql/error.log
maxretry = 10
findtime = 600
bantime = 3600
EOL
# Ensure fail2ban can read the MySQL log
@ -58,9 +59,9 @@ EOL
# usermod -a -G adm fail2ban
# Create MySQL auth filter for fail2ban
cat > /etc/fail2ban/filter.d/mysqld-auth.conf << EOL
tee /etc/fail2ban/filter.d/mysql.conf << 'EOL'
[Definition]
failregex = ^%(__prefix_line)s[0-9]+ \[Warning\] Access denied for user '\w+'@'<HOST>'
failregex = ^\s*\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+Z\s+\d+\s+\[Warning\].*IP address '<HOST>'.*$
ignoreregex =
EOL

View file

@ -0,0 +1,55 @@
#!/bin/bash
# Check if script is run as root
if [ "$EUID" -ne 0 ]; then
echo "Please run as root or with sudo"
exit 1
fi
# Install requirements
echo "Installing required packages..."
apt-get install -y nginx-extras
# Create the fail2ban check script
echo "Creating fail2ban check script..."
tee /usr/local/bin/check_fail2ban.sh << 'SCRIPT'
#!/bin/bash
IP="$1"
# Get list of all active jails
JAILS=$(fail2ban-client status | grep "Jail list:" | sed "s/^[^:]*:[ \t]*//" | sed "s/,//g")
# Check each jail for the IP
for JAIL in $JAILS; do
if fail2ban-client status "$JAIL" | grep -q "IP list:\s*.*$IP"; then
exit 0 # IP is banned in at least one jail
fi
done
exit 1 # IP is not banned in any jail
SCRIPT
chmod +x /usr/local/bin/check_fail2ban.sh
chown www-data:www-data /usr/local/bin/check_fail2ban.sh
# Create the JavaScript module for NGINX
echo "Creating NGINX JavaScript module..."
mkdir -p /etc/nginx/modules-available/
tee /etc/nginx/modules-available/check_ban.js << 'JSMODULE'
function checkBan(r) {
var ip = r.variables.http_cf_connecting_ip;
var s = require('process').spawnSync('/usr/local/bin/check_fail2ban.sh', [ip]);
return s.status === 0 ? '1' : '0';
}
export default {checkBan};
JSMODULE
# Test NGINX configuration
echo "Testing NGINX configuration..."
nginx -t
# Restart services
echo "Restarting services..."
systemctl restart fail2ban
systemctl restart nginx
echo "Installation complete!"
echo "Please check /var/log/nginx/error.log for any issues."

View file

@ -0,0 +1,9 @@
load_module modules/ngx_http_js_module.so;
js_import /etc/nginx/modules-available/check_ban.js;
js_set $exec_check_ban check_ban.checkBan;
map $http_cf_connecting_ip $is_banned {
default 0;
"~.*" "${exec_check_ban $http_cf_connecting_ip}";
}

View file

@ -17,13 +17,17 @@ server {
ssl_certificate_key /etc/letsencrypt/live/$DOMAIN/privkey.pem;
include snippets/ssl.conf;
# Check for banned IPs
if ($is_banned) {
return 403 "Forbidden";
}
# Apply general rate limit
limit_req zone=general burst=100 nodelay;
# Content Security Policy (needs to be per-domain)
add_header Content-Security-Policy "default-src 'self' *.$DOMAIN; script-src 'self' 'unsafe-inline' 'unsafe-eval' *.$DOMAIN; style-src 'self' 'unsafe-inline' *.$DOMAIN; img-src 'self' data: *.$DOMAIN; font-src 'self' data: *.$DOMAIN; connect-src 'self' *.$DOMAIN; frame-src 'self' *.$DOMAIN; media-src 'self' *.$DOMAIN; object-src 'none'; base-uri 'self'; form-action 'self' *.$DOMAIN" always;
# Subdomain handling
set $subdomain '';
set $full_root "/var/www/$DOMAIN/_main/www";