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