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

9

J'ai une configuration nginx qui reçoit les demandes des hôtes externes et les envoie par proxy à 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, je voudrais pouvoir exécuter ce avec quoi l'hôte interne a répondu via un binaire arbitraire et répondre avec ce que le binaire répond.

Par exemple , si je voulais réduire le format html sur le proxy, j'exécuterais la réponse du serveur via htmlcompressor, puis j'enverrais la sortie en tant que réponse du proxy au client. Le résultat final serait que le client final récupère du code HTML minifié.

Je sais qu'il existe toutes sortes d'addons et d'exemples pour nginx pour accomplir cela pour les données servies localement, mais comment le configurer pour un proxy?

0x6A75616E
la source
Juste pour clarifier. Vous souhaitez que nginx transfère la demande au serveur mandaté, reçoive une réponse, la compresse, 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 dans n'importe quel programme arbitraire et utilisez la sortie comme ce qui est envoyé au client. Donc, essentiellement, oui, je veux modifier la sortie allant du serveur au client.
0x6A75616E

Réponses:

10

Donc, vous voulez nginxproxy une demande du client au serveur principal, puis, avant de renvoyer la réponse du backend au client, redirigez cette réponse via un autre processeur externe?

Je ne pense pas que vous puissiez faire ce qui précède avec les nginxmodules officiels fournis par Igor Sysoev et Nginx, Inc actuellement. La chose la plus proche disponible pour modifier le corps de la réponse est quelques modules de filtrage qui viennent avec nginx, mais sont désactivés par défaut, y compris les directives add_before_body, add_after_bodyet sub_filter:

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

Aussi, 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 perlet êtes prêt à exécuter un module entièrement expérimental, jetez un œil à l'intégration perldans nginx, avec un module nginx officiel qui est désactivé par défaut et est (quelque peu é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, où, à son tour, votre script Fast-CGI fera des demandes au backend, puis au traitement final, avant de retourner les réponses sont retournées à nginx pour être mises en cache et renvoyées à l'utilisateur.

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

(De plus, vous vous rendez compte qu'une approche naïve de forkréponses et de réponses via un exécutif régulier va être extrêmement lente, non?)

Pour résumer , je pense que gzip on;c'est exactement ce que vous recherchez; Sinon, à condition que vous puissiez modifier la webapp d'origine, je pense que votre meilleur pari pourrait être d'installer une sorte de post-processeur dans la webapp elle-même, ce qui semblerait être la prochaine solution la plus simple dans l'ensemble. Potentiellement, vous pouvez examiner la façon dont les modules de filtrage sont mis en œuvre, par exemple le ngx_http_addition_filter_module.c susmentionné, ainsi que des filtres plus évidents comme ngx_http_gzip_filter_module.c, et implémenter votre propre module de filtre intégré. Ou embauchez Nginx, Inc. pour écrire ceci pour vous! Mais, sérieusement, cela gzip on;fonctionne et est susceptible de vous donner de bien meilleurs résultats sans problèmes, performances ou stabilité, et il est déjà compilé par défaut, il vous suffit de l'activer dansnginx.conf.

cnst
la source
Merci pour votre réponse! Je connais gzip on et ce que j'essaie d'accomplir est plus haut que dégonfler la sortie. J'ai un proxy qui contrôle l'accès à certains services Web internes et je voulais pouvoir ajouter des choses comme 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!
0x6A75616E
Si vous souhaitez simplement ajouter des éléments ou ajouter des analyses Google, alors add_after_bodyou sub_filterc'est exactement ce dont vous avez besoin. L'exemple sur 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 afin d'activer ces modules (vérifiez nginx -Vcomment votre nginx a été compilé), mais ce sont déjà des modules standard sinon.
2013
Jetez également un œil au module subs_filter .
franzlorenzon