dns-server: Lua DNS-Server-Treiber für nginx-module-lua
Installation
Wenn Sie noch kein RPM-Repository-Abonnement eingerichtet haben, melden Sie sich an. Dann können Sie mit den folgenden Schritten fortfahren.
CentOS/RHEL 7 oder Amazon Linux 2
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install lua-resty-dns-server
CentOS/RHEL 8+, Fedora Linux, Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install lua5.1-resty-dns-server
Um diese Lua-Bibliothek mit NGINX zu verwenden, stellen Sie sicher, dass nginx-module-lua installiert ist.
Dieses Dokument beschreibt lua-resty-dns-server v0.2, veröffentlicht am 23. Juli 2019.
Diese Lua-Bibliothek bietet einen DNS-Server-Treiber für das ngx_lua NGINX-Modul:
https://github.com/openresty/stream-lua-nginx-module/#readme
Synopsis
stream {
server {
listen 53 udp;
content_by_lua_block {
local server = require 'resty.dns.server'
local sock, err = ngx.req.socket()
if not sock then
ngx.log(ngx.ERR, "Fehler beim Abrufen des Anfrage-Sockets: ", err)
return ngx.exit(ngx.ERROR)
end
local req, err = sock:receive()
if not req then
ngx.log(ngx.ERR, "Fehler beim Empfangen: ", err)
return ngx.exit(ngx.ERROR)
end
local dns = server:new()
local request, err = dns:decode_request(req)
if not request then
ngx.log(ngx.ERR, "Fehler beim Dekodieren der Anfrage: ", err)
local resp = dns:encode_response()
local ok, err = sock:send(resp)
if not ok then
ngx.log(ngx.ERR, "Fehler beim Senden: ", err)
ngx.exit(ngx.ERROR)
end
return
end
local query = request.questions[1]
ngx.log(ngx.DEBUG, "qname: ", query.qname, " qtype: ", query.qtype)
local subnet = request.subnet[1]
if subnet then
ngx.log(ngx.DEBUG, "Subnetzadresse: ", subnet.address, " Maske: ", subnet.mask, " Familie: ", subnet.family)
end
local cname = "sinacloud.com"
if query.qtype == server.TYPE_CNAME or
query.qtype == server.TYPE_AAAA or query.qtype == server.TYPE_A then
local err = dns:create_cname_answer(query.qname, 600, cname)
if err then
ngx.log(ngx.ERR, "Fehler beim Erstellen der CNAME-Antwort: ", err)
return
end
else
dns:create_soa_answer("test.com", 600, "a.root-test.com", "vislee.test.com", 1515161223, 1800, 900, 604800, 86400)
end
local resp = dns:encode_response()
local ok, err = sock:send(resp)
if not ok then
ngx.log(ngx.ERR, "Fehler beim Senden: ", err)
return
end
}
}
server {
listen 53;
content_by_lua_block {
local bit = require 'bit'
local lshift = bit.lshift
local rshift = bit.rshift
local band = bit.band
local byte = string.byte
local char = string.char
local server = require 'resty.dns.server'
local sock, err = ngx.req.socket()
if not sock then
ngx.log(ngx.ERR, "Fehler beim Abrufen des Anfrage-Sockets: ", err)
return ngx.exit(ngx.ERROR)
end
local buf, err = sock:receive(2)
if not buf then
ngx.log(ngx.ERR, "Fehler beim Empfangen: ", err)
return ngx.exit(ngx.ERROR)
end
local len_hi = byte(buf, 1)
local len_lo = byte(buf, 2)
local len = lshift(len_hi, 8) + len_lo
local data, err = sock:receive(len)
if not data then
ngx.log(ngx.ERR, "Fehler beim Empfangen: ", err)
return ngx.exit(ngx.ERROR)
end
local dns = server:new()
local request, err = dns:decode_request(data)
if not request then
ngx.log(ngx.ERR, "Fehler beim Dekodieren der DNS-Anfrage: ", err)
return
end
local query = request.questions[1]
ngx.log(ngx.DEBUG, "qname: ", query.qname, " qtype: ", query.qtype)
local subnet = request.subnet[1]
if subnet then
ngx.log(ngx.DEBUG, "Subnetzadresse: ", subnet.address, " Maske: ", subnet.mask, " Familie: ", subnet.family)
end
if query.qtype == server.TYPE_CNAME or query.qtype == server.TYPE_A then
dns:create_cname_answer(query.qname, 600, "sinacloud.com")
elseif query.qtype == server.TYPE_AAAA then
local resp_header, err = dns:create_response_header(server.RCODE_NOT_IMPLEMENTED)
resp_header.ra = 0
else
dns:create_soa_answer("test.com", 600, "a.root-test.com", "vislee.test.com", 1515161223, 1800, 900, 604800, 86400)
end
local resp = dns:encode_response()
local len = #resp
local len_hi = char(rshift(len, 8))
local len_lo = char(band(len, 0xff))
local ok, err = sock:send({len_hi, len_lo, resp})
if not ok then
ngx.log(ngx.ERR, "Fehler beim Senden: ", err)
return
end
return
}
}
}
Methoden
new
syntax: s, err = class:new()
Erstellt ein dns.server-Objekt. Gibt nil und eine Fehlermeldung im Fehlerfall zurück.
decode_request
syntax: request, err = s:decode_request(buf)
Analysiert die DNS-Anfrage.
Die zurückgegebene Anfrage ist eine Lua-Tabelle, die einige der folgenden Felder enthält:
-
header: Derheaderist ebenfalls eine Lua-Tabelle, die normalerweise einige der folgenden Felder enthält:id: Die Kennung, die vom Programm zugewiesen wird, das eine Art von Anfrage generiert.qr: Das Feld gibt an, ob diese Nachricht eine Anfrage (0) oder eine Antwort (1) ist.opcode: Das Feld gibt die Art der Anfrage in dieser Nachricht an.tc: Das Feld gibt an, dass diese Nachricht aufgrund einer Länge, die die auf dem Übertragungskanal zulässige Länge überschreitet, gekürzt wurde.rd: Rekursion gewünscht. WennRDgesetzt ist, weist es den Nameserver an, die Anfrage rekursiv zu verfolgen.rcode: Antwortcode.qdcount: Das Feld, das die Anzahl der Einträge im Fragenabschnitt angibt.
-
questions: Jeder Eintrag in denquestionsist ebenfalls eine Lua-Tabelle, die einige der folgenden Felder enthält:qname: Ein Domainname der Anfrage.qtype: Gibt den Typ der Anfrage an.qclass: Gibt die Klasse der Anfrage an. Normalerweise ist das FeldINfür das Internet.
create_a_answer
syntax: err = s:create_a_answer(name, ttl, ipv4)
Erstellt die A-Records. Gibt nil oder eine Fehlermeldung im Fehlerfall zurück. Die normalerweise einige der folgenden Felder enthält:
-
nameDer Name des Ressourcensatzes. *
ttlDer Time-to-Live (TTL)-Wert in Sekunden für den aktuellen Ressourcensatz. *
ipv4Die IPv4-Adresse.
create_aaaa_answer
syntax: err = s:create_aaaa_answer(name, ttl, ipv6)
Erstellt die AAAA-Records. Gibt nil oder eine Fehlermeldung im Fehlerfall zurück. Die normalerweise einige der folgenden Felder enthält:
-
nameDer Name des Ressourcensatzes. *
ttlDer Time-to-Live (TTL)-Wert in Sekunden für den aktuellen Ressourcensatz. *
ipv6Die IPv6-Adresse.
create_cname_answer
syntax: err = s:create_cname_answer(name, ttl, cname)
Erstellt die CNAME-Records. Gibt nil oder eine Fehlermeldung im Fehlerfall zurück. Die normalerweise einige der folgenden Felder enthält:
-
nameDer Name des Ressourcensatzes. *
ttlDer Time-to-Live (TTL)-Wert in Sekunden für den aktuellen Ressourcensatz. *
cnameDer Name für ein Alias.
create_txt_answer
syntax: err = s:create_txt_answer(name, ttl, txt)
Erstellt die TXT-Records. Gibt nil oder eine Fehlermeldung im Fehlerfall zurück. Die normalerweise einige der folgenden Felder enthält:
-
nameDer Name des Ressourcensatzes. *
ttlDer Time-to-Live (TTL)-Wert in Sekunden für den aktuellen Ressourcensatz. *
txtDie Textzeichenfolgen.
create_ns_answer
syntax: err = s:create_ns_answer(name, ttl, nsdname)
Erstellt die NS-Records. Gibt nil oder eine Fehlermeldung im Fehlerfall zurück. Die normalerweise einige der folgenden Felder enthält:
-
nameDer Name des Ressourcensatzes. *
ttlDer Time-to-Live (TTL)-Wert in Sekunden für den aktuellen Ressourcensatz. *
nsdnameGibt einen Host an, der für die angegebene Klasse und Domain autoritativ sein sollte.
create_soa_answer
syntax: err = s:create_soa_answer(name, ttl, mname, rname, serial, refresh, retry, expire, minimum)
Erstellt die SOA-Records. Gibt nil oder eine Fehlermeldung im Fehlerfall zurück. Die normalerweise einige der folgenden Felder enthält:
-
nameDer Name des Ressourcensatzes. *
ttlDer Time-to-Live (TTL)-Wert in Sekunden für den aktuellen Ressourcensatz. *
mnameDer Nameserver, der die ursprüngliche oder primäre Datenquelle für diese Zone war. *
rnameDie Mailbox der Person, die für diese Zone verantwortlich ist. *
serialDie unsigned 32-Bit Versionsnummer der ursprünglichen Kopie der Zone. *
refreshEin 32-Bit Zeitintervall, bevor die Zone aktualisiert werden sollte. *
retryEin 32-Bit Zeitintervall, das vergehen sollte, bevor ein fehlgeschlagenes Update erneut versucht werden sollte. *
expireEin 32-Bit Zeitwert, der das obere Limit für das Zeitintervall angibt, das vergehen kann, bevor die Zone nicht mehr autoritativ ist. *
minimumDas unsigned 32-Bit Minimum TTL-Feld, das mit jedem RR aus dieser Zone exportiert werden sollte.
create_mx_answer
syntax: err = s:create_mx_answer(name, ttl, preference, exchange)
Erstellt die MX-Records. Gibt nil oder eine Fehlermeldung im Fehlerfall zurück. Die normalerweise einige der folgenden Felder enthält:
-
nameDer Name des Ressourcensatzes. *
ttlDer Time-to-Live (TTL)-Wert in Sekunden für den aktuellen Ressourcensatz. *
preferenceDie Präferenz dieses Mail-Exchange. *
exchangeDer Mail-Exchange.
create_srv_answer
syntax: err = s:create_srv_answer(name, ttl, priority, weight, port, target)
Erstellt die SRV-Records. Gibt nil oder eine Fehlermeldung im Fehlerfall zurück. Die normalerweise einige der folgenden Felder enthält:
-
nameDer Name des Ressourcensatzes. *
ttlDer Time-to-Live (TTL)-Wert in Sekunden für den aktuellen Ressourcensatz. *
priorityDie Priorität dieses Zielhosts. *
weightDas Gewichtsfeld gibt ein relatives Gewicht für Einträge mit derselben Priorität an. *
portDer Port auf diesem Zielhost für diesen Dienst. *
targetDer Domainname des Zielhosts.
create_response_header
syntax: resp_header, err = s:create_response_header(rcode)
encode_response
syntax: resp = s:encode_response()
Kodiert die DNS-Antworten. Gibt eine Fehlermeldung bei der Antwort oder nil zurück.
Konstanten
TYPE_A
Der A Ressourcensatztyp, gleich der Dezimalzahl 1.
TYPE_NS
Der NS Ressourcensatztyp, gleich der Dezimalzahl 2.
TYPE_CNAME
Der CNAME Ressourcensatztyp, gleich der Dezimalzahl 5.
TYPE_SOA
Der SOA Ressourcensatztyp, gleich der Dezimalzahl 6.
TYPE_MX
Der MX Ressourcensatztyp, gleich der Dezimalzahl 15.
TYPE_TXT
Der TXT Ressourcensatztyp, gleich der Dezimalzahl 16.
TYPE_AAAA
syntax: typ = s.TYPE_AAAA
Der AAAA Ressourcensatztyp, gleich der Dezimalzahl 28.
TYPE_SRV
syntax: typ = s.TYPE_SRV
Der SRV Ressourcensatztyp, gleich der Dezimalzahl 33.
Siehe RFC 2782 für Details.
TYPE_ANY
syntax: typ = s.TYPE_ANY
Der Typ aller Ressourcensätze, gleich der Dezimalzahl 255.
RCODE_FORMAT_ERROR
RCODE_NOT_IMPLEMENTED
Siehe auch
- das stream-lua-nginx-module: https://github.com/openresty/stream-lua-nginx-module/#readme
- die lua-resty-dns Bibliothek.
- diese ngx_stream_ipdb_module Bibliothek kann die Regionsauflösung unterstützen.
GitHub
Sie finden zusätzliche Konfigurationstipps und Dokumentationen für dieses Modul im GitHub-Repository für nginx-module-dns-server.