Modifique os dados que estão sendo procurados pelo nginx em tempo real

9

Eu tenho uma instalação nginx que recebe solicitações de hosts externos e as envia como proxy para um servidor interno.

A configuração é mais ou menos assim:

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

Para fins experimentais / de teste, eu gostaria de poder executar com o que o host interno respondeu através de um binário arbitrário e responder com o que o binário responde.

Por exemplo , se eu quisesse minificar html no proxy, executaria a resposta do servidor através do htmlcompressor e enviaria a saída como resposta do proxy ao cliente. O resultado final seria o cliente final recebendo html reduzido novamente.

Eu sei que existem todos os tipos de complementos e exemplos para o nginx fazer isso para dados fornecidos localmente, mas como configurá-lo para um proxy?

0x6A75616E
fonte
Só para esclarecer. Você deseja que o nginx encaminhe a solicitação ao servidor em proxy, receba uma resposta de volta, comprima-a e encaminhe-a ao usuário? Deseja que o nginx o processe no meio do servidor e do usuário?
sjdaws
@sjdaws, não necessariamente o comprime, mas executa-o através de qualquer programa arbitrário e usa a saída como o que é enviado ao cliente. Então, em essência, sim, quero modificar a saída do servidor para o cliente.
0x6A75616E

Respostas:

10

Portanto, você deseja nginxproxy de uma solicitação do cliente para o servidor de back-end e, antes de retornar a resposta do back-end ao cliente, canalize essa resposta por outro processador externo?

Eu não acho que você possa fazer o acima com qualquer nginxmódulo oficial, conforme fornecido por Igor Sysoev e Nginx, Inc atualmente. A coisa mais próxima disponível para alterar o corpo da resposta é alguns módulos de filtro que se juntam ao nginx, mas são desativados por padrão, incluindo as diretivas add_before_body, add_after_bodye sub_filter:

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

Além disso, talvez gzip on;seja o que você realmente deseja?

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

Ou, potencialmente, se você souber perle estiver disposto a executar um módulo totalmente experimental, observe a incorporação perlem nginx, com um módulo nginx oficial que é desativado por padrão e é (um tanto obviamente) totalmente experimental:

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

Outra opção é usar algum tipo de configuração Fast-CGI para a qual você redirecionará as solicitações, onde, por sua vez, seu script Fast-CGI fará solicitações ao back-end e depois o processamento final antes de retornar as respostas retornam ao nginx para armazenar em cache e retornar ao usuário.

Também há proxy_set_body(mas fastcgi_set_bodyainda não ) para alterar o corpo da solicitação (por exemplo, do que o cliente forneceu), mas não parece haver nenhuma diretiva ou variável equivalente para obter o corpo da resposta, a fim de passar a uma solicitação de alguma forma subsequente para um pós-processador. De qualquer forma, um módulo de filtro é provavelmente o que você deseja para um pós-processador.

(Além disso, você percebe que uma abordagem ingênua de obter forke enviar respostas por meio de um executivo regular será extremamente extra lenta, certo?)

Para resumir , acho que gzip on;é exatamente o que você está procurando; caso contrário, desde que você possa modificar o webapp original, acho que sua melhor aposta pode ser instalar algum tipo de pós-processador dentro do próprio webapp, o que pareceria a próxima solução mais fácil em geral. Potencialmente, você pode examinar como os módulos de filtro são implementados, por exemplo, o mencionado ngx_http_addition_filter_module.c, além de alguns filtros mais obviamente relevantes, como ngx_http_gzip_filter_module.c, e implementar seu próprio módulo de filtro incorporado. Ou contrate a Nginx, Inc. para escrever isso para você! Mas, sério, gzip on;simplesmente funciona e provavelmente fornecerá resultados muito melhores sem problemas, problemas de desempenho ou estabilidade, e já está compilado por padrão, você só precisa habilitá-lo nonginx.conf.

cnst
fonte
Obrigado pela sua resposta! Estou ciente do gzip on e o que estou tentando realizar é um nível mais alto do que esvaziar a saída. Eu tenho um proxy que controla o acesso a determinados serviços da Web internos e queria poder anexar coisas como o Google Analytics à saída, como o cloudflare. Como você diz, parece que o fastcgi é uma opção, então analisarei isso. Obrigado novamente!
0x6A75616E
Se você deseja apenas adicionar coisas ou adicionar o Google Analytics, então add_after_bodyou sub_filteré exatamente o que você precisa. O exemplo em nginx.org/en/docs/http/ngx_http_sub_module.html mostra exatamente esse cenário: substituindo "</head>" por "</head> <script…". Pode ser necessário recompilar o nginx para habilitar esses módulos (verifique nginx -Vcomo o nginx foi compilado), mas eles já são módulos padrão.
CNST
Ter um olhar para subs_filter módulo também.
franzlorenzon 28/01