Изменение данных, передаваемых через nginx на лету

9

У меня есть установка nginx, которая получает запросы от внешних хостов и передает их на внутренний сервер.

Конфиг выглядит примерно так:

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

Для экспериментальных целей / целей тестирования я хотел бы иметь возможность запускать то, на что отвечал внутренний хост, через произвольный двоичный файл и отвечать тем, чем отвечает двоичный файл.

К примеру , если бы я хотел преуменьшать HTML на прокси я бы запустить ответ сервера через htmlcompressor , а затем направить вывод в ответ прокси-сервера к клиенту. Конечным результатом будет конечный клиент, получающий минимизированный HTML обратно.

Я знаю, что есть все виды дополнений и примеров для nginx, чтобы выполнить это для локально обслуживаемых данных, но как настроить его для прокси?

0x6A75616E
источник
Просто для уточнения. Вы хотите, чтобы nginx перенаправил запрос на прокси-сервер, получил ответ обратно, сжал его, а затем направил его пользователю? Вы хотите, чтобы nginx обрабатывал его в середине сервера и пользователя?
sjdaws
@sjdaws, не обязательно сжимать его, но запустить его через любую произвольную программу и использовать вывод как то, что отправляется клиенту. В сущности, да, я хочу изменить вывод с сервера на клиент.
0x6A75616E

Ответы:

10

Итак, вы хотите nginxпередать запрос от клиента на внутренний сервер, а затем, перед возвратом ответа внутреннего компонента клиенту, передать такой ответ через другой внешний процессор?

Я не думаю, что вы можете сделать вышеупомянутое с какими-либо официальными nginxмодулями, предоставленными Igor Sysoev и Nginx, Inc в настоящее время. Ближе всего , что доступно для изменения тела ответа является несколько фильтрующих модулей , которые приходят вместе с Nginx, но по умолчанию отключены, в том числе add_before_body, add_after_bodyи sub_filterдирективы:

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

Кроме того, возможно, gzip on;это то, что вы на самом деле хотите вместо этого?

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

Или, возможно, если вы знаете perlи готовы запустить полностью экспериментальный модуль, взглянуть на вложение perlв nginx, с официальным модулем Nginx , который выключен по умолчанию и является (несколько очевидно) полностью экспериментальным:

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

Другой вариант - использовать какую-то настройку Fast-CGI, на которую вы будете перенаправлять запросы, где, в свою очередь, ваш скрипт Fast-CGI будет выполнять запросы к бэкэнду, а затем выполнять окончательную обработку перед возвратом. ответы возвращаются в nginx для кэширования и возврата пользователю.

Существует также proxy_set_body(но fastcgi_set_bodyпока нет ) изменение тела запроса (например, из того, что предоставил клиент), но, похоже, не существует какой-либо эквивалентной директивы или переменной для получения тела ответа для передачи как-то последующий запрос к постпроцессору. В любом случае, модуль фильтра - это то, что вам нужно для постпроцессора.

(Кроме того, вы понимаете, что наивный подход forkк получению ответов от обычного руководителя будет очень медленным, верно?)

Подводя итог , я думаю, gzip on;это именно то, что вы ищете; иначе, при условии, что вы можете изменить исходное веб-приложение, я думаю, что вам лучше всего установить какой-то постпроцессор внутри самого веб-приложения, что в целом выглядит как следующее простое решение. Потенциально вы можете посмотреть, как реализованы модули фильтров , например, вышеупомянутый ngx_http_addition_filter_module.c, а также некоторые более важные фильтры, такие как ngx_http_gzip_filter_module.c, и реализовать свой собственный встроенный модуль фильтра. Или нанять Nginx, Inc., чтобы написать это для вас! Но, если серьезно, gzip on;просто работает, и, вероятно, даст вам гораздо лучшие результаты без каких-либо хлопот, проблем с производительностью или стабильностью, и он уже скомпилирован по умолчанию, вам просто нужно включить его вnginx.conf,

CNST
источник
Спасибо за ответ! Я знаю о gzip, и то, что я пытаюсь сделать, это более высокий уровень, чем дефлирование вывода. У меня есть прокси-сервер, который контролирует доступ к определенным внутренним веб-службам, и я хотел иметь возможность добавлять в вывод такие вещи, как аналитика Google, что-то вроде того, как это делает cloudflare. Как вы говорите, похоже, что fastcgi - это вариант, так что я рассмотрю это. Еще раз спасибо!
0x6A75616E
Если вы просто хотите добавить материал или добавить аналитику Google, тогда add_after_bodyили sub_filterэто именно то, что вам нужно. Пример на nginx.org/en/docs/http/ngx_http_sub_module.html показывает именно этот сценарий: замена «</ head>» на «</ head> <script…». Возможно, вам придется перекомпилировать nginx, чтобы включить эти модули (проверьте, nginx -Vкак был скомпилирован ваш nginx), но в противном случае они уже являются стандартными модулями.
CNST
Посмотрите также на модуль subs_filter .
franzlorenzon