V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
0o0O0o0O0o
V2EX  ›  Linux

如何保护 $HOME/.ssh

  •  1
     
  •   0o0O0o0O0o · 2022-03-18 11:17:20 +08:00 · 6658 次点击
    这是一个创建于 1014 天前的主题,其中的信息可能已经有所发展或是发生改变。
    /t/841188

    以普通用户权限运行的程序也可以读取修改它们,有什么简单的操作可以避免这一点吗?
    第 1 条附言  ·  2022-03-18 17:31:31 +08:00
    • Linux Desktop
    • 尽可能无感,不影响别的依赖 ssh 的程序
    51 条回复    2022-03-24 19:27:59 +08:00
    villivateur
        1
    villivateur  
       2022-03-18 11:24:21 +08:00 via Android
    配置好 SELinux
    pengtdyd
        2
    pengtdyd  
       2022-03-18 11:26:51 +08:00
    $HOME 就是当前用户目录,当前用户当然有权限操作自己的文件了
    adeweb
        3
    adeweb  
       2022-03-18 11:29:20 +08:00
    避免不了,但可以在生成 ssh key 时加上 passphrase
    guang19
        4
    guang19  
       2022-03-18 11:29:36 +08:00
    你是想让普通用户没有权限操作自己的文件吗?
    adoal
        5
    adoal  
       2022-03-18 11:37:44 +08:00
    #1 提的 SELinux 是个好办法,不过这玩意不太容易上手
    Sinow
        6
    Sinow  
       2022-03-18 11:41:15 +08:00 via iPhone
    owner 改成 root ,sudo 访问
    codehz
        7
    codehz  
       2022-03-18 11:41:20 +08:00 via Android   ❤️ 7
    这时候一定会有相关的 xkcd
    https://xkcd.com/1200/
    paxnil
        8
    paxnil  
       2022-03-18 11:41:34 +08:00
    chattr +i
    0o0O0o0O0o
        9
    0o0O0o0O0o  
    OP
       2022-03-18 11:44:15 +08:00
    > 配置好 SELinux
    > #1 提的 SELinux 是个好办法,不过这玩意不太容易上手
    SELinux 可能有点太复杂了,而且不知道会不会影响需要调用 ssh 的程序。

    > owner 改成 root ,sudo 访问
    理由同上,会影响别的程序以普通用户权限运行
    codehz
        10
    codehz  
       2022-03-18 11:47:07 +08:00 via Android
    Linux 实际上没有什么好办法防止相关问题,通常能获得你 shell 访问权限的约等于能做除了帮你开机之外的任何事了(
    包括偷密码,即使找不到提权漏洞,也可以轻易安装 shell 记录器 ( codehz/bashrc-backdoor )

    本来 snap 算是一个好的隔离解决方案,但是实际情况是鲜有软件开启沙箱功能(
    0o0O0o0O0o
        11
    0o0O0o0O0o  
    OP
       2022-03-18 11:52:01 +08:00
    @codehz 我是非常赞同这种观念的,我只是想尽量无感地给大部分程序设置一个屏障

    我打算本地用 docker 跑一个简单的跳板机来做这件事
    dzdh
        12
    dzdh  
       2022-03-18 11:53:11 +08:00
    前提是 你的 user/.ssh 不允许当前的用户进行编辑和修改只能通过 root 修改。

    否则这是个伪命题,或者你的需求不明确。

    apparmor 可以满足需求,所属用户属于$USER 但是不能主动 R/W(如 cat/sed)但是又可以被 SSHD 读取使用。
    codehz
        13
    codehz  
       2022-03-18 11:54:08 +08:00 via Android
    @0o0O0o0O0o 反了,得把其他程序放容器里才有效果(
    0o0O0o0O0o
        14
    0o0O0o0O0o  
    OP
       2022-03-18 12:11:51 +08:00
    @codehz #13 那样好像就不是很无感了,私钥文件放在 docker 容器内,普通用户不提权或者不利用漏洞无法访问到
    codehz
        15
    codehz  
       2022-03-18 12:14:42 +08:00 via Android
    @0o0O0o0O0o ( docker 运行不是得 root 权限吗(然后你是不是还想无密码 sudo ?)
    或者说把用户加到 docker 组(然后技术上就是 root 了)
    pelloz
        16
    pelloz  
       2022-03-18 12:17:14 +08:00   ❤️ 4
    linux 正确的使用方式不是每个应用都专门给一个用户吗
    0o0O0o0O0o
        17
    0o0O0o0O0o  
    OP
       2022-03-18 12:21:26 +08:00
    @codehz 该容器一直保持运行而不是 alias ,用户不加 docker 组,所以操作 docker 容器需要提权。

    容器运行 sshd 服务来“转发”ssh 连接。
    0o0O0o0O0o
        18
    0o0O0o0O0o  
    OP
       2022-03-18 12:23:15 +08:00
    @pelloz 很正确...但 Linux Desktop 这样用感觉有点难...
    yin1999
        19
    yin1999  
       2022-03-18 12:28:31 +08:00   ❤️ 1
    systemd 有 DynamicUser ,可以创建临时用户给程序使用,如果不用写文件,配合 LoadCredential 来加载需要特定用户权限才能读取的文件还是挺不错的,可以试试(临时运行而不是长期运行的服务,可以使用 systemd-run )
    0o0O0o0O0o
        20
    0o0O0o0O0o  
    OP
       2022-03-18 12:32:39 +08:00
    @yin1999 同#18 ,我在云服务器上是用这些 systemd 的加固方案的,但是在本地桌面这样用可能就很不方便了
    codehz
        21
    codehz  
       2022-03-18 12:57:05 +08:00 via Android   ❤️ 1
    @0o0O0o0O0o 那你这个和单独开一个用户跑跳板没啥区别了(仔细想想你 docker 究竟隔离了什么)
    yanqiyu
        22
    yanqiyu  
       2022-03-18 13:01:11 +08:00   ❤️ 2
    ssh key 放到硬件里面,openssh 支持 pkcs11 或者是 fido2 的硬件来存储证书,这才能做到万无一失,私钥谁也拿不到,要用私钥签名必须要用户按一下硬件按钮 /输入 pin

    其他各种方式都会带来麻烦,比如 SELinux 的话你就需要给整个用户会话一个单独的上下文(默认情况下是 unconfined_t ),以及给 ssh 一个单独的上下文,分别配置权限。当然,对于系统服务的限制早就有 SELinux 的解决方案了,用户的 .ssh 文件夹是 ssh_home_t,多数系统服务的上下文(e.g. init_t)没权限访问。

    要是用 systemd 的话如果你限制整个用户会话访问 ~/.ssh 那你启动的 ssh 也访问不了。你要是只限制系统服务也很简单,ProtectHome 就行,但是不够,用户自己运行有问题的程序你也没办法。
    jim9606
        23
    jim9606  
       2022-03-18 13:13:09 +08:00   ❤️ 1
    Linux 确实没有比较靠谱的通用的平台凭据保护方案,靠谱的可能得靠专门的安全硬件( TPM 或者 FIDO 之类的)
    我的建议是密钥设一个 KDF 循环次数较高的加密(例如 1000 ,解密要几秒),然后首次使用 ssh 前先 ssh-add 托管到 ssh-agent 。
    ```
    ssh-keygen -p -f ~/.ssh/id_ed25519 -a 1000
    ```
    654656413245
        24
    654656413245  
       2022-03-18 13:15:47 +08:00 via iPhone
    chroot
    namespace
    hwdef
        25
    hwdef  
       2022-03-18 14:06:40 +08:00
    都在说 linux ,,也想问下 macos 和 windows 要怎么办
    vone
        26
    vone  
       2022-03-18 14:36:30 +08:00
    passphrase
    libook
        27
    libook  
       2022-03-18 15:06:06 +08:00   ❤️ 1
    Linux 权限机制是以用户、用户组来管理权限,那么权限设计思路应该是确保每个用户、用户组只能干自己能干的事情。

    $HOME/.ssh 是属于当前用户的,所以理应让当前用户可读、可改,题主要解决的问题是如何不让当前用户读写它自己的文件,而是应该确保这个用户的.ssh 里面没有这个用户不应该访问的文件。

    一种处理方式是不以当前用户来使用 SSH 相关功能,需要使用 SSH 相关功能的时候切换到另一个用户;
    或者让不应该访问此用户文件的程序以其他用户来运行。
    tomychen
        28
    tomychen  
       2022-03-18 16:08:53 +08:00
    你的意思是想让“我”访问不了“我的文件”?这逻辑,好像有点不太对。

    那能不能换个思路,让“其他”人访问不了“我的”文件。


    为啥不考虑一下像很多服务一样添加一个新的服务用户如 mysql 和组,再配上 chroot 也算已经很 OK 了。

    实在懒也可以用 nobody

    事情上很多发行的 linux 在用户权限上已经做得很好了,也相对比较人性化了。
    更多的时候是权限滥用引发的事故,而把责任归到操作系统上,这锅让操作系统背,是有点无辜的。
    FrankHB
        29
    FrankHB  
       2022-03-18 16:26:54 +08:00
    @libook UNIX 这种思路(包括管这种用户自行可以覆盖的 DAC 机制叫“权限”)很烂。多用户本来只是为了在系统中分配任务资源;就算是持久资源,owner 决定的也仅仅只是资源的生死(创建 /删除),rw 与其说是权限还不如说就只是个访问属性,而 x 根本就是个给 shell 偷懒用的标记。这些东西根本就算不上什么安全特性。
    要考虑安全就不能依赖这种防君子不防小人的做法(你一个用户根本没法审计程序运行时会干什么)。这种情况就应该让专业的上,比如基于 MAC 的 SELinux 之类的玩意儿,然后限制程序可以访问的上下文。这类解决方案的 UI 的渣体验就是另一回事了。
    libook
        30
    libook  
       2022-03-18 16:54:10 +08:00
    @FrankHB #29 工具的特性就是这个样子的,怎么用取决于使用者,简单需求可以用简单方法来实现,复杂需求也可以考虑复杂方案,还有 Cgroup 、虚拟机等方案可以考虑。

    我个人是认为,在日常使用过程中的大部分需求都可以用 Unix 这套来满足了,使用成本也比较低,剩下的特殊需求值得花些成本用更复杂方案来,只要用户能有个清晰合理的规划。
    tomychen
        31
    tomychen  
       2022-03-18 17:14:15 +08:00
    @FrankHB 这杆子挥得有点狠...
    从历史层面上来讲也确实是先有 DAC ,而后引入的 MAC ,这并没什么毛病,而从设计年代上来讲也并没什么毛病。

    而从使用者的角度而言,是使用 DAC 还是 MAC ,这得使用者,也是用户本身去评估,就像 linux 已经用了 SELinux ,但并没有强制用户去使用,这也是有原因。

    在用户的使用颗粒并没达到 MAC 时,强制去推行,那让非专业的用户使用起来,只是一种负担。
    反之,就是强制让对安全敏感的用户去用 DAC ,只会让他们无法相信这种模式能够保证自己的数据安全。

    所以抛开场景去谈论这个确实有点不公平。

    而操作系统本身就是,只是保证系统运行的稳定性,健壮性,和合乎逻辑性。

    再者别忘了 Unix 的初衷 KISS
    sampeng
        32
    sampeng  
       2022-03-18 17:52:21 +08:00
    这机器和 linux 有什么关系。。。你到底是让其他人进来还是不让其他人进来???
    这机器干嘛用的?很多研发公用一台服务器?虚拟化就是了啊。。。
    james122333
        33
    james122333  
       2022-03-18 18:31:53 +08:00
    @FrankHB

    越来越喜欢 DAC MAC 的复杂度有没有漏洞你都不知道
    x 对于文件是可执行 对于目录是可进入 而且八楼说的对
    0o0O0o0O0o
        34
    0o0O0o0O0o  
    OP
       2022-03-18 18:34:31 +08:00
    @sampeng 不是服务器,是笔记本上的桌面版,日常使用,我很难做到按用户隔离。。。
    FrankHB
        35
    FrankHB  
       2022-03-18 19:32:30 +08:00
    @tomychen @james122333 关键问题是所谓的访问控制本来就不应该是安全特性。
    一般意义上任何可预期的访问都涉及访问控制,并且没有特定的规则的限制,默认就是 DAC 。
    事实上非安全上下文的访问控制普遍存在各种具有一定抽象能力的可编程上下文中。例如 C++ 和 Java 之类的所谓 OOP 语言中,private 这样的关键字就用来提供基于名称检查的数据访问控制的限制,你能把它当作“安全”么。
    这种基于名称检查的访问控制是为了实现信息隐藏来提供封装性。从这个意义上来讲,所谓的就是利用名称访问资源的日常操作的一部分,只要不是检查就不用强调。
    并且,不管是不是系统安全的目的,实际上还有更靠谱的:直接不提供可见的名称,连检查都不用。(例如,包括基于求值环境的隐藏,或者弱化一点,ES 的 WeakMap 之类: https://github.com/tc39/proposal-class-fields/blob/main/PRIVATE_SYNTAX_FAQ.md#how-can-you-model-encapsulation-using-weakmaps 。)

    在信息安全上下文的上下文,管理资源的 API 经常退化为 UI (例如 shell 命令),处理的输入限制也弱很多(例如 VFS 路径相对一般 PL 里的引用),这里的相关设计体现出在想象力就弱上许多,也更依赖具体名称限定的少数检查入口,以至于会滥用半吊子解决方案。
    对用户来说,尽管 DAC 无处不在,去在乎权限位这种多数情况就是自欺欺人的机制只是浪费精力。

    UNIX 的 FS 的这种设计其实就是附加了一些元数据,让 VFS 的系统调用保证可以获取。
    这种实现手段是整体容易批判的:比一般编程机制的手段(比如说,类型系统)弱得实在发指而不成提供。
    无能性首先体现在因为大部分情况下用户就不会关心这个,却又时常被坑;真要关心的时候,却又经常不顶用,而不得不指望另外的像样的 MAC 和审计措施来补救。
    一部分代价跟用户是否容易误操作无关。比如,我凭什么要忍受 FS 多占用一个位来允许 drw- 这样没卵用的组合呢?(我知道扇区存储的磁盘不用纠结空间浪费,但是 tar 一下还是可以有感知的。)
    并且,这还可能真的使用户增加看似便宜,实际坑爹的误操作的机会,像 chmod -R 777 这种低成本一键搞砸系统的冗余手段;如果说 rm -rf 姑且算是管理系统资源的必要手段的滥用,这就算是凭空多出来的 side channel 了。
    另一方面,这种元数据就算留着,也没什么扩展性。类似的简单水平扩展,如 sticky bit ,也就是另外附加,而不是取代鸡肋设计。结果,整个设计还是同样的馊味。

    于是,这样的设计,就日用来说,基本上还不如没有。如果非要实现现有 UNIX 权限位类似的功能,大可以让像样的实现(如系统级 MAC )来作为基础,重新建立适当的 UI 。
    遗憾的是,不管是 SELinux 还是 NT 安全性模型,这些系统级设计都过于依赖系统机制自身,也没有充分的 UI 来让用户便于使用。但我不认为这是个安全性原则问题;易用性上的尴尬是产品力缺失的表现。

    那么,为什么 UNIX 的 VFS 会特别明显地暴露这类缺陷?这恐怕根本就不是安全设计或者“用户”应该代表什么的个别问题,而是更一般意义上的“哲学”出了岔子,导致各种抽象都和开始的原意若即若离地背离,却又无法甩脱兼容性而一直被滥用。这种鸡肋抽象,最典型的就是“文件”:
    cf. https://github.com/FrankHB/pl-docs/blob/master/zh-CN/about-operating-systems.md#%E4%B8%80%E5%88%87%E7%9A%86%E6%96%87%E4%BB%B6everything-is-a-file
    在用户空间滥用“文件”作为首要的操作实体,与其说这是简化用户的手续(不用去学 PL 而只用学 shell ;不用认真了解怎么折腾 API 去避免非预期行为而只要等待 CLI 的反馈),倒不如说是系统设计者没能力把两种面向不同用户的可编程手段统一起来。
    更一般地,这表现在对“无名师和万行码”的吹捧上——表面上看,是让 shell 干 shell 该干的活,让 C 不要掺和,属于使用合适的工具完成任务的典范;而事实上,这只是掩盖了 UNIX 祖师没能力发明出涵盖 shell 编程和更严肃的“系统”编程的统一接口而已。
    比如,要是当年有像 scsh 类似的实现,现在可能就不会坚持 pid_t 乱飞导致僵尸进程这种层次的设计问题暴露给系统管理员添堵了。
    FrankHB
        36
    FrankHB  
       2022-03-18 19:47:31 +08:00
    @tomychen 出现的先后不是重点。而推行的实际复杂度或者说代价对非专业用户来讲,很多情况只是错觉。
    如果基于上下文的机制有像样的实现,完全可以让用户感知不到复杂性,并且可能简化自动管理和修复安全规则问题的 demon 实现,而避免绝大多数系统管理员还要手动处理文件权限之类的问题,反而能整体削减用户的成本。

    这在其它领域中存在先例。大部分非研究者的普通开发者认为,在动态 PL 中实现静态的词法作用域因为需要单独管理更多的上下文而不易高效实现,因此即便知道显著缺陷(但“又不是不能用”),大多数动态语言的设计者和用户还是接受继续使用动态作用域。
    尽管大约 1954 年就出现了一般的解决方案(闭包),直到 1980 年代 Scheme 的高效实现才让主流开发者认识到代价到底可以怎样被有效控制。这之后大部分语言都不再采用默认动态作用域的设计。

    这个领域面临的问题类似:现有的机制看上去有时候能用,就被姑息了;而更完善或者说原则上更正确的方案因为少人使用,而仅限于少数专业玩家才会考虑使用,结果不够易用。这种情况迟早应被改变。
    FrankHB
        37
    FrankHB  
       2022-03-18 19:51:55 +08:00
    @FrankHB typo ,闭包是 1964 年前后出现的( SECD machine, P. Landin )。
    james122333
        38
    james122333  
       2022-03-18 20:56:34 +08:00 via Android
    @FrankHB

    访问控制是安全特性之一 为何要允许不可预期状况出现? 而且说的不就是实现方式差异而已 你觉得限制多好但有侯灵活性以及易用性也很重要 看这回文大概知道你是 lisp 系的 但为何类型就是系统安全保证呢? 依照现今状况不是如此吧。 而且说的 777 那是人被忽悠的问题 流行的是另一种照常可以忽悠 必定提供类似的机能
    james122333
        39
    james122333  
       2022-03-18 21:18:13 +08:00 via Android
    我都不觉得一个语言只能有一个用途 但你不能要求人人都是程序员 lisp 来讲是如此
    james122333
        40
    james122333  
       2022-03-18 21:31:06 +08:00 via Android
    @FrankHB
    你还是得处理文件权限 不管你是规则 代码还是命令
    james122333
        41
    james122333  
       2022-03-18 21:43:56 +08:00 via Android
    其中最特厌的还是纯设置 程序都不是自己规划自己写的还要去分析究竟有多少影响
    getadoggie
        42
    getadoggie  
       2022-03-18 23:30:08 +08:00 via iPhone
    firejail 了解一下,你会感谢我的
    ZeroClover
        43
    ZeroClover  
       2022-03-19 00:35:12 +08:00
    https://developer.1password.com/docs/ssh

    https://smallstep.com/blog/use-ssh-certificates/

    虽然并不能解决其他程序读取 .ssh 目录的问题,但是可以极大地减少风险。
    baobao1270
        44
    baobao1270  
       2022-03-19 04:45:23 +08:00
    方法一:使用硬件密钥,如 YubiKey 存储 SSH 密钥
    方法二:只使用信任的软件,不使用来源不明的软件,定期或不定期轮换密钥

    不要寻求技术上的绝对安全,正确的做法是在安全和成本间取得平衡。与其花费很高的成本去搞一套安全方案,不如在发生问题时尽力止损。如果发生问题的损失小于增强安全的代价,那就让问题发生去吧。
    cwyalpha
        45
    cwyalpha  
       2022-03-19 08:32:49 +08:00 via iPhone
    生产环境下 selinux 不大好开。。
    tomychen
        46
    tomychen  
       2022-03-19 14:54:47 +08:00
    @FrankHB 其实我想表达的一个意思是,先有 UNIX 、Linux ,而后才有了强制控制访问一说。而整体的 Unix 或者类 Unix 系统的最初模型也是基于 DAC 模型。而后,为了适用于这个模型,才引用到操作系统中。
    不瞒你说,我大概是 2010 年左右才听到这种说法,而还是因为当时公司参与了等级保护的项目。

    当时我熟悉另一家公司的产品,除了 FreeBSD 以外,类 AIX ,HPUNIX 包括了 Windows 这类闭源系统,他们采用都是非常暴力的 Hacking 式介入,从而达到“强制访问控制”的需求。

    但这些也正如你所说的,因为历史遗留问题。但是确实不能把文件系统做得不那么“烂”么,我觉得以维护 linux kernel 那帮老头的能力,并不是什么太大的问题吧,以 Windows 这么有经济实力的企业重新设计也不是多大难题吧。

    但更多的时候,我觉得操作系统的迭代除了引入,加强新的功能和特性外,应该还要考虑的是“用户”,用户包括了使用者和开发者和硬件厂家。推倒一个文件系统去重新实现一个满足于并不算多数用户需要使用到的功能重要,还是只是兼容某个特性重要,这个问题似乎套在 linux 上,它似乎已经承受了太多它不应该承受的包袱,我并不是指它有多完美或者多优秀。

    从为课堂而生的它到今天已经演变成了一个主流操作系统,它已经不是当年的那个研究的课件。

    再回到 VFS ,从设计模式来看,我觉得 VFS 是一个非常棒的东西。当然可能是我格局小了,我看到的是这个内核层的接口,让后来的开发者在这个接口上重新设计一套 FS ,将变得更简单,而且不用过度参与到更底层的现实层去。总不能因为一个新的 FS fork 一个新的分支吧。

    同样,参考你的 “about-operating-systems.md” ,整个文档看下来,你的思维更多想完成一个更合乎于“现代”的一个操作系统的模型,或者说更理想化的一个模型。

    从我的理解和认知里,Linux 也好其他 Unix 也好,更多的时候,在对现代模型的支持在当年那个年代没有办法设计出来,而后通过这种补丁式,侵入式,或者模块化的方式集成的现有的模型里面。当然,可能像你说的“懒”,但是我的理解可能是会了兼容更多的用户,满足更多的用户。


    SELinux 可能对很多用户来讲太复杂了,但更多人没注意到一个简单的

    https://elixir.bootlin.com/linux/v3.10/source/security/tomoyo

    而这是一个 LMK 的存在,当然,官方现在已经引入,也就是说已经可以在编译内核的时候选择编译到内核。

    同样引用了 VFS 。

    看了你的文档,才发现你对操作系统这么有研究,一个门外汉,跟你说了这么多,显得有点,不那么从容和淡定。
    FrankHB
        47
    FrankHB  
       2022-03-19 19:11:13 +08:00
    @james122333 尽管访问控制在描述计算机安全系统的文献中比较流行,访问控制既不是通用的安全(safety)也不是系统安全(或者说安保)(security)专属的特性,而是一种要求系统具有特定属性时的实现手段。

    对上层系统的需求描述来讲,可预期应当是自然的,但实现上不可能无限担保,总有一些前提。逻辑上任何一个不满足假设前提的非预期行为的脆弱性都可以导致一整套机制实效。
    例如,基本上重大的软件安全漏洞都源自于安全软件的实现违反可预期的语义保证的程序行为。符合语言规范要求的正确编码就是这里的一种前提。

    如果真要用于安全目的,笼统的访问控制的效果除了“可预期”(但是因为许可证经常不担保承担责任,出 bug 嘛……),几乎等于没有。
    即便说的是 MAC ,也要求区分正确不同的敏感性才可能提供有意义的保证。当然,不是说不满足 MAC 就无所谓安全,但说实话就算具有 MAC 的系统,也可能只提供很入门级的系统安全性。
    对控制整个计算机的操作系统,没有 MAC 意味着系统管理员基本没什么手段最终可以区分针对系统资源利用的无意和恶意的历史行为,在此之上的保护仅仅是防止手贱的程度了。
    所以光是考虑对非专业用户的认知友好(避免误导)上,这类访问控制还不如彻底排除出安全目的,就像设计用于摘要的散列函数不应当被视为“加密”一样。

    处理文件权限的要求是软件接口的要求,包括 API 和 UI 。没什么实际应用故意去利用文件权限来编码无关的业务信息,所以如果放弃基于文件权限的访问控制,这就是多余的。考虑到上下文(比如沙箱)可以代替文件作为更强力的安全措施,这原则上不会损害安全性。
    另一方面,摈弃权限的思路,特定的属性反而可以编码原先没有不能充分被利用的更上层信息。例如,限制写访问不作为访问控制,而是明确作为文件的只读属性的实现,可以类似 PL 中的对象引用的只读访问限制;如果能假定上下文而确保只读访问不和其它数据访问(比如并发写内容或者修改属性)冲突,传统 PL 上的优化也可以适用于 VFS 及其它持久对象系统。对只读属性,典型的优化是常量传播。结合这些优化,可以轻易地实现文件系统去重这样的高级功能,而不用单独重新实现(除非是为了性能调优进行特化)和验证。
    遗憾的是,传统的操作系统设计并不适合这种实践——非但缺乏普遍可编程的上下文,还普遍不能排除 TOCTTOU 这种并发访问冲突。
    (作为实现细节,虚存分页机制上的权限可以继续维持 RWX 的基础设计以避免开销;这不和上层的高级语言语义或者持久存储要求的属性矛盾。)

    考虑这种遗憾的相当大一部分,来自系统和应用开发者的墨守成规(不愿意承认上下文的必要性),现在来看,UNIX 权限这种设计,还不如一开始就没存在过。
    多用户自然还是得有的,但不应该和 UNIX 权限那么强绑定:而是更接近 NT 的 SID 这样的间接抽象;虽然 SID 用起来的体验嘛……

    @tomychen 这里的阻碍很大程度上来自 UNIX 等上古系统设计的思维惯性,使系统设计和维护人员乃至大多数应用开发人员都难以适应范式转移,而不是具体维护工作的开销(虽然这对绝大多数组织已经够要命了)。
    更根本地,这可以追溯为主流的设计人员没有理解清真正的需求,而直接偷懒复用了旧的设计,恰好旧的设计因为时代局限性等历史原因也没有解决一系列关键问题。这同时是懒惰和教条主义的体现。
    这种消极的懒惰不是强到一定的地步,TOCTTOU 这种低级的问题不可能不被处理掉,而不是 POSIX.1-2008 这样一堆 at 补丁就能凑数了。

    所谓设计模式是另外一种业界体系性缺陷的集中体现:www.v2ex.com/t/835769#r_11427195 ,所以看起来像设计模式味儿的设计,本身就暗示存在一些没解决的糊涂问题。
    老实说,UNIX 这种一切皆文件的设计和 OOP 语言所谓一切都是对象的设计是类似的问题,比所有所谓的设计模式都高层一些,更应当是架构上的。
    即便如此,这里也是高下立判。OOP 类似主张的主要问题是根本没拎清楚“对象”本来就应该有的含义,重要原则(设计上鼓吹 LSP )其实也是老调重弹(这其实就是许多更传统多态类型系统上的公理),而在更具体设计(类型系统上基于继承这种序结构实现的包含多态)多少还有点进步意义;反观文件,则更像是需求假设破碎却又应对不了新的需求(要求常规文件和目录以外新的类型的持久对象)之后的近乎不作为放任自流的结果罢了,在古典设计之后基本就不存在实质的创新。

    SELinux 的出发点(看到现有系统设计不足,应对真实安全保证的需求很无能)没太大问题,复杂主要也是来自安全保证需求自身。
    但另一方面还有它是在传统 UNIX 的 VFS 上的强行修补的原因。如果 UNIX 权限不存在,那么结果大约会好那么一些。
    (嘛,只是好一些,因为缺乏像样的 UI ,也确实太复杂了,并且这玩意儿文档也不大好找,具体配置非常依赖用户自己发挥; Linux 桌面系统要是开箱可用不折腾也就算了,Android 手机我是折腾吐了弃疗了。另外 Android 的魔改权限正是我黑 UNIX 的动力之一,即便折腾起来比 SELinux 仍然容易多了……)

    没有后退的余地会让开发者使 UI 更加友好易用。这才是最终能使这种机制普遍实用化的动力,而现在做得还是很不够。排除掉上面的来自开发者懒惰和墨守教条的原因,还有个重要因素是最终用户推动不够。大多数用户甚至都未必知道这个难用到什么程度,知道“难关闭”(但这姑且算是个预期中的 feature……)就不错了。
    这方面我强调:不好用,也尽量不要回避,否则只会恶性循环而无法改善现状。

    TOMOYO 这样的尝试对引入安全保证的能力是好事,但是长期来讲,仍然不算受到足够的重视(这个应该 2.6 时代就有了,长期也没啥存在感)。
    Linux 社区,特别是 Linux Torvalds 本人,传统上并不怎么在乎安全需求(传说中的 masturbating monkeys……)。
    独立于内核之外的 Grsecurity/PaX 是早年一个比较著名的例子。
    当然,其实我也没那么在乎……至少没在乎到像 old school hacker 一样亲自糊个类似 LSM 的东西;毕竟成本过于离谱。
    我更在乎的是不合时宜的旧设计无法被移除,并且越来越没戏。
    毕竟,软件安全的一个持久的重要未决问题是:现有代码写得太长了,导致看不完而没法完成审计。
    FrankHB
        48
    FrankHB  
       2022-03-19 19:30:34 +08:00
    补充以上的个别零碎观点:
    1.MAC 的概念应该在 1980 年代中期就算成熟了,比 Linux 早。
    2.上面绝大多数安全值的都是 security 而不是 safety 。需要 protect 的也主要是这种安全。
    另一方面,对 PL 用户来讲,所谓 safety ( memory safety/type safety/...)也的确主要只是为了防手贱的,并不能指望多 secure ;虽然:
    (1)手贱了的确可能导致写出来的代码更容易有缺陷可被利用;
    (2)违反 safety 在某些 PL 中直接引起未定义行为而破坏了 security 假设的常见前提。
    这体现防手贱也有单独的必要性,某些情况下算是实现 security 的一种前提。
    james122333
        49
    james122333  
       2022-03-21 10:09:38 +08:00
    @FrankHB

    只有应用本身安全性不够才需要以非应用本身机制来限制 更上层的信息 只要你需要提供应用使用 你就非得暴露它 不管以何种形式 看应用要不要使用而已
    但现今应用多数是如此 包含 MAC 本身 所以个人都不会使用这些工作上使用的 DAC 的变化已经符合需求 hash 本来就是验证用 你再加密一层都可以 虽然现在都是 https
    FrankHB
        50
    FrankHB  
       2022-03-21 18:54:10 +08:00
    @james122333 安全性这个话题的口水来源之一就是需求没有上界。你可能认为某个应用够安全了,但换个环境别的用户就未必。这没法定义清楚。
    所以跟你说的类似,现在系统设计者基本也不会替用户决定应该安全到什么程度,大多只是提供材料(安全机制),让用户决定怎么用。但系统的用户包括应用(开发者)和最终用户(系统管理员),究竟何者来决定,就比较微妙了。
    这个问题还涉及公共安全决策,比如浏览器厂商决定不提供 http (强制 https ),各方利益有冲突而更加混乱。考虑到 http 确有合理用途(可控的上下文中避免安全实现的开销),这更应当让用户自决而非供应商独断,即便用户决策错误,也不会自然坑到决策正确的其他用户。UNIX 权限的问题则略有不同:它是半吊子,明确想要安全或者明确不想被安全性成本拖累的两边都不讨好,维持现状也无助于改善混乱局面,除了用脚投票的用户也就是系统厂商的责任了,应用厂商反而没什么存在感。
    无论如何,至少有一点还是确定的:最终用户多了解现状,多明确表达自身的需求,多参与安全事务的决策,对整体减少非预期安全风险和安全实现的开销以及解决历史遗留问题都有好处。
    james122333
        51
    james122333  
       2022-03-24 19:27:59 +08:00
    @FrankHB

    所以要慎选应用 然而现在的状况是哪个热门用哪个 unix 的话 DAC 就挺够了 有时候读写不应该是靠 MAC 决定的 而且那堆 MAC 的 role 事实上也与 DAC 差不多...
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5822 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 02:40 · PVG 10:40 · LAX 18:40 · JFK 21:40
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.