Rewrite WebSocket messages via Nginx? - nginx

Is it possible to rewrite the content of a websocket message proxied through Nginx?
For example, say I've sent a message with the contents JSON.stringify({ auth: 'someIdKey' }). On Nginx, I would to substitute the value of someIdKey to someJwt, then forward it to the proxied upstream resource. I'd also want to do the reverse translation when the upstream resource sends out messages back to the client.
I know how to do this (and am doing this) for HTTP requests, rewriting custom headers to do an on-the-fly translation, but I'm not sure how to approach carrying over the pattern to websocket communication.
I'm using OpenResty as my Nginx distribution and am passably-ok at Lua scripting.
Would appreciate any ideas/help.

You can use https://github.com/openresty/lua-resty-websocket module.
It has both server and client side non-blocking API. So you can program anything you want.

Related

NGINX Forwarding a request

I have an NGINX Server set up, I'd like to take a request and forward it to another application on a TCP port.
Let's say I have the following JSON payload
{
"someKey1": 1234,
"someKey2": "a string"
}
This is sent inside query parameters like the following
https://mywebsite.com?payload=%7B%0A%20%22someKey1%22%3A%201234%2C%0A%20%22someKey2%22%3A%20%22a%20string%22%0A%7D
Is there a way to forward that JSON payload to TCP port 1234 natively with NGINX?
Additionally, can I do any pre-processing of the above payload prior to it being forwarded to TCP port 1234. For example, I'd like to covert the above JSON to
someKey1=1234,someKey2="a string"
And then forward this data to TCP port 1234
I understang I'd have to create some sort of REST endpoint using something like springboot to do this, but I'd really like to try and accomplish the above natively with NGINX if possible.
Nginx's primary purpose is HTTP server/proxy.
It can be scripted via ngx_http_lua_module, but for your task it is much simpler to make an app/microservice that will listen HTTP and forward your custom protocol, or modify your app that listens mentioned port to understand HTTP.
When your endpoint talks HTTP - nginx can then be used for routing:
location /some_path/ {
proxy_pass http://localhost:1234/;
}
location /some_other_path/ {
proxy_pass http://localhost:1235/;
}
NGINX is simple web-server, which accepts HTTP requests and forwards them to configured location (may be application server, or any other web-server), and responds back on HTTP to the requester. Data can't be processed inside NGINX.
You can configure forwarding rules in default file under sites-available directory in NGINX installation directory.
Here is the nice tutorial of NGINX configuration which might help you.

Nginx - Reacting to Upstream Response

I am using nginx as reverse proxy for file storage upload with an external provider.
When I am processing a file upload, I need to keep track (in my database) whether an upload was successful before returning the response to the user. I would therefore like to use the ngx.location.capture method provided in the lua-nginx-module to talk to my backend about the outcome of the request. Since I need to wait for the response of the upstream server I can only issue the capture in header_filter_by_lua. Unluckily I cannot issue any outwards communication in header_filter_by_lua. ngx.location.capture, ngx.socket.* and ngx.exec are only available when the response has not yet arrived.
How can I react to an upstream response in nginx?
Other approaches I've thought about:
Have a script watch the access log and then issue a curl request. (Seems like there should be an easier way)
Initially send the file via ngx.location.capture in content_by_lua (I don't think this would handle up to 5 GB filesize)
Help is appreciated :)
use for /upload location:
content_by_lua_file with resty.upload module

HTTP on a HTTPS Website

I was just wondering this small little question. I know it is irreverent to coding, but I just had to know quickly.
If you type in http:// for a https:// will it still take you to the correct place?
That is mostly dependent on the server configuration. The server has to accept the initial HTTP request and be configured to redirect the client to an appropriate HTTPS url.
That being said, there are some Internet standards related to automating HTTP-to-HTTPS upgrades. HTTP Strict Transport Security and Upgrade Insecure Requests allow an HTTP/S server to tell clients that it wants them to automatically use HTTPS for all subsequent requests. If a client visits an HSTS/UIR-enabled server, it will receive a normal HTTP response with additional HSTS/UIR-related headers. If the client supports HSTS/UIR, it will then know to automatically send all subsequent HTTP requests to that same server using HTTPS, and in the case of UIR also treat any received HTTP URLs as if they were HTTPS URLs.

HTTP connect with Transparent proxy

I am trying to write (and understand) a transparent proxy.
My setup would look like this
Client Browser ---> TProxy ----> Upstream Proxy ------> cloud
When the client browser makes a GET request, the idea is TProxy would then CONNECT to the Upstream proxy. The upstream proxy requires digest authentication. So, essentially the flow would look like
Client Browser ---> TProxy --------> Upstream Proxy ---------------> cloud
GET BBC.co.uk
CONNECT
407 PROXY AUTH REQUIRED
CONNECT
(with proxy-authorization)
200 OK
GET BBC.co.uk
I am confused what happens once CONNECT with authorization succeeds.
Am I suppose to modify the original GET request now to include a
Proxy-Authorization header?
or would the original GET request be then tunnelled in another http header something like
HTTP Header
Proxy Authorization
HTTP Header (GET BBC.CO.UK)
Data
or I can just pass the original GET request as is?
I am just starting with http and would appreciate any help.
Thanks
When you authenticate upstream from your transparent proxy, the Proxy-Authorization header applies only to the CONNECT.
The GET requests happen within the tunnel, so the upstream explicit proxy is not supposed to see them, and for sure does not expect any proxy authentication headers on them.
In short, you do not need to worry about the GET, but not because of the answer given above, but because there is a tunnel between the transparent proxy and the site, and the explicit proxy only sees and authenticates the CONNECT.
There is no such thing as nested headers in HTTP.
A proxy - whether transparent or not - always terminates the HTTP connection from the client, and initiates a new one to the server.
That means that the HTTP GET from the client goes to your TProxy. TProxy creates a new GET request to Upstream Proxy. Ideally, TProxy will simply pass on all the headers. That would make it (nearly) undetectable.
The same goes in reverse for the response headers.
In reality, proxy servers will, and in many cases have to, manipulate some headers. They will often add their own header (for instance, to alert the communication partners to the presence of a proxy), and they can also manipulate existing headers.
So, the short answer to your question: whatever header field your TProxy receives, pass it on unchanged unless you fully understand the implications.

Connect to external HTTP server from Netty

I need some help with understanding how to write HTTP router, which recognizes HTTP header as routing criteria. I found the link https://github.com/cgbystrom/netty-tools/blob/master/src/main/java/se/cgbystrom/netty/http/router/RouterHandler.java which seems to do the routing itself. But now it is not clear, how to
connect to another HTTP server
send HTTP request
wait for HTTP response
forward the HTTP response to client
can somebody please give me some explanations?
http://static.netty.io/3.5/xref/org/jboss/netty/example/proxy/package-summary.html
the example of proxy server in Netty, essentially what I wanted

Resources