外观
PostgreSQL 暴力攻击防护
fail2ban 配置
fail2ban 是防止暴力攻击的有效工具,可以监控日志并自动封禁恶意IP。
1. 安装与配置
bash
# 安装 fail2ban
sudo apt-get install fail2ban
# 或
sudo yum install fail2ban2. 配置 fail2ban 规则
bash
# 创建 PostgreSQL 配置文件
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local在 jail.local 文件中添加 PostgreSQL 规则:
ini
# PostgreSQL 暴力攻击防护配置
[postgresql]
enabled = true
port = 5432
filter = postgresql
logpath = /var/log/postgresql/postgresql-15-main.log
maxretry = 3
findtime = 600
bantime = 3600
ignoreip = 127.0.0.1 192.168.1.0/243. 创建 PostgreSQL 过滤器
bash
# 创建 PostgreSQL 过滤器配置
sudo nano /etc/fail2ban/filter.d/postgresql.conf添加以下内容:
ini
# Fail2Ban filter for PostgreSQL authentication failures
#
[Definition]
# 匹配 PostgreSQL 认证失败日志
failregex = FATAL: password authentication failed for user \"<F-USER>.*</F-USER>"
FATAL: no pg_hba.conf entry for host \"<HOST>", user \"<F-USER>.*</F-USER>", database \"<F-DATABASE>.*</F-DATABASE>", SSL off
FATAL: no pg_hba.conf entry for host \"<HOST>", user \"<F-USER>.*</F-USER>", database \"<F-DATABASE>.*</F-DATABASE>", SSL on
ignoreregex =4. 启动和测试 fail2ban
bash
# 启动 fail2ban 服务
sudo systemctl start fail2ban
sudo systemctl enable fail2ban
# 检查 fail2ban 状态
sudo fail2ban-client status
sudo fail2ban-client status postgresql
# 手动解封 IP
sudo fail2ban-client set postgresql unbanip 192.168.1.100密码策略配置
1. 使用 pgcrypto 实现强密码
sql
-- 安装 pgcrypto 扩展
CREATE EXTENSION IF NOT EXISTS pgcrypto;
-- 创建用户表,使用强密码
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL,
password TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 插入用户,使用强密码哈希
INSERT INTO users (username, password)
VALUES (
'admin',
crypt('StrongPassword123!', gen_salt('bf', 12)) -- 成本因子 12,增强安全性
);
-- 验证密码
SELECT * FROM users
WHERE username = 'admin'
AND password = crypt('StrongPassword123!', password);2. 使用 passwordcheck 扩展
bash
# 安装 passwordcheck 扩展
sudo apt-get install postgresql-15-passwordcheck
# 或
sudo yum install postgresql15-passwordcheck
# 修改 postgresql.conf 启用扩展
shared_preload_libraries = 'passwordcheck'
# 重启 PostgreSQL
sudo systemctl restart postgresqlpg_hba.conf 配置
pg_hba.conf 是 PostgreSQL 的主机基础认证配置文件,可以限制哪些 IP 可以连接到数据库。
1. 基础配置
txt
# PostgreSQL 主机基础认证配置
# TYPE DATABASE USER CIDR-ADDRESS METHOD
# 允许本地连接
local all all peer
# 允许特定 IP 连接
host all all 192.168.1.0/24 md5
host all admin 10.0.0.50/32 md5
# 允许特定用户从特定 IP 连接特定数据库
host mydb myuser 192.168.1.10/32 md5
# 拒绝其他所有连接
host all all 0.0.0.0/0 reject
host all all ::/0 reject2. 高级配置
txt
# 使用 scram-sha-256 认证(更安全)
host all all 192.168.1.0/24 scram-sha-256
# 要求 SSL 连接
hostssl all all 192.168.1.0/24 md5
# 拒绝特定 IP
host all all 10.0.0.100/32 reject
# 限制连接数量(结合 fail2ban 使用)
host all all 0.0.0.0/0 md5其他防护措施
1. 限制连接数
sql
-- 修改 postgresql.conf 限制最大连接数
max_connections = 100
-- 限制特定用户的连接数
ALTER ROLE myuser CONNECTION LIMIT 10;
-- 限制特定数据库的连接数
ALTER DATABASE mydb CONNECTION LIMIT 50;2. 使用连接池
bash
# 使用 PgBouncer 或 PGPool-II 作为连接池
# 配置 PgBouncer 限制连接数
max_client_conn = 1000
default_pool_size = 20
min_pool_size = 5
reserve_pool_size = 53. 监控登录尝试
sql
-- 查看当前连接
SELECT usename, client_addr, application_name, backend_start
FROM pg_stat_activity
WHERE state = 'active';
-- 查看失败的连接尝试(需要 pgaudit 扩展)
SELECT * FROM pg_audit_log
WHERE command_tag = 'FATAL'
ORDER BY statement_timestamp DESC;4. 使用防火墙
bash
# 使用 iptables 限制 PostgreSQL 端口访问
iptables -A INPUT -p tcp -s 192.168.1.0/24 --dport 5432 -j ACCEPT
iptables -A INPUT -p tcp --dport 5432 -j DROP
# 使用 ufw 限制 PostgreSQL 端口访问
sudo ufw allow from 192.168.1.0/24 to any port 5432
sudo ufw deny 5432
sudo ufw enable暴力攻击防护最佳实践
1. 多层次防护策略
- 第一层:防火墙限制(iptables/ufw)
- 第二层:pg_hba.conf 访问控制
- 第三层:fail2ban 自动封禁
- 第四层:强密码策略
- 第五层:连接数限制
- 第六层:监控与告警
2. 定期审计
bash
# 定期检查 fail2ban 日志
sudo cat /var/log/fail2ban.log | grep -i postgresql
# 检查 PostgreSQL 认证日志
sudo grep -i "FATAL" /var/log/postgresql/postgresql-15-main.log | tail -n 20
# 定期检查当前连接
sudo -u postgres psql -c "SELECT usename, client_addr, count(*) FROM pg_stat_activity GROUP BY usename, client_addr;"3. 安全更新
bash
# 定期更新系统和 PostgreSQL
sudo apt-get update && sudo apt-get upgrade -y
sudo yum update -y
# 定期更新 fail2ban
sudo apt-get update && sudo apt-get install --only-upgrade fail2ban常见问题(FAQ)
Q1:fail2ban 误封了合法 IP 怎么办?
A1:可以手动解封 IP:
bash
sudo fail2ban-client set postgresql unbanip 192.168.1.100或者在 jail.local 中添加 ignoreip 配置,排除合法 IP 段。
Q2:如何调整 fail2ban 的敏感度?
A2:修改 jail.local 中的 maxretry、findtime 和 bantime 参数:
- maxretry:允许的失败尝试次数
- findtime:在多长时间内统计失败尝试
- bantime:封禁时间(秒)
Q3:passwordcheck 扩展支持哪些密码策略?
A3:passwordcheck 扩展默认检查:
- 密码长度至少 8 个字符
- 密码包含至少一个大写字母
- 密码包含至少一个小写字母
- 密码包含至少一个数字
- 密码不包含用户名
Q4:如何监控暴力攻击尝试?
A4:
- 使用 fail2ban 监控认证失败日志
- 使用 pgaudit 扩展记录详细审计日志
- 配置日志告警,当认证失败次数超过阈值时发送告警
Q5:如何防止 DDoS 攻击?
A5:
- 使用防火墙限制连接速率
- 配置连接池限制并发连接数
- 使用 CDN 或 DDoS 防护服务
- 优化 PostgreSQL 配置,提高抗攻击能力
Q6:如何验证暴力攻击防护是否生效?
A6:
- 从测试 IP 故意多次输入错误密码,检查是否被封禁
- 检查 fail2ban 状态,确认封禁记录
- 检查 PostgreSQL 日志,确认认证失败记录
- 模拟大量连接,检查系统资源使用情况
