使用官方最新的HAProxy Docker容器和以下配置文件:
frontend logging_frontend
bind *:1514
mode tcp
timeout client 1m
default_backend logging_backend
backend logging_backend
mode tcp
balance roundrobin
timeout connect 10s
timeout server 1m
server logstash-collector-01 logstash-collector-01:1514 check
server logstash-collector-02 logstash-collector-02:1514 check
server logstash-collector-03 logstash-collector-03:1514 check
我收到的日志(通过 nxlog 通过 TCP 发送到 1514)并未存储实际的客户端 IP,而是存储了 Docker 网关 IP。例如:
2017-03-02T15:57:41.585Z 172.18.0.1 {“EventTime”:“2017-03-01 15:25:02”,“Hostname”:“server.mycompany.net”,“关键字”:58096435992,“EventType”:“错误”,“SeverityValue”:“4”,“Severity”:“错误”,“EventID”:551,“SourceName”:“Microsoft-Windows-SMBServer”,“ProviderGuid”:“{D48CE617-33A2-4BC3-A5C7-11AA4F29619E}”,“版本”:1,“任务”:551,“OpcodeValue”:0,“RecordNumber”:5267740,“ProcessID”:4,“ThreadID”:5732,“Channel”:“Microsoft-Windows-SMBServer / Security”,“Domain”:“NT AUTHORITY","AccountName":"SYSTEM","UserID":"S-1-5-184","AccountType":"User","Message":"SMB 会话身份验证失败\r\n\r\n客户端名称:\\10.1.1.43\r\n客户端地址:10.1.1.43:54118\r\n用户名:\r\n会话 ID:0xAF9FC8000015\r\n状态:尝试登录无效。这是由于用户名或身份验证信息错误造成的。(0xC000006D)\r\n\r\n指导:\r\n\r\n当尝试使用不正确的凭据连接到共享时,您应该会遇到此错误。\r\n\r\n此错误并不总是表示授权问题,而主要是身份验证问题。这种情况在非 Windows 客户端上更为常见。\r\n\r\n当使用不正确的 NTLM 用户名和密码、客户端和服务器之间的 LmCompatibility 设置不匹配、Kerberos 服务主体名称重复、Kerberos 票证授予服务票证不正确或未启用来宾访问权限的来宾帐户时,可能会发生此错误","Opcode":"Info","EventReceivedTime":1488470262,"SourceModuleName":"eventlog","SourceModuleType":"im_msvistalog"}
请注意,报告服务器是 10.2.3.95,Docker 主机是 10.1.38.223,Docker 桥接接口(和本地容器子网)是 172.18.0.0/16(日志中记录的 172.18.0.1 是网关)。
- 外部接口 eno16777728 从 10.2.3.95 获取到主机 IP 10.1.38.223 的 PUSH 数据包(包含日志数据)
- Docker 将对其进行 DNAT,从 10.2.3.95 转至 HAProxy 容器 (172.18.0.6)
- HAProxy 确认了 PUSH(屏幕截图的最后一个数据包显示使用 10.xxx IP 在外部接口上进行了 SNAT 回复)
- (图像乱序 - 检查时间戳)HAProxy 决定将后端容器 172.18.0.3 作为负载平衡目标
- (图像乱序 - 检查时间戳)Docker 接口网关在其虚拟以太网接口上对数据包进行 SNAT(为什么?)
- 后端服务器向 Docker 网关发送 ACK
- 从后端服务器到 HAProxy 的 ACK(?)
- 从后端服务器到 HAProxy 的 ACK(?)
source 0.0.0.0 usesrc clientip
当我尝试使用节中的功能让 HAProxy 透明地传递客户端 IP 时backend
,根本没有记录任何内容。
对我来说,这个问题有两个成功途径:要么:
- 记录Docker网关IP的行为该如何解释?
或者更重要的是:
- 我怎样才能让原始客户端 IP 出现在这些日志中,最好作为客户端 IP 字段(在日志开头的时间戳之后)?