Nginx reverse proxy with code injection
Using nginx as a reverse proxy is very easy to do and there are many guides on the internet on this topic. However there’s not a lot of content regarding modifying proxied data on-the-fly. Here’s how to do it
There are many reasons why you’d want to modify page content on your reverse proxy/load balancer. Maybe you want to insert your analytics script or even do some templating.
We’ll be using the ngx_http_sub_module
nginx module (link to official documentation), which should be available by default in most builds. If you are compiling nginx on your own, you have to manually enable it by adding --with-http_sub_module
to your compile arguments, as it’s not a default option. You can check if your installation includes this module by running nginx -V
Enough preface, let’s get to the code:
location / {
proxy_set_header Accept-Encoding "";
proxy_pass http://backend;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_set_header Connection "Keep-Alive";
proxy_set_header Proxy-Connection "Keep-Alive";
sub_filter '</head>' '<script src="https://example.com/injected.js"></script></head>';
sub_filter_once on;
}
This location block will accept requests and pass them to an upstream called backend
. It will then search for string </head>
in the responses and if it finds a match, it will replace it with the string <script src="https://example.com/injected.js"></script></head>
sub_filter_once on
basically means that if the filter finds multiple occurrences of </head>
in our response, it will replace just the first one. For replacement of all occurrences just set the value to off
By default sub_filter
modifies just content with text/html
mime-type. This is important to ensure it doesn’t try to perform substitution on files such as images or executables. For adding multiple mime-types use the sub_filter_types
directive.
Copied from: https://blog.fhrnet.eu/2017/09/20/nginx-reverse-proxy-with-code-injection/