| 1 | |
| 2 |
|
| 3 | ===================
|
| 4 | DNS Resolver Module
|
| 5 | ===================
|
| 6 |
|
| 7 | |
| 8 |
|
| 9 | - Overview.
|
| 10 | - Compilation.
|
| 11 | - Setting up.
|
| 12 | - Usage.
|
| 13 | - Mechanism.
|
| 14 | - Debugging.
|
| 15 |
|
| 16 |
|
| 17 | Overview
|
| 18 | ========
|
| 19 |
|
| 20 | The DNS resolver module provides a way for kernel services to make DNS queries
|
| 21 | by way of requesting a key of key type dns_resolver. These queries are
|
| 22 | upcalled to userspace through /sbin/request-key.
|
| 23 |
|
| 24 | These routines must be supported by userspace tools dns.upcall, cifs.upcall and
|
| 25 | request-key. It is under development and does not yet provide the full feature
|
| 26 | set. The features it does support include:
|
| 27 |
|
| 28 | * Implements the dns_resolver key_type to contact userspace.
|
| 29 |
|
| 30 | It does not yet support the following AFS features:
|
| 31 |
|
| 32 | * DNS query support for AFSDB resource record.
|
| 33 |
|
| 34 | This code is extracted from the CIFS filesystem.
|
| 35 |
|
| 36 |
|
| 37 | Compilation
|
| 38 | ===========
|
| 39 |
|
| 40 | The module should be enabled by turning on the kernel configuration options::
|
| 41 |
|
| 42 | CONFIG_DNS_RESOLVER - tristate "DNS Resolver support"
|
| 43 |
|
| 44 |
|
| 45 | Setting up
|
| 46 | ==========
|
| 47 |
|
| 48 | To set up this facility, the /etc/request-key.conf file must be altered so that
|
| 49 | /sbin/request-key can appropriately direct the upcalls. For example, to handle
|
| 50 | basic dname to IPv4/IPv6 address resolution, the following line should be
|
| 51 | added::
|
| 52 |
|
| 53 |
|
| 54 | #OP TYPE DESC CO-INFO PROGRAM ARG1 ARG2 ARG3 ...
|
| 55 | #====== ============ ======= ======= ==========================
|
| 56 | create dns_resolver * * /usr/sbin/cifs.upcall %k
|
| 57 |
|
| 58 | To direct a query for query type 'foo', a line of the following should be added
|
| 59 | before the more general line given above as the first match is the one taken::
|
| 60 |
|
| 61 | create dns_resolver foo:* * /usr/sbin/dns.foo %k
|
| 62 |
|
| 63 |
|
| 64 | Usage
|
| 65 | =====
|
| 66 |
|
| 67 | To make use of this facility, first ``dns_resolver.h`` must be included::
|
| 68 |
|
| 69 | #include <linux/dns_resolver.h>
|
| 70 |
|
| 71 | Then queries may be made by calling::
|
| 72 |
|
| 73 | int dns_query(const char *type, const char *name, size_t namelen,
|
| 74 | const char *options, char **_result, time_t *_expiry);
|
| 75 |
|
| 76 | This is the basic access function. It looks for a cached DNS query and if
|
| 77 | it doesn't find it, it upcalls to userspace to make a new DNS query, which
|
| 78 | may then be cached. The key description is constructed as a string of the
|
| 79 | form::
|
| 80 |
|
| 81 | [<type>:]<name>
|
| 82 |
|
| 83 | where <type> optionally specifies the particular upcall program to invoke,
|
| 84 | and thus the type of query, and <name> specifies the string to be looked up.
|
| 85 | The default query type is a straight hostname to IP address set lookup.
|
| 86 |
|
| 87 | The name parameter is not required to be a NUL-terminated string, and its
|
| 88 | length should be given by the namelen argument.
|
| 89 |
|
| 90 | The options parameter may be NULL or it may be a set of options
|
| 91 | appropriate to the query type.
|
| 92 |
|
| 93 | The return value is a string appropriate to the query type. For instance,
|
| 94 | for the default query type it is just a list of comma-separated IPv4 and
|
| 95 | IPv6 addresses. The caller must free the result.
|
| 96 |
|
| 97 | The length of the result string is returned on success, and a negative
|
| 98 | error code is returned otherwise. -EKEYREJECTED will be returned if the
|
| 99 | DNS lookup failed.
|
| 100 |
|
| 101 | If _expiry is non-NULL, the expiry time (TTL) of the result will be
|
| 102 | returned also.
|
| 103 |
|
| 104 | The kernel maintains an internal keyring in which it caches looked up keys.
|
| 105 | This can be cleared by any process that has the CAP_SYS_ADMIN capability by
|
| 106 | the use of KEYCTL_KEYRING_CLEAR on the keyring ID.
|
| 107 |
|
| 108 |
|
| 109 | Reading DNS Keys from Userspace
|
| 110 | ===============================
|
| 111 |
|
| 112 | Keys of dns_resolver type can be read from userspace using keyctl_read() or
|
| 113 | "keyctl read/print/pipe".
|
| 114 |
|
| 115 |
|
| 116 | Mechanism
|
| 117 | =========
|
| 118 |
|
| 119 | The dns_resolver module registers a key type called "dns_resolver". Keys of
|
| 120 | this type are used to transport and cache DNS lookup results from userspace.
|
| 121 |
|
| 122 | When dns_query() is invoked, it calls request_key() to search the local
|
| 123 | keyrings for a cached DNS result. If that fails to find one, it upcalls to
|
| 124 | userspace to get a new result.
|
| 125 |
|
| 126 | Upcalls to userspace are made through the request_key() upcall vector, and are
|
| 127 | directed by means of configuration lines in /etc/request-key.conf that tell
|
| 128 | /sbin/request-key what program to run to instantiate the key.
|
| 129 |
|
| 130 | The upcall handler program is responsible for querying the DNS, processing the
|
| 131 | result into a form suitable for passing to the keyctl_instantiate_key()
|
| 132 | routine. This then passes the data to dns_resolver_instantiate() which strips
|
| 133 | off and processes any options included in the data, and then attaches the
|
| 134 | remainder of the string to the key as its payload.
|
| 135 |
|
| 136 | The upcall handler program should set the expiry time on the key to that of the
|
| 137 | lowest TTL of all the records it has extracted a result from. This means that
|
| 138 | the key will be discarded and recreated when the data it holds has expired.
|
| 139 |
|
| 140 | dns_query() returns a copy of the value attached to the key, or an error if
|
| 141 | that is indicated instead.
|
| 142 |
|
| 143 | See Documentation/security/keys/request-key.rst for further information about
|
| 144 | request-key function.
|
| 145 |
|
| 146 |
|
| 147 | Debugging
|
| 148 | =========
|
| 149 |
|
| 150 | Debugging messages can be turned on dynamically by writing a 1 into the
|
| 151 | following file::
|
| 152 |
|
| 153 | /sys/module/dns_resolver/parameters/debug
|