Question Modifier les données étant proxy par nginx à la volée


J'ai une configuration nginx qui reçoit les requêtes des hôtes externes et les envoie à un serveur interne.

La configuration ressemble à ceci:

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/;
        }
}

À des fins expérimentales / de test, j'aimerais pouvoir exécuter ce que l'hôte interne a répondu via un binaire arbitraire et répondre avec ce à quoi le binaire répond.

Pour Exemple, si je voulais minimiser html sur le proxy, j’exécutais la réponse du serveur via htmlcompressor, puis envoyais la sortie au client en tant que réponse du proxy. Le résultat final serait que le client final récupère le fichier html minifié.

Je sais qu’il existe toutes sortes d’addons et d’exemples permettant à nginx de le faire pour les données servies localement, mais comment le configurer pour un proxy?


8
2018-02-19 16:40


origine


Juste pour clarifier. Vous souhaitez que nginx transfère la demande au serveur mandaté, reçoive une réponse, la comprime, puis la transmette à l'utilisateur? Vous voulez que nginx le traite au milieu du serveur et de l'utilisateur? - sjdaws
@sjdaws, ne le compressez pas nécessairement, mais exécutez-le via n'importe quel programme et utilisez la sortie comme ce qui est envoyé au client. Donc, essentiellement, oui, je veux modifier la sortie allant du serveur au client. - thatjuan


Réponses:


Alors tu veux nginx adresser une requête du client au serveur principal, puis, avant de renvoyer la réponse du serveur au client, diriger cette réponse vers un autre processeur externe?

Je ne pense pas que vous puissiez faire ce qui précède avec aucun officiel nginx modules tels que fournis par Igor Sysoev et Nginx, Inc. actuellement. La chose la plus proche qui soit disponible pour modifier le corps de la réponse est constituée de quelques modules de filtrage associés à nginx, mais désactivés par défaut, y compris add_before_body, add_after_body et sub_filter directives:

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

Également, peut-être gzip on; est ce que vous voulez réellement à la place?

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

Ou, potentiellement, si vous connaissez perl et êtes prêt à exécuter un module entièrement expérimental, jetez un oeil à l'intégration perl dans nginx, avec un module officiel nginx qui est désactivé par défaut et qui est (assez évidemment) totalement expérimental:

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

Une autre option consiste à utiliser une sorte de configuration Fast-CGI vers laquelle vous redirigerez les demandes. Dans ce cas, votre script Fast-CGI traitera les demandes vers le backend, puis le traitement final, avant de renvoyer les réponses à nginx à mettre en cache et à retourner à l'utilisateur.

Il y a aussi proxy_set_body (mais non fastcgi_set_body encore), pour changer le corps de la requête (par exemple par rapport à ce que le client a fourni), mais il ne semble pas exister de directive ou variable équivalente pour obtenir le corps de la réponse, afin de passer à une requête ultérieure un post-processeur. Dans tous les cas, un module de filtrage est probablement ce que vous voulez pour un post-processeur.

(Vous réalisez également qu’une approche naïve de la forkLes réponses reçues et envoyées par le biais d'un exécutif régulier vont être très lentes, non?)

Pour résumer, Je pense gzip on; est exactement ce que vous recherchez; Dans le cas contraire, à condition que vous puissiez modifier l'application Web d'origine, je pense que votre meilleur choix serait d'installer une sorte de post-processeur dans l'application Web elle-même, ce qui semblerait être la prochaine solution la plus simple. Potentiellement, vous pourriez regarder comment le modules de filtrage sont mis en œuvre, par exemple ngx_http_addition_filter_module.c, ainsi que des filtres plus pertinents, comme ngx_http_gzip_filter_module.c, et implémentez votre propre module de filtrage intégré. Ou engagez Nginx, Inc. pour écrire ceci pour vous! Mais sérieusement, gzip on; Cela fonctionne bien et vous donnera probablement de bien meilleurs résultats sans problèmes, sans problèmes de performances ou de stabilité, et il est déjà compilé par défaut, il vous suffit de l'activer dans. nginx.conf.


10
2018-02-28 21:15



Merci pour votre réponse! Je suis conscient de gzip et ce que j'essaie d'accomplir est de plus haut niveau que de dégonfler la sortie. J'ai un proxy qui contrôle l'accès à certains services Web internes et je voulais pouvoir ajouter des éléments tels que Google Analytics à la sortie, un peu comme la façon dont cloudflare le fait. Comme vous le dites, il semble que fastcgi soit une option, je vais donc examiner cela. Merci encore! - thatjuan
Si vous souhaitez simplement ajouter des éléments ou ajouter Google Analytics, alors add_after_body ou sub_filter est exactement ce dont vous avez besoin. L'exemple à nginx.org/en/docs/http/ngx_http_sub_module.html montre exactement ce scénario: remplacer "</ head>" par "</ head> <script ...". Vous devrez peut-être recompiler nginx pour activer ces modules (cochez nginx -V comment votre nginx a été compilé), mais ce sont déjà des modules standard autrement. - cnst
Jettes un coup d'oeil à subs_filter module aussi. - franzlorenzon


Je pense que si vous voulez exécuter du code arbitraire pour améliorer la sortie de nginx, ... Vous pouvez écrire un script lua.

Cherchez "nginx lua".

(Exemple: http://www.londonlua.org/scripting_nginx_with_lua/slides.html?full#hello-lua)


1
2018-02-14 10:21