Ändern Sie Daten, die von nginx im laufenden Betrieb übertragen werden

9

Ich habe ein Nginx-Setup, das Anforderungen von externen Hosts empfängt und diese an einen internen Server weiterleitet.

Die Konfiguration sieht ungefähr so ​​aus:

server {

        listen 10.0.0.66:443;

        server_name my.example.com;

        root /websites/my.example.com

        ssl on;
        ssl_certificate /websites/ssl/my.example.com.crt;
        ssl_certificate /websites/ssl/my.example.com.key;

        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header Host $http_host;

        location / {
                proxy_pass https://10.0.0.100:3000/;
        }
}

Zu Versuchs- / Testzwecken möchte ich in der Lage sein, die Antwort des internen Hosts über eine beliebige Binärdatei auszuführen und mit der Antwort der Binärdatei zu antworten.

Zum Beispiel , wenn ich minify html auf dem Proxy wollte würde ich die Antwort des Servers durch htmlcompressor läuft und dann die Ausgabe als Reaktion auf die Client-Proxy senden. Das Endergebnis wäre, dass der Endclient minimiertes HTML zurückbekommt.

Ich weiß, dass es für Nginx alle möglichen Addons und Beispiele gibt, um dies für lokal bereitgestellte Daten zu erreichen, aber wie kann man sie für einen Proxy einrichten?

Thatjuan
quelle
Nur um klarzustellen. Sie möchten, dass nginx die Anforderung an den Proxyserver weiterleitet, eine Antwort zurückerhält, komprimiert und dann an den Benutzer weiterleitet? Sie möchten, dass Nginx es in der Mitte des Servers und Benutzers verarbeitet?
Sjdaws
@sjdaws, komprimieren Sie es nicht unbedingt, sondern führen Sie es durch ein beliebiges Programm aus und verwenden Sie die Ausgabe als das, was an den Client gesendet wird. Also im Wesentlichen ja, ich möchte die Ausgabe ändern, die vom Server zum Client geht.
Thatjuan

Antworten:

10

Sie möchten also nginxeine Anfrage vom Client an den Backend-Server weiterleiten und diese Antwort dann, bevor Sie die Antwort des Backends an den Client zurücksenden, über einen anderen externen Prozessor weiterleiten?

Ich glaube nicht, dass Sie dies mit offiziellen nginxModulen tun können, wie sie derzeit von Igor Sysoev und Nginx, Inc bereitgestellt werden. Die nächste Sache , die zur Veränderung des Körpers der Antwort verfügbar ist , ist ein paar Filtermodule , die zusammen kommen mit nginx, ist aber standardmäßig deaktiviert gedreht, darunter die add_before_body, add_after_bodyund sub_filterRichtlinien:

http://nginx.org/en/docs/http/ngx_http_addition_module.html
http://nginx.org/en/docs/http/ngx_http_sub_module.html

Auch vielleicht gzip on;ist das, was Sie eigentlich wollen stattdessen?

http://nginx.org/en/docs/http/ngx_http_gzip_module.html

Oder, wenn Sie perlein vollständig experimentelles Modul kennen und bereit sind, es auszuführen, werfen Sie einen Blick auf die Einbettung perlin nginxein offizielles Nginx-Modul, das standardmäßig deaktiviert ist und (etwas offensichtlich) vollständig experimentell ist:

http://nginx.org/en/docs/http/ngx_http_perl_module.html

Eine andere Möglichkeit besteht darin, eine Art Fast-CGI-Setup zu verwenden, zu dem Sie die Anforderungen umleiten, wobei Ihr Fast-CGI-Skript wiederum Anforderungen an das Backend und anschließend die endgültige Verarbeitung vor der Rückkehr ausführt Die Antworten werden an nginx zurückgegeben, um sie zwischenzuspeichern und an den Benutzer zurückzugeben.

Es gibt auch proxy_set_body(aber noch keine fastcgi_set_body) Möglichkeiten, den Hauptteil der Anfrage zu ändern (z. B. von dem, was der Client angegeben hat), aber es scheint keine äquivalente Anweisung oder Variable zu geben, um den Hauptteil der Antwort zu erhalten, um zu bestehen zu einer irgendwie nachfolgenden Anfrage an einen Postprozessor. In jedem Fall ist ein Filtermodul wahrscheinlich das, was Sie für einen Postprozessor wünschen.

(Sie wissen auch, dass ein naiver Ansatz, forkAntworten durch eine reguläre Führungskraft zu geben und zu leiten, besonders langsam sein wird, oder?)

Zusammenfassend denke ich, dass gzip on;es genau das ist, wonach Sie suchen. Andernfalls können Sie, sofern Sie die ursprüngliche Webanwendung ändern können, am besten eine Art Postprozessor in der Webanwendung selbst installieren, was insgesamt als die nächst einfachere Lösung erscheint. Möglicherweise können Sie untersuchen, wie die Filtermodule implementiert sind, z. B. das oben erwähnte ngx_http_addition_filter_module.c sowie einige offensichtlich relevantere Filter wie ngx_http_gzip_filter_module.c, und Ihr eigenes eingebettetes Filtermodul implementieren. Oder beauftragen Sie Nginx, Inc., dies für Sie zu schreiben! Aber im Ernst, gzip on;funktioniert einfach und liefert wahrscheinlich viel bessere Ergebnisse ohne Probleme, Leistung oder Stabilitätsprobleme. Es ist bereits standardmäßig kompiliert. Sie müssen es nur aktivierennginx.conf.

cnst
quelle
Danke für deine Antwort! Ich bin mir bewusst, dass gzip aktiviert ist, und was ich erreichen möchte, ist ein höheres Niveau als das Entleeren der Ausgabe. Ich habe einen Proxy, der den Zugriff auf bestimmte interne Webdienste steuert, und ich wollte in der Lage sein, Dinge wie Google Analytics an die Ausgabe anzuhängen, ähnlich wie Cloudflare dies tut. Wie Sie sagen, es klingt so, als wäre Fastcgi eine Option, also werde ich das untersuchen. Danke noch einmal!
Thatjuan
Wenn Sie nur Inhalte anhängen oder Google Analytics hinzufügen möchten, ist add_after_bodyoder sub_filtergenau das, was Sie benötigen. Das Beispiel unter nginx.org/en/docs/http/ngx_http_sub_module.html zeigt genau dieses Szenario: Ersetzen von "</ head>" durch "</ head> <script ...". Möglicherweise müssen nginx -VSie nginx neu kompilieren, um diese Module zu aktivieren (überprüfen Sie, wie Ihr nginx kompiliert wurde), aber ansonsten handelt es sich bereits um Standardmodule.
cnst
Schauen Sie sich auch das Modul subs_filter an .
Franzlorenzon