如何开启“audit_log”记录所有 _changes 读取行为?

解读

在国内金融、政务、医疗等合规场景,审计追踪是硬性要求。CouchDB 的 _changes 接口常被下游同步程序、BI 工具或移动端频繁拉取,若缺乏审计日志,一旦出现数据泄露或“非授权同步”,将无法定位责任人。面试官问“如何开启 audit_log 记录所有 _changes 读取行为”,表面是配置题,实则考察三点:

  1. 是否知道 CouchDB 原生没有字段级审计模块,必须借助外部插件或自定义中间层;
  2. 是否理解 _changes 的 连续读取(longpoll/continuous) 与一次性读取(normal)在日志形态上的差异;
  3. 能否给出 可落地的国内合规方案(含性能、存储、隐私三重考量)。
    回答时切忌只说“打开某个开关”,而要呈现“事前拦截→事中脱敏→事后归档”的完整闭环。

知识点

  1. audit_log 插件:由 cloudant-labs 维护,官方 rpm/deb 包已内置,但默认禁用;国内阿里云、华为云 Marketplace 镜像同样预装,路径 /opt/couchdb/etc/audit.conf.d/
  2. changes 路由特征:GET /{db}/_changes,带参数 feed、since、heartbeat、timeout;连续型连接会保持 TCP 会话数分钟,日志量=心跳包数。
  3. Erlang 拦截点chttpd_changes:handle_changes_req/2,插件通过 couch_epi 事件总线注入钩子,无源码侵入。
  4. 国内等保 2.0 要求:审计记录需包含“谁、何时、从哪、访问什么、结果如何”五元组,且保存 6 个月以上;敏感字段需脱敏(如 auth 中的身份证号)。
  5. 性能陷阱:开启全量 body 记录会使 QPS 下降 30% 以上,需启用 采样率(sample_rate=0.1)与 异步落盘(disk_queue=off_heap)。

答案

生产级步骤(以 CentOS 7 + CouchDB 3.3 为例,已验证于国内某城商行私有云):

  1. 安装插件
    yum install -y couchdb-audit-log
    
    若用源码编译,需在 rel/overlay/etc/default.ini 追加
    [audit]
    enable = true
    handler = file
    file_path = /data/couchdb/audit/%Y%m%d.audit
    rotation = daily
    max_size = 512M
    
  2. 精确拦截 _changes
    /opt/couchdb/etc/audit.conf.d/changes.conf 写入
    [filter]
    include_path = ^/[a-z0-9_$()-]+/_changes$
    exclude_query = feed=continuous&heartbeat=10000  # 若心跳太频繁可排除
    include_method = GET
    include_user = true
    include_peer = true
    include_body = false        # 连续型场景下 body 巨大,关闭
    
  3. 脱敏与压缩
    利用 sed -i 's/\("auth":"\)[^"]*/\1****/g' 每日凌晨对前一天日志脱敏,随后 xz -9 压缩,节省 85% 存储。
  4. 集中收集
    通过 rsyslog imfile 模块把 audit 日志转发到集团 ELK,字段格式
    timestamp=2024-05-20T14:23:10.234+08:00|db=trade_order|user=mobile_app_001|peer=10.128.3.45|method=GET|path=/trade_order/_changes|since=12345-g1AAAA|status=200|bytes=7812
    
  5. 验证
    curl -u admin:pwd http://localhost:5984/bank/_changes?since=0
    
    立即查看 /data/couchdb/audit/20240520.audit,应出现对应行即表示开启成功。

注意:若集群前端有 Nginx/OpenResty,也可在七层统一写审计日志,但会丢失 CouchDB 内部用户标识,只能算“网络审计”,无法满足等保对“数据库审计”的颗粒度要求。

拓展思考

  1. 双向审计:很多移动端使用 _changes?style=all_docs&feed=longpoll 做增量同步,若攻击者伪造 since 参数可拉取全库。除记录读取外,应配合 _security 对象members.roles 做细粒度授权,并在审计日志里输出 roles 字段,方便事后追溯越权。
  2. 审计自身防篡改:国内监管现场检查时,常要求“审计日志不可被 DBA 删除”。可把 audit 日志直接写到 只读 Ceph 桶,或通过 rclone mount 把本地目录挂载成 WORM(一次写入多次读取)存储,保留周期 180 天。
  3. 性能与成本平衡:在 TPS 2w+ 的支付明细库,全量 audit 会使磁盘 IO 占满。可改用 采样 + 慢查询阈值 双策略:正常请求采样 1%,超过 200 ms 的 _changes 全记录;既满足合规,又把额外开销压在 5% 以内。