Deploy UrlShortner to prodction - express

I am trying to create a urlshortner which would redirect the user to an external url.
I am using node express + nginx to host it.
My express routing is very simple and is as below:
router.get('/:code', async (req, res) => {
fetch code from db
return res.redirect(longUrl)
}
and my nginx conf looks like:
server {
listen 443 ssl;
listen [::]:443 ssl;
ssl_certificate /etc/ssl/cert/ssl.pem;
ssl_certificate_key /etc/ssl/cert/ssl.pem;
server_name {server_name};
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "keep-alive";
}
}
This works well over http without nginx but when I introduce proxy using nginx it starts to redirect me to https://localhost/longUrl rather than https://longUrl
I also tried https module without nginx and I got the same result.
Any suggestions would be great, thanks.

Related

Expressjs + Peerjs + nginx : Unable to connect to Peerjs server

I am working on building videoapp using expressjs, peerjs. I am getting the below error while connecting to peerjs server. The app is running behind a proxy server (nginx). The code works fine in my local machine (I am not using proxy server while testing in my local).
`GET https://<servername>/peerjs/id?ts=16228299262200.9619575641336071 404 (Not Found)`
I am getting the result when I do "https://<servername>/peerjs". I assume the I am able to connect to peerjs server. I do not understand why I am getting the above error.
{"name":"PeerJS Server","description":"A server side element to broker
connections between PeerJS clients.","website":"https://peerjs.com/"}
I am combining peerjs along expressjs
const ExpressPeerServer = require('peer').ExpressPeerServer;
const peerServer = ExpressPeerServer(server, {
debug: true,
proxied:true,
});
app.use('/peerjs', peerServer);
Client side code
let myPeer = new Peer({host :'servername',secure:true})
Below is the configuration for nginx
server {
server_name <server_name>;
location / {
proxy_pass http://localhost:3000;
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;
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/<server_name>/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/<server_name>/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
}
server {
if ($host = <server_name>) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name <server_name>;
return 404; # managed by Certbot
}
PS: I am new to nodejs and nginx. I feel I am missing something very basic that I am not able to figure it out.
Hi in your nginx config file add /peerjs in proxy_pass . So your location block should look something like
location / {
proxy_pass http://localhost:3000/peerjs;
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;
}

Configuration issues trying to get 2 apps to work on nginx

I'm trying to deploy a Vue app with a Strapi backend on nginx.
I created 2 files in sites-available, and symlinks in sites-enabled.
I also got an ssl-cert from let’s encrypt.
When I visit the domain, I see nothing in the browser, and have a 304 and some 404 errors in the network tab. When I visit domain.com/admin, I see a strapi splashscreen, but not the login form that I need.
When I go directly to the ip, I see the frontend app, and when I visit :1337/admin, I see the backend. Any idea what I’m doing wrong here?
Thanks
my frontend.conf looks like this
server {
# Listen HTTP
listen 80;
server_name companynamefront.com;
# Redirect HTTP to HTTPS
return 301 https://$host$request_uri;
}
server {
# Listen HTTPS
listen 443 ssl;
server_name companynamefront.com;
# SSL config
ssl_certificate /etc/letsencrypt/live/new.companyname.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/new.companyname.com/privkey.pem;
# Static Root
location / {
root /var/www/html/companyname/v-frontend/dist;
}
}
and the backend.conf looks like this
server {
# Listen HTTP
listen 80;
server_name companyname.com;
# Redirect HTTP to HTTPS
return 301 https://$host$request_uri;
}
server {
# Listen HTTPS
listen 443 ssl;
server_name companyname.com;
# SSL config
ssl_certificate /etc/letsencrypt/live/new.companyname.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/new.companyname.com/privkey.pem;
# Static Root
location / {
root /var/www/html/companyname/backend/build;
}
# Strapi API and Admin
location /admin/ {
rewrite ^/admin/(.*)$ /$1 break;
proxy_pass http://localhost:1337;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $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 Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_pass_request_headers on;
}
}

Configuring SSL with Nginx

Now this might be a very simple issue but I can't seem to figure out how get SSL to work with Nginx. I will list what I have done so far:
Used certbot to create a fullchain.pem and privkey.pem file
Added the following code to /etc/nginx/conf.d/pubgstats.info
server {
listen 80;
server_name pubgstats.info www.pubgstats.info;
location '/.well-known/acme-challenge' {
root /srv/www/pubg-stats;
}
location / {
proxy_pass http://localhost:4200;
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 /secure {
auth_pam "Secure zone";
auth_pam_service_name "nginx";
}
}
server {
listen 443;
ssl on;
ssl_certificate /srv/www/pubg-stats/certs/fullchain.pem;
ssl_certificate_key /srv/www/pubg-stats/certs/privkey.pem;
server_name pubgstats.info www.pubgstats.info;
location / {
root /srv/www/pubg-stats/;
}
}
From what I understand, the configuration listens on port 80 and upgrades a HTTP request to HTTPS. The code was mostly taken from this article. I added the SSL part of the configuration as stated here. Now visiting the site over HTTP works. On HTTPS, the connection is reset. What am I missing in the configuration and what's the best way to configure SSL with Nginx in this case?
I don't understand why you didn't add this to /etc/nginx/nginx.conf, but the issue appears to be that you've declared multiple server blocks for the same server. In that case, nqinx will usually choose the first depending on different criteria.
With this configuration, nginx will use SSL by default. If that is not what you want, remove default_server. You don't need ssl on as that is now obsolete and replaced with the ssl parameter in the listen directive.
server {
listen 80;
listen 443 default_server ssl;
ssl_certificate /srv/www/pubg-stats/certs/fullchain.pem;
ssl_certificate_key /srv/www/pubg-stats/certs/privkey.pem;
server_name pubgstats.info www.pubgstats.info;
location '/.well-known/acme-challenge' {
root /srv/www/pubg-stats;
}
location / {
proxy_pass http://localhost:4200;
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 /secure {
auth_pam "Secure zone";
auth_pam_service_name "nginx";
}
}

nginx+socket.io+ssl: WebSocket connection to 'ws://wechat.pageguy.tech/socket.io/?EIO=3&transport=websocket' failed: Unexpected response code: 302

I want to configure an node.js project using socket.io through nginx with ssl,But I failed,when I start it an error occours like this:
I spent a whole noon search and read documents but still can not figure out how to solve this..If anyone meet this problem before or have any idea about it please help me,thanks a lot.
This is my client side js code:
let socket = io.connect('//wechat.pageguy.tech/ws', {transports: ['websocket']});
This is nginx code:
server {
listen 443;
server_name wechat.pageguy.tech;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Real-IP $remote_addr;
#charset koi8-r;
#access_log /var/log/nginx/log/host.access.log main;
ssl on;
ssl_certificate /etc/ssl/private/pageguy.crt;
ssl_certificate_key /etc/ssl/private/pageguy.key.unsecure;
location / {
#root /usr/share/nginx/html;
#index index.html index.htm;
proxy_pass http://localhost:3335;
}
location /ws/ {
proxy_pass http://localhost:3005;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 86400;
}
}
My express port is 3335,my socket.io port is 3005.Everything were fine before I added ssl in the nginx configuration file.
Nobody help me 555, but I solved problems by myself.
in client side js code:
let socket = io.connect('https//wechat.pageguy.tech/', {transports: ['websocket']});
in nginx configure file:
location /socket.io/(not /ws/ because its default value)

How to redirect on the same port from http to https with nginx reverse proxy

I use reverse proxy with Nginx and I want to force the request into HTTPS, so if a user wants to access the url with http, he will be automatically redirected to HTTPS.
I'm also using a non-standard port.
Here is my nginx reverse proxy config:
server {
listen 8001 ssl;
ssl_certificate /home/xxx/server.crt;
ssl_certificate_key /home/xxx/server.key;
location / {
proxy_pass https://localhost:8000;
proxy_redirect off;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Ssl on;
proxy_set_header X-Forwarded-Proto https;
}
}
I've tried many things and also read posts about it, including this serverfault question, but nothing has worked so far.
Found something that is working well :
server {
listen 8001 ssl;
ssl_certificate /home/xxx/server.crt;
ssl_certificate_key /home/xxx/server.key;
error_page 497 301 =307 https://$host:$server_port$request_uri;
location /{
proxy_pass http://localhost:8000;
proxy_redirect off;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Ssl on;
}
}
Are you sure your solution is working? It is listening for 8001 ssl. Will it accept http request?
I do it this way:
server {
listen 80;
server_name yourhostname.com;
location / {
rewrite ^(.*) https://yourhostname.com:8001$1 permanent;
}
}
Then goes your config:
server {
listen 8001 ssl;
ssl_certificate /home/xxx/server.crt;
ssl_certificate_key /home/xxx/server.key;
location / {
proxy_pass https://localhost:8000;
proxy_redirect off;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Ssl on;
proxy_set_header X-Forwarded-Proto https;
}
}
This worked for me:
server {
listen 80;
server_name localhost;
...
if ($http_x_forwarded_proto = "http") {
return 301 https://$server_name$request_uri;
}
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;
}
...
}
You can
use $server_name to avoid hard coding your domain name again (DRY),
use return 301 for a bit easier reading (a web dev should know this http status code)
Note: I put 443 for https server. You may listen to 8001 if you really want that.
server {
listen 80;
server_name your_hostname.com;
return 301 https://$server_name$request_uri;
}
...
server {
listen 443 ssl;
server_name your_hostname.com
...
}
This is my approach, which I think is quite clean and allows you to add further locations if needed. I add a test on the $http_x_forwarded_proto property which if true forces all HTTP traffic to HTTPS on a NGINX Reverse Proxy setup
upstream flask_bootstrap {
server flask-bootstrap:8000;
}
server {
# SSL traffic terminates on the Load Balancer so we only need to listen on port 80
listen 80;
# Set reverse proxy
location / {
proxy_pass http://flask_bootstrap;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect http://localhost/;
# Permanently redirect any http calls to https
if ($http_x_forwarded_proto != 'https') {
return 301 https://$host$request_uri;
}
}
}