-
-
Notifications
You must be signed in to change notification settings - Fork 10.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
伪造客户端访问服务端,容易泄漏配置信息 #2099
Comments
对于安全要求相对较高的公司,这确实是个问题,我司版本已在adminservice, configService中,对于部分服务增加了访问权限控制。 |
这块是一直想增强的功能,之前应该也有过类似讨论:
|
针对第一种方案,能否做成一个开关,用户可以选择配置的项目是否需要认证? |
是否可以在 apollo 上配置项目的时候,生成一个 token 作为凭证,后续可以通过这个 token 进行操作。每个客户端连接的时候,需要配置一下对应的token。然后这个配置作为一个非必选项配置,来兼容旧的版本。如果 apollo 开启了这个配置项,apollo 就需要客户端提供 token 才能进行配置获取。 |
token/access key对于私有的namespace应该是可以的,对于公共的namespace可能就不太适用了 |
请问一下这个功能会在近期进行完善吗? |
配置中心选型中,wiki看了、issue搜了一圈,发现客户端获取配置居然没有权限控制,这个风险实在太大了。建议至少得在app这个级别可以设置有查看权限的token |
生产环境不都是内网么,加上安全组限制就没啥问题吧 如果内网被入侵了,用啥验证都等于白搭 |
@wkcaeser 这个想法太理想了。不考虑生产环境,有的测试环境用了开发方便是对公网开放的。即使是生产环境,也可能存在一个公司或部门用一个统一的配置中心,但不同应用间也不允许互相泄露敏感配置。 如果按内网就够了这个思路,那么所有数据库或中间件都不需要提供权限控制了,显然安全上是不够的,有些需要安全评审的公司,这个问题可能是属于一票否决的 |
很多公司目前的实现都是基于内网可信这个原则,如果有敏感数据比如数据库连接串会特殊处理来提高安全级别(比如加密)。 |
@nobodyiam 我觉得像上面讨论的第1种思路,如 @g5niusx 补充的,就有一定保障了,至少安全这项不会成为明显的短板。其实我不是很理解,对敏感数据如数据库连接进行加密等处理,那加解密密钥理论上不是也成了一个新的配置(也本该放apollo)吗,如果我们不敢把敏感配置放在配置中心,那这可能本身就是一个问题 |
敏感信息集中存储,可能本身就不是一个好主意 |
正好我们有个需求,需要放开配置中心到公网,因为客户端IP可能会变,不好添加ACL,逛了一圈,没找到apollo-config可以支持鉴权的方式,无奈之下,用nginx做了一个反向代理,把apollo-config放在反向代理的后面,在反向代理模块里面添加Auth验证,这种方案也能满足需求,给大家参考一下,nginx的代理配置:
访问:
我们没有用sdk,直接http方式访问,如果用sdk,估计需要hack一下 另外:如果像前面的同学说的内网也不完全可信的话,可以给apollo机器的端口再做ACL,用iptables或者云安全组都行,限制只允许nginx和部分需要机器可以访问apollo-config的端口 |
+1,我们也需要。我们现在是 混合云方案,但跨云专有网打通(涉及5大区域)很贵,以至于我们每个云一套,甚至不同区域还得搞一套。 |
@nobodyiam 看了大家的讨论,主要是对第1种方案提出了补充的建议,第2种方案可能大家不太了解hook具体实现是什么,比较模糊。 目前由于安全审计需求,我们考虑加上这个客户端认证的功能,先总结了大家讨论的几个点:
现在我们准备朝着第1种方案的方向去做,不知道 |
如果只对私有namespace做认证的话,会简单很多,因为这样其实只要验证应用级别的token就可以了,不需要到namespace级别?那么对API可能影响不大,因为token可以放在配置文件中,比如app.properties或-D参数,就不需要改动获取配置的api接口了,我觉得这个解法应该是现实可行的。 |
嗯,目前具体的细节准备是这么做的:
顺哥,您有空的话帮忙看下这样实现是否合理? |
需要在ApolloPortalDB和ApolloConfigDB库中的App表中都添加“是否启用token校验“ token的话参照ApolloPortalDB.ConsumerToken表创建一个新的表吧,这个表也需要和App一样同步到ApolloConfigDB 另外还有一个点是可以考虑一下是否需要按环境开启”是否启用token校验“ |
有考虑按环境区分,并且也有开关,开关的粒度也是到环境。但是只在 CREATE TABLE `ApolloConfigDB.AccessKey` (
`Id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键',
`AppId` varchar(500) NOT NULL DEFAULT 'default' COMMENT 'AppID',
`Secret` varchar(128) NOT NULL DEFAULT '' COMMENT 'Secret',
`IsEnabled` bit(1) NOT NULL DEFAULT b'0' COMMENT '1: enabled, 0: disabled',
`IsDeleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '1: deleted, 0: normal',
`DataChange_CreatedBy` varchar(32) NOT NULL DEFAULT 'default' COMMENT '创建人邮箱前缀',
`DataChange_CreatedTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`DataChange_LastModifiedBy` varchar(32) DEFAULT '' COMMENT '最后修改人邮箱前缀',
`DataChange_LastTime` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后修改时间',
PRIMARY KEY (`Id`),
KEY `AppId` (`AppId`(191)),
KEY `DataChange_LastTime` (`DataChange_LastTime`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='访问密钥'; |
不过这样是不是意味着每个环境的secret都不一样?那这个secret作为一个新的配置项在应用代码中该咋配置? |
是的,每个环境secret不一样,对于安全需求来说我们不希望生产环境的secret与其他环境一样。在应用中配置secret的方式现在与app.id的方式保持一致,加载顺序如下:
Portal上也可以添加accesskey时同时应用到多个环境,正在实现中,等功能好了给顺哥review下,预计最近两周内可以完成。 |
是否需要考虑支持secret轮转的场景?比如定期更新secret或者secret上增加过期时间之类的?也就意味着在同一时间可以有两个secret同时生效? |
@nobodyiam 有的,上述的DDL就可以单个app支持多个secret。在configservice的filter会匹配可用的secret列表。暂时还没考虑到自动过期时间,默认用 |
@nisiyong 所以是否意味着app级别并没有一个开关来设置是否启用访问校验,而是通过是否有secret记录来判断是否启用访问校验? |
是的,如果该应用有对应的secret并且是 |
@nobodyiam 顺哥有空帮忙Review下PR😬 |
@nisiyong 你好,浏览了下PR。这里解决“伪造客户端访问服务器”的主要手段是检验签名。若一致,则认为请求有效。若不一致,请拒绝请求。有两个问题想请教下,如有不对的地方请指点。1:如何解决请求被抓包。因为请求是明文,被抓包后,数据也就泄露了。2:如何解决重放攻击。 |
嗯,这两个问题都有考虑过。
|
客户端只需要服务地址和appid就可以获取配置信息,如何鉴别客户端时一个安全的客户端而不是伪造客户端?
建议服务端提供对应的鉴权方式,避免非法客户端连接获取配置
The text was updated successfully, but these errors were encountered: