今天遇到了之前没遇到过的问题(倒不如说之前没遇到才是真的玄学),.ssh/authorized_keys
明明存在,但却没法免密登录。在一番搜索之后,我发现问题的关键在于权限问题。之前对权限的了解较浅,知道的也就 777
、644
这几个数字,平时用到的也就只有 chmod +x
,正好借这个机会好好学习一下。
文件和目录的权限在 《Beginning Unix》 中位于第 67 页。简单来说,权限可以分为四种:
r
:读取权限(read)w
: 写入权限(write)x
: 执行权限(execute)-
: 无权限(deny)
通过 ls -l
,我们可以很方便的看到文件当前的权限配置:
值得注意的是,第一个字符代表的是“目录”的类型,有如下三种形式:
- d: 目录
- l: 符号链接
- -: 非目录(一般来说就是文件)
而之后的 9 个字符,则代表了三种不同用户对该文件/目录的权限。2-4 位是当前用户(user
,简写为 u
)的权限,5-7 位是当前用户组(group
,简写为 g
) 的权限,而 8-10 位则是其他用户(all
,简写为 a
)的权限。
权限的概念对于文件和目录而已也不尽相同。对文件而已,
r
就是读取,w
就是写入,x
就是执行;而对目录而言,r
是允许读取目录及子目录中的内容,w
是允许向目录和子目录中写入,而x
则是允许进入该目录。
现在我们知道了权限的字面表达方式,接下来就是修改了。
chmod 命令提供了三种修改权限的方式,其按照字符划分如下:
+
: 增加权限,使用方式为chmod [用户组简写]+[权限] [文件]
,如chmod u+x ./run.sh
-
: 取消权限,使用方式为chmod [用户组简写]-[权限] [文件]
,如chmod -x ./run.sh
(这里省略了 u)=
: 设置权限,即覆盖当前权限设置,使用方式为chmod [用户组简写]=[权限] 文件
,如chmod u=rwx ./run.sh
- 以上三者可以同时使用,通过逗号连接。这里用原书中的例子好了:
chmod o+wx,u-x,g=r-x testfile
按照上文描述的方式,我们可以很方便(?)直观(!)地修改文件和目录的权限。
等等,方便?你不觉得这么长一段很费事吗?
于是,就有了数字表示法。其实数字表示法和上文的表示方法有简单的一一对应关系,而这种表示的本质——将其加和,实际上就是位运算:
0
:-
1
:x
2
:w
4
:r
于是我们就知道了,700
代表的实际上是 u=rwx,g=---,a=---
,而 600
则是 u=rw-
。
回到最开始的问题:为什么 sshd
要求我们的 authorized_keys
必须为 600
权限呢?
我的猜想是这样的:密钥,就算是公钥,也不应该被其他未经许可的用户读取(当然 root
除外);而公钥也是不需要执行的。由此,我们便需要将 g
和 a
的权限全部取消,并且设置当前用户 u
也只能 rw
。而对于 sshd 而言,通常是以 root 权限运行的(观察 /etc/systemd/system/multi-user.target.wants/ssh.service
,可以发现其并没有规定用户,而不规定用户的情况下默认即为 root
),因此可以直接读取内容。
当然了,这只是我的猜测。由于本人 C 语言8行,没在源码里找到佐证。
ま、それでは(