Board logo

标题: Linux 密钥保留服务入门(3) [打印本页]

作者: look_w    时间: 2018-6-14 17:30     标题: Linux 密钥保留服务入门(3)

启用密钥服务因为 Linux 密钥保留服务仍然非常新,在默认情况下 Linux 内核中关闭了这个服务。要想启用密钥服务,必须使用 CONFIG_KEYS=y 选项对内核进行配置。可以在内核编译的 make *config 步骤中 Security options 下面找到这个选项。
清单 4 给出在 Linux 内核中启用密钥服务的配置。
清单 4. 在 Linux 内核中启用密钥服务
1
2
3
4
5
6
7
8
9
".config" file ...
#
# Security options
#
CONFIG_KEYS=y
CONFIG_KEYS_DEBUG_PROC_KEYS=y
CONFIG_SECURITY=y
CONFIG_SECURITY_NETWORK=y
CONFIG_SECURITY_CAPABILITIES=y




密钥的源代码被组织在目录 linux-2.6.x/security/keys 中。
接下来,需要 。keyutils 包含 keyctl 命令,可以使用这个命令在密钥上执行各种操作。前面已经列出了 。更多信息参见 Linux 手册页。
创建新的密钥类型学习 Linux 密钥保留服务最容易的方式就是进行实践。下面的示例使用 Linux 密钥保留服务创建一个新类型的密钥。如果还没有 ,                                现在就执行这个步骤。执行 make 来构建内核模块和用户级程序的二进制代码。这些代码已经在 Linux 内核版本 2.6.20 上测试过了。
示例程序有两个组件:一个内核模块和一个用户空间程序。这个内核模块注册一个新的密钥类型。这个用户空间程序在预定义的 proc-entries 上执行 ioctl,这会导致对内核模块的调用。这个调用会产生一个新的密钥。然后,一个 “bash” shell 返回给用户,它带有新的会话 keyring 和链接到这个 keyring 的新类型的密钥。
因为这个用户空间程序将执行 ioctl,内核模块必须注册 proc_ioctl() 函数来处理 ioctl 请求。所有 ioctl 通信都使用 /proc 接口来进行。清单 5 给出在内核模块中声明的一个新的密钥类型。
清单 5. 声明新的密钥类型
1
2
3
4
5
6
7
struct key_type new_key_type = {
   .name = "mykey",
   .instantiate = instantiate_key,
   .describe = key_desc,
   .destroy = key_destroy,
   .match = key_match,
};




然后,模块在它的 init 函数中调用 register_key_type() 来注册这个新密钥类型(名为 mykey)。当内核模块收到 ioctl 请求时,它首先调用 key_alloc() 来分配一个新的密钥,从而创建一个会话 keyring。在成功调用 key_alloc() 之后,调用 key_instantiate_and_link() 对密钥进行实例化。在创建并实例化会话 keyring 之后,为用户的会话创建密钥。同样,依次调用 key_alloc() 和 key_instantiate_and_link()。成功完成这些调用之后,用户空间会话就有了一个新密钥。
使用模块创建了新的密钥类型之后,我们来试用一下这个内核模块。模块中的一个基本操作是查看一个进程与哪些 keyring 相关联,以及这些 keyring 包含哪些密钥和其他 keyring。调用 keyctl show 就可以在树结构中显示密钥。清单 6 显示在运行程序之前密钥的状态。
清单 6. 查看进程的 keyring
1
2
3
4
[root@phoenix set.5]# keyctl show
Session Keyring
       -3 --alswrv      0     0  keyring: _ses.1976
        2 --alswrv      0     0   \_ keyring: _uid.0




清单 7 显示插入模块或者卸载模块或用户级程序的命令的输出。这些消息会放在一个系统日志文件中(通常是 /var/log/messages)。
清单 7. 插入内核模块
1
2
3
[root@phoenix set.5]# insmod ./kernel.land/newkey.ko
Loading the module ...
Registered "learning_key"




接下来,执行用户级程序。
清单 8. 执行用户级程序
1
2
3
4
5
6
7
8
9
[root@phoenix set.5]# ./user.land/session
  
In /var/log/message, you will see similar output
Installing session keyring:
keyring allocated successfully.
keyring instantiated and linked successfully.
New session keyring installed successfully.
key of new type allocated successfully.
New key type linked to current session.




再看一下密钥的状态,见清单 9。
清单 9. 运行用户级程序之后的密钥状态
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
[root@phoenix set.5]# keyctl show
Session Keyring
       -3 --alswrv      0     0  keyring: session.2621
39044642 --alswrv      0     0   \_ mykey: New key type
  
[root@phoenix set.5]# cat /proc/keys
00000001 I-----     1 perm 1f3f0000     0     0 keyring   _uid_ses.0: 1/4
00000002 I-----     5 perm 1f3f0000     0     0 keyring   _uid.0: empty
0253c622 I--Q--     1 perm 3f3f0000     0     0 mykey   New key type: 0
11a490da I--Q--     2 perm 3f3f0000     0     0 keyring   session.2621: 1/4
13670439 I--Q--     2 perm 1f3f0000     0     0 keyring   _ses.1977: 1/4
159d39b8 I--Q--     5 perm 1f3f0000     0     0 keyring   _ses.1976: 1/4
3a14f259 I--Q--     3 perm 1f3f0000     0     0 keyring   _ses.1978: 1/4
[root@phoenix set.5]# cat /proc/key-users
    0:     8 7/7 5/100 136/10000
   43:     2 2/2 2/100 56/10000
   48:     2 2/2 2/100 56/10000
   81:     2 2/2 2/100 56/10000
  786:     4 4/4 4/100 113/10000
  
"keyctl describe <Key>" command gives the description of key.
  
[root@phoenix set.5]# keyctl describe -3
       -3: alswrvalswrv------------     0     0 keyring: session.2621
[root@phoenix set.5]# keyctl describe 39044642
39044642: alswrvalswrv------------     0     0 mykey: New key type
[avinesh@phoenix set.5]$ keyctl search -3 mykey "New key type"
39044642
[root@phoenix set.5]# exit
exit
Now back to our previous state  
[root@phoenix set.5]# keyctl show
Session Keyring
       -3 --alswrv      0     0  keyring: _ses.1976
        2 --alswrv      0     0   \_ keyring: _uid.0
[root@phoenix set.5]# rmmod ./kernel.land/newkey.ko
Unloading the module.
Unregistered "learning_key"




与密钥相关的 proc 文件/proc 中添加了两个文件来管理密钥:/proc/keys 和 /proc/key-users。我们来仔细看看这些文件。
/proc/keys

如果一个进程希望了解它可以查看哪些密钥,它可以通过读取 /proc/keys 获得这些信息。在配置内核时,必须启用这个文件,因为它允许任何用户列出密钥数据库。
清单  10. /proc/keys 文件
1
2
3
4
5
6
7
[root@phoenix set.5]# cat /proc/keys
00000001 I-----  1     perm    1f3f0000      0    0    keyring    _uid_ses.0 : 1/4
00000002 I-----  5     perm    1f3f0000      0    0    keyring    _uid.0     : empty
13670439 I--Q--  2     perm    1f3f0000      0    0    keyring    _ses.1977  : 1/4
159d39b8 I--Q--  6     perm    1f3f0000      0    0    keyring    _ses.1976  : 1/4
3a14f259 I--Q--  3     perm    1f3f0000      0    0    keyring    _ses.1978  : 1/4
[Serial][Flags][Usage][Expiry][Permissions][UID][GID][TypeName][Description] :[Summary]




*Source: linux_kernel_source/security/keys/proc.c:proc_keys_show()
在以上文件中看到的大多数字段来自 include/linux/key.h 中定义的 struct key。可能的标志值见清单 11。
清单 11. struct key 字段可能的标志值
1
2
3
4
5
6
I        Instantiated
R        Revoked
D        Dead
Q        Contributes to user's quota
U        Under construction by callback to user-space
N        Negative key




/proc/key-users

清单 12 显示 /proc/key-users 文件。
清单 12. /proc/key-users 文件
1
2
3
4
5
6
[root@phoenix set.5]# cat /proc/key-users
    0:     6 5/5 3/100 90/10000
   43:     2 2/2 2/100 56/10000
   48:     2 2/2 2/100 56/10000
   81:     2 2/2 2/100 56/10000
  786:     4 4/4 4/100 113/10000




清单 13 给出每个字段的含义。
清单 13. /proc/key-users 文件的字段
1
2
3
4
5
<UID>                     User ID
<usage>                 Usage count
<inst>/<keys>      Total number of keys and number instantiated
<keys>/<max>     Key count quota
<bytes><max>     Key size quota




*Source: linux_kernel_source/security/keys/proc.c:proc_key_users_show()
大多数字段是 security/keys/internal.h 中定义的 struct key_user 的字段。
示例程序中演示了所有这些步骤。




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0