大多数人学Linux靠背命令。ls、cd、mkdir,天天敲,可这压根没碰到系统底层的边。Linux这个操作系统,越往里挖越觉得它整个就是把所有东西都装进一个巨大的、结构井然的文件堆里,再用这些文件去操控一切。我前阵子决定不再闭着眼跑命令,要真的去文件系统里翻一翻,结果翻出来的东西着实让我兴奋了半天。

这篇记录的是我在Linux文件系统里摸索时最有趣的几个发现,全是那些刚入门时特希望有人能掰开揉碎讲给我的底层逻辑。这不是命令清单。是一次对系统本质的深潜。出发前得先看眼地图,顶层文件目录大致就长这样。

打开网易新闻 查看精彩图片

我先盯上了/etc/passwd这个文件。这名字太有欺骗性了,叫“密码文件”,谁听了不觉得里头存的就是密码?可随便找台现在的Linux机器敲一条cat /etc/passwd,每个用户的那一行长得都差不多是这样:root:x:0:0:root:/root:/bin/bash或者john:x:1001:1001:John Doe:/home/john:/bin/bash。注意第二个字段那个x,那里原本是真存过密码哈希的。在早期的Unix系统上,密码就这么赤裸裸地以明文形式躺着,任何能读这个文件的程序或用户都能看见。想想都后怕。后来系统设计者总算反应过来,把世界可读的密码摆在明面上是天大的隐患,于是真实的密码哈希被移进了另一个文件/etc/shadow,那个文件只许root碰。

/etc/passwd里真正留下来的几个字段逐一告诉你:用户名、密码占位符、用户ID(UID)、组ID(GID)、全名、家目录、默认命令行。这个文件就是Linux上用户身份的基石。每次你登入,总有什么系统组件要跑过来读它,靠它确认你是谁、你家目录在哪、该给你起哪个命令行。我越看越觉着有意思的是,里头列着的并不只有你我这样的真人用户。www-data、nobody、daemon这些系统服务也全在里头。它们不是给人登录用的,是服务账户。造出这些账户来,就是为了让网页服务器、后台进程之类的不用顶着root权限跑。思路直白又聪明——一旦哪个服务被人攻破,造成的破坏也就能缩在一个受限账户的范围内。

看完/etc/passwd,紧接着就得摸进/etc/shadow。这才是真正藏秘密的地方。拿到root权限后敲一下sudo cat /etc/shadow,每行大概是这个模样:john:$6$randomsalt$longhashstring...:19800:0:99999:7:::。把那段密文拆开看:开头的$6$代表SHA-512哈希算法,更老的系统上见过$1$标记的MD5,那算法放到现在已经被认为不够结实了。紧接着是一段随机盐值,再往后才是哈希本身。那一长串数字分别记录了从上次改密码过了多少天、两次改密码之间最少要隔多久、最多隔多久系统强制你改、以及过期前提前多少天开始警告。这个文件之所以单独存在,就是因为/etc/passwd必须让所有人都能读,太多程序需要靠它查用户名和用户信息,但密码显然不该如此敞开。于是Linux做了一个关注点拆分:公开信息搁在一个文件里,绝密信息锁进另一个文件,再用严格的文件权限卡死后者。

我在这趟翻找里收获的最大触动,就是Linux把文件权限本身当成了一道安全边界,没去叠什么花哨的加密层,就靠一板一眼的属主规则守住了一切的底线。系统里压根没有什么魔法,全是一个文件叠一个文件,一层权限套一层权限,简简单单就把该控的控住了。