强曰为道

与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

第 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 隧道内安全)
EXTERNALTLS 证书认证,无密码传输
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 配置

  1. 将 DNS 指向 Cloudflare
  2. 配置 Spectrum 规则转发 6697/TCP
  3. 启用代理保护
  4. 配置客户端连接到 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" [email protected]
    exit 1
fi

# 检查端口
if ! ss -tlnp | grep -q ":6697"; then
    echo "CRITICAL: IRC TLS 端口未监听" | mail -s "IRC Alert" [email protected]
    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" [email protected]
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 等平台互通。