I'm kinda new with NGINX, so still learning how to deploy it correctly. At this moment I'm running into a problem.
My project exists of a frontend in HTML (JS etc), and an API in nodeJS running on port 5000.
I've created my Nginx file and it kinda works at the moment. The HTML page is shown with Letsecrypt certificate over port 443. And I can fire fetch requests over http to my api. But, when firing from the website, I get a mixed-content warning. Since the XHR requests are fired at the http version and not the https version. I'm trying to setup my Nginx conf to XHR over https, but no luck yet.
This is my conf file (I starred out the original domain)
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
index index.html;
server_name pim.********.***;
location / {
try_files $uri $uri/ =404;
}
}
server {
root /var/www/html;
index index.html;
server_name pim.*****.***; # managed by Certbot
location / {
try_files $uri $uri/ =404;
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/pim.*******.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/pim.*******.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
}
server {
if ($host = pim.******.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80 ;
listen [::]:80 ;
server_name pim.******.com;
return 404; # managed by Certbot
}
server {
listen 5000 ;
listen [::]:5000 ;
server_name pim.*******.com;
location / {
proxy_pass http://localhost:5000;
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;
}
}
I've tried to create a location at /api with the port 443, but this gives an error when testing the nginx file.
If you want to keep this setup as is (http -> https redirection and api access via port 5000).
This nginx config should work:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name pim.******.com;
# redirect to the https version
return 301 https://$host$request_uri;
}
server {
# handles normal ssl/tls traffic
# i would also use http2 on https
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
server_name pim.*****.***;
root /var/www/html;
index index.html;
ssl_certificate /etc/letsencrypt/live/pim.*******.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/pim.*******.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location / {
try_files $uri $uri/ =404;
}
}
server {
# same as 443 but with the differnt port
listen 5000 ssl http2;
listen [::]:5000 ssl http2;
server_name pim.*******.com;
# certs are required for ssl/tls traffic
ssl_certificate /etc/letsencrypt/live/pim.*******.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/pim.*******.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location / {
proxy_pass http://localhost:5000;
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;
}
}
I personally would suggest to useing the normal port and either use a subdomain (api.example.com) or a subpath (https://example.com/api/).
Config for Subdomain:
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name api.pim.*******.com;
ssl_certificate /etc/letsencrypt/live/pim.*******.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/pim.*******.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location / {
proxy_pass http://localhost:5000;
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;
}
}
Config for SubPath:
server {
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
server_name pim.*****.***;
root /var/www/html;
index index.html;
ssl_certificate /etc/letsencrypt/live/pim.*******.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/pim.*******.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location / {
try_files $uri $uri/ =404;
}
location /api/ {
proxy_pass http://localhost:5000/;
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;
}
}
Use whatever suits you.
Related
I configured Nginx as a reverse proxy for a front-end application. The front-end takes an endpoint URL via a .env file. when I change the endpoint's value which is a URL on the .env, Nginx still picks the old value even after restarting Nginx
my Nginx config
upstream App{
ip_hash;
server localhost:3050;
}
server {
server_name app.com www.app.com ;
root /var/www/App;
access_log /var/log/nginx/app-access.log;
error_log /var/log/nginx/app-error.log;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
add_header 'Content-Security-Policy' 'upgrade-insecure-requests';
location / {
proxy_pass http://App/;
}
location /socket.io/ {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass http://App/socket.io/;
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/app.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/app.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
}
server {
if ($host = www.app.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = app.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80 ipv6only=on default_server;
server_name app.com www.app.com ;
return 404; # managed by Certbot
}
I become desparate... I want to write a configuration for nginx where shell.foo.org use a reverse proxy and *.shell.foo.org use a wildcard subdomain, so e.g. name1.shell.foo.org read /var/www/name1.shell.foo.org and name2.shell.foo.org read /var/www/name2.shell.foo.org. I tried a lot of versions but either the reverse proxy work or the wildcard subdomains.
My nginx-configuration is:
server {
listen 80;
listen [::]:80;
server_name ~^(www\.)(?<subdomain>.+).shell.foo.org$
~^(?<subdomain>.+).shell.foo.org$ ;
return 301 https://$host$request_uri;
}
server {
# SSL configuration
#
listen [::]:443 ssl ipv6only=on;
listen 443 ssl;
server_name ~^(www\.)(?<subdomain>.+).shell.foo.org$
~^(?<subdomain>.+).shell.foo.org$ ;
ssl_certificate /etc/letsencrypt/live/shell.foo.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/shell.foo.org/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
if ($scheme != "https") {
return 301 https://$host$request_uri;
}
root /var/www/$subdomain;
index index.html index.htm;
location / {
# if I comment this out the wildcard subdomains work;
# in this version, the reverse proxy work
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_read_timeout 300;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Real-PORT $remote_port;
}
root /var/www/$subdomain;
index index.html index.htm;
}
Anyone an idea where my mistake is?
Thanks,
bengoshi
here's my nginx.conf:
upstream blah_upstream {
server web:7000;
}
server {
listen 80;
server_name blah.com www.blah.com;
# redict to HTTPS for all requests
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name blah_upstream;
server_tokens off;
# generated with help of certbot
ssl_certificate /etc/letsencrypt/live/blah.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/blah.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location / {
proxy_pass http://blah_upstream;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /static/ {
alias /usr/src/app/public/;
}
}
this works for http://www.blah.com -> https://www.blah.com (it redirects fine).
however http://blah.com -> https://blah_upstream which of course absolutely doesn't work.
what am I doing wrong? I don't understand why it would work for the www version and not the other.
I tried switching the server_name order in
server_name blah.com www.blah.com;
but that didn't work either.
I'm trying to redirect www to non-www but it doesn't work. I've tried various answers from similar questions but those haven't worked.
I have SSL cert using certbot for 3 domains example.com, www.example.com and admin.example.com.
This is my current config, which works for non-www and admin, however www.example.com doesn't work.
# HTTP - redirect all requests to HTTPS
server {
listen 80;
listen [::]:80;
return 301 https://$host$request_uri;
}
# Redirect to non-www
server {
server_name www.example.com;
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/example.se/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/example.se/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
return 301 https://example.com$request_uri;
}
# non-www
server {
server_name example.com;
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; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/example.se/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/example.se/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
}
# CMS
server {
server_name admin.example.com;
location / {
proxy_pass http://localhost:1337;
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; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/example.se/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/example.se/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
}
I use DigitalOcean where both admin & non-www points to my droplet and www.example.com has a CNAME record to example.com (non-www).
Firstly, the www.example.com and example.com should be in one server block.
Secondly, you need to add this in your #non-www server configuration blog
if ($host = 'www.example.com') {
return 301 https://example.com$request_uri;
}
Thirdly, to redirect all requests to HTTPS, server_name must be added in your # HTTP - redirect all requests to HTTPS block.
Finally, your NGINX Configuration file will look like this
# HTTP - redirect all requests to HTTPS
server {
server_name example.com www.example.com admin.example.com;
listen 80;
listen [::]:80;
return 301 https://$host$request_uri;
}
# non-www
server {
server_name example.com www.example.com;
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;
}
if ($host = 'www.example.com') {
return 301 https://example.com$request_uri;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/example.se/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/example.se/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
}
# CMS
server {
server_name admin.example.com;
location / {
proxy_pass http://localhost:1337;
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; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/example.se/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/example.se/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
}
Once you update your NGINX configuration file, restart NGINX:
$ sudo systemctl restart nginx
How do i get nginx to serve assets adjacent to index.html when using proxy_pass?
Context: I have a github repository that serves up content using github pages. When serving from a repository, GHP requires a url path that matches the repository name
rightisleft.github.io/repo_name/
Currently index.html and all subdirectories are working as expected. Loading assets from (css/*, images/*) return 200s.
However, assets like robots.txt and other files in the repository root return 404s.
Here's my domain .conf
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name www.redacted.com;
# SSL
ssl_certificate /etc/letsencrypt/live/redacted.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/redacted.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/redacted.com/fullchain.pem;
location / {
proxy_set_header Host rightisleft.github.io;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass https://rightisleft.github.io/redacted/;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
# HTTP redirect
server {
listen 80;
listen [::]:80;
server_name www.redacted.com,redacted.com;
include nginxconfig.io/letsencrypt.conf;
location / {
return 301 https://www.redacted.com$request_uri;
}
}
# subdomains redirect
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name redacted.com;
# SSL
ssl_certificate /etc/letsencrypt/live/redacted.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/redacted.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/redacted.com/fullchain.pem;
return 301 https://www.redacted.com$request_uri;
}
EDIT
Nginx is used for certificate management to tie together a few different micro services.
Try this as it might work (if your css/assets are in github repo pages) and you do not need to setup many redirect unless you have a lot of domains/subdomains and I have also set redacted.com to server_name:
server {
listen 80 http2;
listen [::]:80 http2;
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
server_name redacted.com www.redacted.com;
# SSL
ssl_certificate /etc/letsencrypt/live/redacted.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/redacted.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/redacted.com/fullchain.pem;
location / {
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_pass https://rightisleft.github.io/redacted$request_uri;
proxy_buffering off;
proxy_redirect default; #or off
proxy_intercept_errors on;
# allow GitHub to pass caching headers instead of using your own
expires off;
}
}