如果不这样用,Nacos也有安全问题!
前言
配置管理作為軟件開(kāi)發(fā)中重要的一環(huán),肩負(fù)著連接????代碼和環(huán)境的職責(zé),能很好的分離開(kāi)發(fā)人員和維護(hù)人員的關(guān)注點(diǎn)。
Nacos 的配置管理功能就很好地滿(mǎn)足了云原生應(yīng)用對(duì)于配置管理的需求:既能做到配置和代碼分離,也能做到配置的動(dòng)態(tài)修改。
在 1月份,Nacos 出了一個(gè)安全漏洞,外部用戶(hù)能夠偽裝為 Nacos-server 來(lái)獲取/修改配置( https://github.com/alibaba/nacos/issues/4593 )。確認(rèn)問(wèn)題后,Nacos 火速修復(fù)了漏洞,而阿里云的微服務(wù)引擎(MSE)也已在 1月末將修復(fù)方案反向移植到 MSE 上的 Nacos 實(shí)例上。
在本文中,我們將會(huì)從全局視角入手,討論如何才能保證 Nacos 配置的安全性(security),即如何保證配置信息不被惡意用戶(hù)獲取或者泄漏。
Nacos 配置架構(gòu)
Nacos 配置部分的整體架構(gòu)如下:
對(duì)于上圖中的每一條鏈路,都需要考慮有沒(méi)有兩個(gè)基本的安全動(dòng)作:認(rèn)證(Identification)和鑒權(quán)(Authentication)。
從上圖可以看到,配置信息可能的泄漏方式有:
通過(guò) Nacos-client 獲取配置。
通過(guò)控制臺(tái)獲取配置。
通過(guò)服務(wù)器之間的通信協(xié)議獲取配置。
直接訪(fǎng)問(wèn)持久化層(比如 DB)獲取配置。
可能的泄漏點(diǎn)如下:
認(rèn)證 | 鑒權(quán) | |
Nacos 客戶(hù)端 | 未登錄用戶(hù)通過(guò)客戶(hù)端獲取/修改配置 | 用戶(hù)通過(guò)客戶(hù)端獲取/修改了未授權(quán)的配置 |
配置控制臺(tái) | 未登錄用戶(hù)通過(guò)控制臺(tái)獲取/修改配置 | 用戶(hù)通過(guò)控制臺(tái)獲取/修改了未授權(quán)的配置 |
Nacos 集群內(nèi) | 用戶(hù)偽裝為 Nacos 集群獲取/修改配置 | 不需要 |
持久化層 | 用戶(hù)直接查 DB,獲取/修改配置 | 不需要 |
Nacos 客戶(hù)端場(chǎng)景的認(rèn)證和鑒權(quán)
在 Nacos 客戶(hù)端嘗試從服務(wù)端獲取配置時(shí),服務(wù)端需要確認(rèn)客戶(hù)端的身份,并確認(rèn)該身份有權(quán)限獲取配置。
開(kāi)源版本的 Nacos
在默認(rèn)的 Nacos server 配置中,不會(huì)對(duì)客戶(hù)端鑒權(quán),即任何能訪(fǎng)問(wèn) Nacos server 的用戶(hù),都可以直接獲取 Nacos 中存儲(chǔ)的配置。比如一個(gè)黑客攻進(jìn)了企業(yè)內(nèi)網(wǎng),就能獲取所有的業(yè)務(wù)配置,這樣肯定會(huì)有安全隱患。
所以需要先開(kāi)啟 Nacos server 的鑒權(quán)。在 Nacos server 上修改 application.properties 中的 nacos.core.auth.enabled 值為 true 即可:
nacos.core.auth.enabled=true如上設(shè)置后,Nacos 客戶(hù)端獲取配置時(shí),需要設(shè)置上對(duì)應(yīng)的用戶(hù)名和密碼,才能獲取配置:
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);上面講了如何認(rèn)證用戶(hù),即如何確定現(xiàn)在是哪一個(gè)用戶(hù)在訪(fǎng)問(wèn),但還需要識(shí)別用戶(hù)的權(quán)限,當(dāng)用戶(hù)訪(fǎng)問(wèn)沒(méi)有權(quán)限獲取對(duì)應(yīng)配置的時(shí)候,比如庫(kù)存服務(wù)嘗試獲取支付服務(wù)的配置時(shí),就會(huì)失敗。
我們可以在開(kāi)源的 Nacos 控制臺(tái)上創(chuàng)建用戶(hù)、設(shè)置權(quán)限。步驟如下:
首先,訪(fǎng)問(wèn) localhost:8848/nacos 并登錄,在 權(quán)限控制->用戶(hù)列表 頁(yè)面,添加用戶(hù):
在 權(quán)限控制->角色管理,綁定用戶(hù)和角色:
給對(duì)應(yīng)角色添加權(quán)限,在?權(quán)限控制->權(quán)限管理?頁(yè)面,添加權(quán)限:
經(jīng)過(guò)如上配置后,readonly-user 就只能訪(fǎng)問(wèn) public 命名空間下的配置了。
阿里云 MSE-AK/SK
對(duì)于小團(tuán)隊(duì),用用戶(hù)名和密碼來(lái)做認(rèn)證鑒權(quán)是足夠的。但對(duì)于中大型團(tuán)隊(duì),密碼的定期更換、人員的頻繁變動(dòng)等,都會(huì)導(dǎo)致用戶(hù)名和密碼頻繁變動(dòng)。
這時(shí),使用用戶(hù)名和密碼認(rèn)證鑒權(quán)就需要頻繁修改并發(fā)布應(yīng)用。為了解決這個(gè)問(wèn)題,Nacos 也提供了基于 AK/SK 的認(rèn)證方案、ECS關(guān)聯(lián)RAM角色的方案,可以避免用戶(hù)名和密碼修改導(dǎo)致的頻繁發(fā)布問(wèn)題。
以阿里云 MSE 為例,阿里云用戶(hù)已經(jīng)普遍使用了阿里云訪(fǎng)問(wèn)控制服務(wù)(RAM)作為權(quán)限系統(tǒng),如果 MSE 和開(kāi)源一樣,使用用戶(hù)名和密碼實(shí)現(xiàn)認(rèn)證和鑒權(quán)的話(huà),那么用戶(hù)就需要在 RAM 和 MSE Nacos 兩個(gè)地方配置權(quán)限。這樣既不方便用戶(hù)權(quán)限的統(tǒng)一管理、審查,也給用戶(hù)帶來(lái)了不一致的體驗(yàn)。
所以 MSE(微服務(wù)引擎)提供了基于 AK/SK 的認(rèn)證方式,操作示例如下:
首先,在 MSE 上申請(qǐng)一個(gè) Nacos 實(shí)例(并記下實(shí)例 id),然后在 實(shí)例詳情->參數(shù)設(shè)置?界面,將 ConfigAuthEnabled(配置鑒權(quán))參數(shù)設(shè)置為 true,這樣匿名用戶(hù)就無(wú)法獲取配置:
然后就可以在阿里云RAM系統(tǒng)上配置相關(guān)權(quán)限。RAM子賬號(hào)的權(quán)限系統(tǒng)可以簡(jiǎn)單表示如下:
第一步:創(chuàng)建 RAM 權(quán)限策略如下:
圖中,mse:Get*、mse:List*、mse:Query* 表示能讀取配置,mse:* 表示所有權(quán)限,包括修改權(quán)限。
acs:mse:*:*:instance/${instanceId} 表示授權(quán)到實(shí)例級(jí)別,acs:mse:*:*:instance/${instanceId}/${namespaceId} 表示授權(quán)到命名空間級(jí)別。
第二步:創(chuàng)建用戶(hù)并賦予權(quán)限:
填寫(xiě)用戶(hù)名稱(chēng):
然后獲取到用戶(hù)的 AK/SK:
給這個(gè)用戶(hù)對(duì)應(yīng)的權(quán)限:
最后,只需要在代碼中添加 AK/SK 就可以了:
經(jīng)過(guò)如上配置,客戶(hù)端在訪(fǎng)問(wèn) MSE 上購(gòu)買(mǎi)的 Nacos 實(shí)例的時(shí)候,MSE 會(huì)校驗(yàn) AK 和簽名,確認(rèn)該用戶(hù)是合法的用戶(hù),并校驗(yàn)權(quán)限,否則拒絕提供服務(wù)。
阿里云 MSE- 基于 ECS 的 Ram 角色認(rèn)證
當(dāng)然,在上面的使用方式中,還是要在初始配置(比如 srping-cloud-alibaba-nacos-config 中的 bootstrap.yml 文件)中配置 AK/SK。黑客入侵內(nèi)網(wǎng)、或者源碼泄漏時(shí),也會(huì)存在 AK/SK 泄漏,導(dǎo)致配置信息泄漏的風(fēng)險(xiǎn)。
在這種情況下,推薦使用 ECS 關(guān)聯(lián)的 RAM 角色來(lái)做認(rèn)證。
ECS 關(guān)聯(lián) RAM 角色對(duì)應(yīng)的授權(quán)模型如下:
上述的關(guān)鍵步驟在角色扮演。只有關(guān)聯(lián)了 RAM 角色的云服務(wù)器,才能成功扮演角色,從而獲取操作 MSE Nacos 實(shí)例的權(quán)限。
如果黑客只獲取了代碼,也無(wú)法成功扮演 RAM 角色,無(wú)法操作 MSE Nacos 實(shí)例。如果機(jī)器被攻破,那也能在阿里云控制臺(tái)上取消云服務(wù)器關(guān)聯(lián)的角色,及時(shí)止損。
具體的操作步驟如下:
第一步,創(chuàng)建 MSE Nacos 實(shí)例,并創(chuàng)建對(duì)應(yīng)的權(quán)限策略(上文有說(shuō)明,此處不贅述)。
第二步,創(chuàng)建 RAM 角色并授權(quán)。
創(chuàng)建 RAM 角色:
創(chuàng)建角色后,為該角色添加對(duì)應(yīng)的權(quán)限策略:
第三步,將該角色和 ECS 關(guān)聯(lián):
在對(duì)應(yīng)的 ECS 詳情頁(yè)面,點(diǎn)擊 授予/收回 RAM 角色:
選擇對(duì)應(yīng)的角色并授予:
最后一步,在代碼中 指定 RAM 角色?即可:
經(jīng)過(guò)如上配置,Nacos 客戶(hù)端在獲取配置時(shí),云服務(wù)器會(huì)扮演指定的 RAM 角色,阿里云臨時(shí)安全令牌(Security Token Service,STS)來(lái)訪(fǎng)問(wèn) MSE Nacos 實(shí)例。
如果攻擊者獲取代碼,也無(wú)法在其他機(jī)器上運(yùn)行,因?yàn)楣粽叩臋C(jī)器沒(méi)有扮演 RAM 角色的權(quán)限。
如果攻擊者獲取扮演之后的認(rèn)證信息,由于 STS 失效較短(默認(rèn)是1小時(shí)),攻擊者拿到后很快就失效,有效減少了攻擊面。
如果需要撤銷(xiāo)授權(quán),只需要在阿里云控制臺(tái)上就可以操作,不需要重新發(fā)布應(yīng)用。
相比于?AK/SK?方式的認(rèn)證鑒權(quán),ECS?關(guān)聯(lián)角色的認(rèn)證鑒權(quán)更可控、更安全,所以推薦使用這種認(rèn)證鑒權(quán)方式。
配置控制臺(tái)場(chǎng)景的認(rèn)證和鑒權(quán)
開(kāi)源版本的 Nacos
開(kāi)源版本的 Nacos 控制臺(tái),在登錄的時(shí)候,會(huì)通過(guò)控制臺(tái)的 login 接口,獲取臨時(shí)的 accessToken,然后后續(xù)的操作,都是以 accessToken 來(lái)做認(rèn)證鑒權(quán)。
比如前文提到的 readonly-user 用戶(hù),登錄后,就只能看到 public 命名空間下的配置信息,無(wú)法修改、無(wú)法查看其他命名空間下的配置信息。
另外,如果需要?jiǎng)?chuàng)建命名空間、刪除命名空間,則只能管理員登錄才可以。
開(kāi)源版本 Nacos 的認(rèn)證鑒權(quán),可以參考該文檔:https://nacos.io/zh-cn/docs/auth.html。
阿里云 MSE
阿里云 MSE 由于是對(duì)企業(yè)提供服務(wù),所以在權(quán)限的劃分上會(huì)更加精細(xì)。
資源分為實(shí)例級(jí)別(acs:mse:*:*:instance/${instanceId})和命名空間級(jí)別(acs:mse:*:*:instance/${instanceId}/${namespaceId})。
對(duì)資源的操作也更加精細(xì),比如:
Action | 說(shuō)明 |
CreateEngineNamespace | 創(chuàng)建命名空間 |
DeleteEngineNamespace | 刪除命名空間 |
| mse:Get*,mse:List*,mse:Query* | 讀取配置(Nacos 客戶(hù)端和控制臺(tái)) |
| mse:* | 所有權(quán)限,包括修改、刪除配置 |
| mse:QueryNacosConfig | 客戶(hù)端讀取配置 |
| mse:UpdateNacosConfig | 客戶(hù)端修改配置 |
比如,只允許讀取一個(gè)命名空間下的配置,不允許修改。那權(quán)限策略就可以寫(xiě):
{ "Action": [ "mse:Get*", "mse:List*", "mse:Query*" ], "Resource": [ "acs:mse:*:*:instance/${instanceId}/${namespaceId}" ], "Effect": "Allow"}服務(wù)器之間的認(rèn)證
Nacos 服務(wù)器之間需要同步一些信息,這時(shí)也需要認(rèn)證對(duì)方身份,以確認(rèn)對(duì)方真的是 Nacos-server,而不是偽裝的。
在 1.4.1 之前,是通過(guò) User-Agent 這個(gè) header 來(lái)認(rèn)證的,這種原始的認(rèn)證方式,很容易被偽造。本文開(kāi)頭提到的,1月份 Nacos 爆出的漏洞就是這個(gè)原因。
所以 1.4.1 及之后的版本,認(rèn)證的 header 以及對(duì)應(yīng)的值可以自己配置。在 application.properties 中,修改如下值即可:
# 不使用User-Agent來(lái)認(rèn)證nacos.core.auth.enable.userAgentAuthWhite=false# 認(rèn)證header的keynacos.core.auth.server.identity=Authorization# 認(rèn)證header的valuenacos.core.auth.server.identity.value=secret這樣,只有發(fā)送了 header Authorization: secret 的請(qǐng)求,才能確認(rèn)對(duì)方是服務(wù)端,才能同步集群信息;否則就拒絕同步。
由于 Nacos-server 需要全部權(quán)限才能同步配置數(shù)據(jù),所以對(duì)于 Nacos-server 之間,則不需要做鑒權(quán)。
這樣,就能讓服務(wù)器之間的通信也能做到安全可信了。
阿里云 MSE 上購(gòu)買(mǎi)的 Nacos 實(shí)例,也已經(jīng)將上述方案反向移植到了 1.2 版本上,也不會(huì)有對(duì)應(yīng)的安全問(wèn)題。
持久化層的安全
Nacos 的配置信息,都是存儲(chǔ)在持久化層的。比如 Nacos 默認(rèn)的持久化層是 MySQL。
為了防止通過(guò) git 或者其他方式將 MySQL 的用戶(hù)名和密碼泄漏出去,我們需要定時(shí)修改 MySQL 的用戶(hù)名和密碼。
通常的做法是使用兩個(gè)數(shù)據(jù)庫(kù)用戶(hù),比如 UserA 和 UserB。如果要更新密碼,則按照如下方式操作:
將 Nacos server 訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)的用戶(hù)從 UserA 切換到 UserB。
更新 UserA 的密碼。
將 Nacos server 訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)的用戶(hù)從 UserB 切換回UserA。
更新 UserB 的密碼。
作為阿里云產(chǎn)品,MSE 都有定時(shí)修改數(shù)據(jù)庫(kù)用戶(hù)名密碼的策略,所以如果您購(gòu)買(mǎi)了 MSE 實(shí)例,則不需要擔(dān)心此問(wèn)題。
配置安全最佳實(shí)踐
捋了一遍 Nacos 配置安全的關(guān)鍵點(diǎn),那么怎么才能保證配置安全呢。只需要做到如下最佳實(shí)踐就可以了:
1、定期修改密碼和 ak/sk
在使用 Nacos 用戶(hù)名密碼(或者?AK/SK)認(rèn)證的情況下(比如使用開(kāi)源 Nacos 認(rèn)證方式),如果惡意用戶(hù)拿到了 Nacos 的用戶(hù)名和密碼(或者?AK/SK),那么他就有可能拿到應(yīng)用的配置。但如果定期修改了密碼或者?AK/SK 的話(huà),就能有效限制配置泄漏的時(shí)間段,減少攻擊面。
2、使用 ECS?角色(推薦用法)
當(dāng)然,在上面的解決方案中,還是會(huì)有 Nacos 用戶(hù)名密碼或者 AK/SK 在配置中的,而且這些信息的也有可能泄漏,泄漏后的修改也需要重新發(fā)布才可以。所以推薦使用阿里云的 ECS 角色,所有的權(quán)限管理都是在阿里云控制臺(tái)上完成。
3、輪轉(zhuǎn) Nacos 內(nèi)部認(rèn)證的 key
前文有提到 Nacos 服務(wù)器之間的認(rèn)證是通過(guò) nacos.core.auth.server.identity 來(lái)完成的,但如果惡意用戶(hù)入侵,也會(huì)導(dǎo)致泄漏,從而導(dǎo)致配置泄漏。
所以對(duì)于自建 Nacos,需要定期更換 nacos.core.auth.server.identity.value,確保惡意用戶(hù)無(wú)法偽裝為 Nacos Server 來(lái)獲取、修改配置。
當(dāng)然,如果您使用的是 MSE 托管的 Nacos 實(shí)例的話(huà),MSE 會(huì)自動(dòng)輪轉(zhuǎn),您可以不用擔(dān)心這一點(diǎn)。
4、輪轉(zhuǎn)持久化層的用戶(hù)名和密碼
為了防止配置從持久化層泄漏出去,所以需要定時(shí)修改持久化層的認(rèn)證信息。通常 Nacos 的持久化層都是 DB,所以需要定時(shí)修改數(shù)據(jù)庫(kù)的用戶(hù)名和密碼。
對(duì)于 MSE 用戶(hù),則不需要做任何操作,MSE 內(nèi)部會(huì)定時(shí)修改數(shù)據(jù)庫(kù)的用戶(hù)名和密碼。
5、設(shè)計(jì)安全預(yù)案并定時(shí)執(zhí)行
有了如上重重保險(xiǎn),理論上萬(wàn)無(wú)一失,但是因?yàn)槿说牟僮骺傆惺д`,所以還是需要指定安全預(yù)案:
定時(shí)檢查配置的監(jiān)聽(tīng)列表,確認(rèn)沒(méi)有未授權(quán)的機(jī)器。
AK/SK 泄漏時(shí),該如何更新?AK/SK,如何撤銷(xiāo)泄漏的?AK/SK。
對(duì)于自建 Nacos,服務(wù)器被攻破后,如何修改 nacos.core.auth.server.identity.value 的方案。
總結(jié)
開(kāi)源的 Nacos 在配置管理、權(quán)限管理上,能基本滿(mǎn)足中小企業(yè)需求。
而對(duì)于中大型企業(yè),阿里云產(chǎn)品 MSE 支持更加精細(xì)、更加靈活的權(quán)限配置、安全管理,也能利用和其他阿里云產(chǎn)品一起做到更加安全的配置能力。
當(dāng)然,不論是自建 Nacos 還是使用阿里云 MSE,都需要關(guān)注上述提到的安全點(diǎn),防止配置信息泄漏,造成業(yè)務(wù)損失。最后提到的配置安全最佳實(shí)踐,也能能保證配置泄漏后,有能力及時(shí)修復(fù),做到防患未然。
往期推薦16 條 yyds 的代碼規(guī)范
再見(jiàn)收費(fèi)的 XShell,我改用國(guó)產(chǎn)良心工具!
1.3w字,一文詳解死鎖!
總結(jié)
以上是生活随笔為你收集整理的如果不这样用,Nacos也有安全问题!的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 在C ++中检查一个数组是否是另一个数组
- 下一篇: ruby 数组元素替换_从Ruby中的集