Lost connection to https://... on production setup with grails backend - nginx

I trying to enable websocket on production environment without success.
In dev, locally everything start working after 5 minutes, but on prod with nginx+tomcat+CF I have a problem
Connection closed in a second
Chrome
FireFox
I see problems during connection, but can't fix it.
The setup is:
cloudflare with certificate termination (Tested without proxifying, same result)
nginx on app server
tomcat 8.5
Grails 4.0.13
The setup is very basic:
$(function() {
  var socket = new SockJS("/stomp");
  var client = webstomp.over(socket);
   
  client.connect({}, function() {
  client.subscribe("/topic/hello", function(message) {
  $("#helloDiv").append("ALL:"+message.body);
  });
   
  $("#helloButton").click(function() {
  client.send("/app/hello", JSON.stringify("world"));
  });
  });
java config with one custom line:
#CompileStatic
#Configuration
#EnableWebSocketMessageBroker
class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
#Override
void configureMessageBroker(MessageBrokerRegistry messageBrokerRegistry) {
messageBrokerRegistry.enableSimpleBroker "/queue", "/topic"
messageBrokerRegistry.setApplicationDestinationPrefixes "/app"
}
#Override
void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) {
// ######custom code, to avoid 403 with https
stompEndpointRegistry.addEndpoint("/stomp").setAllowedOrigins("*")
stompEndpointRegistry.addEndpoint("/stomp").setAllowedOrigins("*").withSockJS()
}
#Bean
GrailsSimpAnnotationMethodMessageHandler grailsSimpAnnotationMethodMessageHandler(
SubscribableChannel clientInboundChannel,
MessageChannel clientOutboundChannel,
SimpMessageSendingOperations brokerMessagingTemplate
) {
def handler = new GrailsSimpAnnotationMethodMessageHandler(clientInboundChannel, clientOutboundChannel, brokerMessagingTemplate)
handler.destinationPrefixes = ["/app"]
return handler
}
#Bean
GrailsWebSocketAnnotationMethodMessageHandler grailsWebSocketAnnotationMethodMessageHandler(
SubscribableChannel clientInboundChannel,
MessageChannel clientOutboundChannel,
SimpMessageSendingOperations brokerMessagingTemplate
) {
def handler = new GrailsWebSocketAnnotationMethodMessageHandler(clientInboundChannel, clientOutboundChannel, brokerMessagingTemplate)
handler.destinationPrefixes = ["/app"]
return handler
}
build.gradle
implementation "org.grails.plugins:grails-spring-websocket:2.5.0.RC1"
implementation platform("io.netty:netty-bom:4.1.79.Final")
implementation platform("io.projectreactor:reactor-bom:Californium-SR6")
implementation "io.netty:netty-all"
implementation "io.projectreactor.netty:reactor-netty"
nginx-app
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
....
location /stomp/ {
proxy_pass http://upstr;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 86400;
}
Any ideas in what direction should I dig?
UPDATE
Same thing without https-wss

Related

how to add multiple location blocks for proxy pass in nginx for specific region/URL

I am trying to setup nginx for reverse proxy. But I have to do it for multiple servers which are basically for different regions. I have three regions APAC, Australia, Japan
location /au/myEndPoint1 {
proxy_pass https://AUSTRALIA_SERVER/myEndPoint1 ;
}
location /jp/myEndPoint1 {
proxy_pass https://JAPAN_SERVER/myEndPoint1 ;
}
location /myEndPoint1 {
proxy_pass https://APAC_SERVER/myEndPoint1 ;
}
location /au/myEndPoint2 {
proxy_pass https://AUSTRALIA_SERVER/myEndPoint2 ;
}
location /jp/myEndPoint2 {
proxy_pass https://JAPAN_SERVER/myEndPoint2 ;
}
location /myEndPoint2 {
proxy_pass https://APAC_SERVER/myEndPoint2 ;
}
But when I test this for /au/myEndPoint1, I received request sometimes on location /myEndPoint1 and sometimes on /au/myEndPoint1.

How to specify correctly Nginx reverse proxy configuration for POST /some_endpoint/<product>/<component>/<key> using Regex

How to write properly configuration for Nginx in order to map incoming POST /some_endpoint/product/component/key to the appropriate node?
Product, component, key are different from request to request.
I have tried some variants, no lack.
location /some_endpoint/([0-9A-Za-z]+)$/([0-9A-Za-z]+)$/([0-9A-Za-z]+)$ {
proxy_pass http://first-node:8080/some_endpoint/$1/$2/$3;
}
location /some_endpoint/(~*)$/(~*)$/(~*)$ {
proxy_pass http://first-node:8080/some_endpoint/$1/$2/$3;
}
I have achieved needed behaviour using the following configurations:
location ~/rest-endpoint1/(.*)$ {
proxy_pass http://first-node:8080/rest-endpoint1/$1$is_args$args;
}
location ~/rest-endpoint2/(.*)$ {
proxy_pass http://first-node:8080/rest-endpoint2/$1$is_args$args;
}
location ~/rest-endpoint3/(.*)$ {
proxy_pass http://second-node:8081/rest-endpoint3/$1$is_args$args;
}
location ~/rest-endpoint4/(.*)$ {
proxy_pass http://second-node:8081/rest-endpoint4/$1$is_args$args;
}

how to pass url in request through upstream proxy using Nginx

How to pass our client request through Authorized upstream proxy to specific web address ?
I have to enter username/password to connect an upstream proxy and then open some web page in my browser (for example jj.com) in HTTP and HTTPS protocol (I can set that in Firefox manual proxy options).
So I want make a way to get access for other client to open jj.com whitout need to know and enter username/password and open web page (like jj.com) in her/his browser through NginX.
+--------------------+ +---------------------+
| | | upstramProxy:9090 | +----------+
| Client browser | | user:user-003 |+----->| jj.com |
| | | pass:123456 |<------+----------+
+--------------------+ +---------------------+
| ^ (myProxyService.com:8080/pr?url=jj.com) | ^
| | | |
| | | |
| | +---------------------+
| +--------------------------------| myProxyService.com |
| | NginX in myServer |
+---------------------------------->| Listen to 8080 |
+---------------------+
Is it possible ?
If there is any other approach I want to know.
Simple java web application in witch java send all request through third party proxy named : myProxyServer
public static void processRequest(HttpServletRequest req, HttpServletResponse resp) {
try {
PrintWriter out = resp.getWriter();
System.out.println(req.getRequestURI());
System.out.println(req.getRequestURL());
jjTools.ShowAllParameter(req);
final BasicCredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
new AuthScope("thirdpartyProxy.com", 8080),
new UsernamePasswordCredentials("username", "passss".toCharArray())
);
try (final CloseableHttpClient httpclient = HttpClients.custom()
.setDefaultCredentialsProvider(credsProvider).build()) {
final HttpHost target = new HttpHost("https", "www.targetwebSite.com", 443);
final HttpHost proxy = new HttpHost("http", "thirdpartyProxy.com", 8080);
final RequestConfig config = RequestConfig.custom()
.setProxy(proxy)
.setCircularRedirectsAllowed(true)
.build();
final HttpGet httpget = new HttpGet(req.getRequestURI().replaceFirst("/My_Proxy/", "/"));
httpget.setConfig(config);
System.out.println("Executing request " + httpget.getMethod() + " " + httpget.getUri()
+ " via " + proxy);
try (final CloseableHttpResponse response = httpclient.execute(target, httpget)) {
System.out.println("----------------------------------------");
resp.setContentType(response.getHeader("Content-Type").toString());
System.out.println(response.getHeader("Content-Type").toString());
System.out.println(response.getCode() + " " + response.getReasonPhrase());
out.print(EntityUtils.toString(response.getEntity())+"<scipt>alert");
}
}
out.close();
} catch (Exception ex) {
Logger.getLogger(Listener.class.getName()).log(Level.SEVERE, null, ex);
}
}
Then you have to config nginX.conf like the code below:
server {
listen 80;
server_name targetwebSite.localhost;
location / {
#proxy_set_header X-Forwarded-Host $host;
#proxy_set_header X-Forwarded-Server $host;
#proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://localhost:8080/My_Proxy/;
}
}
And for result it will be working for all page with its CSS and JavaScript files in
http : / / targetwebSite.localhost /
address
note: It have some problem with cookie and accept cookie policies in browser
https://www.tutorialspoint.com/apache_httpclient/apache_httpclient_using_proxy.htm

How to set proxy_http_version dynamically in LUA code before upstreaming the request in nginx

I followed the way suggested in this StackOverflow comment
location / {
content_by_lua_block {
-- some logic here
if flag then
return ngx.exec("#http1_0")
end
return ngx.exec("#http1_1")
}
}
location #http1_0 {
proxy_pass ...;
proxy_http_version 1.0;
...
}
location #http1_1 {
proxy_pass ...;
proxy_http_version 1.1;
...
}
But I am getting the following error:
kong_1 | 2020/11/10 17:19:33 [error] 25#0: 37490 failed to run balancer_by_lua: /usr/local/share/lua/5.1/kong/init.lua:576: attempt to index local 'balancer_data' (a nil value)
kong_1 | stack traceback:
kong_1 | /usr/local/share/lua/5.1/kong/init.lua:576: in function 'balancer'
I want to change the proxy http version in Lua code programmatically. Is there any way?

nginx: read response header in njs subrequest

I'm trying to chain two requests together using nginx's njs module and subrequests. I can see that special_value comes back in the response headers but I don't know how to read the value using proxy_set_header. The code below results in a blank value in X-Special-Value
nginx.conf:
location ~* /step_one {
js_content njs_func;
}
location ~* /step_two {
proxy_pass http://some_other/api;
proxy_set_header X-Special-Value $http_special_val;
}
http.js
function njs_func(r) {
r.headersOut['special_val'] = '42';
r.subrequest('/step_two')
.then(reply => r.return(reply.status, reply.responseBody));
}
you could do something like this:
nginx.conf
set $specialValue "";
location ~* /step_one {
js_content njs_func;
}
location ~* /step_two {
proxy_pass http://some_other/api;
proxy_set_header X-Special-Value $specialValue;
}
https.js
function njs_func(r) {
r.variables.specialValue = '42';
r.subrequest('/step_two')
.then(reply => r.return(reply.status, reply.responseBody));
}

Resources