acme.sh 生成的证书默认放在 /root/.acme/xxx/xxx 里面
用 supervisor 管理程序的自启动,原配置里写的 user=nobody,安全用了几年了
现在程序升级,也想要更高的安全。如果把证书文件(没有移动位置)的权限改为“任何人可读”,不行,程序启动失败(就算启动成功了,acme 自动更新后也要失败的吧,到时候又要操作一番,也麻烦)
supervisor 的配置改为 user=root 就可以成功读取证书运行程序,只要不爆出漏洞好像也没什么问题,但是从安全角度来讲逼格不够
所以,大佬们,该怎么操作可以显得有逼格呢?
1
oott123 2021-09-16 12:59:44 +08:00 1
再专门建个用户,或者你把证书文件移动到别的地方去,再上个 SELinux 啥的
|
2
zengxs 2021-09-16 13:02:03 +08:00
这个是最基础的文件权限问题
只有 root 用户可以读取 /root/ 目录下的文件 还有不建议让 nobody 用户拥有读取证书文件的权限,你感觉「安全用了几年」不代表这个行为就真的安全了 |
3
zengxs 2021-09-16 13:06:50 +08:00 1
参考下这个: https://serverfault.com/questions/62496/ssl-certificate-location-on-unix-linux
建议将证书文件放在 /etc/ssl 目录,这个目录只允许 root 读取 |
4
cz5424 2021-09-16 13:09:25 +08:00 via iPhone
新建 nginx 用户,证书授权 nginx 用户可读
|
5
pupboss 2021-09-16 13:29:21 +08:00 1
root 账户直接搞 acme 从根儿上就不是很有逼格了,一般都会有一个日常普通用户的
想要解决这个问题,最好的办法是用 acme 的 deploy 功能,可以部署到 nginx 甚至用 ssh 部署到其他服务器,在你部署的时候,目标文件夹改好权限 644,覆写的文件权限不会变( root 反正肯定能写进去),这样你的 nobody 可以从 deploy 文件夹读到证书。最好别在 acme 根目录做操作,这和使用 root 账户日常办公一样没逼格 |
6
wffnone 2021-09-16 13:49:22 +08:00 via iPhone 1
你不能脱离场景谈用法。你也不能脱离自己谈习惯。
Linux 有一些基本的使用规则和基本的操作,用户熟悉了之后,用起来就想喝水用杯子一样自然。只是因为方便,不是因为用杯子就比用手高级。 如果你要开始实行这些规则,你就要试着去实行这一系列的整体,让它们变成你的习惯,至少是你工作里的保持着一致性的守则(千万别兴趣一来就高级一点,没兴趣就低级一点)。你的目的是为了完成工作,不是显得“高级”(更不必谈这根本不高级)。你的所有的规则应当构成一个整体,你应当自如于其中。这应当是一个有乐趣的自己进步的过程。 接着往下说,这种乐趣学习的过程,一般来说是阅读文档,阅读他人的项目对这些原则和工具的应用。你需要让自己保持开放心态去学习。而针对(这种如此基础的程度的)具体问题的具体解决方案是有害的,因为如此容易获得的答案反而阻止了你进一步学习,你得到了答案,却错过了一个进步的机会(因为问题给你的动力,能冲到比答案更远的地方)。 |
7
msg7086 2021-09-16 13:53:23 +08:00 1
「
3. copy/安装 证书 前面证书生成以后, 接下来需要把证书 copy 到真正需要用它的地方. 注意, 默认生成的证书都放在安装目录下: ~/.acme.sh/, 请不要直接使用此目录下的文件, 例如: 不要直接让 nginx/apache 的配置文件使用这下面的文件. 这里面的文件都是内部使用, 而且目录结构可能会变化. 正确的使用方法是使用 --install-cert 命令,并指定目标位置, 然后证书文件会被 copy 到相应的位置 」 RTFM 安装命令里可以 chown 把复制后的文件的所属用户改成 nobody,然后再重启服务就可以了。 |
8
ipwx 2021-09-16 13:59:02 +08:00 1
读完以后 fork 然后 setuid
|
9
hushao 2021-09-16 14:19:16 +08:00 1
你用 acme 的姿势是不是不对?我记得 acme 可以安装在用户目录下的,并且不建议直接使用~/.acme.sh/xxx 下的证书,取得证书后要把证书复制到自定义目录。
查查这个命令 `acme.sh --installcert` |
10
cathedrel OP @zengxs 为什么不让 nobody 用户读取证书? nobody 读取证书后也不能做没让它去做的事情啊
|
14
cathedrel OP @msg7086 之前是用这样的命令申请到证书的:
acme.sh --server api.buypass.com/acme/directory --issue -d xxx.com --days 176 --standalone 申请成功之后应该是自动生成了一个 cron 任务检查证书到期时间并在差不多的时候自动续期对吧?续期的证书也是放在原来的位置。如果现在要改动的话,新命令要怎么写?加上--install-cert /xxx 这一段?那个 chown 的部分应该怎么写呢?不好意思,弱手,您再指点一下 |
15
cathedrel OP @ipwx 什么叫读完以后 fork ?完全不懂,setuid 也不懂,您展开说一下好嘛?
|
16
cathedrel OP @oott123 服务器上专门建用户的话怎么能做到权限最小同时该有的都有?不太熟悉这块,我是觉得有个 nobody 用户就好好利用
|
17
princelai 2021-09-16 15:19:05 +08:00
@cathedrel #14 应该是写在--reload-cmd "chmod a+r xxxx",我这里通常是写 systemctl restart,没在这里写过 chmod
|
18
msg7086 2021-09-16 18:37:59 +08:00 via Android
|
19
princelai 2021-09-16 18:40:59 +08:00
@msg7086 #18 是的,就写在~/.acme.sh/name.server/name.server.conf 里,写错了自己手动编辑就能改
|
20
lolizeppelin 2021-09-16 19:10:29 +08:00
楼上说的 fork 以后 setuid 就是最标准的做法
自己翻文档 |
21
guanyin9cn 2021-09-16 19:18:30 +08:00
把证书放到 /opt 下,不要放在 /root 下,这个是 root 用户的 home 目录。
|
22
jim9606 2021-09-16 19:52:53 +08:00
|
23
adoal 2021-09-16 21:18:16 +08:00
运维是一项专门的技能,不是拍拍脑袋就能做好的。
|
24
ysc3839 2021-09-16 21:24:07 +08:00 via Android
@ipwx @lolizeppelin
setuid 不需要 fork 吧,之前见过有的程序有 drop root 功能,似乎就没有 fork,是直接调用一下 setuid 的。 @cathedrel 就是运行时修改进程的用户。 |
25
kaneg 2021-09-16 22:33:31 +08:00
证书 copy 一份到 nobody 能读到的地方很难吗?
|
26
lululau 2021-09-16 23:31:42 +08:00
证书应该是对全宇宙公开的啊。。。chmod o+r 就可以了。。。
|
29
yulgang 2021-09-17 09:16:03 +08:00 1
应该用普通用户签证书,或者签发证书的时候指定--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 |
30
libook 2021-09-17 10:47:39 +08:00 1
可以看一下 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 目录及其子文件。 |
31
msg7086 2021-09-17 15:56:00 +08:00
顺带一提,用 nobody 也不算是很好的做法。
好做法是每个单独的权限个体拥有自己的账号。 如果你一台服务器就一个网站,那网站应该跑在 www-data 或者 www 下。 如果你放了很多个独立的网站,那他们应该分别跑在自己的账号下。 nobody 因为是无权限用户,那就应该以无需读取任何私密信息作为前提。 当你把文件 chown 到 nobody 或者 chmod 给 all,仅仅是为了给 nobody 读写的时候,这做法就已经不对了。 |
32
julyclyde 2021-09-18 12:01:08 +08:00
证书文件本来就可读
关键是密钥要保密 |