服务器上的程序,以前可以用 user=nobody 的方式跑起来,现在需要读取证书文件,证书文件是 acme.sh 在 root 权限下生成的,如何设置可以让程序以 nobody 权限读取到证书文件跑起来?

2021-09-16 12:20:40 +08:00
 cathedrel

acme.sh 生成的证书默认放在 /root/.acme/xxx/xxx 里面

用 supervisor 管理程序的自启动,原配置里写的 user=nobody,安全用了几年了

现在程序升级,也想要更高的安全。如果把证书文件(没有移动位置)的权限改为“任何人可读”,不行,程序启动失败(就算启动成功了,acme 自动更新后也要失败的吧,到时候又要操作一番,也麻烦)

supervisor 的配置改为 user=root 就可以成功读取证书运行程序,只要不爆出漏洞好像也没什么问题,但是从安全角度来讲逼格不够

所以,大佬们,该怎么操作可以显得有逼格呢?

10667 次点击
所在节点    Linux
32 条回复
guanyin9cn
2021-09-16 19:18:30 +08:00
把证书放到 /opt 下,不要放在 /root 下,这个是 root 用户的 home 目录。
jim9606
2021-09-16 19:52:53 +08:00
用 nobody 用户跑 acme.sh 就是了。证书目录你可以手动指定一个,建议在 /etc/ssl/ 下面建。
对于使用 http-01 和 tls-alpn-01 验证的服务器来说 webserver 和 acme 用同一个账户并不会有额外的安全问题。如果你的 webserver 被入侵了,攻击者可以利用这个申请新证书。这跟 acme.sh 的数据被窃取的影响是一样的,所以 acme.sh 不用独立账户并不会额外损失什么。
adoal
2021-09-16 21:18:16 +08:00
运维是一项专门的技能,不是拍拍脑袋就能做好的。
ysc3839
2021-09-16 21:24:07 +08:00
@ipwx @lolizeppelin
setuid 不需要 fork 吧,之前见过有的程序有 drop root 功能,似乎就没有 fork,是直接调用一下 setuid 的。
@cathedrel 就是运行时修改进程的用户。
kaneg
2021-09-16 22:33:31 +08:00
证书 copy 一份到 nobody 能读到的地方很难吗?
lululau
2021-09-16 23:31:42 +08:00
证书应该是对全宇宙公开的啊。。。chmod o+r 就可以了。。。
cathedrel
2021-09-17 01:27:15 +08:00
@kaneg linux 的哪个目录是 nobody 直接可以读的?
cathedrel
2021-09-17 07:45:35 +08:00
@jim9606 acme..sh 没有办法用 nobody 跑起来吧?你试一下看看
yulgang
2021-09-17 09:16:03 +08:00
应该用普通用户签证书,或者签发证书的时候指定--certpath 和--keypath 把证书写到.acme 以外的目录。


50 0 * * * "/path/to/.acme.sh"/acme.sh --cron --home "/path/to/.acme.sh" --server letsencrypt --certpath /path/to/.cert/cert.pem --keypath /path/to/.cert/key.pem > /dev/null 2>&1
libook
2021-09-17 10:47:39 +08:00
可以看一下 Linux 的权限机制 https://wiki.archlinux.org/title/Users_and_groups_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)

用户基本分为三类,root 、普通用户、nobody,分别对应所有权限、有限的权限、无权限。

按照我个人的习惯来说,判断应该使用哪个用户:
root:尽量不用,基本只有我需要在服务器上调整配置和安装系统软件的时候会用到;
nobody:如果只需要让程序或脚本访问服务器上所有人( all )都能访问的资源,或者当所有资源都受权限管控的时候不想让程序或脚本访问任何本地资源,那么就用 nobody ;
普通用户:除了上面需要用 root 和可以用 nobody 的场景以外,基本全都用普通用户。

每个文件和目录本身会有:
1. 归属于的用户和归属于的用户组;
2. 权限标识,按照身份分为自己( user )、群组( group )、所有人( all ),按操作分为读、写、运行权限。
root 不受权限标识的限制,nobody 只能访问所有人都能访问的资源,普通用户可以访问归属于自己的文件和目录,初次之外具体看权限标识的设定。

回到题主的情境,签证书可能可以用普通用户和 nobody 来做,所以可以不用 root ;证书文件又属于需要保密的,不能让所有人都能访问,所以不用 nobody,那么最好用普通用户来做。
即你可以创建一个普通用户,如名叫 signer,同时创建一个存放证书的目录,比如叫 ca ;
ca 目录和 acme.sh 文件归属于 signer 所有,设定为所有人不能访问、自己可以读、写、运行;
同时 acme.sh 脚本不需要被群组访问,所以把这个文件单独设定为群组不可访问;
执行签证书的任务的时候使用 signer 用户来执行 acme.sh 脚本,在 ca 目录下生成证书文件。

然后确保 ca 下的证书文件和 ca 目录所有者、权限标识一致。

接下来就是需要用证书的程序了,它们只需要对证书的读权限,所以可以让 signer 和需要读取证书的用户在同一个用户组里,比如叫 ca_ro,并让 ca 目录及其中的证书文件属于 ca_ro 组,且权限标识设定为群组可读、不可写、不可运行。

至此,就能确保:
0. 除了 root 以外;
1. 只有 signer 用户能读写运行 acme.sh 脚本;
2. 只有 signer 用户能写 ca 目录及其子文件;
3. 除了 signer 用户以外,所有加入到 ca_ro 群组的用户都能读取 ca 目录及其子文件。
msg7086
2021-09-17 15:56:00 +08:00
顺带一提,用 nobody 也不算是很好的做法。
好做法是每个单独的权限个体拥有自己的账号。
如果你一台服务器就一个网站,那网站应该跑在 www-data 或者 www 下。
如果你放了很多个独立的网站,那他们应该分别跑在自己的账号下。
nobody 因为是无权限用户,那就应该以无需读取任何私密信息作为前提。
当你把文件 chown 到 nobody 或者 chmod 给 all,仅仅是为了给 nobody 读写的时候,这做法就已经不对了。
julyclyde
2021-09-18 12:01:08 +08:00
证书文件本来就可读
关键是密钥要保密

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/802263

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX