如果不这样用,Nacos也有安全问题!

前言



配置管理作为软件开发中重要的一环,肩负着连接    代码和环境的职责,能很好的分离开发人员和维护人员的关注点。

Nacos 的配置管理功能就很好地满足了云原生应用对于配置管理的需求:既能做到配置和代码分离,也能做到配置的动态修改。

在 1月份,Nacos 出了一个安全漏洞,外部用户能够伪装为 Nacos-server 来获取/修改配置( https://github.com/alibaba/nacos/issues/4593 )。确认问题后,Nacos 火速修复了漏洞,而阿里云的微服务引擎(MSE)也已在 1月末将修复方案反向移植到 MSE 上的 Nacos 实例上。

在本文中,我们将会从全局视角入手,讨论如何才能保证 Nacos 配置的安全性(security),即如何保证配置信息不被恶意用户获取或者泄漏。

Nacos 配置架构


Nacos 配置部分的整体架构如下:

对于上图中的每一条链路,都需要考虑有没有两个基本的安全动作:认证(Identification)和鉴权(Authentication)。

从上图可以看到,配置信息可能的泄漏方式有:

  • 通过 Nacos-client 获取配置。

  • 通过控制台获取配置。

  • 通过服务器之间的通信协议获取配置。

  • 直接访问持久化层(比如 DB)获取配置。

可能的泄漏点如下:


认证

鉴权

Nacos 客户端

未登录用户通过客户端获取/修改配置

用户通过客户端获取/修改了未授权的配置

配置控制台

未登录用户通过控制台获取/修改配置

用户通过控制台获取/修改了未授权的配置

Nacos 集群内

用户伪装为 Nacos 集群获取/修改配置

不需要

持久化层

用户直接查 DB,获取/修改配置

不需要

Nacos 客户端场景的认证和鉴权


在 Nacos 客户端尝试从服务端获取配置时,服务端需要确认客户端的身份,并确认该身份有权限获取配置。

开源版本的 Nacos

在默认的 Nacos server 配置中,不会对客户端鉴权,即任何能访问 Nacos server 的用户,都可以直接获取 Nacos 中存储的配置。比如一个黑客攻进了企业内网,就能获取所有的业务配置,这样肯定会有安全隐患。

所以需要先开启 Nacos server 的鉴权。在 Nacos server 上修改 application.properties 中的 nacos.core.auth.enabled 值为 true 即可:

nacos.core.auth.enabled=true

如上设置后,Nacos 客户端获取配置时,需要设置上对应的用户名和密码,才能获取配置:

String serverAddr = "{serverAddr}";Properties properties = new Properties();properties.put("serverAddr", serverAddr);properties.put("username","nacos-readonly");properties.put("password","nacos");ConfigService configService = NacosFactory.createConfigService(properties);

上面讲了如何认证用户,即如何确定现在是哪一个用户在访问,但还需要识别用户的权限,当用户访问没有权限获取对应配置的时候,比如库存服务尝试获取支付服务的配置时,就会失败。

我们可以在开源的 Nacos 控制台上创建用户、设置权限。步骤如下:

首先,访问 localhost:8848/nacos 并登录,在 权限控制->用户列表 页面,添加用户:

权限控制->角色管理,绑定用户和角色:


给对应角色添加权限,在 权限控制->权限管理 页面,添加权限:

经过如上配置后,readonly-user 就只能访问 public 命名空间下的配置了。


阿里云 MSE-AK/SK

对于小团队,用用户名和密码来做认证鉴权是足够的。但对于中大型团队,密码的定期更换、人员的频繁变动等,都会导致用户名和密码频繁变动。

这时,使用用户名和密码认证鉴权就需要频繁修改并发布应用。为了解决这个问题,Nacos 也提供了基于 AK/SK 的认证方案、ECS关联RAM角色的方案,可以避免用户名和密码修改导致的频繁发布问题。

以阿里云 MSE 为例,阿里云用户已经普遍使用了阿里云访问控制服务(RAM)作为权限系统,如果 MSE 和开源一样,使用用户名和密码实现认证和鉴权的话,那么用户就需要在 RAM 和 MSE Nacos 两个地方配置权限。这样既不方便用户权限的统一管理、审查,也给用户带来了不一致的体验。

所以 MSE(微服务引擎)提供了基于 AK/SK 的认证方式,操作示例如下:

首先,在 MSE 上申请一个 Nacos 实例(并记下实例 id),然后在 实例详情->参数设置 界面,将 ConfigAuthEnabled(配置鉴权)参数设置为 true,这样匿名用户就无法获取配置:

然后就可以在阿里云RAM系统上配置相关权限。RAM子账号的权限系统可以简单表示如下:

  • 第一步:创建 RAM 权限策略如下:

图中,mse:Get*、mse:List*、mse:Query* 表示能读取配置,mse:* 表示所有权限,包括修改权限。

acs:mse:*:*:instance/${instanceId} 表示授权到实例级别,acs:mse:*:*:instance/${instanceId}/${namespaceId} 表示授权到命名空间级别。

  • 第二步:创建用户并赋予权限:

填写用户名称:

然后获取到用户的 AK/SK:

给这个用户对应的权限:

  • 最后,只需要在代码中添加 AK/SK 就可以了:

String serverAddr = "{serverAddr}";Properties properties = new Properties();properties.put("serverAddr", serverAddr);properties.put(PropertyKeyConst.ACCESS_KEY, "${accessKey}");properties.put(PropertyKeyConst.SECRET_KEY, "${secret}");ConfigService configService = NacosFactory.createConfigService(properties);

经过如上配置,客户端在访问 MSE 上购买的 Nacos 实例的时候,MSE 会校验 AK 和签名,确认该用户是合法的用户,并校验权限,否则拒绝提供服务。

阿里云 MSE- 基于 ECS 的 Ram 角色认证

当然,在上面的使用方式中,还是要在初始配置(比如 srping-cloud-alibaba-nacos-config 中的 bootstrap.yml 文件)中配置 AK/SK。黑客入侵内网、或者源码泄漏时,也会存在 AK/SK 泄漏,导致配置信息泄漏的风险

在这种情况下,推荐使用 ECS 关联的 RAM 角色来做认证。

ECS 关联 RAM 角色对应的授权模型如下:

上述的关键步骤在角色扮演。只有关联了 RAM 角色的云服务器,才能成功扮演角色,从而获取操作 MSE Nacos 实例的权限。

如果黑客只获取了代码,也无法成功扮演 RAM 角色,无法操作 MSE Nacos 实例。如果机器被攻破,那也能在阿里云控制台上取消云服务器关联的角色,及时止损。

具体的操作步骤如下:

  • 第一步,创建 MSE Nacos 实例,并创建对应的权限策略(上文有说明,此处不赘述)。

  • 第二步,创建 RAM 角色并授权。

创建 RAM 角色:

创建角色后,为该角色添加对应的权限策略:


  • 第三步,将该角色和 ECS 关联:

在对应的 ECS 详情页面,点击 授予/收回 RAM 角色

选择对应的角色并授予

  • 最后一步,在代码中 指定 RAM 角色 即可:

String serverAddr = "{serverAddr}";
Properties properties = new Properties();
properties.put("serverAddr", serverAddr);
properties.put(PropertyKeyConst.RAM_ROLE_NAME, "StoreServiceRole");
ConfigService configService = NacosFactory.createConfigService(properties);

经过如上配置,Nacos 客户端在获取配置时,云服务器会扮演指定的 RAM 角色,阿里云临时安全令牌(Security Token Service,STS)来访问 MSE Nacos 实例。

如果攻击者获取代码,也无法在其他机器上运行,因为攻击者的机器没有扮演 RAM 角色的权限。

如果攻击者获取扮演之后的认证信息,由于 STS 失效较短(默认是1小时),攻击者拿到后很快就失效,有效减少了攻击面。

如果需要撤销授权,只需要在阿里云控制台上就可以操作,不需要重新发布应用。

相比于 AK/SK 方式的认证鉴权,ECS 关联角色的认证鉴权更可控、更安全,所以推荐使用这种认证鉴权方式。

配置控制台场景的认证和鉴权



开源版本的 Nacos

开源版本的 Nacos 控制台,在登录的时候,会通过控制台的 login 接口,获取临时的 accessToken,然后后续的操作,都是以 accessToken 来做认证鉴权。

比如前文提到的 readonly-user 用户,登录后,就只能看到 public 命名空间下的配置信息,无法修改、无法查看其他命名空间下的配置信息。

另外,如果需要创建命名空间、删除命名空间,则只能管理员登录才可以。

开源版本 Nacos 的认证鉴权,可以参考该文档:https://nacos.io/zh-cn/docs/auth.html。


阿里云 MSE

阿里云 MSE 由于是对企业提供服务,所以在权限的划分上会更加精细。

资源分为实例级别(acs:mse:*:*:instance/${instanceId})和命名空间级别(acs:mse:*:*:instance/${instanceId}/${namespaceId})。

对资源的操作也更加精细,比如:

Action

说明

CreateEngineNamespace

创建命名空间

DeleteEngineNamespace

删除命名空间

mse:Get*,mse:List*,mse:Query*

读取配置(Nacos 客户端和控制台)

mse:*

所有权限,包括修改、删除配置

mse:QueryNacosConfig

客户端读取配置

mse:UpdateNacosConfig

客户端修改配置

比如,只允许读取一个命名空间下的配置,不允许修改。那权限策略就可以写:

{  "Action": [    "mse:Get*",    "mse:List*",    "mse:Query*"  ],  "Resource": [    "acs:mse:*:*:instance/${instanceId}/${namespaceId}"  ],  "Effect": "Allow"}

服务器之间的认证


Nacos 服务器之间需要同步一些信息,这时也需要认证对方身份,以确认对方真的是 Nacos-server,而不是伪装的。

在 1.4.1 之前,是通过 User-Agent 这个 header 来认证的,这种原始的认证方式,很容易被伪造。本文开头提到的,1月份 Nacos 爆出的漏洞就是这个原因。

所以 1.4.1 及之后的版本,认证的 header 以及对应的值可以自己配置。在 application.properties 中,修改如下值即可:

# 不使用User-Agent来认证nacos.core.auth.enable.userAgentAuthWhite=false# 认证header的keynacos.core.auth.server.identity=Authorization# 认证header的valuenacos.core.auth.server.identity.value=secret

这样,只有发送了 header Authorization: secret 的请求,才能确认对方是服务端,才能同步集群信息;否则就拒绝同步。

由于 Nacos-server 需要全部权限才能同步配置数据,所以对于 Nacos-server 之间,则不需要做鉴权。

这样,就能让服务器之间的通信也能做到安全可信了。

阿里云 MSE 上购买的 Nacos 实例,也已经将上述方案反向移植到了 1.2 版本上,也不会有对应的安全问题。

持久化层的安全



Nacos 的配置信息,都是存储在持久化层的。比如 Nacos 默认的持久化层是 MySQL。

为了防止通过 git 或者其他方式将 MySQL 的用户名和密码泄漏出去,我们需要定时修改 MySQL 的用户名和密码。

通常的做法是使用两个数据库用户,比如 UserA 和 UserB。如果要更新密码,则按照如下方式操作:

  • 将 Nacos server 访问数据库的用户从 UserA 切换到 UserB。

  • 更新 UserA 的密码。

  • 将 Nacos server 访问数据库的用户从 UserB 切换回UserA。

  • 更新 UserB 的密码。

作为阿里云产品,MSE 都有定时修改数据库用户名密码的策略,所以如果您购买了 MSE 实例,则不需要担心此问题。

配置安全最佳实践



捋了一遍 Nacos 配置安全的关键点,那么怎么才能保证配置安全呢。只需要做到如下最佳实践就可以了:

1、定期修改密码和 ak/sk

在使用 Nacos 用户名密码(或者 AK/SK)认证的情况下(比如使用开源 Nacos 认证方式),如果恶意用户拿到了 Nacos 的用户名和密码(或者 AK/SK),那么他就有可能拿到应用的配置。但如果定期修改了密码或者 AK/SK 的话,就能有效限制配置泄漏的时间段,减少攻击面。

2、使用 ECS 角色(推荐用法)

当然,在上面的解决方案中,还是会有 Nacos 用户名密码或者 AK/SK 在配置中的,而且这些信息的也有可能泄漏,泄漏后的修改也需要重新发布才可以。所以推荐使用阿里云的 ECS 角色,所有的权限管理都是在阿里云控制台上完成

3、轮转 Nacos 内部认证的 key

前文有提到 Nacos 服务器之间的认证是通过 nacos.core.auth.server.identity 来完成的,但如果恶意用户入侵,也会导致泄漏,从而导致配置泄漏。

所以对于自建 Nacos,需要定期更换 nacos.core.auth.server.identity.value,确保恶意用户无法伪装为 Nacos Server 来获取、修改配置。

当然,如果您使用的是 MSE 托管的 Nacos 实例的话,MSE 会自动轮转,您可以不用担心这一点。

4、轮转持久化层的用户名和密码

为了防止配置从持久化层泄漏出去,所以需要定时修改持久化层的认证信息。通常 Nacos 的持久化层都是 DB,所以需要定时修改数据库的用户名和密码。

对于 MSE 用户,则不需要做任何操作,MSE 内部会定时修改数据库的用户名和密码。

5、设计安全预案并定时执行

有了如上重重保险,理论上万无一失,但是因为人的操作总有失误,所以还是需要指定安全预案:

  • 定时检查配置的监听列表,确认没有未授权的机器。

  • AK/SK 泄漏时,该如何更新 AK/SK,如何撤销泄漏的 AK/SK。

  • 对于自建 Nacos,服务器被攻破后,如何修改 nacos.core.auth.server.identity.value 的方案。

总结


开源的 Nacos 在配置管理、权限管理上,能基本满足中小企业需求。

而对于中大型企业,阿里云产品 MSE 支持更加精细、更加灵活的权限配置、安全管理,也能利用和其他阿里云产品一起做到更加安全的配置能力。

当然,不论是自建 Nacos 还是使用阿里云 MSE,都需要关注上述提到的安全点,防止配置信息泄漏,造成业务损失。最后提到的配置安全最佳实践,也能能保证配置泄漏后,有能力及时修复,做到防患未然。


往期推荐

16 条 yyds 的代码规范


再见收费的 XShell,我改用国产良心工具!


1.3w字,一文详解死锁!


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/544585.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

聊聊Spring事务失效的12种场景,太坑了

前言对于从事java开发工作的同学来说,spring的事务肯定再熟悉不过了。在某些业务场景下,如果一个请求中,需要同时写入多张表的数据。为了保证操作的原子性(要么同时成功,要么同时失败),避免数据…

什么是可中断锁?有什么用?怎么实现?

作者 | 王磊来源 | Java中文社群(ID:javacn666)转载请联系授权(微信ID:GG_Stone在 Java 中有两种锁,一种是内置锁 synchronized,一种是显示锁 Lock,其中 Lock 锁是可中断锁&#xff…

10个经典又容易被人疏忽的JVM面试题

前言整理了10个经典又容易被疏忽的JVM面试题,谢谢阅读,大家加油哈.1. 对象一定分配在堆中吗?有没有了解逃逸分析技术?「对象一定分配在堆中吗?」 不一定的,JVM通过「逃逸分析」,那些逃不出方法的…

面试官:怎么解决MySQL中的死锁问题?

咱们使用 MySQL 大概率上都会遇到死锁问题,这实在是个令人非常头痛的问题。本文将会对死锁进行相应介绍,对常见的死锁案例进行相关分析与探讨,以及如何去尽可能避免死锁给出一些建议。话不多说,开整!什么是死锁死锁是并…

ubuntu双系统导致进windows花屏

2019独角兽企业重金招聘Python工程师标准>>> 5600U的集成显卡,装了ubuntu的双系统,居然导致进win7的时候花屏,度娘狗哥都不得求解 网上很多解决方法都说在启动时加上nomodeset,发现对ubuntu15没用,且失去了…

工作总结:日志打印的15个建议

前言 日志是快速定位问题的好帮手,是撕逼和甩锅的利器!打印好日志非常重要。今天我们来聊聊日志打印的15个好建议~1. 选择恰当的日志级别 常见的日志级别有5种,分别是error、warn、info、debug、trace。日常开发中,我们需要选择恰…

MFC属性页对话框

属性页对话框 分类 分页和引导 类 CPropertyPage-父亲CDialog类别,所谓的属性页或网页对话框。 CPropertySheet-父类是CWnd,称为属性表单。 一个完整的属性页对话框由一个属性表单多个属性页组成。属性页嵌套在属性表单内。 标签式属性页的创建步骤&…

面试官:ConcurrentHashMap为什么放弃了分段锁?

今天我们来讨论一下一个比较经典的面试题就是 ConcurrentHashMap 为什么放弃使用了分段锁,这个面试题阿粉相信很多人肯定觉得有点头疼,因为很少有人在开发中去研究这块的内容,今天阿粉就来给大家讲一下这个 ConcurrentHashMap 为什么在 JDK8 …

C语言函数指针的应用——自制谐波分析软件

文章目录函数指针简介格式介绍颜色头文件计算机仿真使用说明完整代码部分效果图函数指针简介 如果在一个大型C语言程序中要反复调用函数,而调用的函数又不明确时,函数指针就是一个非常有用的东西。如果你的函数体内可以传递不同的函数,那就非…

PHP5.5四种序列化性能对比

2019独角兽企业重金招聘Python工程师标准>>> 结论: 1、小数组用msgpack,无论空间和性能都最好 2、大数组,考虑空间用igbinary,考虑性能用msgpack json_encode,serialize,igbinary,msgpack四种序列化方式&am…

MyBatis Plus 批量数据插入功能,yyds!

作者 | 王磊来源 | Java中文社群(ID:javacn666)转载请联系授权(微信ID:GG_Stone最近 Review 小伙伴代码的时候,发现了一个小小的问题,小伙伴竟然在 for 循环中进行了 insert (插入&a…

C语言打印彩色字符——以(枚举法+字符串查找)为例展示

文章目录C语言颜色头文件——自制非常简单的调用函数实战演练——一个基础的枚举变量小程序牛刀小试——查找字符小程序C语言颜色头文件——自制非常简单的调用函数 显然,C语言是不会提供打印彩色字符的标准函数,而我们有时候为了强调C语言打印的部分字…

再见 Spring Task,这个定时任务框架真香!

最近有朋友问到定时任务相关的问题。于是,我简单写了一篇文章总结一下定时任务的一些概念以及一些常见的定时任务技术选型。希望能对小伙伴们有帮助!个人能力有限。如果文章有任何需要补充/完善/修改的地方,欢迎在评论区指出,共同…

C语言实现动画控制

文章目录原材料说明一场革命原材料 下载原材料网址: https://www.easyx.cn/downloads/ 下载easyx2014冬至版,将lib文件放在编译器默认的lib文件夹,h头文件放在编译器默认的include文件夹即可 说明 C语言可以用系统内部的定时函数sleep和usleep定时(需…

聊聊redis分布式锁的8大坑

前言在分布式系统中,由于redis分布式锁相对于更简单和高效,成为了分布式锁的首先,被我们用到了很多实际业务场景当中。但不是说用了redis分布式锁,就可以高枕无忧了,如果没有用好或者用对,也会引来一些意想…

MyBatis 批量插入数据的 3 种方法!

作者 | 王磊来源 | Java中文社群(ID:javacn666)转载请联系授权(微信ID:GG_Stone批量插入功能是我们日常工作中比较常见的业务功能之一,之前我也写过一篇关于《MyBatis Plus 批量数据插入功能,yy…

MongoDB: The Definitive Guide

第一章 简介 MongoDB是面向文档的数据库,不是关系型数据库。内置对MapReduce的支持,以及对地理空间索引的支持。 丰富的数据模型容易扩展,它所采用的面向文档的数据模型可以使其在多台服务器之间分割数据丰富的功能,索引、存储Jav…

Python联网下载文件

声明 Python版本2.7.3所需Py文件——urllib22.7.3版本的Python Shell即可直接执行,但需要联网若程序执行成功,则会下载以下网址的txt文本并打印在shell中 http://helloworldbook2.com/data/message.txt 本代码来源于《父与子的编程之旅——与小卡特一起…

如何给SpringBoot配置轻松加密?

在实践中,项目的某些配置信息是需要进行加密处理的,以减少敏感信息泄露的风险。比如,在使用Druid时,就可以基于它提供的公私钥加密方式对数据库的密码进行加密。但更多时候,比如Redis密码、MQ密码等敏感信息&#xff0…

C语言将循环小数/有限小数转换为分数

文章目录数学基础编程思路代码数学基础 早在小学的时候我就对循环小数非常感兴趣,加上初中和高中对循环小数可以说有一定基础研究,因此想到写一个将循环下小数转换为分数的程序,非常有意思,并且对初学者来说,它的输入…