dns: DNS-Resolver für nginx-module-lua
Installation
Wenn Sie das RPM-Repository-Abonnement noch nicht 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
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
Um diese Lua-Bibliothek mit NGINX zu verwenden, stellen Sie sicher, dass nginx-module-lua installiert ist.
Dieses Dokument beschreibt lua-resty-dns v0.23, veröffentlicht am 06. August 2023.
Diese Lua-Bibliothek bietet einen DNS-Resolver für das ngx_lua NGINX-Modul:
https://github.com/openresty/lua-nginx-module/#readme
Diese Lua-Bibliothek nutzt die cosocket-API von ngx_lua, die ein 100% nicht blockierendes Verhalten gewährleistet.
Beachten Sie, dass mindestens ngx_lua 0.5.12 oder OpenResty 1.2.1.11 erforderlich ist.
Außerdem wird die bit-Bibliothek benötigt. Wenn Sie LuaJIT 2.0 mit ngx_lua verwenden, ist die bit-Bibliothek standardmäßig bereits verfügbar.
Beachten Sie, dass diese Bibliothek im OpenResty-Bundle gebündelt und standardmäßig aktiviert ist.
WICHTIG: Um eindeutige IDs generieren zu können, muss der Zufallszahlengenerator vor der Verwendung dieses Moduls ordnungsgemäß mit math.randomseed initialisiert werden.
Synopsis
server {
location = /dns {
content_by_lua_block {
local resolver = require "resty.dns.resolver"
local r, err = resolver:new{
nameservers = {"8.8.8.8", {"8.8.4.4", 53} },
retrans = 5, -- 5 Retransmissionen bei Empfangszeitüberschreitung
timeout = 2000, -- 2 Sek
no_random = true, -- immer mit dem ersten Nameserver beginnen
}
if not r then
ngx.say("Fehler beim Instanziieren des Resolvers: ", err)
return
end
local answers, err, tries = r:query("www.google.com", nil, {})
if not answers then
ngx.say("Fehler beim Abfragen des DNS-Servers: ", err)
ngx.say("Wiederholungsprotokoll:\n ", table.concat(tries, "\n "))
return
end
if answers.errcode then
ngx.say("Server hat Fehlercode zurückgegeben: ", answers.errcode,
": ", answers.errstr)
end
for i, ans in ipairs(answers) do
ngx.say(ans.name, " ", ans.address or ans.cname,
" Typ:", ans.type, " Klasse:", ans.class,
" TTL:", ans.ttl)
end
}
}
}
Methoden
new
syntax: r, err = class:new(opts)
Erstellt ein dns.resolver-Objekt. Gibt nil und eine Fehlermeldung zurück, wenn ein Fehler auftritt.
Es akzeptiert ein opts-Tabellenargument. Die folgenden Optionen werden unterstützt:
-
nameserversEine Liste von Nameservern, die verwendet werden sollen. Jeder Nameserver-Eintrag kann entweder eine einzelne Hostnamen-Zeichenfolge oder eine Tabelle sein, die sowohl die Hostnamen-Zeichenfolge als auch die Portnummer enthält. Der Nameserver wird für jeden Aufruf der
query-Methode durch einen einfachen Round-Robin-Algorithmus ausgewählt. Diese Option ist erforderlich. *retransDie Gesamtanzahl der Übertragungen der DNS-Anfrage, wenn der Empfang einer DNS-Antwort zeitüberschreitet, gemäß der
timeout-Einstellung. Standardmäßig5Mal. Bei dem Versuch, die Anfrage erneut zu übertragen, wird der nächste Nameserver gemäß dem Round-Robin-Algorithmus ausgewählt. *timeoutDie Zeit in Millisekunden, die auf die Antwort für einen einzelnen Übertragungsversuch gewartet wird. Beachten Sie, dass dies ''nicht'' die maximale Gesamtwartezeit ist, bevor aufgegeben wird; die maximale Gesamtwartezeit kann durch den Ausdruck
timeout x retransberechnet werden. Dietimeout-Einstellung kann auch durch Aufrufen der Methodeset_timeoutgeändert werden. Die Standard-timeout-Einstellung beträgt 2000 Millisekunden oder 2 Sekunden. *no_recurseEin boolescher Flag, das steuert, ob das "Recursion Desired" (RD)-Flag in der UDP-Anfrage deaktiviert werden soll. Standardmäßig
false. *no_randomEin boolescher Flag, das steuert, ob der Nameserver zufällig ausgewählt werden soll, um zuerst abgefragt zu werden. Wenn
true, wird immer mit dem ersten aufgeführten Nameserver begonnen. Standardmäßigfalse.
destroy
syntax: r:destroy()
Zerstört das dns.resolver-Objekt, indem alle intern belegten Ressourcen freigegeben werden.
query
syntax: answers, err, tries? = r:query(name, options?, tries?)
Führt eine standardmäßige DNS-Abfrage an die durch die new-Methode angegebenen Nameserver durch und gibt alle Antwortdatensätze in einer array-ähnlichen Lua-Tabelle zurück. Im Fehlerfall gibt es nil und eine Zeichenfolge zurück, die den Fehler beschreibt.
Wenn der Server einen Fehlercode ungleich Null zurückgibt, werden die Felder errcode und errstr entsprechend in der zurückgegebenen Lua-Tabelle gesetzt.
Jeder Eintrag in der zurückgegebenen answers-Tabelle ist ebenfalls eine hash-ähnliche Lua-Tabelle, die normalerweise einige der folgenden Felder enthält:
-
nameDer Name des Ressourcendatensatzes. *
typeDer aktuelle Typ des Ressourcendatensatzes, mögliche Werte sind
1(TYPE_A),5(TYPE_CNAME),28(TYPE_AAAA) und andere durch RFC 1035 erlaubte Werte. *addressDie IPv4- oder IPv6-Adresse in ihrer textuellen Darstellung, wenn der Ressourcendatensatztyp entweder
1(TYPE_A) oder28(TYPE_AAAA) ist. Erfolgreiche 16-Bit-Nullgruppen in IPv6-Adressen werden standardmäßig nicht komprimiert; wenn Sie dies möchten, müssen Sie stattdessen die statische Methodecompress_ipv6_addraufrufen. *sectionDie Kennung des Abschnitts, zu dem der aktuelle Antwortdatensatz gehört. Mögliche Werte sind
1(SECTION_AN),2(SECTION_NS) und3(SECTION_AR). *cnameDer (dekodierte) Datensatzwert für
CNAME-Ressourcendatensätze. Nur vorhanden fürCNAME-Datensätze. *ttlDer Time-to-Live (TTL)-Wert in Sekunden für den aktuellen Ressourcendatensatz. *
classDie aktuelle Klasse des Ressourcendatensatzes, mögliche Werte sind
1(CLASS_IN) oder andere durch RFC 1035 erlaubte Werte. *preferenceDie Präferenz ganzzahlig für
MX-Ressourcendatensätze. Nur vorhanden fürMX-Typ-Datensätze. *exchangeDer Austausch-Domainname für
MX-Ressourcendatensätze. Nur vorhanden fürMX-Typ-Datensätze. *nsdnameEin Domainname, der einen Host angibt, der für die angegebene Klasse und Domain autoritativ sein sollte. Üblicherweise vorhanden für
NS-Typ-Datensätze. *rdataDie Rohressourcendaten (RDATA) für Ressourcendatensätze, die nicht erkannt werden. *
txtDer Datensatzwert für
TXT-Datensätze. Wenn es nur eine Zeichenfolge in diesem Datensatz gibt, dann nimmt dieses Feld eine einzelne Lua-Zeichenfolge an. Andernfalls nimmt dieses Feld eine Lua-Tabelle an, die alle Zeichenfolgen enthält. *ptrdnameDer Datensatzwert für
PTR-Datensätze.
Diese Methode akzeptiert auch ein optionales options-Argument, das die folgenden Felder enthält:
-
qtypeDer Typ der Frage. Mögliche Werte sind
1(TYPE_A),5(TYPE_CNAME),28(TYPE_AAAA) oder andere QTYPE-Werte, die durch RFC 1035 und RFC 3596 angegeben sind. Standardmäßig1(TYPE_A). *authority_sectionWenn auf einen wahren Wert gesetzt, enthält der Rückgabewert
answersden AbschnittAuthorityder DNS-Antwort. Standardmäßigfalse. *additional_sectionWenn auf einen wahren Wert gesetzt, enthält der Rückgabewert
answersden AbschnittAdditionalder DNS-Antwort. Standardmäßigfalse.
Der optionale Parameter tries kann als leere Tabelle bereitgestellt werden und wird als drittes Ergebnis zurückgegeben. Die Tabelle wird ein Array mit der Fehlermeldung für jeden (falls vorhanden) fehlgeschlagenen Versuch sein.
Wenn es zu Datenabschneidungen kommt, wird der Resolver automatisch erneut versuchen, den aktuellen Nameserver im TCP-Transportmodus abzufragen. Alle TCP-Verbindungen sind kurzlebig.
tcp_query
syntax: answers, err = r:tcp_query(name, options?)
Genau wie die query-Methode, aber erzwingt den TCP-Transportmodus anstelle von UDP.
Alle TCP-Verbindungen sind kurzlebig.
Hier ist ein Beispiel:
local resolver = require "resty.dns.resolver"
local r, err = resolver:new{
nameservers = { "8.8.8.8" }
}
if not r then
ngx.say("Fehler beim Instanziieren des Resolvers: ", err)
return
end
local ans, err = r:tcp_query("www.google.com", { qtype = r.TYPE_A })
if not ans then
ngx.say("Fehler bei der Abfrage: ", err)
return
end
local cjson = require "cjson"
ngx.say("Datensätze: ", cjson.encode(ans))
set_timeout
syntax: r:set_timeout(time)
Überschreibt die aktuelle timeout-Einstellung durch das time-Argument in Millisekunden für alle Nameserver-Peers.
compress_ipv6_addr
syntax: compressed = resty.dns.resolver.compress_ipv6_addr(address)
Komprimiert die aufeinanderfolgenden 16-Bit-Nullgruppen in der textuellen Darstellung der IPv6-Adresse.
Zum Beispiel,
local resolver = require "resty.dns.resolver"
local compress = resolver.compress_ipv6_addr
local new_addr = compress("FF01:0:0:0:0:0:0:101")
ergibt FF01::101 im Rückgabewert new_addr.
expand_ipv6_addr
syntax: expanded = resty.dns.resolver.expand_ipv6_addr(address)
Erweitert die aufeinanderfolgenden 16-Bit-Nullgruppen in der textuellen Darstellung der IPv6-Adresse.
Zum Beispiel,
local resolver = require "resty.dns.resolver"
local expand = resolver.expand_ipv6_addr
local new_addr = expand("FF01::101")
ergibt FF01:0:0:0:0:0:0:101 im Rückgabewert new_addr.
arpa_str
syntax: arpa_record = resty.dns.resolver.arpa_str(address)
Generiert den umgekehrten Domainnamen für PTR-Abfragen für sowohl IPv4- als auch IPv6-Adressen. Komprimierte IPv6-Adressen werden automatisch erweitert.
Zum Beispiel,
local resolver = require "resty.dns.resolver"
local ptr4 = resolver.arpa_str("1.2.3.4")
local ptr6 = resolver.arpa_str("FF01::101")
ergibt 4.3.2.1.in-addr.arpa für ptr4 und 1.0.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0.F.F.ip6.arpa für ptr6.
reverse_query
syntax: answers, err = r:reverse_query(address)
Führt eine PTR-Abfrage für sowohl IPv4- als auch IPv6-Adressen durch. Diese Funktion ist im Grunde ein Wrapper für den query-Befehl, der den arpa_str-Befehl verwendet, um die IP-Adresse im laufenden Betrieb zu konvertieren.
Konstanten
TYPE_A
Der A-Ressourcendatensatztyp, gleich der Dezimalzahl 1.
TYPE_NS
Der NS-Ressourcendatensatztyp, gleich der Dezimalzahl 2.
TYPE_CNAME
Der CNAME-Ressourcendatensatztyp, gleich der Dezimalzahl 5.
TYPE_SOA
Der SOA-Ressourcendatensatztyp, gleich der Dezimalzahl 6.
TYPE_PTR
Der PTR-Ressourcendatensatztyp, gleich der Dezimalzahl 12.
TYPE_MX
Der MX-Ressourcendatensatztyp, gleich der Dezimalzahl 15.
TYPE_TXT
Der TXT-Ressourcendatensatztyp, gleich der Dezimalzahl 16.
TYPE_AAAA
syntax: typ = r.TYPE_AAAA
Der AAAA-Ressourcendatensatztyp, gleich der Dezimalzahl 28.
TYPE_SRV
syntax: typ = r.TYPE_SRV
Der SRV-Ressourcendatensatztyp, gleich der Dezimalzahl 33.
Siehe RFC 2782 für Details.
TYPE_SPF
syntax: typ = r.TYPE_SPF
Der SPF-Ressourcendatensatztyp, gleich der Dezimalzahl 99.
Siehe RFC 4408 für Details.
CLASS_IN
syntax: class = r.CLASS_IN
Der Internet-Ressourcendatensatztyp, gleich der Dezimalzahl 1.
SECTION_AN
syntax: stype = r.SECTION_AN
Kennung des Answer-Abschnitts in der DNS-Antwort. Gleich der Dezimalzahl 1.
SECTION_NS
syntax: stype = r.SECTION_NS
Kennung des Authority-Abschnitts in der DNS-Antwort. Gleich der Dezimalzahl 2.
SECTION_AR
syntax: stype = r.SECTION_AR
Kennung des Additional-Abschnitts in der DNS-Antwort. Gleich der Dezimalzahl 3.
Automatische Fehlerprotokollierung
Standardmäßig protokolliert das zugrunde liegende ngx_lua-Modul Fehler, wenn Socket-Fehler auftreten. Wenn Sie bereits eine ordnungsgemäße Fehlerbehandlung in Ihrem eigenen Lua-Code durchführen, wird empfohlen, diese automatische Fehlerprotokollierung zu deaktivieren, indem Sie die lua_socket_log_errors-Direktive von ngx_lua deaktivieren, das heißt,
lua_socket_log_errors off;
Einschränkungen
- Diese Bibliothek kann nicht in Codekontexten wie
set_by_lua*,log_by_lua*undheader_filter_by_lua*verwendet werden, in denen die ngx_lua cosocket-API nicht verfügbar ist. - Die
resty.dns.resolver-Objektinstanz kann nicht auf Modulebene in einer Lua-Variablen gespeichert werden, da sie dann von allen gleichzeitigen Anfragen, die vom selben NGINX-Worker-Prozess verarbeitet werden, geteilt wird (siehe https://github.com/openresty/lua-nginx-module/#data-sharing-within-an-nginx-worker) und zu schlechten Race-Conditions führen kann, wenn gleichzeitige Anfragen versuchen, dieselberesty.dns.resolver-Instanz zu verwenden. Sie sollten immerresty.dns.resolver-Objekte in lokalen Funktionsvariablen oder in derngx.ctx-Tabelle initiieren. Diese Orte haben alle ihre eigenen Datenkopien für jede Anfrage.
Siehe auch
- das ngx_lua-Modul: https://github.com/openresty/lua-nginx-module/#readme
- die lua-resty-memcached Bibliothek.
- die lua-resty-redis Bibliothek.
- die lua-resty-mysql Bibliothek.
GitHub
Sie finden zusätzliche Konfigurationstipps und Dokumentationen für dieses Modul im GitHub-Repository für nginx-module-dns.