DNS 解析器模块¶
概述¶
DNS 解析器模块通过请求类型为 dns_resolver 的密钥,为内核服务提供了一种进行 DNS 查询的方式。这些查询通过 /sbin/request-key 向上调用到用户空间。
这些例程必须由用户空间工具 dns.upcall、cifs.upcall 和 request-key 支持。它仍在开发中,尚未提供完整的功能集。它目前支持的功能包括:
(*) 实现 dns_resolver 密钥类型以联系用户空间。
它尚不支持以下 AFS 功能:
(*) 对 AFSDB 资源记录的 DNS 查询支持。
此代码是从 CIFS 文件系统中提取的。
编译¶
应通过开启内核配置选项来启用此模块。
CONFIG_DNS_RESOLVER - tristate "DNS Resolver support"
设置¶
要设置此功能,必须修改 /etc/request-key.conf 文件,以便 /sbin/request-key 能够适当引导上层调用。例如,要处理基本的域名到 IPv4/IPv6 地址解析,应添加以下行:
#OP TYPE DESC CO-INFO PROGRAM ARG1 ARG2 ARG3 ...
#====== ============ ======= ======= ==========================
create dns_resolver * * /usr/sbin/cifs.upcall %k
要引导对查询类型“foo”的查询,应在上面给出的更通用行之前添加以下行,因为会采用第一个匹配项。
create dns_resolver foo:* * /usr/sbin/dns.foo %k
用法¶
要使用此功能,在执行后可以调用模块中实现的以下函数之一:
#include <linux/dns_resolver.h>
::
int dns_query(const char *type, const char *name, size_t namelen,
const char *options, char **_result, time_t *_expiry);
This is the basic access function. It looks for a cached DNS query and if
it doesn't find it, it upcalls to userspace to make a new DNS query, which
may then be cached. The key description is constructed as a string of the
form::
[<type>:]<name>
where <type> optionally specifies the particular upcall program to invoke,
and thus the type of query to do, and <name> specifies the string to be
looked up. The default query type is a straight hostname to IP address
set lookup.
The name parameter is not required to be a NUL-terminated string, and its
length should be given by the namelen argument.
The options parameter may be NULL or it may be a set of options
appropriate to the query type.
The return value is a string appropriate to the query type. For instance,
for the default query type it is just a list of comma-separated IPv4 and
IPv6 addresses. The caller must free the result.
The length of the result string is returned on success, and a negative
error code is returned otherwise. -EKEYREJECTED will be returned if the
DNS lookup failed.
If _expiry is non-NULL, the expiry time (TTL) of the result will be
returned also.
内核维护一个内部密钥环,用于缓存查找到的密钥。任何拥有 CAP_SYS_ADMIN 能力的进程都可以通过对密钥环 ID 使用 KEYCTL_KEYRING_CLEAR 来清除它。
从用户空间读取 DNS 密钥¶
可以使用 keyctl_read() 或“keyctl read/print/pipe”从用户空间读取 dns_resolver 类型的密钥。
机制¶
dns_resolver 模块注册了一个名为“dns_resolver”的密钥类型。此类型的密钥用于从用户空间传输和缓存 DNS 查找结果。
当调用 dns_query() 时,它会调用 request_key() 在本地密钥环中搜索缓存的 DNS 结果。如果未找到,它将向上调用到用户空间以获取新结果。
向上调用到用户空间通过 request_key() 上调向量进行,并通过 /etc/request-key.conf 中的配置行进行引导,这些配置行告诉 /sbin/request-key 运行哪个程序来实例化密钥。
上调处理程序程序负责查询 DNS,将结果处理成适合传递给 keyctl_instantiate_key() 例程的形式。然后,它将数据传递给 dns_resolver_instantiate(),后者剥离并处理数据中包含的任何选项,然后将字符串的其余部分作为其有效载荷附加到密钥。
上调处理程序程序应将密钥的过期时间设置为其从中提取结果的所有记录中最低 TTL 的时间。这意味着当密钥持有的数据过期时,密钥将被丢弃并重新创建。
dns_query() 返回附加到密钥的值的副本,或者如果指示错误,则返回错误。
有关 request-key 函数的更多信息,请参阅 <file:Documentation/security/keys/request-key.rst>。
调试¶
通过向以下文件写入 1,可以动态开启调试消息:
/sys/module/dns_resolver/parameters/debug