聊聊 Zookeeper 的 4lw 与信息安全
1. 4lw 与信息泄露问题概述
最近有个客户在扫描安全漏洞时,反馈 ZOOKEEPER 存在信息泄露问题,即:ZooKeeper默认开启在2181端口,在未进行任何访问控制情况下,攻击者可通过执行envi命令获得系统大量的敏感信息,包括系统名称、Java环境;
大家可以通过 telnet zk-ip zk-port 和 envi 等 4lw复现该问题:
2. 4lw 与信息泄露问题分析与解决
- 客户反馈的信息泄露问题“攻击者可通过执行envi命令获得系统大量的敏感信息,包括系统名称、Java环境”,在 zookeeper3.4.5-cdh6.3.2 中确实存在,但泄露的信息仅仅是系统名称和Java环境;
- 由于我们已经配置开启了 ZOOKEEPER 的 Kerberos安全认证,攻击者在未经过 kerberos 认证的情况下是无法正常访问 ZOOKEEPER 的任何ZNODE节点的,即无法通过 zkCli.sh 正常登录并执行 set/get/ls等命令:
- 在当前版本的zookeeper(zookeeper3.4.5-cdh6.3.2)中,为降低上述 zookeeper 的 TCP four-letter word (4lw) 引起的信息泄露的风险,可以通过配置 4lw 白名单的方式进行安全加固,比如 zookeeper.4lw.commands.whitelist=srvr (部分版本zk中该白名单参数默认只有 srvr 一个命令,笔者不知道如何配置该白名单为空);
- 在当前版本的zookeeper(zookeeper3.4.5-cdh6.3.2)中,如果需要彻底杜绝 4lw 引起的信息泄露的风险,只能通过禁止把Zookeeper直接暴露在公网,并通过防火墙限制IP和端口的访问;
3. 4lw 与 acl
有同学建议对 zk 添加acl 访问控制,比如限制只有指定的认证用户或指定的IP才能访问 zk节点,来杜绝上述 4lw 引起的信息泄露的风险的:
- acl能限制只有指定用户或指定IP才能登录zk并访问特定的znode,也就是说可以起到杜绝未授权访问漏洞的效果;
- 但执行 zookeeper 4lw 命令是不需要登录zk服务器的,也是不需要经过认证的,只要对应2181端口的tcp连接是通畅的即可,所以 acl 杜绝不了 4lw 的信息泄露问题;
- 事实上,CDH中不应该对根节点配置 ACL,比如setAcl / auth:xyz:r059lA6OcDNg:cdrwa 或 setAcl / ip:10.9.100.49:cdrwa, 此时zk的金丝雀检查,yarn的ha服务等都会因无法在根节点下创建和删除znode 而报错:
4. 4lw 与 AdminServer
zk社区后续有彻底淘汰 4lw 命令并使用 AdminServer 替代其功能的计划,Admin Server 是基于Jetty 的http服务并默认监听在8080端口,在 zookeeper3.5.0及之后版本就可以使用 AdminServer了.
- 4lw:The Four Letter Words: ZooKeeper responds to a small set of commands, Each command is composed of four letters. You issue the commands to ZooKeeper via telnet or nc, at the client port. Three of the more interesting commands: “stat” gives some general information about the server and connected clients, while “srvr” and “cons” give extended details on server and connections respectively.
- New in 3.5.3: Four Letter Words need to be explicitly white listed before using. Moving forward, Four Letter Words will be deprecated, please use AdminServer instead.
- New in 3.5.3: A valid Four Letter Words command must be put in this 4lw.commands.whitelist, else ZooKeeper server will not enable the command. By default the whitelist only contains “srvr” command which zkServer.sh uses. The rest of four-letter word commands are disabled by default: attempting to use them will gain a response “… is not executed because it is not in the whitelist.” If you really need enable all four-letter word commands by default, you can use the asterisk option so you don’t have to include every command one by one in the list. As an example, this will enable all four-letter word commands:4lw.commands.whitelist=*
- The AdminServer is an embedded Jetty server that provides an HTTP interface to the four-letter word commands. By default, the server is started on port 8080, and commands are issued by going to the URL “/commands/[command name]”, e.g., http://localhost:8080/commands/stat.
- AdminServer is enabled by default (system property zookeeper.admin.enableServer is set to true by default), but can be disabled by either Setting the zookeeper.admin.enableServer system property to false,or by removing Jetty from the classpath.
- Note that the TCP four-letter word interface is still available if the AdminServer is disabled.
5 相关命令与参考连接
- telnet localhost 2181
- addauth digest xxxx:r059lA6OcDNg
- setAcl / auth:cshj49:r059lA6OcDNg:cdrwa
- setAcl / ip:10.9.100.49:cdrwa
- setAcl / world:anyone:cdrwa
- curl http://localhost:8080/commands/srvr
- https://www.cnblogs.com/aongao/p/14366127.html
- https://issues.apache.org/jira/browse/ZOOKEEPER-1392
- https://zookeeper.apache.org/security.html
- http://www.cnnvd.org.cn/web/xxk/ldxqById.tag?CNNVD=CNNVD-201905-954