POST response body empty on NGINX server - node.js

I am running a Node.js application on a NGINX server with an SSL certificate. I just realized that all of my POST/PUT requests that the application attempts to return to the front end are empty; essentially the response is an empty string. The application works fine in a local environment as well as Heroku, with all images and GET requests resolving as they should.
I am expecting JSON to come back in my HTTP responses, whether the request was successful or had errors. Right now I am getting an empty string. Below is a screenshot of my response, you will notice that the Content Length header is completely missing.
Screenshot of my headers
Essentially, is there something wrong with my NGINX proxy that is preventing my HTTP responses to come back blank?
Below is my NGINX configuration file
server {
listen 80;
server_name blah.com;
rewrite ^/(.*) https://blah.com/$1 permanent;
}
server {
# SSL configuration
#
listen 443 ssl default_server;
ssl_certificate XXX;
ssl_certificate_key XXX;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
root /var/www/html;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name blah.com;
location / {
proxy_pass http://127.0.0.1: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;
}
}
Bellow are the access logs that application is generating:
24.123.110.242 - - [27/Jul/2017:21:10:45 +0000] "POST /sign-up HTTP/1.1" 400 5 "https://app.quiqmath.com/sign-up" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36"
24.123.110.242 - - [27/Jul/2017:21:10:47 +0000] "POST /socket.io/?__sails_io_sdk_version=0.11.0&__sails_io_sdk_platform=browser&__sails_io_sdk_language=javascript&EIO=3&transport=polling&t=Ls5upja&sid=4mrvSlNzMv9ZCetHAAAL HTTP/1.1" 502 182 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.1.2 Safari/603.3.8"
24.123.110.242 - - [27/Jul/2017:21:10:47 +0000] "GET /socket.io/?__sails_io_sdk_version=0.11.0&__sails_io_sdk_platform=browser&__sails_io_sdk_language=javascript&EIO=3&transport=polling&t=Ls5ujej&sid=4mrvSlNzMv9ZCetHAAAL HTTP/1.1" 200 4 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.1.2 Safari/603.3.8"
24.123.110.242 - - [27/Jul/2017:21:10:48 +0000] "GET /socket.io/?__sails_io_sdk_version=0.11.0&__sails_io_sdk_platform=browser&__sails_io_sdk_language=javascript&EIO=3&transport=polling&t=Ls5upzL HTTP/1.1" 200 101 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.1.2 Safari/603.3.8"
24.123.110.242 - - [27/Jul/2017:21:10:49 +0000] "GET /socket.io/?__sails_io_sdk_version=0.11.0&__sails_io_sdk_platform=browser&__sails_io_sdk_language=javascript&EIO=3&transport=polling&t=Ls5up_l&sid=XSl8MUuC7TH6v4iLAAAM HTTP/1.1" 200 5 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.1.2 Safari/603.3.8"

In Sails.js applications that have a version that are greater than 0.11.X and less than 1.0, the res.badRequest() response strips the data out of the response when the application is in production mode. To fix this, either upgrade the Sails.js application to 1.X and the documentation can be found here on how to do it, or you can comment out the following line in the api/responses/badRequest.js file:
// Only include errors in response if application environment
// is not set to 'production'. In production, we shouldn't
// send back any identifying information about errors.
if (sails.config.environment === 'production') {
//data = undefined;
}

Related

Nodejs Nginx 502 Bad Gateway

I have set up my server on Digital Ocean and running it on port: 3000 using pm2. when I curl to my server in the do it responds correctly.
curl http://localhost:3000/
This is my nginx configuration.
server {
listen 80;
#root /var/www/html;
# Add index.php to the list if you are using PHP
#index index.html index.htm index.nginx-debian.html;
server_name api.skreem.co;
access_log /var/log/nginx/api.skreem.access.log;
error_log /var/log/nginx/api.skreem.error.log;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://localhost:3000;
proxy_set_header Host $http_host;
proxy_cache_bypass $http_upgrade;
proxy_redirect off;
}
}
I am getting logs on my Nginx access and error logs as follows
#access_log
106.51.111.247 - - [20/Mar/2020:09:27:34 +0000] "GET /favicon.ico HTTP/1.1" 502 584 "http://api.skreem.co/api/v2/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/
537.36"
#error_log
2020/03/20 09:27:34 [error] 1651#1651: *121 connect() failed (111: Connection refused) while connecting to upstream, client: 106.51.111.247, server: api.skreem.co, request: "GET /favicon.ico HTTP/1.1", upstream: "ht
tp://127.0.0.1:3000/favicon.ico", host: "api.skreem.co", referrer: "http://api.skreem.co/api/v2/"
On my Pm2 monitor I am not getting any Logs. I have rechecked the proxy_pass but still not able to get nginx to pass it on to the nodejs server.
Am getting
502 Bad Gateway error

Nginx Security Configuration

I am kind of new to the configuration for the Nginx as a proxy for an internal web service, which is needed to be forwarded using SSL connections.
The setup currently involves to serve an internal web-application which is currently running on a public cloud infrastructure.
Below is my nginx configuration:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name www.somedomain.com;
# Refer:
# https://www.nginx.com/blog/http-strict-transport-security-hsts-and-nginx/
# Discourage deep links by using a permanent redirect to home page of HTTPS site
return 301 https://$server_name;
}
server {
# User Defined
listen 443 ssl http2;
# SSL Certificate Paths
ssl_certificate /home/secured/ssl/certs/mycustomapp.cert;
ssl_certificate_key /home/secured/ssl/private/mycustomapp.key;
# Nginx Access and Error Logs
access_log /var/log/nginx/mycustomapp.access.log;
error_log /var/log/nginx/mycustomapp.error.log;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
# User Defined
server_name www.somedomain.com;
# HSTS header for always https option
add_header Strict-Transport-Security "max-age=36000; includeSubDomains" always;
add_header X-Frame-Options "DENY";
location / {
# User Defined
include /etc/nginx/proxy_params;
proxy_pass http://localhost:9090;
proxy_read_timeout 90s;
proxy_redirect http://localhost:9090 https://$server_name;
}
}
Where I have generated a self-signed certificates for the server:mycustomapp.cert and corresponding key in: mycustomapp.key, and the local service/application is running on http://localhost:9090 and is not running on global access port 0.0.0.0:9090.
Here is the snippet of access.log available at this location /var/log/nginx/.
106.51.17.223 - - [23/Dec/2018:17:51:22 +0000] "GET / HTTP/1.1" 301 194 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36"
47.75.165.214 - - [23/Dec/2018:18:16:47 +0000] "PROPFIND / HTTP/1.1" 301 194 "-" "-"
47.75.165.214 - - [23/Dec/2018:18:16:47 +0000] "GET /webdav/ HTTP/1.1" 301 194 "-" "Mozilla/5.0"
47.75.165.214 - - [23/Dec/2018:18:16:47 +0000] "GET /help.php HTTP/1.1" 301 194 "-" "Mozilla/5.0 (Windows NT 5.2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0"
47.75.165.214 - - [23/Dec/2018:18:16:48 +0000] "GET /java.php HTTP/1.1" 301 194 "-" "Mozilla/5.0 (Windows NT 5.2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0"
47.75.165.214 - - [23/Dec/2018:18:16:58 +0000] "POST /wuwu11.php HTTP/1.1" 301 194 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)"
47.75.165.214 - - [23/Dec/2018:18:16:58 +0000] "POST /xw.php HTTP/1.1" 301 194 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)"
47.75.165.214 - - [23/Dec/2018:18:16:59 +0000] "POST /xw1.php HTTP/1.1" 301 194 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)"
47.75.165.214 - - [23/Dec/2018:18:16:59 +0000] "POST /9678.php HTTP/1.1" 301 194 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)"
I have also observed some malformed requests in both the access.log and mycustomapp.access.log(not replicated here).
Is the configuration enough for delaying/thwarting these penetration attack attempts or is there a redundant configuration which is exposing a channel which currently I am unable to comprehend?
Currently I am enabling the service when someone requires an access, but going forward it is not a suitable scenario when more and more people start using the application.
This configuration is enough as usual. For more security watch this list:
https://github.com/nbs-system/naxsi
Use this to opimize SSL performance.
Read about server_tokens and disable it.
Read about error_page and use your own pages.

Nginx: proxy_pass + websocket + basic authentication + Safari = endless loop in access log

Safari (Desktop & iOS)
Meteor web application protected by nginx basic authentication.
I see the following access log records in an endless loop when I visit the app on Safari. Chrome works as expected. No record appears in nginx error logs. My guess is that for some reason the user/password auth does not work and the request gets redirected in a loop, causing new sockets / sockjs connections to be opened.
The application does not produce any output, a white screen of death is shown.
144.MY.IP.ADDR - - [25/Sep/2018:17:48:06 -0400] "GET /sockjs/958/msx234wb/websocket HTTP/1.1" 401 195 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Safari/605.1.15"
144.MY.IP.ADDR - username [25/Sep/2018:17:48:06 -0400] "POST /sockjs/656/mgln1mi5/xhr_send HTTP/1.1" 204 0 "https://my.site.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Safari/605.1.15"
144.MY.IP.ADDR - username [25/Sep/2018:17:48:06 -0400] "POST /sockjs/958/x9wngcy3/xhr HTTP/1.1" 200 12 "https://my.site.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Safari/605.1.15"
144.MY.IP.ADDR - username [25/Sep/2018:17:48:06 -0400] "POST /sockjs/958/x9wngcy3/xhr_send HTTP/1.1" 204 0 "https://my.site.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Safari/605.1.15"
144.MY.IP.ADDR - username [25/Sep/2018:17:48:06 -0400] "GET /sockjs/info?cb=35tsuy5ber HTTP/1.1" 200 90 "https://my.site.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Safari/605.1.15"
144.MY.IP.ADDR - username [25/Sep/2018:17:48:06 -0400] "POST /sockjs/958/x9wngcy3/xhr_send HTTP/1.1" 204 0 "https://my.site.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Safari/605.1.15"
Here is my nginx configuration:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
listen 443 ssl http2;
server_name my.site.com;
ssl_certificate /etc/letsencrypt/live/my.site.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/my.site.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
add_header Strict-Transport-Security "max-age=31557600; includeSubDomains";
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Xss-Protection "1";
ssl_stapling on;
ssl_stapling_verify on;
root html; # irrelevant
index index.html; # irrelevant
location / {
# forward http to https
if ($scheme = http) {
return 301 https://$server_name$request_uri;
}
proxy_pass http://localhost:8080;
proxy_redirect off;
proxy_intercept_errors on;
proxy_http_version 1.1; # recommended with keepalive connections - http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_http_version
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host; # pass the host header - http://wiki.nginx.org/HttpProxyModule#proxy_pass
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto http;
proxy_set_header X-Forwarded-Host $host:$server_port;
proxy_set_header X-Forwarded-For $remote_addr; # preserve client IP
proxy_set_header X-Nginx-Proxy true;
auth_basic "Restricted Access"; # auth realm
auth_basic_user_file .htpasswd-users; # htpasswd file
# the root path (/) MUST NOT be cached
if ($uri != '/') {
expires 30d;
}
}
}
I have no idea why this happens where Chrome works as expected and safari does not.
Here is the solution. Saved by the magic proxy_read_timeout line:
location / {
auth_basic "Restricted Access"; # auth realm
auth_basic_user_file .htpasswd-users-paco; # htpasswd file
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_pass "http://127.0.0.1:SOME_PORT";
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 86400;
# the root path (/) MUST NOT be cached
if ($uri != '/') {
expires 30d;
}
}
nginx
proxy_hide_header Upgrade;
Apache
Header unset Upgrade
https://megamorf.gitlab.io/2019/08/27/safari-nsposixerrordomain-100-error-with-nginx-and-apache/

Nginx upstream as url

I'm trying to use a domain with ur as proxy_pass as below:
set $full_uri "http://domian.com/resize$remote_uri";
proxy_pass $full_uri;
Now nginx is sending the request of the IP of the domain and it's inaccessible through the IP so all requests fail.
How can i force nginx to send request to the domain itself not to the IP?
Nginx access_log:
109.xxx.xxx.xxx - JOR - [21/Feb/2016:19:59:27 +0000] GET /1000x900/images/pic1.jpg HTTP/1.1 "504" 578 domain.com "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.109 Safari/537.36" "109.xxx.xxx.xxx" upstream_response_time 30.001 upstream_addr xxx.xxx.xxx.xxx:80 msec 1456084767.428 request_time 30.002
Thanks
Use proxy_set_header. This should be enough:
proxy_pass "http://domian.com/resize/";
proxy_set_header Host domian.com;

How to resolve 504 Gateway Timeout and WebSockets errors with Nginx and Express app

When I run my express app locally, there are no issues whatsoever, but since I've placed it on an AWS EC2 instance running an Nginx web server, there are a few problems whenever I visit the designated domain.
Whenever I go to the domain, it displays a 504 Gateway Timeout for the main.css file that is being served from the public directory. Not sure if it's relevant, but I am using Jade templates with Express, and sass files are being compiled at runtime to the public/css directory.
Here's the request headers:
GET /css/main.css HTTP/1.1
Host: dispatch.nucleus.technology
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Accept: text/css,/;q=0.1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36
DNT: 1
Referer: http://dispatch.nucleus.technology/
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
There also seems to be a websocket error:
WebSocket connection to 'ws://dispatch.nucleus.technology/socket.io/?EIO=3&transport=websocket&sid=W0qJNlmaVdFbKoeBAAAA' failed: Error during WebSocket handshake: Unexpected response code: 400
I've since fixed the css problem, and it seems that running the app as root solves it, but I'm not sure why - if anyone has some insight regarding that it would be very helpful.
As for the websocket error, I'm still receiving that despite running the app as root.
Adding this to the nginx config should get rid of the websocket error:
location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
...

Resources