如何在Linux Kernel Keyring中跨会话及用户共享密钥?
利用Linux Kernel Keyring实现全系统跨用户/会话共享密钥
要让密钥在全系统所有用户、会话(包括systemd以不同身份启动的服务)中共享,核心是将密钥存入系统级全局密钥环,并配置合适的权限让所有用户进程可读取。以下是具体实现步骤:
1. 以root身份创建全局共享密钥
Linux内核提供两个系统级密钥环:
@s:.system_keyring,系统默认的全局密钥环,所有进程默认可搜索(需权限允许读取)@r:.root_keyring,root用户的私有密钥环,需手动开放权限给其他用户
方式1:存入.system_keyring(推荐)
直接创建密钥并设置全用户可读权限:
# 创建密钥(替换my_shared_secret为你的密钥名称,supersecret为密钥内容) keyctl add user my_shared_secret "supersecret" @s # 给所有用户添加搜索、读取权限(自动获取密钥ID) KEY_ID=$(keyctl search @s user my_shared_secret) keyctl setperm $KEY_ID g:search:read,o:search:read
方式2:存入.root_keyring
如果选择root密钥环,需额外开放权限:
keyctl add user my_shared_secret "supersecret" @r KEY_ID=$(keyctl search @r user my_shared_secret) # 所有者全权限,组和其他用户可搜索、读取 keyctl setperm $KEY_ID 0xf7700
2. 验证普通用户/其他会话的访问权限
切换到任意普通用户(或通过systemd启动其他用户身份的服务),执行以下命令验证:
# 搜索密钥 KEY_ID=$(keyctl search @s user my_shared_secret) # 读取密钥内容 keyctl pipe $KEY_ID
若能输出密钥内容,说明共享生效。
3. 持久化密钥(避免重启丢失)
系统重启后,.system_keyring和.root_keyring中的密钥会丢失,需通过systemd服务自动加载:
- 创建密钥存储文件(仅root可读):
echo "supersecret" > /etc/my_shared_secret chmod 600 /etc/my_shared_secret
- 创建systemd服务文件
/etc/systemd/system/load-shared-key.service:
[Unit] Description=Load global shared secret into system keyring [Service] Type=oneshot # 从文件读取密钥内容并添加到.system_keyring ExecStart=/bin/bash -c 'keyctl add user my_shared_secret "$(cat /etc/my_shared_secret)" @s' # 自动设置权限给所有用户 ExecStartPost=/bin/bash -c 'KEY_ID=$(keyctl search @s user my_shared_secret); keyctl setperm $KEY_ID g:search:read,o:search:read' User=root RemainAfterExit=yes [Install] WantedBy=multi-user.target
- 启用并启动服务:
systemctl daemon-reload systemctl enable --now load-shared-key.service
关键注意事项
- 权限控制:严格限制密钥的写入权限,仅开放读和搜索权限给普通用户,防止密钥被篡改。
- 密钥类型:示例使用
user类型密钥(通用文本/二进制密钥),你也可以根据需求使用asymmetric(非对称密钥)等其他类型。 - systemd服务适配:无论systemd以哪个用户身份启动服务,只要进程未被限制访问系统密钥环(默认无限制),即可读取共享密钥。
内容的提问来源于stack exchange,提问作者synalice
相关产品推荐
相关产品推荐

