Modifique los datos que nginx representa por proxy sobre la marcha

9

Tengo una configuración nginx que recibe solicitudes de hosts externos y las envía a un servidor interno.

La configuración se parece a esto:

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 fines experimentales / de prueba, me gustaría poder ejecutar lo que respondió el host interno a través de un binario arbitrario y responder con lo que responde el binario.

Por ejemplo , si quisiera minimizar html en el proxy, ejecutaría la respuesta del servidor a través de htmlcompressor y luego enviaría la salida como la respuesta del proxy al cliente. El resultado final sería que el cliente final recuperara el html minimizado.

Sé que hay todo tipo de complementos y ejemplos para que nginx logre esto para los datos servidos localmente, pero ¿cómo configurarlo para un proxy?

0x6A75616E
fuente
Solo para aclarar. ¿Desea que nginx reenvíe la solicitud al servidor proxy, reciba una respuesta, la comprima y luego la reenvíe al usuario? ¿Desea que nginx lo procese en el medio del servidor y el usuario?
sjdaws
@sjdaws, no necesariamente lo comprime, pero ejecútelo a través de cualquier programa arbitrario y use la salida como lo que se envía al cliente. Entonces, en esencia sí, quiero modificar la salida que va del servidor al cliente.
0x6A75616E

Respuestas:

10

Entonces, ¿desea nginxenviar una solicitud del cliente al servidor de fondo y luego, antes de devolver la respuesta del cliente al cliente, canalizar dicha respuesta a través de otro procesador externo?

No creo que pueda hacer lo anterior con ningún nginxmódulo oficial tal como lo proporcionan actualmente Igor Sysoev y Nginx, Inc. Lo más parecido que está disponible para alterar el cuerpo de la respuesta es de unos módulos de filtro que se unen con Nginx, pero están desactivados por defecto, incluyendo el add_before_body, add_after_bodyy sub_filterdirectivas:

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

Además, ¿ quizás gzip on;es lo que realmente quieres en su lugar?

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

O, potencialmente, si sabe perly está dispuesto a ejecutar un módulo totalmente experimental, echar un vistazo a la incorporación perlen nginx, con un módulo oficial nginx que está desactivada por defecto y es (algo obvio) totalmente experimental:

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

Otra opción es utilizar algún tipo de configuración Fast-CGI a la que redirigirá las solicitudes, donde, a su vez, su secuencia de comandos Fast-CGI realizará solicitudes al back-end y luego al procesamiento final, antes de regresar las respuestas vuelven a nginx a la memoria caché y vuelven al usuario.

También hay proxy_set_body(pero fastcgi_set_bodyaún no ), para cambiar el cuerpo de la solicitud (por ejemplo, de lo que ha proporcionado el cliente), pero no parece haber ninguna directiva o variable equivalente para obtener el cuerpo de la respuesta, para pasar a una solicitud posterior de alguna manera a un postprocesador. En cualquier caso, un módulo de filtro es probablemente lo que desea para un postprocesador.

(Además, te das cuenta de que un enfoque ingenuo de forkresponder y canalizar las respuestas a través de un ejecutivo regular será muy lento, ¿verdad?)

Para resumir , creo que gzip on;es exactamente lo que estás buscando; de lo contrario, siempre que pueda modificar la aplicación web original, creo que su mejor opción podría ser instalar algún tipo de postprocesador dentro de la aplicación web, que parece ser la próxima solución más fácil en general. Potencialmente, podría analizar cómo se implementan los módulos de filtro , por ejemplo, el ngx_http_addition_filter_module.c mencionado anteriormente, además de algunos filtros obviamente más relevantes como ngx_http_gzip_filter_module.c e implementar su propio módulo de filtro incorporado. ¡O contrate a Nginx, Inc. para que escriba esto para usted! Pero, en serio, gzip on;simplemente funciona, y es probable que le brinde resultados mucho mejores sin problemas, problemas de rendimiento o estabilidad, y ya está compilado de forma predeterminada, solo tiene que habilitarlo ennginx.conf.

cnst
fuente
¡Gracias por su respuesta! Soy consciente de gzip y lo que intento lograr es un nivel más alto que desinflar la salida. Tengo un proxy que controla el acceso a ciertos servicios web internos y quería poder agregar cosas como Google Analytics a la salida, algo así como Cloudflare lo hace. Como usted dice, parece que fastcgi es una opción, así que lo investigaré. ¡Gracias de nuevo!
0x6A75616E
Si solo desea agregar cosas o agregar Google Analytics, entonces add_after_bodyo sub_filteres exactamente lo que necesita. El ejemplo en nginx.org/en/docs/http/ngx_http_sub_module.html muestra exactamente ese escenario: reemplazando "</head>" con "</head> <script ...". Es posible que deba volver a compilar nginx para habilitar esos módulos (verifique nginx -Vcómo se compiló su nginx), pero de lo contrario ya son módulos estándar.
cnst
Eche un vistazo al módulo subs_filter también.
franzlorenzon