How to set nginx reverse proxy at localhost - angularjs

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;

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;
}

Problem hosting react app at sub route of website - multiple websites one IP address NGINX

I am new to NGINX so this may be a simple fix, but i cant find any great documentation about what i am trying to do here.
So I have a website which is hosted on an ubuntu aws server by nginx and pm2. my problem is that I want to serve the website at www.mysite.com and the react app at www.mywebsite.com/app. this doesnt seem like it should be the hardest thing to do. However I have been having problems and cannot get it to work as i would like. (part of this is because i also wish to host an API server at www.mywebsite.com/api but that is a problem for after this). I was able to first just host the react app at www.mysite.com with the following nginx config:
server {
listen 80;
server_name 18.191.56.251;
root /home/ubuntu/app/src;
location / {
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_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_max_temp_file_size 0;
proxy_pass http://127.0.0.1:3000/;
proxy_redirect off;
proxy_read_timeout 240s;
}
}
But when i switch it to the sub route by altering the config as so:
server {
listen 80;
server_name x.x.x.x;
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_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_redirect off;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
send_timeout 600;
location /status {
return 200;
}
location /app {
proxy_pass http://127.0.0.1:3000;
}
location / {
proxy_pass http://...:3011/;
}
}
Then my base route www.mywebsite.com for the static website works fine, but www.mywebsite.com/app does not and "loads" a blank page but if you inspect you see that the app is unable to load some resources:
bundle.js:1
Failed to load resource: the server responded with a status of 404 (Not Found)
0.chunk.js:1
Failed to load resource: the server responded with a status of 404 (Not Found)
main.chunk.js:1
Failed to load resource: the server responded with a status of 404 (Not Found)
EDIT more research:
If i examine the request for the resource i see its url is www.mywebsite.com/static/js/XXX.js but the static folder is at ~/app/build/static. is this a nginx or a pm2 problem with hosting the static files?
Any help is appreciated, thanks
So I would still love a different result then this but i figured out a workaround for this, i added the following after location /app:
location /static {
proxy_pass http://127.0.0.1:3000;
}
i dont love this solution because if i end up having static content as part of other projects then it will not work, but somehow all the resources for my website are packaged within the correct proxy at /. so currently it is all working.

Nginx - allow user to hit seperate URIs to reach seperate internal copies of the same React app

----- SECOND ATTEMPT ------
The problem and idea is still the same as below, but this is what I have for NGINX now:
set $QA "http://reactapp-qa:80";
set $DEV "http://reactapp-dev:80";
set $PROD "http://reactapp-prod:80";
location /dev {
rewrite ^/dev(.*)$ /$1 break;
proxy_pass $DEV;
}
location /qa {
rewrite ^/qa(.*)$ /$1 break;
proxy_pass $QA;
}
#reactapp
location / {
rewrite /(.*) /$1 break;
proxy_pass $PROD;
}
My / location works great
The other locations load the header and some page elements from the app but do not trigger react axios api calls like the / location does, so they fail.
I feel like I am much closer, just need to figure out what is happening with the axios calls.
----- ORIGINAL POST ------
PROBLEM SUMMARY
We have a React app in a container and nginx in another container in the host.
The configuration works now but we want to make it work a little differently - we want three seperate copies of the React app in their own containers to be reachable from different addresses - but are having problems understanding what we need to do to make it work.
BACKGROUND
The app is using React/Dotnetcore app in a stack in a host in Rancher 1.6.
I am not a React Developer but can talk to the one who wrote the app Monday! We also inherited Nginx and i've been learning to use it by trial by fire.
CONFIGURATION EXAMPLES
Here is our NGINX location block for our currently functioning configuration. This all works great as outlined in the Actual and Expected Results section below:
set $ReactAppDev_url "http://reactapp-development:80";
set $ReactAppQA_url "http://reactapp-qa:80";
set $ReactAppProd_url "http://reactapp-production:80";
location / {
rewrite /(.*) /$1 break;
proxy_set_header Authorization $http_authorization;
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-Host $server_name;
proxy_set_header X-Forwarded-Proto https;
resolver {{DNS_RESOLVER}} valid=30s;
proxy_pass $ReactAppDev_url;
}
I'm sure what i've tried as a start is probably going about things the wrong way but replacing the / location blocks with /production was my first attempt. I don't really think I understand how it all fits together despite reading a handful of articles and nginx official docs about the rewrite module and locations:
set $ReactAppDev_url "http://reactapp-development:80";
set $ReactAppQA_url "http://reactapp-qa:80";
set $ReactAppProd_url "http://reactapp-production:80";
location /production {
rewrite /production/(.*) /$1 break;
proxy_set_header Authorization $http_authorization;
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-Host $server_name;
proxy_set_header X-Forwarded-Proto https;
resolver {{DNS_RESOLVER}} valid=30s;
proxy_pass $ReactAppProd_url;
}
location /dev {...same as above but dev in rewrite and proxy_pass $ReactAppDev_url}
location /qa {...same as above but qa in rewrite and proxy_pass $ReactAppQA_url}
This resulted in the page not working:
[error] 29#29: *5 directory index of "/" is forbidden, client: , server: localhost, request: "GET / HTTP/1.1", host: ""
1/19/2019 8:01:52 PM - - [20/Jan/2019:03:01:52 +0000] "GET / HTTP/1.1" 403 555 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36"
ACTUAL AND EXPECTED RESULTS
Here is what a user does to interact with the site now - this all functions:
User hits https://www.servername.com/ and the React app shows a login page.
User enters login credentials and React app detects identity
If identity is good React app displays https://www.servername.com/request with request data
I am trying to make it so that the user can access one of three uris and be routed to different internal services depending on which uri is hit:
User hits https://www.servername.com/development> location block above functions
User hits https://www.servername.com/qa> location block above functions but proxy_pass directive uses ReactAppQA_url instead
User hits https://www.servername.com/production> location block above functions but proxy_pass directive uses ReactAppProduction_url instead
Each url is a copy of the app just at a different internal rancher service; user enters login credentials, app detects identity
If identity is good app opens www.servername.com/request
I'm not sure if this gets configured in Nginx or if the React app itself would need configuration to enable users to reach /development, /qa, /production.
Would anyone be so kind as to offer any suggestions about how we might be able to configure this?
I ended up dropping URI's as a method of determining which of three 'environments' a user would want to reach and just used ports instead.
That made the configuration much simpler and made it so that I could just have three server blocks - one listening on 443(production), one listening on port 8443(qa) and one listening on port 8444 (development), each directing users to a different container containing the same app.
Here is a stripped down version of the final version:
worker_processes 2;
events {
worker_connections 8096;
multi_accept on;
use epoll;
}
worker_rlimit_nofile 40000;
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on;
tcp_nopush on;
keepalive_timeout 15;
server { #Handles port 443 traffic (Production)
#Setup port and server
listen 443 ssl;
server_name {{SERVER_NAME}};
#omitted SSL and proxy settings
set $ReactApp1_url "http://reactapp1:81";
location / {
rewrite /(.*) /$1 break;
proxy_set_header Authorization $http_authorization;
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-Host $server_name;
proxy_set_header X-Forwarded-Proto https;
resolver {{DNS_RESOLVER}} valid=30s;
add_header X-Environment "production";
proxy_pass $ReactApp1_url;
}
}
server { #Handles port 8444 traffic (Development)
#Setup port and server
listen 8444 ssl;
server_name {{SERVER_NAME}};
#omitted SSL and proxy settings
set $ReactApp2_url "http://reactapp2:80";
location / {
rewrite /(.*) /$1 break;
proxy_set_header Authorization $http_authorization;
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-Host $server_name;
proxy_set_header X-Forwarded-Proto https;
resolver {{DNS_RESOLVER}} valid=30s;
add_header X-Environment "dev";
proxy_pass $ReactApp2_url;
}
}
server { #Handles all port 8443 traffic (QA)
listen 8443 ssl;
server_name {{SERVER_NAME}};
#omitted SSL and proxy settings
set $ReactApp3_url "http://reactapp3:80";
location / {
rewrite /(.*) /$1 break;
proxy_set_header Authorization $http_authorization;
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-Host $server_name;
proxy_set_header X-Forwarded-Proto https;
resolver {{DNS_RESOLVER}} valid=30s;
add_header X-Environment "qa";
proxy_pass $ReactApp3_url;
}
}
}

How to configure NGINX to serve a JSON API and a React.js on the same box

I have been working on JSON API written in Elixir using the phoenix framework, and I successfully deployed yesterday. However, the API is not that useful with out a web frontend, which I wrote one as well using React.js.
I'm deploying the phoenix API using a combination of distillery and gatling, and everything appears to be working when I test it using Postman.
Then I edited the nginx configuration file to loook like the following,
/etc/nginx/sites-available/kegcopr_api
server {
listen 80;
server_name kegcopr.chrisrjones.com;
root /opt/Code/react/kegcopr-frontend/build;
index index.html index.htm;
access_log /home/deploy/deployments/kegcopr_api/nginx.access.log;
error_log /home/deploy/deployments/kegcopr_api/nginx.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 Host $http_host;
proxy_redirect off;
proxy_pass http://localhost:33725;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
I then created a .env file in the root of React.js project with the following line,
REACT_APP_API_URL=http://localhost:33725/api
Any help on how to get this configured would greatly be appreciated.
UPDATE
I changed the .env file to,
REACT_APP_API_URL=http://kegcopr.chrisrjones.com/api
and ran the below command,
npm run build
but I am still not seeing the React.js frontend display in the browser.
You have set the root directory, but you're sending all requests unconditionally to localhost:33725. If you want to serve static files from the root directory and pass all other requests to the proxy_pass, you can use try_files like this:
location / {
try_files $uri #proxy;
}
location #proxy {
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_pass http://localhost:33725;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
try_files will try to locate the file within root with the same name as the URL, and if it fails to find a file, it'll pass the request to #proxy, which will pass it to the Phoenix app running on localhost:33725.

Nginx - configure location regex for all static file in sub alias

I've been trying almost one day with no luck to configure nginx as proxy reverse for apache.
I expect that nginx will serve all static file, and the rest is passed to apache.
It's not hard to achieve this if the site resides on the root domain name.
For example, I've successfully set:
www.mydomain.com
location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml|rss|txt)$ {
root /path/to/mysite;
}
location / {
proxy_pass 127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
now the problem arises as I want to configure site within alias
for example:
www.mydomain.com/site1
Does anybody know how to achieve the same purpose?
I tried below configuration doesn't work:
location /site1 {
location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml|rss|txt)$ {
root /path/to/anothersite1;
}
proxy_pass apache:8080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
the problem is that the 'root' directive doesn't replace the /site1 URI.
For example, a request to
www.mydomain.com/site1/folder/pic.jpg
will be handled by opening file:
/path/to/anothersite1/site1/folder/pic.jpg;
instead of:
/path/to/anothersite1/folder/pic.jpg
I really appreciate any help on this.
I've tried to replace 'root' directive with 'alias' but still no luck.
Thanks beforehand,

Resources