Nginx reverse proxy problem on an specified location - reactjs

I wanted to access one of the react projects as the following instruction.
https://my.domain.com/app1 ==> HTTP://localhost:7001
The following is the Nginx config:
server {
listen 80;
server_name my.domain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/my.domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/my.domain.com/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
server_name my.domain.com;
error_log /var/log/nginx/my.domain.com.err;
access_log /var/log/nginx/my.domain.com.log;
location /app1 {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
add_header Pragma "no-cache";
add_header Cache-Control "no-cache";
proxy_pass http://localhost:7001/;
proxy_redirect default;
sub_filter_types *;
sub_filter 'action="/' 'action="/app1/';
sub_filter 'href="/' 'href="/app1/';
sub_filter 'src="/' 'src="/app1/';
sub_filter_once off;
}
}
The problem is that some of the source files responded by https://my.domain.com/app1/... but some responded by https://my.domain.com/..., there for the second one is not accessible and gives HTTP 404 error.
For example, the following sources have been responded as HTTP 200:
https://my.domain.com/app1/static/css/main.091g2s3f.chunk.css
https://my.domain.com/app1/static/js/2.29c551h6.chunk.js
And the following is responded as HTTP 404:
https://my.domain.com/media/contact-title.png
https://my.domain.com/static/media/Yekan.05744gh2.woff
https://my.domain.com/logo.svg
Any idea?
Thanks in advance.
What I did and not solved:
I did configure the Nginx rewrite, simple proxy_pass and regex but the problem not solved, in addition, I got all the responses as HTTP 404.

You are only forwarding /app1 to upstream, if u want to forward media and static etc, then you need to change the following
location /app1
to
location /
OR if you are serving them as static files, add the following
location /static {
root /path/to/your/static/path;
}
then you can call all your static files from example.com/static/something.css

Related

How to call an hls server in a react app that is using https

So, I have a react app that is built and run through a nodejs server. This nodejs server is run with nginx which handles the cert. This react/nodejs server also is running a RTMP server this RTMP server is running an hls server.
So, basically the website has certs and runs over https://. I need to know what approach to take to call the hls server to display a stream on the website. The problem is that the package I am using "node-media-server" doesn't make it obvious how to convert the http to https and so when I cam calling the url from the react app I get a "(blocked:mixed-content)" error. when i am calling the .m3u8 file. So the react app will call the url "http://website.com/live/stream/index.m3u8". Do I need to convert this hls stream to https? If so how do I do this? maybe I need to change my nginx config?
Below is my nginx configuration.
upstream socketio {
# ip_hash;
server 127.0.0.1:8174;
}
upstream reactserve {
server 127.0.0.1:3000;
}
upstream hls {
server 127.0.0.1:8179;
}
#server {
# listen 80;
# server_name www.idealgambler.com;
# rewrite ^(.*) https://$host$1 permanent;
#}
server {
listen 443 ssl;
ssl on;
server_name idealgambler.com www.idealgambler.com;
access_log /var/log/nginx/access-ssl.log;
error_log /var/log/nginx/error-ssl.log;
location / {
# include proxy_params;
proxy_pass http://socketio;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_redirect off;
proxy_buffering off;
proxy_set_header Host $host;
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 Access-Control-Allow-Origin *;
add_header Front-End-Https on;
add_header Access-Control-Allow-Origin *;
}
location /socket.io/ {
proxy_pass http://socketio;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Origin *;
}
location /hls {
proxy_pass http://hls;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Origin *;
}
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/idealgambler.com-0001/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/idealgambler.com-0001/privkey.pem; # managed by Certbot
}
Here is the NodeMediaServer code in nodejs:
require("./Casino/CasinoRouters/client-connected")(app, io);
const NodeMediaServer = require("node-media-server");
const config = {
rtmp: {
port: 1935,
chunk_size: 60000,
gop_cache: true,
ping: 60,
ping_timeout: 30,
},
http: {
port: 8179,
mediaroot: "./media",
allow_origin: "*",
},
log_file: "./logs/nms.log",
trans: {
ffmpeg: process.env.FFMPEG_PATH,
tasks: [
{
app: "live",
hls: true,
hlsFlags: "[hls_time=2:hls_list_size=3:hls_flags=delete_segments]",
hlsKeep: true, // to prevent hls file delete after end the stream
dash: true,
dashFlags: "[f=dash:window_size=3:extra_window_size=5]",
dashKeep: true, // to prevent dash file delete after end the stream
},
],
},
};
var nms = new NodeMediaServer(config);
nms.run();
So I have tried to update the nginx file, as well as changing the config for the nodemediaserver to https. The problem with changing http to https in the config is that the key "mediaroot" does not exist in https of nodemediaserver. The error I get is that it can't find the file "./media" when changing it to https in the express app. So basically the https hls will not run only http will run. perhaps there is a different config for running it through https.
I have tried adding the hls to the nginx configuration, but I don't think this did anything.
Ideally you should try to fix the URL and make it match the scheme of application (i.e. never mix http:// with https://) or make the app detect and correct it if the URL comes from an external source.
If it's not doable you might try to fall back to inserting Content-Security-Policy: upgrade-insecure-requests in the HTTP response headers. This would make the browser automatically convert all http:// to https:// as if the latter was originally requested by the app. You seem to have control over the deployment so this can be accomplished within Nginx configuration. Alternatively the header can be added to HTML head, as shown in this answer.
Watch out for WebSockets too. Secure ones (wss://) may require Sec-WebSocket-* headers to be passed by the proxy as per RFC6455. Nginx doesn't do it by default. You will probably want to add the following lines to the configuration:
location /socket.io/ {
# ...
# pass client-to-server Sec-WebSocket-* headers
proxy_set_header Sec-WebSocket-Key $http_sec_websocket_key;
proxy_set_header Sec-WebSocket-Version $http_sec_websocket_version;
proxy_set_header Sec-WebSocket-Extensions $http_sec_websocket_extensions;
proxy_set_header Sec-WebSocket-Protocol $http_sec_websocket_protocol;
}

Request from front end to backend is interupt

I have api (have use load balance). when I send requests from front-end to back-end, then back-end intermittent receive these requests. This request is show "pending" and the end show:
*"Access to XMLHttpRequest at 'https://frontend.domain.com' from origin 'https://backend.domain.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The 'Access-Control-Allow-Origin' header contains multiple values 'https://backend.domain, ', but only one is allowed."
Although, I have already opened cors in back-end. Below is file config nginx of front-end domain.
config nginx
server {
if ($host = frontend.domain.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = frontend.domain.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
access_log off;
server_name frontend.domain.com;
client_max_body_size 20M;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name frontend.domain.com
client_max_body_size 20M;
ssl off;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
proxy_pass http://0.0.0.0:3000;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_method GET;
proxy_connect_timeout 6000;
proxy_send_timeout 6000;
proxy_read_timeout 6000;
send_timeout 6000;
client_max_body_size 20M;
}
ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem; # managed by Certbot
}
And addition before I no have, suddenly after I restart the server I have this error.
Any tip to this error goes away. Thanks.

Express API backend receiving requests but not responding, Nginx

I have a front end reactjs being served by nginx. shown here:
server {
listen 80 default_server;
server_name website.* www.website.*;
root /home/developer/website/frontend/build;
location / {
try_files $uri /index.html;
}
location /api {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:4000;
}
}
Additionally, I have a second express app receiving requests at 127.0.0.1:4000. The front end calls fetch to 'api/something' and the express app receives that and handles it but does not respond, the client side errors with 504 (Gateway Time-out). Any ideas?
You are missing the upstream server directive. Try this
upstream api {
server 127.0.0.1:4000;
}
# remove www from the url
server {
listen 80;
server_name www.website.com;
return 301 $scheme://website.com$request_uri;
}
server {
listen 0.0.0.0:80;
server_name website.com website;
error_log /var/log/nginx/website.com-error.log error;
access_log /var/log/nginx/website.log;
# pass the request to the node.js server with the correct headers
location /api/ {
proxy_pass http://api/;
proxy_ignore_headers X-Accel-Expires Expires Cache-Control;
proxy_ignore_headers Set-Cookie;
proxy_hide_header Set-Cookie;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-NginX-Proxy true;
}
}

Nginx setup for angular app with node API

I have been building API using express and front end using angular. Both are in different directory named /var/www/apps/client and /var/www/apps/server.
I want to deploy my application using nginx as a webserver. I am able to host angular application but when trying to request my API getting following error on browser.
Mixed Content: The page at 'https://xxx.xxx.xxx.xxx/' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://xxx.xxx.xxx.xxx:3000/api/videos'. This request has been blocked; the content must be served over HTTPS.
Nginx config
server {
listen 80;
server_name localhost;
access_log /var/log/client/access.log;
error_log /var/log/client/error.log;
root /var/www/apps/client/dist;
charset utf-8;
location / {
rewrite ^ https://$host$request_uri? permanent;
}
}
server {
listen 443 ssl;
server_name localhost;
access_log /var/log/client/access.log;
error_log /var/log/client/error.log;
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;
keepalive_timeout 5;
root /var/www/apps/client/dist;
charset utf-8;
location ~ ^/(scripts.*js|styles|images) {
gzip_static on;
expires 1y;
add_header Cache-Control public;
add_header ETag "";
break;
}
location / {
try_files $uri /index.html;
}
}
My express server code -
var express = require("express"),
app = express(),
mongoose = require("mongoose"),
config = require("./config");
app.set("appPath", config.root);
mongoose.connect(config.mongo.uri, config.mongo.options);
app.use(function (req, res, next) {
"use strict";
// Website you wish to allow to connect
res.setHeader("Access-Control-Allow-Origin", "*");
// Request methods you wish to allow
res.setHeader("Access-Control-Allow-Methods",
"GET, POST, OPTIONS, PUT, PATCH, DELETE");
// Request headers you wish to allow
res.setHeader("Access-Control-Allow-Headers",
"X-Requested-With,content-type,api_key,adminid,userid");
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader("Access-Control-Allow-Credentials", true);
// Pass to next layer of middleware
next();
});
app.use(function (req, res, next) {
"use strict";
next();
});
require("./routes")(app);
app.listen(config.port);
console.log("Listening on port " + config.port)
Serving API at 3000 port. I found this If possible use nginx to redirect by location to node app?
But this is also not working. Any kind of help would be great.
I don't think, the issue is completely with your nginx config. The error message implies that the initial connection from the browser and nginx server was over https. And then you are trying to make an insecure connection through XMLHttpRequest with http.
Solution:
Either load up the initial connection as insecure i.e http
Or make your XMLHttpRequest with a secure connection i.e https.
To help with the config file
# For http
server {
listen 80
server_name localhost
access_log /var/log/client/access.log
error_log /var/log/client/error.log
root /var/www/apps/client/dist
charset utf-8
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://localhost:3000/;
}
}
# For https
server {
listen 443 ssl
server_name localhost
access_log /var/log/client/access.log
error_log /var/log/client/error.log
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;
root /var/www/apps/client/dist
charset utf-8
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://localhost:3000/;
}
}
Restart Nginx
sudo /etc/init.d/nginx restart
Issue is the other endpoint which you are hitting internally is not Https protected, because of which you are getting the error
http://xxx.xxx.xxx.xxx:3000/api/videos
So, you should write a separate config for client to make the connection https secured. Add that proxy pass also to redirect all your request coming to port 443 to 3000 similar what you did for server
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://localhost:3000/;
}
Make sure ports are different for node and client app

How to set nginx reverse proxy at localhost

I attempt to do reverse proxy to resolve the cross-domain issue, and I have done my nginx.config file like below:
server {
listen 8080;
root <here is my project url>;
index index.html;
server_name localhost;
location ^~ /api/ {
rewrite ^/api/(.x) /$1 break;
proxy_pass http://www.example.com:80/;
proxy_redirect off;
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-NginX-Proxy true;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
and actually the localhost was setup successful.
But I still cannot get the token inside response headers from server api and also cannot add customer headers inside request headers, I try to call http get request to local data.json and the customer was added...
sorry for every one, I want to present my situation and I'm not good at english, hope every one can get me! Thank you!!
You might have to set headers with Authorizaiton which has the token.
proxy_set_header Authorization $http_authorization;

Resources