无数的坑。
一、nacos1.3的漏洞
客户组织安全测试,我们系统测出了好几个高危问题,其中大部分是关于nacos的,有:
1)spring boot actuator 未授权访问,即访问/nacos/actuator得到许多链接,进一步访问可拿到许多信息
(这说明nacos是用spring boot开发的?)
2)nacos未授权访问
3)nacos身份绕过漏洞
4)heapdump泄露(这也是从actuator拿到链接,可以下载heapdump文件,从里面分析出敏感信息)
我们nacos版本是1.3.X的,版本太低了,现在(2024.01)已经是2.3.0了。测试方和网上都说,解决之道是将nacos升级到最新版。
二、下载nacos2.3 for arm64
我们用docker来跑nacos。这是一个信创项目,服务器的CPU架构是ARM的,因此需要下载支持arm64的nacos镜像。服务器也不能上网。安装思路是“
1)在能上网的服务器上下载支持arm64的镜像
2)将该镜像打包,拷贝到生产服务器上安装
详见拙作《下载nacos 2.3 for arm64》
三、安装
(一)概述
1、备份nacos的配置
这个非常重要。所谓的备份,首先是指把nacos的配置全部导出来,异机保存,下载到本地。同时不要删除现有的docker容器,可以将其停止,这样不影响新创建的容器使用现有的端口。不过,容器名不能重复。比如现有容器名为nacos,那么新创建的容器可以叫ncos23。
2、命名空间截图
这其实也算是备份现有nacos的一部分。命名空间最好能截屏,避免在新创建的nacos中,命名空间不一致。
3、保留旧容器,停止
呼应第一条。
4、创建新容器
nacos2.3.0取消了一些默认值,也就是说,如果开启鉴权,那么安装时必须显式指定这些属性值,否则无法启动(不开启鉴权,也就是无须登录,就不需要指定)。以往在低版本,不指定的话,系统自动采用默认值,用户是无感的。取消默认值是基于加强安全性的考虑,从2.*就开始了,但应该不是2.0.x。2.0.x还是会有上面说的安全性问题。
具体的配置,可参考:nacos鉴权
设置这些属性值,如果用docker直接创建,可以将nacos的配置文件application.properties外挂到宿主机,方便修改;如果用docker-compose创建,可以将属性值写到yaml文件(参考拙作:docker-compose初探)。
(二)如果用docker创建
1、首先创建nacos2.3实例
这其实是临时的,目的是得到它的配置文件。假设镜像是jiehoom/nacos-server-dm:2.3.0-arm
docker run --name nacos23 -e MODE=standalone -p 8848:8848 -d --restart=always jiehoom/nacos-server-dm:2.3.0-arm
2、拷贝配置文件到宿主机
将配置文件拷贝到宿主机的/root/nacos:
mkdir /root/nacos
docker cp nacos:/home/nacos/conf/ /root/nacos
3、修改配置文件
root/nacos/application.properties
### The auth system to use, currently only 'nacos' and 'ldap' is supported:
nacos.core.auth.system.type=nacos
nacos.core.auth.enabled=true
### worked when nacos.core.auth.system.type=nacos
### The token expiration in seconds:
nacos.core.auth.plugin.nacos.token.expire.seconds=${NACOS_AUTH_TOKEN_EXPIRE_SECONDS:18000}
### The default token:
nacos.core.auth.plugin.nacos.token.secret.key=不小于32个字符的BASE64字符串
### Turn on/off caching of auth information. By turning on this switch, the update of auth information would have a 15 seconds delay.
nacos.core.auth.caching.enabled=${NACOS_AUTH_CACHE_ENABLE:false}
nacos.core.auth.enable.userAgentAuthWhite=${NACOS_AUTH_USER_AGENT_AUTH_WHITE_ENABLE:false}
nacos.core.auth.server.identity.key=WhoAreYou
nacos.core.auth.server.identity.value=DiuDiu
nacos.core.auth.server.identity.key和nacos.core.auth.server.identity.value有什么卵用我不清楚,但是,它们并非一个是用户名,一个是密码。
4、删掉刚创建的nacos2.3实例,然后再创建一个挂载的
docker run --name nacos23 --env MODE=standalone -d --restart=always -p 8848:8848 \
-v /root/nacos/conf/:/home/nacos/conf \
jiehoom/nacos-server-dm:2.3.0-arm
如此,新的nacos创建矣。
(三)如果用docker-compose创建
如果是docker-compose,步骤就精简些,直接写好yaml文件:
1、写好yaml文件
nacos.yaml
version: '3.1'
services:
nacos:
image: jiehoom/nacos-server-dm:2.3.0-arm
container_name: nacos23
env_file:
- PREFER_HOST_MODE=hostname
- MODE=standalone
- NACOS_AUTH_ENABLE=true
- NACOS_AUTH_USER_AGENT_AUTH_WHITE_ENABLE=false
- NACOS_AUTH_TOKEN=R3owMS1MQU5EdG9vbDIwMTYtMjAyMS1ieS1jaGVuZGFxdQ==
- NACOS_AUTH_IDENTITY_KEY=test
- NACOS_AUTH_IDENTITY_VALUE=test1234
volumes:
- ../log/nacos/:/home/nacos/logs
- ./nacos/custom.properties:/home/nacos/init.d/custom.properties
ports:
- "8848:8848"
- "9848:9848"
restart: always
networks:
- pig
networks:
pig:
external: true
2、创建容器
docker-compose -f nacos.yml up -d
四、使用新版nacos
新版的nacos,默认是不需要登录的。但经过我们上面的设置后,就需要登录。账号密码是nacos/nacos,首次登录后可以将密码改掉。然后,看原先应用程序是用什么账号访问nacos的。如果账号是”nacos“,那么密码保持一致,将备份的配置导回来,理论上就能无缝访问了,丝滑得很。如果是用别的账号,那还要新建账号,分配权限才行。
1、如果访问账号是nacos
导入备份的配置即可。
2、如果访问账号是别的
1)新建用户
2)绑定角色
角色要新建一个,比如ROLE_READER,名字自己起。ROLE_ADMIN就别想了,这是系统保留字,不给绑定。
3)给ROLE_READER分配权限
注意最好分配读写权限。我也不知道为什么,分配只读,应用程序就无法使用;分配读写就可以。也许是我的程序里会修改配置?不清楚。
五、一些坑
事实上,我安装了新版naocs后,遇到许多坑,费了好多功夫才最终正常使用。
1、web防火墙
如前所述,我们项目是一个信创项目,各种限制,还搞了WEB防火墙。结果,我进新版的nacos,想将默认密码改掉,就失败了,提示什么
真是兜头一盆冷水。我这个镜像,后缀写着什么dm,然后它的数据库属性,也是DM(达梦),一般都是MYSQL。莫非是数据库有问题?
db.num=${DM_DATABASE_NUM:1}
#db.url.0=jdbc:mysql://${MYSQL_SERVICE_HOST}:${MYSQL_SERVICE_PORT:5236}/${MYSQL_SERVICE_DB_NAME}?${MYSQL_SERVICE_DB_PARAM:characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useSSL=false}
db.url.0=jdbc:dm://DAMENG?DAMENG=(${DM_SERVICE_HOST}:${DM_SERVICE_PORT:5236})&LOGIN_ENCRYPT=(0)&DIRECT=(Y)&LOGIN_MODE=(1)&SWITCH_TIME=(3)&SWITCH_INTERVAL=(1000)
db.user.0=${DM_SERVICE_USER}
db.password.0=${DM_SERVICE_PASSWORD}
但没有理由,我能导配置进去,而且后面证明,这些数据库属性,只要我们创建容器的时候不显式指定,系统会使用内嵌的数据库Derby,所以没啥意义。
然则莫非是是包的问题?拿到别的机器上试,又可以。
新建用户,新建命名空间都可以,但修改它们就不行。关键是,我在旧的nacos上试,也是新建可以,修改删除不行。在浏览器上观察,发现删除时,HTTP的访问方式是DELETE;修改是PUT。我就问业主是不是有什么安全策略,原来是有WEB应用防火墙(WAF),申请临时解除后可以修改删除了。
其实这WAF有啥意义呢?nacos这个RESTful比较标准,同一个资源,采用不同的访问方式来实现不同操作,DELETE代表删除,PUT代表修改,POST是新增,防火墙就限制前面2种。但像我们项目,写法不标准,增删改全部是POST,怎么防?典型的防君子不防小人。
2、nacos1.3导出配置有数量限制问题
这次捣鼓之前,我特地从旧容器上将配置全部导出来了。但是!老版本的配置页,每页只能呈现30条配置,导的时候,我每页都勾选了,整整60条,结果导出来时,只导出了30条!系统也没啥提示,我以为已经全部导出来了,傻傻的导到新系统里,只有30条,我也没有留意。结果应用程序死活不正常。后来只能在旧容器上分批导出。
这也说明,捣鼓之前,做好备份,保留旧容器是多么的重要。不然的话,docker容器,一个删除,说没有就没有了,万劫不复。
3、新建的nacos账号,要赋予读写权限
这个上面说过了。按道理,只读就好了,但我的程序,真的要赋读写,也不知道为啥。
六、小结
没想到nacos有这么多的问题。新版的话,算是解决了已知的安全问题,但这种解决方式,我觉得不是最好的。开启鉴权这些,需要在安装的时候配置,真繁琐。为什么不能安装以后,在界面上配置呢?估计也是降本增效以后,原来那批人都走了,面对屎山,新丁无人敢动,只能采取代价最小的办法修修补补。
我看有别的项目使用consul,未知如何。