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