IRC 服务器搭建完全指南 / 第 7 章:安全加固
第 7 章:安全加固
安全不是可选项,而是底线。本章从 TLS 加固、认证机制、网络防护到审计日志,全方位提升 IRC 服务器的安全性。
7.1 TLS/SSL 配置
7.1.1 TLS 的重要性
| 风险 | 说明 | 是否使用 TLS |
|---|
| 中间人攻击 | 攻击者可以窃听和篡改通信 | ✅ 防护 |
| 密码泄露 | 明文传输的密码可被截获 | ✅ 防护 |
| IP 泄露 | 用户真实 IP 可被追踪 | ✅ 防护(Cloaking) |
| 会话劫持 | 攻击者可以接管用户会话 | ✅ 防护 |
| 内容篡改 | 消息可被篡改 | ✅ 防护 |
7.1.2 申请 Let’s Encrypt 证书
# 安装 certbot
sudo apt install -y certbot
# 使用 standalone 模式申请证书
sudo certbot certonly --standalone -d irc.example.com
# 证书文件位置
# /etc/letsencrypt/live/irc.example.com/fullchain.pem
# /etc/letsencrypt/live/irc.example.com/privkey.pem
# 设置自动续期(certbot 通常自动处理)
sudo certbot renew --dry-run
7.1.3 UnrealIRCd TLS 加固配置
/* TLS 服务器配置 */
tls {
/* 证书文件 */
certificate "/etc/letsencrypt/live/irc.example.com/fullchain.pem";
key "/etc/letsencrypt/live/irc.example.com/privkey.pem";
/* 协议版本 */
protocols "TLSv1.2 TLSv1.3";
/* 密码套件(Mozilla Intermediate) */
ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384";
/* DH 参数 */
dh-file "conf/tls/dhparam.pem";
/* 启用 OCSP Stapling */
# stapling yes;
}
/* 生成 DH 参数 */
/* openssl dhparam -out conf/tls/dhparam.pem 4096 */
7.1.4 TLS 版本与密码套件推荐
# 生成 DH 参数(耗时较长)
openssl dhparam -out /opt/irc/conf/tls/dhparam.pem 4096
# 测试 TLS 配置
openssl s_client -connect irc.example.com:6697 \
-tls1_2 -brief
# 检查支持的密码套件
nmap --script ssl-enum-ciphers -p 6697 irc.example.com
推荐的 TLS 配置:
| 参数 | 推荐值 |
|---|
| 最低 TLS 版本 | TLS 1.2 |
| 推荐 TLS 版本 | TLS 1.3 |
| 密码套件 | ECDHE + AES-GCM |
| DH 参数 | 4096 位 |
| 证书密钥 | RSA 4096 或 ECDSA P-256 |
7.1.5 禁用明文连接
/* UnrealIRCd - 强制 TLS */
/* 方法 1:只监听 TLS 端口 */
listen {
ip *;
port 6697;
options { clients; tls; }
}
/* 不监听 6667 */
/* 方法 2:要求 TLS 的连接类 */
allow {
mask *@*;
class clients;
# 通过 flags 要求 TLS
}
/* 方法 3:通过模式强制 */
set {
modes-on-connect "+xz"; /* +z = secure connection */
}
7.2 SASL 强制认证
7.2.1 配置强制 SASL 登录
# Ergo 配置强制 SASL
accounts:
require-sasl:
enabled: true
# 允许的例外(如 Tor 连接)
allow-tor: false
# 策略解释
# - 新连接必须通过 SASL 认证
# - 未认证的连接将被断开
/* UnrealIRCd - 通过 sasl 模块配置 */
loadmodule "sasl";
/* 可以通过 AuthPrompt 模块实现强制 SASL */
loadmodule "authprompt";
set {
authprompt {
/* 启用认证提示 */
mask *@*;
enable-sasl yes;
}
}
7.2.2 SASL 机制对比
| 机制 | 安全性 | 说明 |
|---|
| PLAIN | 中 | 明文密码(在 TLS 隧道内安全) |
| EXTERNAL | 高 | TLS 证书认证,无密码传输 |
| SCRAM-SHA-256 | 高 | 挑战-响应机制,密码不传输 |
7.2.3 客户端 SASL 配置
# Weechat SASL EXTERNAL 配置
set irc.server.example.tls on
set irc.server.example.tls_verify on
set irc.server.example.ssl_cert "%h/ssl/client.pem"
set irc.server.example.sasl_mechanism external
set irc.server.example.sasl_username "alice"
# Weechat SASL PLAIN 配置
set irc.server.example.sasl_mechanism plain
set irc.server.example.sasl_username "alice"
set irc.server.example.sasl_password "mypassword"
7.3 网络层防护
7.3.1 防火墙配置
# iptables 基础规则
# 允许 SSH
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# 允许 IRC TLS
sudo iptables -A INPUT -p tcp --dport 6697 -j ACCEPT
# 允许 WebSocket TLS
sudo iptables -A INPUT -p tcp --dport 8443 -j ACCEPT
# 限制每 IP 连接速率(防 DDoS)
sudo iptables -A INPUT -p tcp --dport 6697 \
-m connlimit --connlimit-above 5 -j DROP
# 限制新建连接速率
sudo iptables -A INPUT -p tcp --dport 6697 \
-m state --state NEW -m recent --set
sudo iptables -A INPUT -p tcp --dport 6697 \
-m state --state NEW -m recent --update --seconds 60 --hitcount 10 -j DROP
# 保存规则
sudo iptables-save > /etc/iptables/rules.v4
7.3.2 使用 fail2ban
# 安装 fail2ban
sudo apt install -y fail2ban
# 创建 IRC jail 配置
cat > /etc/fail2ban/jail.d/ircd.conf << 'EOF'
[ircd]
enabled = true
port = 6667,6697
filter = ircd
logpath = /opt/irc/logs/ircd.log
maxretry = 5
findtime = 600
bantime = 3600
EOF
# 创建过滤器
cat > /etc/fail2ban/filter.d/ircd.conf << 'EOF'
[Definition]
failregex = ^.*Client connecting: .* \(<HOST>\)$
ignoreregex =
EOF
# 启动 fail2ban
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
7.3.3 DDoS 防护策略
# Ergo 连接限制配置
server:
# 连接速率限制
connection-throttling:
enabled: true
max-connections: 5 # 同一 IP 最大连接数
window: "10s" # 时间窗口
burst: 3 # 允许的突发连接数
limits:
# 每 IP 连接限制
max-connections-per-ip: 5
/* UnrealIRCd 连接限制 */
class clients {
pingfreq 60;
maxclients 5000;
sendq 300k;
recvq 8k;
}
allow {
mask *@*;
class clients;
maxperip 3; /* 每 IP 最多 3 个连接 */
}
7.3.4 使用 CDN/代理保护
┌──────────┐ ┌─────────────┐ ┌──────────┐
│ Client │───►│ Cloudflare │───►│ IRC 服务器│
│ │ │ Spectrum │ │ │
└──────────┘ └─────────────┘ └──────────┘
│
隐藏真实 IP
防护 DDoS
WebSocket 支持
Cloudflare Spectrum 配置:
- 将 DNS 指向 Cloudflare
- 配置 Spectrum 规则转发 6697/TCP
- 启用代理保护
- 配置客户端连接到
irc.example.com:6697
7.4 审计与日志
7.4.1 日志级别
| 级别 | 说明 | 使用场景 |
|---|
debug | 调试信息 | 开发环境 |
info | 一般信息 | 日常运维 |
warn | 警告 | 需关注的事件 |
error | 错误 | 需立即处理 |
fatal | 致命错误 | 服务中断 |
7.4.2 UnrealIRCd 日志配置
log {
source { *; }
destination {
file "logs/ircd.log" { maxsize 100M; }
/* 同时记录到 syslog */
/* syslog { facility local3; } */
}
}
/* 单独的安全事件日志 */
log {
source { security; oper; }
destination {
file "logs/security.log" { maxsize 50M; }
}
}
7.4.3 Ergo 日志配置
logging:
- method: file
filename: "/var/log/ergo/ircd.log"
level: info
# 安全事件单独记录
- method: file
filename: "/var/log/ergo/security.log"
level: warn
type: security
# JSON 格式日志(便于分析)
- method: file
filename: "/var/log/ergo/ircd.json"
level: info
type: "*"
json: true
7.4.4 日志轮转
# /etc/logrotate.d/ircd
/opt/irc/logs/*.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
create 0640 irc irc
postrotate
systemctl reload unrealircd > /dev/null 2>&1 || true
endscript
}
7.4.5 监控告警
#!/bin/bash
# monitor_ircd.sh - IRC 服务器健康检查
LOG_FILE="/opt/irc/logs/ircd.log"
# 检查进程
if ! pgrep -x "unrealircd" > /dev/null; then
echo "CRITICAL: IRC 服务进程不存在" | mail -s "IRC Alert" admin@example.com
exit 1
fi
# 检查端口
if ! ss -tlnp | grep -q ":6697"; then
echo "CRITICAL: IRC TLS 端口未监听" | mail -s "IRC Alert" admin@example.com
exit 1
fi
# 检查最近日志中的错误
ERRORS=$(tail -100 "$LOG_FILE" | grep -i "error\|fatal" | wc -l)
if [ "$ERRORS" -gt 10 ]; then
echo "WARNING: 发现 $ERRORS 条错误日志" | mail -s "IRC Warning" admin@example.com
fi
# 检查连接数
CONNECTIONS=$(ss -tnp | grep ":6697" | wc -l)
echo "当前连接数: $CONNECTIONS"
7.5 运行时安全
7.5.1 以非特权用户运行
# 创建专用用户
sudo useradd -r -m -s /bin/false ircd
sudo chown -R ircd:ircd /opt/irc/
# systemd 服务文件
# [Service]
# User=ircd
# Group=ircd
7.5.2 文件权限
# 正确的文件权限
chmod 700 /opt/irc/
chmod 700 /opt/irc/conf/
chmod 600 /opt/irc/conf/*.conf
chmod 600 /opt/irc/conf/tls/server.key
chmod 644 /opt/irc/conf/tls/server.crt
chmod 700 /opt/irc/logs/
chmod 644 /opt/irc/logs/*.log
7.5.3 资源限制
# /etc/security/limits.conf
ircd soft nofile 65536
ircd hard nofile 65536
ircd soft nproc 4096
ircd hard nproc 4096
# systemd 服务配置
[Service]
LimitNOFILE=65536
LimitNPROC=4096
MemoryMax=512M
CPUQuota=200%
7.5.4 Seccomp 和 AppArmor
# AppArmor 配置
cat > /etc/apparmor.d/usr.local.ircd << 'EOF'
#include <tunables/global>
/opt/irc/bin/unrealircd {
#include <abstractions/base>
#include <abstractions/nameservice>
/opt/irc/** r,
/opt/irc/conf/** r,
/opt/irc/logs/** rw,
/opt/irc/run/** rw,
network inet stream,
network inet6 stream,
/etc/ssl/openssl.cnf r,
}
EOF
sudo apparmor_parser -r /etc/apparmor.d/usr.local.ircd
7.6 安全检查清单
| 检查项 | 状态 | 说明 |
|---|
| TLS 1.2+ 强制 | ☐ | 禁用 SSLv3, TLS 1.0, TLS 1.1 |
| 明文连接禁用 | ☐ | 不监听 6667 端口 |
| 证书自动续期 | ☐ | Let’s Encrypt + certbot renew |
| 密码强加密 | ☐ | Argon2id 或 bcrypt |
| 强制 SASL | ☐ | 生产环境推荐 |
| 防火墙配置 | ☐ | 仅开放必要端口 |
| fail2ban 部署 | ☐ | 自动封禁异常连接 |
| 日志轮转 | ☐ | 防止磁盘占满 |
| 非 root 运行 | ☐ | 专用用户运行服务 |
| 文件权限 | ☐ | 敏感文件 600 权限 |
| 定期备份 | ☐ | 配置 + 数据库 + 日志 |
| 安全审计 | ☐ | 定期检查日志和连接 |
| 资源限制 | ☐ | 防止单用户耗尽资源 |
| DDoS 防护 | ☐ | Cloudflare Spectrum 或自建防护 |
扩展阅读
下一章: 第 8 章:桥接与互通 — 将 IRC 与 Discord、Slack、Matrix 等平台互通。