How to debug remote Java application through nginx reverse proxy - java

I need to debug a remote java application running behind an nginx reverse proxy.
I get the following error:
Failed to attach to remote debuggee VM. Reason: java.io.IOException: Received invalid handshake
What should be the right nginx configuration to achieve this?
I have successfully attached vscode java debugger to the remote java application by targeting the app's host directly.
Resolver is 127.0.0.11 because I'm using nginx docker image.
My nginx config file app.xyz.com.conf in conf.d:
server {
listen 1043;
resolver 127.0.0.11 valid=30s;
server_name app.xyz.com;
include /etc/nginx/mime.types;
location / {
proxy_buffer_size 8k;
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_set_header X-Real-IP $remote_addr;
set $upstream "http://java-app:1043";
proxy_pass $upstream;
client_max_body_size 10M;
}
}
Thanks in advance!

You should declare tcp port instead http for debug java application.

Related

Nginx proxy-pass to HTTPS Wildfly gives blocked MIME Type message and dont load UI

I have a Nginx proxy pass that redirects to the HTTPS address of my Widlfly deployant.
If I call my URL only via http:// the page loads normally. But if I call the url with https:// I get these messages in the browser developer tool:
Loading the module of
"https://www.planyourplaylist.com/VAADIN/build/vaadin-bundle-b84b24669ab9c1964b96.cache.js"
was blocked due to an unapproved MIME type ("text/html").
Uncaught (in promise) TypeError: ServiceWorker script at https://www.planyourplaylist.com/sw.js for scope https://www.planyourplaylist.com/ encountered an error during installation.
My widlfly.conf for the nginx looks like this:
upstream wildfly {
# List of Widlfly Application Servers
server <ip-adress>;
}
server {
listen 80;
server_name <ip-adress>;
location / {
#return 301 https://<ip-adress>:8443/;
proxy_pass http://<ip-adress>:8080/;
}
location /management {
proxy_pass http://<ip-adress>:9990/management;
}
location /console {
proxy_pass http://<ip-adress>:9990/console;
}
location /logout {
proxy_pass http://<ip-adress>:9990/logout;
}
location /error {
proxy_pass http://<ip-adress>:9990;
}
}
server {
listen 443 ssl ;
server_name <ip-adress>;
ssl_certificate ssl_cert/planyourplaylist_cert.cer;
ssl_certificate_key ssl_cert/planyourplaylist_private.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
# when user requests /
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 https://<ip-adress>:8443/;
}
location ~ \.(css|js|png|gif|jpeg|jpg|swf|ico|woff){
root /opt/wildfly/standalone/deployments/planyourplaylist.war;
expires 360d;
}
}
Thanks for your help. :)
Thanks to #SimonMartinelli for the link to the post.
The problem was actually fixed by including the mime.types file in nginx.
What I unfortunately dont understand is, I had the mime.types file already included but in the nginx.conf file as described in the ofiziellen eyample.
https://www.nginx.com/resources/wiki/start/topics/examples/full/
Therefore the question where is the difference if I include the mime.types file in the nginx.conf file under http{...} or in the widlfly.conf under server{...}.
In my understanding the file should already be included when the nginx.conf file is loaded.
Thanks for your Help. :)

Minio with Nginx and presigned URL

Is it possible do run MinIO not on default path on nginx?
I have a backend that generate presigned url with this code:
MinioClient minioClient = new MinioClient("http://x.x.x.x:9000", "key", "key");
String url = minioClient.presignedGetObject("bucket", "name", 60 * 60 * 24);
where http://x.x.x.x:9000 is the local minio.
It return:
http://x.x.x.x:9000/bucket/name?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=admin%2F20181122%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20181122T072255Z&X-Amz-Expires=184&X-Amz-SignedHeaders=host&X-Amz-Signature=460b9b46f5fac13f29de4372dd7c1e8d6d6c747510761695a40d6b9ff08ba7d8
This link work under VPN as expected, but when i rewrite the url as https://example.com/bucket/name?... to be reached to all users I get signature error.
I have a nginx as reverse proxy and a frontend on default location:
location / {
proxy_pass http://x.x.x.x:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
location /bucket/ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host $http_host;
proxy_connect_timeout 300;
# Default is HTTP/1, keepalive is only enabled in HTTP/1.1
proxy_http_version 1.1;
proxy_set_header Connection "";
chunked_transfer_encoding off;
proxy_pass http://x.x.x.x:9000;
}
The problem is when i rewrite the url it invalidate the signature.
Probably if i run minio for example in https://example.com/minio and then use this link as endpoint to generate the presigned url I will not have problem of signature.
Minio uses the host for the signatures, so when the host changes (x.x.x.x:9000 to example.com), the signed URL becomes invalid. Try this -
proxy_set_header Host 'x.x.x.x:9000';
We use something similar for our Kubernetes ingress.

Unable to remote deploy on Tomcat through Nginx reverse proxy

Installed a tomcat environment on my test server (Fedora 26). Everything is stock package. I've also installed and setup Nginx reverse proxy on the front. tomcat-users.xml is set and I can login to the app manager as expected.
Now, when I try to deploy a WAR to it, I get critical failure on my Nginx log:
2017/09/25 15:12:21 [crit] 13878#0: *36 open() "/var/lib/nginx/tmp/client_body/000000XXXX" failed (13: Permission denied), client: 200.x.x.x, server: some-sandbox.com, request: "POST /manager/html/upload?org.apache.catalina.filters.CSRF_NONCE=XXXXXXXxxxx HTTP/1.1", host: "some-sandbox.com", referrer: "https://some-sandbox.com/manager/html/upload?org.apache.catalina.filters.CSRF_NONCE=XXXXXXXxxxx
Nginx then return 500 internal server to browser.
What could I have get wrong? Any suggestion how to tackle?
Thanks.
Apparently there is some permission issue with the temporary upload folder /var/lib/nginx/tmp. I've made sure that the whole path is owned by the correct system user. But the issue still exists.
So to circumvent the issue, I decided to config Nginx to skip caching the client body at all. For my purpose, there is no practically value to cache before proxying.
Nginx 1.7.11 introduced a new proxy_request_buffering directive. If you set it to off, the buffering would be disabled. And hence any permission issue would not affect the upload.
So my server section has this:
location / {
proxy_request_buffering off;
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://127.0.0.1:8080/;
}
You can check the user privilage on the file for current user.

SSL SpringBoot App Docker container behind Nginx Proxy

I have a Docker container, with spring boot microservice.
Also I have a Docker container, with jwilder/nginx-proxy configured with SSL working fine. The idea is to do a proxy with SSL.
But when i try call spring boot microservice I get next error:
Is necesary to do SSL configuration in the SpringBoot App too ?
Like this ?:
server.port: 443
server.ssl.key-store: keystore.p12
server.ssl.key-store-password: mypassword
server.ssl.keyStoreType: PKCS12
server.ssl.keyAlias: tomcat
Default.conf Nginx file (Autogenerated by Nginx Docker image).
# If we receive X-Forwarded-Proto, pass it through; otherwise, pass along the
# scheme used to connect to this server
map $http_x_forwarded_proto $proxy_x_forwarded_proto {
default $http_x_forwarded_proto;
'' $scheme;
}
# If we receive X-Forwarded-Port, pass it through; otherwise, pass along the
# server port the client connected to
map $http_x_forwarded_port $proxy_x_forwarded_port {
default $http_x_forwarded_port;
'' $server_port;
}
# If we receive Upgrade, set Connection to "upgrade"; otherwise, delete any
# Connection header that may have been passed to this server
map $http_upgrade $proxy_connection {
default upgrade;
'' close;
}
# Apply fix for very long server names
server_names_hash_bucket_size 128;
# Default dhparam
ssl_dhparam /etc/nginx/dhparam/dhparam.pem;
# Set appropriate X-Forwarded-Ssl header
map $scheme $proxy_x_forwarded_ssl {
default off;
https on;
}
gzip_types text/plain text/css application/javascript application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
log_format vhost '$host $remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
access_log off;
resolver 10.12.149.2;
# HTTP 1.1 support
proxy_http_version 1.1;
proxy_buffering off;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $proxy_connection;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
proxy_set_header X-Forwarded-Ssl $proxy_x_forwarded_ssl;
proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port;
# Mitigate httpoxy attack (see README for details)
proxy_set_header Proxy "";
server {
server_name _; # This is just an invalid value which will never trigger on a real hostname.
listen 80;
access_log /var/log/nginx/access.log vhost;
return 503;
}
server {
server_name _; # This is just an invalid value which will never trigger on a real hostname.
listen 443 ssl http2;
access_log /var/log/nginx/access.log vhost;
return 503;
ssl_session_tickets off;
ssl_certificate /etc/nginx/certs/default.crt;
ssl_certificate_key /etc/nginx/certs/default.key;
}
# app.example.com
upstream app.example.com {
## Can be connect with "bridge" network
# crdx_app-test
server 172.18.0.2:80;
}
server {
server_name app.example.com;
listen 80 ;
access_log /var/log/nginx/access.log vhost;
return 301 https://$host$request_uri;
}
server {
server_name app.example.com;
listen 443 ssl http2 ;
access_log /var/log/nginx/access.log vhost;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:!DSS';
ssl_prefer_server_ciphers on;
ssl_session_timeout 5m;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
ssl_certificate /etc/nginx/certs/app.example.com.crt;
ssl_certificate_key /etc/nginx/certs/app.example.com.key;
add_header Strict-Transport-Security "max-age=31536000";
location / {
proxy_pass https://app.example.com;
}
}
I have found the solution and it is very simple.
Both containers, the Nginx and the container of the application, must be under the same network, which should not be the default one.
For example:
Nginx Container
docker run -d -p 80:80 -p 443:443 --network="mynetwork" -v /path/to/certs:/etc/nginx/certs -v /var/run/docker.sock:/tmp/docker.sock:ro jwilder/nginx-proxy:alpine
App Container
docker run -p 8080 --network="mynetwork" -e VIRTUAL_HOST=app.example.com --name ssl_test -d sslapptest
This way SSL works perfectly
Is necessary to do SSL configuration in the SpringBoot App too ?
No. As long as you are sure that the nginx to spring boot network cannot be listened or tampered with by any other party you don't have to enable SSL on your spring boot app.
Then why nginx is giving 503.
I don't know the answer until I see your nginx config. Most likely, your nginx config has some issues. This article may help you to set up nginx reverse proxy with SSL termination.

nginx as a proxy for Websocket to send text messages

I have a websocket service running on vm (remote address port 8090). Using Nginx to proxy the connections. nginx config as follows:
server {
listen 80;
server_name _;
location / {
proxy_pass http://127.0.0.1:8090;
proxy_pass_request_headers on;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
}
From my local host I was able to connect to the websocket using ip as ws://111.11.1.1/websocket
But, when I send a message from my local host or application to the remote websocket websocket.sendTextMessage("Message") I am not able to hit the socket..assuming there is something wrong with my nginx config..
UPDATE: Changed the config for Nginx by adding
http{ server{..location/{...}}}
and when I restart Nginx service, i got an error
nginx emerg http directive is not allowed here in /default.conf:1
nginx: configuration file /nginx.conf test failed
Any suggestions are helpful!
Use the following configs, it might help.
server {
listen 80;
server_name _;
location / {
proxy_pass http://127.0.0.1:8090;
proxy_redirect off;
proxy_pass_request_headers on;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
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;
}
}

Categories