Nacos配置安全最佳实践

本文涉及的产品
Serverless 应用引擎免费试用套餐包,4320000 CU,有效期3个月
性能测试 PTS,5000VUM额度
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: 本文讨论了自建Nacos和阿里云MSE的配置安全原理。并提出配置安全最佳实践。

作者:鲁严波

前言


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


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


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


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

Nacos配置架构


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

image.png

Nacos服务端

Nacos-client

业务代码获取/修改配置

节点1

配置信息持久化存储

节点之间同步信息

节点2

配置持久化层

控制台获取/修改配置

节点3

用户操作控制台

配置管理

用户

控制台

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


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


  1. 通过Nacos-client获取配置
  2. 通过控制台获取配置
  3. 通过服务器之间的通信协议获取配置
  4. 直接访问持久化层(比如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客户端获取配置时,需要设置上对应的用户名和密码,才能获取配置:

StringserverAddr="{serverAddr}";
Propertiesproperties=newProperties();
properties.put("serverAddr", serverAddr);
properties.put("username","nacos-readonly");
properties.put("password","nacos");
ConfigServiceconfigService=NacosFactory.createConfigService(properties);


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


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


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

image.png

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

image.png

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

image.png

添加权限

角色名

public-readonly

资源

public

只读(0)

动作

确认

取消

经过如上配置后,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,这样匿名用户就无法获取配置:


image.png

微服务引擎/实例列表参数设置

实例详情(mse-0..a)参数设置

基础信息

编辑

命名空间

描述

参数名

服务管理

是否打开记置模块队w整仪功能,MAo打开此开关后,客护灵使用coske/才能获取几营,体开关不服务注量模

配查管理

true

ConfigAuthenabled

打开此开关后,没有配置Accesskey的客户端将无法获取配营,请谨侗操作!

监控

参数设百

MCPEnabled

false

Nacos打开MCPI功能后可以支持与服务网格连援,支持SpingCloud服务和非Java应用的互通.


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


image.png

操作资源

(MSENacos实例)

RAM用户

RAM权限策略

(子账号)

操作资源

AK/SK1

RAM权限策略

AK/SK2

操作资源


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


image.png


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


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


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


填写用户名称:


image.png

RAM访问控制/用户创建用户

创建用户

用户账号信息

显示名称

登录名称

库存服务

@middleware-edas.onaliyun.com

storeservice

-添加用户

访问方式

用户使用账号密码访问阿里云控制台

控制台访问

编程访问

启用AccesskeyID和Accesskeysecret,支持通过API或其他开发工具访问

确定

返回


然后获取到用户的ak/sk:


image.png


给这个用户对应的权限:


image.png

RAM访问控制+用户+SToresenviceEmiddlware-edascnalyuncom

添加权限

storeservice@middleware-edas.onaliyun.com

指定资组的授权生效前提是该云服务已支持资源姐,舌当的支村责源相的云服务,(前往查]

单次授权最多支持5条需棉,义需绑定更多策略,请分多次进行.

用户基本信息

绵辑基本信品

授权范用

SRESNViceMdDLEwwareEdAsONAliyUNCom制

用户名

云账号全部资源

星示名称

库存服务

指定责药组

备注

请选择或蜂入源组名称进行摆索

邮箱

遂接权主体

认证管理

加入的组

权限管理

storeserice@mlddleware-edas.onaliyun.com

个人权限

继承用户组的权限

选择权限

+新廷权限策格

自定义策路

系维策露

活G

已选择(1)

添加视眼

x

权障应用范压

权限酒路名称

权蔬策赔类型

各注

权限详路名称


最后,只需要在代码中添加ak/sk就可以了:


StringserverAddr="{serverAddr}";
Propertiesproperties=newProperties();
properties.put("serverAddr", serverAddr);
properties.put(PropertyKeyConst.ACCESS_KEY, "${accessKey}");
properties.put(PropertyKeyConst.SECRET_KEY, "${secret}");
ConfigServiceconfigService=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角色对应的授权模型如下:

image.png

操作资源

(MSENacos实例)

RAM角色

RAM权限策略

操作资源

角色扮演

RAM权限策略

云服务器

操作资源

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


如果黑客只获取了代码,也无法成功扮演RAM角色,无法操作MSE Nacos实例。

如果机器被攻破,那也能在阿里云控制台上取消云服务器关联的角色,及时止损。

具体的操作步骤如下:


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


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


创建RAM角色:


image.png

image.png

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


image.png


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


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


image.png

付费信息

按量付费转包年包月为按量付费购买预留实例券

带宽计费方式

付费类型

按使用流量

按量

其他信息

本实例诊断历史

诊断健康状态

授予/收回RAM角色

维护属性

NO优化

自动重启恢复

实例类型

修改实例释放保护

释放保护

集群ID

修改实例维护属性

停止模式

无性能约束模式

设置用户数据

密钥对

RAM角色

保存为启动模板


选择对应的角色并授予:

image.png


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


StringserverAddr="{serverAddr}";
Propertiesproperties=newProperties();
properties.put("serverAddr", serverAddr);
properties.put(PropertyKeyConst.RAM_ROLE_NAME, "StoreServiceRole");
ConfigServiceconfigService=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的key
nacos.core.auth.server.identity=Authorization
# 认证header的value
nacos.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。如果要更新密码,则按照如下方式操作:


  1. 将Nacos server访问数据库的用户从UserA切换到UserB
  2. 更新UserA的密码
  3. Nacos server访问数据库的用户从UserB切换回UserA
  4. 更新UserB的密码


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

配置安全最佳实践


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


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


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


  1. 使用ECS角色(推荐用法)


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


  1. 轮转Nacos内部认证的key


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


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


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


  1. 轮转持久化层的用户名和密码


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


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


  1. 设计安全预案并定时执行


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


  • 定时检查配置的监听列表,确认没有未授权的机器在获取配置
  • ak/sk泄漏时,该如何更新ak/sk,如何撤销泄漏的ak/sk
  • 自建Nacos,服务器被攻破后,如何修改nacos.core.auth.server.identity.value的方案


总结


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


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


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


招贤纳士


我们 Dubbo /  Spring Cloud 商业化团队正在招人,除了 EDAS,我们还有 ARMS  (应用实时监控服务)、MSE(微服务引擎)、SAE(Serverless  应用引擎)等独立产品。我们在忙什么?用心打磨这些产品,就是我们的工作。团队的目标是将阿里巴巴在服务治理上的最佳实践通过产品化的形式输出给阿里云上的企业客户,帮助客户实现业务永远在线。


简历投递方式:https://job.alibaba.com/zhaopin/position_detail.htm?positionId=98290


扫码了解更多技术干货和客户案例:

image.png


相关实践学习
2分钟自动化部署人生模拟器
本场景将带你借助云效流水线Flow实现人生模拟器小游戏的自动化部署
7天玩转云服务器
云服务器ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,可降低 IT 成本,提升运维效率。本课程手把手带你了解ECS、掌握基本操作、动手实操快照管理、镜像管理等。了解产品详情: https://www.aliyun.com/product/ecs
相关文章
|
11天前
|
负载均衡 应用服务中间件 Nacos
Nacos配置中心
Nacos配置中心
40 1
Nacos配置中心
|
7天前
|
监控 Java 测试技术
Nacos 配置中心变更利器:自定义标签灰度
本文是对 MSE Nacos 应用自定义标签灰度的功能介绍,欢迎大家升级版本进行试用。
|
10天前
|
网络安全 Nacos 开发者
Nacos作为流行的微服务注册与配置中心,“节点提示暂时不可用”是常见的问题之一
Nacos作为流行的微服务注册与配置中心,其稳定性和易用性备受青睐。然而,“节点提示暂时不可用”是常见的问题之一。本文将探讨该问题的原因及解决方案,帮助开发者快速定位并解决问题,确保服务的正常运行。通过检查服务实例状态、网络连接、Nacos配置、调整健康检查策略等步骤,可以有效解决这一问题。
22 4
|
10天前
|
Java 网络安全 Nacos
Nacos作为流行的微服务注册与配置中心,其稳定性和易用性备受青睐。
Nacos作为流行的微服务注册与配置中心,其稳定性和易用性备受青睐。然而,实际使用中常遇到“客户端不发送心跳检测”的问题。本文深入探讨该问题的原因及解决方案,帮助开发者快速定位并解决问题,确保服务正常运行。通过检查客户端配置、网络连接、日志、版本兼容性、心跳策略、注册状态、重启应用和环境变量等步骤,系统地排查和解决这一问题。
26 3
|
10天前
|
安全 Nacos 数据库
Nacos是一款流行的微服务注册与配置中心,但直接暴露在公网中可能导致非法访问和数据库篡改
Nacos是一款流行的微服务注册与配置中心,但直接暴露在公网中可能导致非法访问和数据库篡改。本文详细探讨了这一问题的原因及解决方案,包括限制公网访问、使用HTTPS、强化数据库安全、启用访问控制、监控和审计等步骤,帮助开发者确保服务的安全运行。
24 3
|
2月前
|
安全 Cloud Native 测试技术
Star 3w+,向更安全、更泛化、更云原生的 Nacos3.0 演进
祝贺 Nacos 社区 Star 数突破 30000!值此时机,回顾过去的两年时间,Nacos 从 2.0.4 版本演进到了 2.4.2 版本,基本完成了当初构想的高性能、易拓展的目标,并且对产品的易用性和安全性进行了提升,同时优化了新的官网,并进行了多语言和更多生态支持。未来,Nacos 会向更安全、更泛化、更云原生的 Nacos3.0 演进。
146 16
|
19天前
|
SQL 关系型数据库 数据库连接
"Nacos 2.1.0版本数据库配置写入难题破解攻略:一步步教你排查连接、权限和配置问题,重启服务轻松解决!"
【10月更文挑战第23天】在使用Nacos 2.1.0版本时,可能会遇到无法将配置信息写入数据库的问题。本文将引导你逐步解决这一问题,包括检查数据库连接、用户权限、Nacos配置文件,并提供示例代码和详细步骤。通过这些方法,你可以有效解决配置写入失败的问题。
44 0
|
2月前
|
负载均衡 Java Nacos
SpringCloud基础2——Nacos配置、Feign、Gateway
nacos配置管理、Feign远程调用、Gateway服务网关
SpringCloud基础2——Nacos配置、Feign、Gateway
|
3月前
|
安全 Nacos 数据安全/隐私保护
升级指南:从Nacos 1.3.0 到 2.3.0,并兼容 Seata 的鉴权配置
本文详细介绍了如何在微服务环境下从 Nacos 1.3.0 升级到 2.3.0,并确保 Seata 各版本的兼容性。作者小米分享了升级过程中的关键步骤,包括备份配置、更新鉴权信息及验证测试等,并解答了常见问题。通过这些步骤,可以帮助读者顺利完成升级并提高系统的安全性与一致性。
118 8
升级指南:从Nacos 1.3.0 到 2.3.0,并兼容 Seata 的鉴权配置
|
3月前
|
运维 Java Nacos
Spring Cloud应用框架:Nacos作为服务注册中心和配置中心
Spring Cloud应用框架:Nacos作为服务注册中心和配置中心