要在nginx tcp代理模式下实现连接会话审计与日志追踪,核心在于启用stream模块、定义结构化日志格式,并理解日志触发时机——它只在tcp连接关闭后才落盘,不是实时流式记录;需确认nginx支持--with-stream、在main上下文定义tcp_audit格式、server块中指定access_log路径及格式、确保权限正确,并结合上游服务日志或siem系统补全审计上下文。

要在 Nginx TCP 代理模式下实现连接会话审计与日志追踪,核心在于启用 stream 模块、定义结构化日志格式,并理解日志触发时机——它只在 TCP 连接关闭后才落盘,不是实时流式记录。
确认并启用 stream 模块
这是前提,缺一不可:
- 运行
nginx -V 2>&1 | grep -- '--with-stream',输出含--with-stream才表示支持;若无,需重装或重编译(如 Ubuntu 可装nginx-extras,CentOS/RHEL 用nginx-mod-stream) - 确保配置中没有遗漏
stream { ... }块,且该块不能放在http内,必须是同级顶层模块 - 检查 Nginx 启动时无
unknown directive "stream"报错,否则配置不生效
配置会话级 TCP 日志格式
日志内容需覆盖审计关键字段:源 IP、目标服务、连接时长、流量收发量、状态码:
- 在
stream块外(通常在 main 上下文)定义日志格式,例如:log_format tcp_audit '$remote_addr:$remote_port → $upstream_addr [$time_local] ' 'proto=$protocol status=$status ' 'session_time=$session_time ' 'bytes_sent=$bytes_sent bytes_received=$bytes_received ' 'upstream_bytes_sent=$upstream_bytes_sent upstream_bytes_received=$upstream_bytes_received ' 'upstream_connect_time=$upstream_connect_time'; - 注意变量含义:
$session_time是连接总时长(秒),$bytes_sent是发给客户端的字节数,$upstream_bytes_received是从后端收到的字节数 - 避免使用
$request或$uri等 HTTP 变量——TCP 层无请求行,它们为空或报错
为每个代理服务单独配置访问日志
不同端口或后端服务建议分离日志文件,便于按业务归档与分析:
- 在具体
server块内指定日志路径和所用格式,例如:server { listen 3306; proxy_pass mysql_backend; access_log /var/log/nginx/mysql_access.log tcp_audit; error_log /var/log/nginx/mysql_error.log warn; } - 日志路径需确保 Nginx 工作进程(通常是
www-data或nginx用户)有写权限,推荐提前创建目录并赋权:sudo mkdir -p /var/log/nginx && sudo chown nginx:nginx /var/log/nginx - 日志仅在连接断开后写入,因此短连接(如部分 MySQL 客户端行为)会产生大量小日志条目;长连接(如 Redis Pub/Sub)则单条日志跨度可能达数小时
补充审计能力:结合应用层与外部工具
纯 Nginx TCP 日志有局限,需搭配其他手段补全上下文:
- 心跳、命令交互等细粒度行为不在 TCP 会话日志中体现,必须由上游服务(如 MySQL 的 general_log、Redis 的
monitor)或客户端 SDK 自行记录 - 对异常连接做初步识别,可配合
fail_timeout和max_fails在upstream中设置熔断,再通过日志关键词(如status=502或upstream_connect_time=0.000)筛选失败会话 - 安全审计场景下,建议将日志接入 SIEM(如 ELK 或 Splunk),用
$remote_addr和时间窗口聚合统计频次,快速发现暴力连接或扫描行为











