Nginx Lua ProxyPass

Bipul Kuri
2 min readJan 12, 2021

There was a need to secure content. The content can have links to external which may be http or https ,To be fully security complaint on https and browsers don’t raise red flags. We have to make all http links to https so that the browsers do not complain. Nginx Encoding/Decoding problem

One of the solution was to use NGINX proxy pass. http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass

Nginx has ability to read query param directly by Embedded Variables http://nginx.org/en/docs/http/ngx_http_core_module.html#var_arg_

When doing proxy_pass

events {
worker_connections 1024;
}http
{
server {
# ENABLE 443 and its config when doing actual prod deployment
listen 8081;
location /proxy {
resolver XX.XX.XX.XX;
proxy_pass $arg_source;
}
}
}

This worked for a proxy which is not encoded

A normal url works

curl http://127.0.0.1:8081/proxy?source=https://mediacdn.espssl.com/9850/Shared/Perfumania/Template/perf-ship.jpg

and DECODED source

curl http://127.0.0.1:8081/proxy?source=https%3A%2F%2Fmediacdn.espssl.com%2F9850%2FShared%2FPerfumania%2FTemplate%2Fperf-ship.jpg

does not work. Nginx logs shows, i.e. Nginx is not able to decode during proxy_pass

invalid URL prefix in "https%3A%2F%2Fmediacdn.espssl.com%2F9850%2FShared%2FPerfumania%2FTemplate%2Fperf-ship.jpg", client: 127.0.0.1, server: localhost, request: "GET /?source=https%3A%2F%2Fmediacdn.espssl.com%2F9850%2FShared%2FPerfumania%2FTemplate%2Fperf-ship.jpg HTTP/1.1", host: "127.0.0.1:8081"

SOLUTION:

with OPENRESTY https://openresty.org/en/ lua support use unescape feature https://openresty-reference.readthedocs.io/en/latest/Lua_Nginx_API/#ngxescape_uri

following server configuration

server {
listen 8081;
location /proxy {
resolver XX.XX.XX.xx;
set $proxy "";
rewrite_by_lua_block {
local myu = ngx.var.arg_source ;
ngx.var.proxy = ngx.unescape_uri(myu)
}
proxy_pass $proxy;
}
}

A normal url

curl http://127.0.0.1:8081/proxy?source=https://mediacdn.espssl.com/9850/Shared/Perfumania/Template/perf-ship.jpg

and DECODED source

curl http://127.0.0.1:8081/proxy?source=https%3A%2F%2Fmediacdn.espssl.com%2F9850%2FShared%2FPerfumania%2FTemplate%2Fperf-ship.jpg

both work.

Additional checks can be added in the location to check refrrer host and hmac to reduce abuse.

--

--