快连VPN 官方站点 · 容器网络加速服务 镜像版本 v2.4.1 · 文档更新
隐私 · 零日志与内存加密

零日志隐私栈:白名单、关转储、管密钥

快连VPN 的隐私栈由四部分组成:日志白名单限定可输出的状态事件、镜像内关闭崩溃转储避免内存内容落盘、密钥与凭据常驻内存加密区域、以及密钥生命周期管理确保使用后立即销毁。本文逐项说明各类数据是否落盘、密钥如何加载与销毁,并明确审计导出能力的边界。本文涉及的技术细节为示例口径,用于说明设计方式。

01 · 日志白名单

日志白名单

快连VPN 采用白名单而非黑名单:只有被显式列出的事件类型才允许写入日志,其余内容一律不记录。白名单内的状态事件共四类——启动、握手、规则加载、异常。

启动事件

进程与监听端口就绪

记录版本号、加载的配置文件路径与监听端口,用于确认实例是否正常起来。

握手事件

上游链路协商结果

记录使用哪个协议出口与握手成功或失败,不记录握手过程中使用的凭据内容。

规则加载事件

规则条数与语法校验

记录规则文件版本、条目数量与语法校验结果,不记录规则命中的具体目标。

异常事件

错误码与发生阶段

记录原因码与发生阶段,用于定位失败环节,不附带请求内容或响应内容。

不进入日志的内容

以下数据无论连接是否成功、无论是否命中分流规则,都不会出现在日志中,也不会写入任何本地文件:

表 1:不进入日志的数据类别与原因(示例口径,用于说明白名单边界)
数据类别 是否进入日志 说明
访问域名 否 仅在连接建立与传输期间存在于内存,连接结束即释放
目标 IP 否 不写入日志,不落盘,不参与审计导出
连接时间 否 不记录每条连接的起止时刻,避免通过时间序列反推访问行为
流量大小 否 不按连接统计上下行字节数
账号标识 否 不记录用户、订阅或设备标识,日志中不存在可用于关联到自然人的字段

查看白名单级别日志时使用下列命令。日志输出到 stderr 与容器日志驱动之间,默认不在容器内生成持久化日志文件。

终端 · 查看白名单级别日志
# 只输出白名单内的状态事件(启动 / 握手 / 规则加载 / 异常)
docker logs --tail 200 kl-proxy 2>&1 | grep '\[state\]'

# 仅看异常与原因码,用于排障
docker logs kl-proxy 2>&1 | grep '\[error\]'

# 确认日志中不存在访问明细类字段:应无任何匹配输出
docker logs kl-proxy 2>&1 | grep -E '(host=|dest=|bytes=|uid=)'
需要审计时导出什么

当合规要求提供可核查证据时,正确做法是导出规则决策元数据(规则 ID、命中维度、动作、时间戳),而不是会话内容。前者解释分流行为且不含访问明细,后者会破坏零日志前提。两者的边界与导出方式见 命中审计。

02 · 崩溃转储

崩溃转储关闭

崩溃转储(core dump)会把进程内存整体写入磁盘,其中包含会话密钥、订阅凭据以及正在传输的流量内容。快连镜像在构建阶段即关闭这一路径。

镜像内的两项设置

设置 core 大小为 0
镜像的启动脚本中已执行 ulimit -c 0,进程即使异常终止也不会生成 core 文件。
屏蔽 core dump 输出路径
同时将 /proc/sys/kernel/core_pattern 指向不可写路径(容器内为 /dev/null),即使宿主机策略允许转储,也没有可写入的位置。
不使用持久卷承载转储
容器运行参数中不挂载任何用于接收转储的卷,因此不存在转储被保留在宿主机上的可能。
排障信息以原因码输出
排障需要的最小信息以原因码形式输出到 stderr,包含失败阶段与错误类型,不包含内存快照。

部署完成后应当验证这两项设置确实生效,而不是默认相信镜像声明:

终端 · 验证崩溃转储已关闭
# 查看容器内的 core 大小限制,输出 0 即为生效
docker exec kl-proxy sh -c 'ulimit -c'

# 输出示例:
# 0

# 确认 core_pattern 指向不可写路径
docker exec kl-proxy sh -c 'cat /proc/sys/kernel/core_pattern'

# 确认容器未挂载任何持久卷
docker inspect kl-proxy --format '{{json .Mounts}}'
需要完整调用栈时怎么办

若确实需要完整调用栈,使用排障镜像在隔离环境复现问题,不要在生产实例上临时放开 core 大小限制。排障镜像的差异见 镜像矩阵。

03 · 密钥生命周期

密钥生命周期

密钥在内存加密区域中完成加载、使用与销毁三个阶段,全程不落盘、不进入 swap。理解这三个阶段,就知道了密钥在任意时刻可能出现在哪些位置。

  • 加载:进程启动时按生命周期表读取

    为什么在这一步加载

    凭据在进程启动阶段一次性读取并解析,写入内存加密区域。读取完成后不再保留原始明文副本,配置来源也不会被二次读取。容器重建即产生一份全新的内存状态,不继承上一次运行的密钥。

  • 使用:常驻内存加密区域

    为什么这样存放

    密钥与订阅凭据在使用期间常驻内存加密区域,不写入持久卷、不写入规则配置文件、也不进入 swap。运行时若需要临时派生会话密钥,仅在内存中完成,用毕随会话一并销毁。

  • 销毁:使用结束立即覆写

    为什么要显式覆写

    会话结束即对内存中的密钥材料做覆写处理,使其不可继续使用。进程退出时不保留可复用的历史副本,容器删除后内存状态随之释放,不存在可供事后提取的残留。

  • 表 2:各类密钥与配置的存储位置、生命周期与销毁时机(示例口径,实际字段以 v2.4.1 规则格式为准)
    密钥类型 存储位置 生命周期 销毁时机
    会话密钥 内存加密区 单次会话 会话结束即销毁
    订阅凭据 内存加密区,不写持久卷 进程存活期 进程退出即销毁
    设备标识 内存,容器重建即失效 容器生命周期 容器删除即销毁
    规则配置 只读挂载的 YAML 配置周期 容器停止后卸载
    规则配置文件里不存凭据

    规则配置只描述分流规则与出口定义,通过只读方式挂载,内容中不包含订阅地址等凭据。把凭据写进规则文件等于把它变成一份可被备份、可被版本管理、可被读取的明文文件,与内存加密的前提直接冲突。凭据的传入方式见 部署文档。

    04 · 数据分类

    数据分类与处理方式

    下表是本页的核心结论:每一类数据是否落盘、是否进入日志、是否内存加密,三项属性分别独立成立。凭据与会话密钥三项全为否或全为是,是零日志设计的落点。

    表 3:数据分类与处理方式对照(示例口径,用于说明各项数据的落盘与日志策略)
    数据类别 是否落盘 是否进日志 是否内存加密
    订阅地址 / 凭据 否 否 是
    会话密钥 否 否 是
    访问域名与目标 IP 否 否 仅内存
    连接时间与流量大小 否 否 仅内存
    规则命中决策元数据 可选 可选 否
    运行状态(启动 / 重连 / 错误码) 可选 是 否

    「可选」表示由部署方决定是否开启:默认运行时不落盘,若确有审计或留存需求,可显式开启对应的导出目标,但开启范围仅限决策元数据与运行状态,不覆盖访问明细。分流引擎产生的决策记录字段见 命中审计。

    05 · 合规边界

    审计与合规边界

    零日志与可审计并不冲突,因为两者约束的不是同一类数据:零日志排除的是会话内容,可审计依赖的是规则决策元数据。

    审计导出只含决策元数据

    审计导出内容仅包含四个字段:规则 ID、命中维度、动作、时间戳。不包含访问域名、目标 IP、会话内容与账号标识,也不包含任何可用于还原用户身份的字段。这四个字段回答的是「这条连接依据哪条规则、走了哪个出口」,不回答「用户访问了什么」——前者是配置行为的证据,后者才是访问行为。

    为什么两者可以同时成立

    零日志约束对象

    会话内容

    访问域名、目标 IP、连接时间、流量大小、账号标识一律不落盘、不进日志。这一侧回答「系统记住了什么」,答案是:只记住四类状态事件。

    可审计依赖对象

    决策元数据

    规则 ID、命中维度、动作、时间戳。这一侧回答「系统为什么这样转发」,答案来自规则文件本身,而不是来自对用户访问行为的记录。

    两者的交集

    配置行为的证据

    决策元数据的取值只由规则文件与连接属性决定,与访问的具体内容无关。因此导出它不会扩大任何隐私暴露面。

    交付时能提供什么

    合规评审通常需要三类材料,均可在本页口径下提供:日志白名单范围说明、崩溃转储关闭的验证方式与输出、密钥生命周期表(即表 2)。需要提交正式材料或对适用范围有疑问时,通过 备案与联系方式列出的渠道联系,材料中请勿附带任何订阅地址等凭据。

    06 · 常见问题

    隐私相关问题

    以下四条是隐私与合规场景中最常被问到的问题。更完整的问题清单见 快连VPN 常见问题。

    快连VPN 会记录我访问了哪些网站吗?

    不会。访问域名与目标 IP 不进入日志,也不落盘,仅在连接建立与传输期间存在于内存中,连接结束即释放。日志只有启动、握手、规则加载、异常这四类状态事件。排障需要的信息以原因码形式输出,不含具体访问内容。

    关闭崩溃转储会不会影响排障能力?

    不会明显影响。镜像内已设置 ulimit -c 0 并屏蔽 core dump 输出路径,进程崩溃时不会把内存中的密钥与流量信息写入磁盘。排障需要的最小信息以原因码形式输出到 stderr,足以定位绝大多数启动与握手阶段的问题;需要完整调用栈时应使用排障镜像在隔离环境复现,而不是在生产开启转储。

    零日志和可审计之间是否矛盾?

    不矛盾。两者依赖的不是同一类数据:零日志约束的是会话内容,审计依赖的是规则决策元数据。审计导出只含规则 ID、命中维度、动作与时间戳四个字段,不含访问域名、目标 IP、会话内容与账号标识,因此可以在不记录任何访问明细的前提下解释每条流量的出口选择。

    订阅地址会被写入配置文件或持久卷吗?

    不会。订阅地址与凭据只在进程启动时读取,随后常驻内存加密区域,不写入持久卷,也不写入规则文件。进程退出时该区域被覆写,不保留可复用的历史副本。规则配置文件本身只保存分流规则与出口定义,不包含任何凭据。