multiplexer: Transparenter Portdienst-Multiplexer für das Stream-Subsystem
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-multiplexer
CentOS/RHEL 8+, Fedora Linux, Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install lua5.1-resty-multiplexer
Um diese Lua-Bibliothek mit NGINX zu verwenden, stellen Sie sicher, dass nginx-module-lua installiert ist.
Dieses Dokument beschreibt lua-resty-multiplexer v0.2, das am 31. August 2020 veröffentlicht wurde.
Diese Bibliothek implementiert einen transparenten Portdienst-Multiplexer, der verwendet werden kann, um mehrere TCP-Dienste auf demselben Port auszuführen.
Beachten Sie, dass das nginx Stream-Modul und das stream-lua-nginx-module erforderlich sind.
Getestet auf OpenResty >= 1.13.6.1.
Mit OpenResty 1.13.6.1 ist ein benutzerdefinierter Patch von @fcicq erforderlich. Die ursprüngliche Diskussion finden Sie hier. Und natives Proxying wird nicht unterstützt, da reqsock:peek fehlt.
Ab OpenResty 1.15.8.1 wird nur natives Proxying unterstützt und kein Patch ist erforderlich. Lua-Land-Proxying wird möglich sein, wenn das stream-lua-nginx-module tcpsock:receiveany implementiert.
Synopsis
stream {
init_by_lua_block {
local mul = require("resty.multiplexer")
mul.load_protocols(
"http", "ssh", "dns", "tls", "xmpp"
)
mul.set_rules(
{{"client-host", "10.0.0.1"}, "internal-host", 80},
{{"protocol", "http"}, {"client-host", "10.0.0.2"}, "internal-host", 8001},
{{"protocol", "http"}, "example.com", 80},
{{"protocol", "ssh"}, "github.com", 22},
{{"protocol", "dns"}, "1.1.1.1", 53},
{{"protocol", "tls"}, {"time", nil}, "twitter.com", 443},
{{"protocol", "tls"}, "www.google.com", 443},
{{"default", nil}, "127.0.0.1", 80}
)
mul.matcher_config.time = {
minute_match = {0, 30},
minute_not_match = {{31, 59}},
}
}
resolver 8.8.8.8;
# für OpenResty >= 1.13.6.1, natives Nginx-Proxying
lua_add_variable $multiplexer_upstream;
server {
error_log /var/log/nginx/multiplexer-error.log error;
listen 443;
resolver 8.8.8.8;
preread_by_lua_block {
local mul = require("resty.multiplexer")
local mp = mul:new()
mp:preread_by()
}
proxy_pass $multiplexer_upstream;
}
# für OpenResty < 1.13.6.1, Lua-Land-Proxying
server {
error_log /var/log/nginx/multiplexer-error.log error;
listen 443;
resolver 8.8.8.8;
server {
listen 80;
content_by_lua_block {
local mul = require("resty.multiplexer")
local mp = mul:new()
mp:content_by()
}
}
}
}
Dieses Modul besteht aus zwei Teilen: Protokoll-Identifikatoren und Matchern.
Protokoll-Identifikatoren müssen über load_protocols im init_by_lua_block-Direktiv geladen werden. Siehe Abschnitt Protokoll für derzeit unterstützte Protokolle und eine Anleitung zum Hinzufügen eines neuen Protokolls.
Regeln werden über set_rules definiert, um den Datenverkehr zu verschiedenen Upstreams zu leiten. Für jeden Matcher, der in der Regel definiert ist, wird der entsprechende Matcher automatisch geladen. Siehe Abschnitt Matcher für derzeit implementierte Matcher und eine Anleitung zum Hinzufügen eines neuen Matchers.
Siehe Abschnitt API für die Syntax von load_protocols und set_rules.
Die definierten Regeln haben Priorität. Im obigen Beispiel haben wir eine Regel definiert, die besagt:
- Wenn die Client-Adresse
10.0.0.1ist, proxy zu internal-host.com:80 - Wenn das Protokoll
HTTPist und die Client-Adresse10.0.0.2ist, proxy zu internal-host:8001 - Wenn das Protokoll
SSHist, proxy zu github.com:22 - Wenn das Protokoll
DNSist, proxy zu 1.1.1.1:53 - Wenn das Protokoll
SSL/TLSist und die aktuelle Minute zwischen 0 und 30 liegt, proxy zu twitter:443 - Wenn das Protokoll
SSL/TLSist und die aktuelle Minute zwischen 31 und 59 liegt, proxy zu www.google.com:443 - Andernfalls proxy zu 127.0.0.1:80
Protokoll
Der Protokollteil analysiert die erste Anfrage, die vom Client gesendet wird, und versucht, sie mithilfe bekannter Protokollsignaturen abzugleichen.
Derzeit unterstützt: dns, http, ssh, tls, xmpp. Basierend auf den Bytes der Signatur kann jedes Protokoll unterschiedliche Möglichkeiten haben, falsch identifiziert zu werden.
| Protokoll | Länge der Signatur | Falsch-Rate |
|---|---|---|
| dns | 9 1/4 | 5.29e-23 |
| http | 4 | 2.33e-10 |
| ssh | 4 | 2.33e-10 |
| tls | 6 | 3.55e-15 |
| xmpp | 6 in 8 1/4 | ? |
Neues Protokoll hinzufügen
Erstellen Sie eine neue protocol_name.lua-Datei unter resty/multiplexer/protocol im Format:
return {
required_bytes = ?,
check = function(buf)
-- überprüfen Sie den buf und geben Sie true zurück, wenn das Protokoll identifiziert wurde
end
}
required_bytes ist die Anzahl der Bytes, die wir lesen müssen, bevor wir das Protokoll identifizieren.
Matcher
client-host
Übereinstimmung, wenn $remote_addr dem erwarteten Wert entspricht.
protocol
Übereinstimmung, wenn das Protokoll dem erwarteten Wert entspricht.
time
Übereinstimmung, wenn die aktuelle Zeit im konfigurierten Bereich in mul.matcher_config.time liegt. Wenn kein Bereich definiert ist, gibt der Matcher immer false zurück.
Zum Beispiel, um das Jahr 2018, Januar und März sowie die Stunde 6 bis 24 außer der Stunde 12 abzugleichen:
init_by_lua_block {
local mul = require("resty.multiplexer")
mul.load_protocols(
"http", "ssh", "dns", "tls", "xmpp"
)
mul.set_rules(
{{"time", ""}, "twitter.com", 443}
)
mul.matcher_config.time = {
year_match = {2018},
year_not_match = {},
month_match = {{1}, {3}},
month_not_match = {},
day_match = {}, -- Tag des Monats
day_not_match = {},
hour_match = {{6, 24}},
hour_not_match = {{12}},
minute_match = {},
minute_not_match = {},
second_match = {},
second_not_match = {},
}
}
default
Immer übereinstimmt.
Neuen Matcher hinzufügen
Erstellen Sie eine neue matcher_name.lua-Datei unter resty/multiplexer/matchers im Format:
local _M = {}
function _M.match(protocol, expected)
-- gibt true zurück, wenn es eine Übereinstimmung gibt
end
return _M
Dabei ist protocol das identifizierte Protokoll in Kleinbuchstaben und expected der erwartete Wert für diesen Matcher, der in set_rules definiert ist.
API
multiplexer.new
Syntax: multiplexer:new(connect_timeout, send_timeout, read_timeout)
Initialisiert die Multiplexer-Instanz. Und setzt die Schwellenwerte für die Verbindungszeitüberschreitung, die Sendezeitüberschreitung und die Lesezeitüberschreitung, wie in tcpsock:settimeouts.
multiplexer.load_protocols
Syntax: multiplexer:load_protocols("protocol-1", "protocol-2", ...)
Lädt die Protokollmodule in den Speicher.
Unterstützte Protokolle finden Sie im Protokoll.
multiplexer.set_rules
Syntax: multiplexer:set_rules(rule1, rule2, ...)
Lädt die Regeln in der angegebenen Reihenfolge. Jede Regel ist eine Array-Tabelle, die im Format ist:
{{"matcher-1", "expected-value-1"}, {"matcher-2", "expected-value-2"}, ..., "upstream_host", upstream_port}
Unterstützte Matcher finden Sie im Matcher.
Siehe auch
GitHub
Sie finden zusätzliche Konfigurationstipps und Dokumentationen für dieses Modul im GitHub-Repository für nginx-module-multiplexer.