sf467
(珂朵莉)
1
用 bwrap 来包装不可信程序还是太费心了,需要考虑通进去的目录,不能留洞。有太多不得不用的商业程序,使再懒得一个一个写包装脚本,社区内的通用包装器也难免损失正常的程序使用体验
那么我们能不能转换思路,用 bwrap 来保护我们想保护的东西
比如 rclone 的配置文件,它记录了很多云盘的 token ,而且只需要被 rclone 读取。那么我们可不可以给本地的 rclone 配置文件加密,然后对 rclone 写 bwrap 包装,把解密后的目录或文件绑进沙盒,这样就只有 bwrap 可以访问那些内容了。这样的包装器脚本写起来也简单很多,可以大量应用于仅为某特定程序的隐私文件
kimiblock
(Kimiblock Moe)
2
systemd 有 encrypted credentials 机制, 不知是否符合你的要求 / 能在 user service manager 上用
sf467
(珂朵莉)
3
这个和我想的确实很像。
但是不能处理对文件的更改,如果有更改,还需要手动复制,然后加密
细想了一下,这个确实没好办法
可能可以把加密的文件通进沙盒里,然后在沙盒里用支持 fuse 的解密程序 ,挂载到沙盒内部目录,供程序读写,更改也可以直接写回
但是不知道安全性怎么样
看下这个是不是你想要的?配置文件用 sops加密,然后只解密给对应的应用
sf467
(珂朵莉)
5
他好像是用在文本编辑上的,编辑前解密,编辑后加密,过程对用户来说透明
但是好像不能直接传递给用于程序。而且想加密的也不只是配置,也有一些程序在运行中会读写的东西,比如照片啥的
你再看看它的文档,可以将解密后的配置传递给应用。至于程序运行中会读写的东西我就不知道了。
我也想要这样的功能。手机上这个功能都很常见了,一个应用的数据能且只能被该应用访问,每个应用都会分配一个应用密钥来加解密自己的文件。
flatpak有类似的设计,即使分配了~/的权限,~/.var/app里其它应用的数据也是不可见的。不过只有flatpak应用会遵守这个限制。
依云
(lilydjwg)
8
手机上那个只是权限控制,并没有加密。并且我很讨厌我自己的数据不让我自己访问。
你是对的。我之前对手机的安全机制有所误解。不过有这样的基于应用的权限系统也不错。
我支持用户应该可以访问所有数据,但有些数据确实需要特别的保护,密钥和密码显然不应该和下载的电影使用相同的保密级别。目前应用如果要保护自己的数据,就必须自己加密,然后让用户提供一个“根密钥”、“主密码”之类的东西来解密,这很不方便。特别是我已经有全盘加密,不需要额外的加密来对抗离线攻击,只是想有一个系统可以保证在线数据安全。
sf467
(珂朵莉)
10
好像有办法了
使用 gocryptfs ,和 fuse
在宿主机上加密 rclone 的配置目录,然后将加密后的目录绑进沙盒
让沙盒可以访问 /dev/fuse,并具有对应的权限,--cap-add CAP_SYS_ADMIN
在沙盒中先运行 gocryptfs 将加密的目录解密,然后挂载在沙盒内的目录中,宿主机是不可见的
因为沙盒的意义是用来运行可信程序,并解密数据,所以不需要太严格的隔离措施
sf467
(珂朵莉)
11
想出了一个可行的脚本,对 zen 浏览器使用的,用于加密 ~/.zen 目录,里面有着浏览器记录和书签
首先创建 .zen-crypt 目录,然后 gocryptfs -init
使用一个长密码
然后为了方便,我使用 GPG 来加密这个密码,然后在沙盒中先用 GPG 解密 gocryptfs 的密码文件,然后再传给 gocryptfs ,这样可以使用 GPG-agent 在短时间内避免手动输入密码
没有想到好的自动传入密码又安全的方法
现在的效果就是 zen-browser 可以正常运行,数据也没有问题。
现在懂的还是太少了,有很多想当然的脑洞,如有纰漏,请各位多多提醒
#!/bin/bash
PROGRAM="/usr/bin/zen-browser"
ENCRYPTED_DIR="/home/sf467/.zen-crypt"
DECRYPTED_MOUNT="/home/sf467/.zen/"
GPG_PASSFILE="/home/sf467/.local/zen.gpg" # GPG 加密的密码文件
GPG_KEY_ID="sf467"
# 环境信息
USER_ID=$(id -u)
RUNTIME_DIR="/run/user/$USER_ID"
GPG_HOME="/home/sf467/.gnupg" # GPG 配置文件路径
# 检查依赖(在宿主机上)
if ! command -v bwrap >/dev/null 2>&1; then
echo "错误:bubblewrap 未安装,请安装 bubblewrap。"
exit 1
fi
if ! command -v gocryptfs >/dev/null 2>&1; then
echo "错误:gocryptfs 未安装,请安装 gocryptfs。"
exit 1
fi
if ! command -v gpg >/dev/null 2>&1; then
echo "错误:gpg 未安装,请安装 gpg。"
exit 1
fi
# 检查 GPG 加密的密码文件是否存在
if \[ ! -f "$GPG_PASSFILE" \]; then
echo "错误:GPG 加密的密码文件 $GPG_PASSFILE 不存在。"
exit 1
fi
# 检查 GPG 配置文件是否存在
if \[ ! -d "$GPG_HOME" \]; then
echo "错误:GPG 配置文件目录 $GPG_HOME 不存在。"
exit 1
fi
# 捕获脚本参数
ARGS=("$@")
# 启动沙盒
/usr/bin/bwrap
--unshare-user
--cap-add CAP_SYS_ADMIN
--symlink usr/lib /lib
--symlink usr/lib /lib64
--symlink usr/bin /bin
--bind / /
--dev-bind /dev /dev
--bind "$GPG_HOME" "$GPG_HOME"
--bind "$GPG_PASSFILE" "$GPG_PASSFILE"
--tmpfs "$DECRYPTED_MOUNT"
--tmpfs /tmp
--die-with-parent
/bin/sh -c "
echo '\[沙盒\] 使用 gpg 解密密码...' >&2
PASSFILE=/tmp/gocryptfs_pass\_$$
gpg --decrypt --recipient '$GPG_KEY_ID' '$GPG_PASSFILE' > $PASSFILE 2>/dev/null
if \[ $? -ne 0 \] || \[ ! -s $PASSFILE \]; then
echo '\[沙盒\] 错误:无法解密密码或密码为空,退出。' >&2
exit 1
fi
chmod 600 $PASSFILE
echo '\[沙盒\] 挂载解密目录...' >&2
gocryptfs -passfile $PASSFILE
'$ENCRYPTED_DIR' '$DECRYPTED_MOUNT' || exit 1
echo '\[沙盒\] 解密成功,启动程序中...' >&2
rm -f $PASSFILE # 在沙盒内清理临时文件
exec '$PROGRAM' "$@"
" \_ "${ARGS\[@\]}"
# 设置退出时卸载挂载点
trap "fusermount -u '$DECRYPTED_MOUNT' 2>/dev/null" EXIT