Pass proxy depending on URL prefix - express

I'm new to NginX and I have been trying to figure out how to do the following;
example.com forwards to the express application running on port 3000 with the purpose of serving clients.
dashboard.example.com forwards to the express application running on port 3001 with the purpose of serving administrators.
For this, I have set up the following configuration;
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com dashboard.example.com;
return 302 https://$server_name$request_uri;
}
# dashboard.example.com for administrators.
server {
listen 80;
server_name dashboard.example.com;
location / {
proxy_pass http://localhost:3001;
}
}
# example.com for normal users.
server {
# SSL configuration
listen 443 ssl http2;
listen [::]:443 ssl http2;
ssl_certificate /etc/ssl/cert.pem;
ssl_certificate_key /etc/ssl/key.pem;
server_name example.com www.example.com;
location / {
proxy_pass http://localhost:3000;
}
}
The problem is that dashboard.example.com and example.com (as does www.example.com) all forward to the client server running on port 3000. How can I make dashboard.example.com forward to 3001?

The issue seems to be that you always redirect to https (good job!), but you only listen for SSL traffic (port 443) on the server_name example.com and www.example.com, and have no proxy configuration for ssl on the dashboard. Try something like:
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com dashboard.example.com;
return 302 https://$server_name$request_uri;
}
# dashboard.example.com for administrators.
server {
# SSL configuration
listen 443 ssl http2;
listen [::]:443 ssl http2;
ssl_certificate /etc/ssl/cert.pem;
ssl_certificate_key /etc/ssl/key.pem;
server_name dashboard.example.com;
location / {
proxy_pass http://localhost:3001;
}
}
# example.com for normal users.
server {
# SSL configuration
listen 443 ssl http2;
listen [::]:443 ssl http2;
ssl_certificate /etc/ssl/cert.pem;
ssl_certificate_key /etc/ssl/key.pem;
server_name example.com www.example.com;
location / {
proxy_pass http://localhost:3000;
}
}
Let me know if re-writing the middle block works for you. If the intention is not to have https on the dashboard for administrators, you need to remove dashboard.example.com from line 4 instead.

Related

NGINX reverse proxy for port 8765 with SSL is not working

I have an Nginx server with SSL. And when I use proxy_pass to http://127.0.0.1:8765 with ssl added its giving "This site can’t be reached". Without SSL it was working correctly. If I send a request as http://domain-name:8765 in a web browser it gave the output correctly. Below is my configuration :
server {
server_name domain-name.in;
access_log /var/log/nginx/reverse-access.log;
error_log /var/log/nginx/reverse-error.log;
location / {
proxy_pass http://127.0.0.1:8765;
}
listen [::]:443 ssl; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/domain-name.in/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/domain-name.in/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 = domain-name.in) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name domain-name.in;
return 404; # managed by Certbot
}

NGINX configurations not redirecting non-www to www

I have a NodeJS app running on port 3000 on an Ubuntu 16 server hosted on an AWS EC2 instance. I want NGINX to redirect each of the following addresses to https://www.example.com:
http://example.com
http://www.example.com
https://example.com
To that end, I have configured my /etc/nginx/sites-available/default file as follows:
server {
listen 80;
listen [::]:80;
server_name example.com;
location / {
# Redirect any http requests to https
return 301 https://www.$server_name$request_uri;
}
location ~* \.(?:ico|svg|woff|woff2|ttf|otf|css|js|gif|jpe?g|png)$ {
proxy_pass http://127.0.0.1:3000;
expires 30d;
add_header Pragma public;
add_header Cache-Control "public";
}
}
# Settings for a TLS enabled server
server {
listen 443 ssl http2;
listen [::]:443 ssl;
server_name www.example.com;
ssl_certificate "/etc/letsencrypt/live/example.com/fullchain.pem";
ssl_certificate_key "/etc/letsencrypt/live/example.com/privkey.pem";
# Automatically route HTTP to HTTPS
add_header Strict-Transport-Security "max-age=31536000";
include /etc/nginx/default.d/*.conf;
location / {
proxy_pass http://127.0.0.1:3000;
}
}
However, this only seems to be working partially:
http://example.com -> goes to https://example.com instead of https://www.example.com
http://www.example.com -> goes to https://example.com instead of https://www.example.com
https://example.com -> goes to https://example.com instead of https://www.example.com
https://www.example.com -> works fine
Any suggestions?
You should have a server block for each case which you want to redirect:
server {
listen 80;
listen [::]:80;
server_name example.com;
return 301 https://www.example.com$request_uri;
}
server {
listen 80;
listen [::]:80;
server_name www.example.com;
return 301 https://www.example.com$request_uri;
}
# Settings for a TLS enabled server
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com;
return 301 https://www.example.com$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name www.example.com;
ssl_certificate "/etc/letsencrypt/live/example.com/fullchain.pem";
ssl_certificate_key "/etc/letsencrypt/live/example.com/privkey.pem";
# Automatically route HTTP to HTTPS
add_header Strict-Transport-Security "max-age=31536000";
include /etc/nginx/default.d/*.conf;
location / {
proxy_pass http://127.0.0.1:3000;
}
}

Nginx rewrite http to https and proxy to another port, ERR_TOO_MANY_REDIRECTS error

Trying to use Nginx as a reverse proxy here. This is what I want to achieve:
Redirect example.com and www.example.com to https://example.com.
Proxy the request to another port.
This is the flow: example.com -> Nginx -> Go web server listening on port 5000
It seems that the rewriting is working properly, cause in the browser I get https://example.com, however I am getting this error in the browser:
ERR_TOO_MANY_REDIRECTS
If it matters, my DNS settings are as such:
# - A - 11.XX.XX.XX
www - A - 11.XX.XX.XX
Here is my /etc/nginx/nginx.conf file:
events {
worker_connections 1024;
}
http {
server {
listen 80;
listen [::]:80;
server_name www.example.com example.com;
rewrite ^(.*)$ https://example.com$request_uri permanent;
location / {
proxy_pass http://127.0.0.1:5000;
}
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name www.example.com example.com;
ssl_certificate "/etc/letsencrypt/live/example.com/fullchain.pem";
ssl_certificate_key "/etc/letsencrypt/live/example.com/privkey.pem";
rewrite ^(.*)$ https://example.com$request_uri permanent;
location / {
proxy_pass http://127.0.0.1:5000;
}
}
}
Any help would be appreciated. Networking noob here.
In this server block, just redirect to HTTPS block, no need a location block here:
server {
listen 80;
listen [::]:80;
server_name www.example.com example.com;
return 301 https://example.com$request_uri;
}
No need to add the redirection 443 block as it is already redirected from 80 block. So try the following configuration:
events {
worker_connections 1024;
}
http {
server {
listen 80;
listen [::]:80;
server_name www.example.com example.com;
return 301 https://example.com$request_uri;
location / {
proxy_pass http://127.0.0.1:5000;
}
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name www.example.com example.com;
ssl_certificate "/etc/letsencrypt/live/example.com/fullchain.pem";
ssl_certificate_key "/etc/letsencrypt/live/example.com/privkey.pem";
location / {
proxy_pass http://127.0.0.1:5000;
}
}
}
The other two answers were very helpful in fixing the answer to this question (Redirect loop). There was another bug however, which is that the www was showing up every time even though I redirected to non-www https version.
Here is the updated config that does the following:
Turn www to non-www
Turn http to https
events {
worker_connections 1024;
}
http {
server {
listen 80;
listen [::]:80;
server_name www.example.com example.com;
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name www.example.com;
ssl_certificate "/etc/letsencrypt/live/example.com-0001/fullchain.pem";
ssl_certificate_key "/etc/letsencrypt/live/example.com-0001/privkey.pem";
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name example.com;
ssl_certificate "/etc/letsencrypt/live/example.com-0001/fullchain.pem";
ssl_certificate_key "/etc/letsencrypt/live/example.com-0001/privkey.pem";
location / {
proxy_pass http://127.0.0.1:5000;
}
}
}

Nginx seems to ignore server_name when ssl and http2 is on

I have this nginx configuration:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name www.example.com;
return 301 https://www.example.com$request_uri;
}
server {
listen 443 ssl http2;
server_name www.example.com;
include snippets/ssl-params.conf;
client_max_body_size 5G;
location / {
proxy_pass http://127.0.0.1:8888;
}
}
So http://www.example.com is redirected to https://www.example.com. Problem is, that https://example.com also works and serves proxy pass to port 8888. How can I prevent it to work? I need just version with www to be working. Parameter server_name does not seem to have any effect. I am using "nginx version: nginx/1.10.1".
Unless you explicitly define a default server for port 443, nginx will use the first matching server block to process the request. See this document for details.
The solution is to explicitly define a default server with the desired behaviour, for example:
server {
listen 443 ssl http2 default_server;
return 301 https://www.example.com$request_uri;
include snippets/ssl-params.conf;
}
In fact, you could probably roll it into your port 80 server block, if you delete the server_name directive:
server {
listen 80 default_server;
listen [::]:80 default_server;
listen 443 ssl http2 default_server;
return 301 https://www.example.com$request_uri;
include snippets/ssl-params.conf;
}
server {
listen 443 ssl http2;
server_name www.example.com;
include snippets/ssl-params.conf;
client_max_body_size 5G;
location / {
proxy_pass http://127.0.0.1:8888;
}
}

nginx simple SSL connection

I am new to setup a simple SSL connection using nginx. The code I wrote below is accessible but it is not running with SSL. What am I missing?
My test site is just a simple index.html. My certificate and key is saved in /etc/ssl/certs.
server {
listen 80;
server_name example.com;
location / {
proxy_pass https://example.com:443;
}
}
server {
listen 443;
root /home/deploy/test;
ssl on;
ssl_certificate /etc/ssl/certs/server.crt;
ssl_certificate_key /etc/ssl/certs/server.key;
}
You have to redirect non-HTTPS to HTTPS, not proxy pass.
server {
listen 80;
server_name example.com;
return 301 https://example.com$request_uri;
}
server {
listen 443;
server_name example.com;
root /home/deploy/test;
ssl on;
ssl_certificate /etc/ssl/certs/server.crt;
ssl_certificate_key /etc/ssl/certs/server.key;
}