nginx proxy and backbone pushstate - unix

I'm trying to set up nginx to work with my backbonejs application and api server.
The API server is external and being routed through https://website.com/api/...
Essentially, I want any non-matched urls to be routed to /index.html for the backbone app to handle.
I've tried using try_files, but that just overrides my API. I've tried setting up another location where I check if the request is a GET and also if it doesn't match register or login or api, but that also doesn't work. Here's my server so far:
server {
listen 80; ssl off;
listen 443 ssl;
server_name app.io;
ssl_certificate /etc/nginx/conf/ssl.crt;
ssl_certificate_key /etc/nginx/conf/app.key;
root /home/ubuntu/app/public;
access_log /var/log/nginx/app.access.log;
error_log /var/log/nginx/app.error.log;
index index.html;
location / {
if ($scheme = "http") {
rewrite ^ https://$http_host$request_uri? permanent;
}
}
location ~ ^/(api)|(auth).*$ {
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 https://app.aws.af.cm;
}
location ~ ^(/(register)|(login)).*$ {
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;
# GETs only
limit_except POST {
proxy_pass https://app.aws.af.cm;
}
}
location ~* \.(?:ico|css|js|gif|jpe?g|png)$ {
expires max;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
}
}
Currently, try_files overrides the API and just redirects to index.html. Any idea how I can get everything to play nicely with one another?
Here's what I want:
if / - /index.html
else if /api/*|/auth/* - external proxy
else if /login|/register - POST - external proxy
else /* - /#$1

Figured it out:
Add try_files #uri #rewrites; to Location / and also add the #rewrites function below.
server {
listen 80; ssl off;
listen 443 ssl;
server_name app.io;
ssl_certificate /opt/nginx/conf/ssl.crt;
ssl_certificate_key /opt/nginx/conf/app.key;
root /home/ubuntu/app/public;
access_log /var/log/nginx/app.access.log;
error_log /var/log/nginx/app.error.log;
index index.html;
location / {
if ($scheme = "http") {
rewrite ^ https://$http_host$request_uri? permanent;
}
try_files $uri #rewrites;
}
location ~ ^/(api)|(auth)|(logout)|(register)|(login).*$ {
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 https://app.cm;
}
location ~* \.(?:ico|css|js|gif|jpe?g|png)$ {
expires max;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
}
location #rewrites {
rewrite ^/.+ /#$uri redirect;
}
}

Related

Nginx dynamic proxy_pass with variable location and relative url

I used this Nginx configuration and everything went well.
server {
listen 80;
server_name 127.0.0.1;
ssl_client_certificate /etc/ssl/certs/server.crt;
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options "nosniff";
location ^~ /api/ {
rewrite /(.*) /proxy/$1;
}
location ^~ /js/ {
rewrite /(.*) /proxy/$1;
}
location ^~ /services/ {
rewrite /(.*) /proxy/$1;
}
location ^~ /payeewebv2/ {
rewrite /(.*) /proxy/$1;
}
location /proxy/ {
proxy_set_header X-SSL-CERT $ssl_client_escaped_cert;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass https://proxieddomain.com/;
proxy_ssl_server_name on;
proxy_set_header host $proxy_host;
}
}
Now I need to proxy to be determined by a COOKIE. I have updated the configuration and it looks like this:
server {
listen 80;
server_name 127.0.0.1;
ssl_client_certificate /etc/ssl/certs/server.crt;
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options "nosniff";
location ^~ /api/ {
rewrite /(.*) /proxy/$1;
}
location ^~ /js/ {
rewrite /(.*) /proxy/$1;
}
location ^~ /services/ {
rewrite /(.*) /proxy/$1;
}
location ^~ /payeewebv2/ {
rewrite /(.*) /proxy/$1;
}
location /proxy/ {
resolver 127.0.0.11;
set $proxy "to_be_replaced";
proxy_set_header X-SSL-CERT $ssl_client_escaped_cert;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
set_by_lua_block $proxy {
return "https://proxieddomain.com/"
}
proxy_pass $proxy$request_uri;
proxy_ssl_server_name on;
proxy_set_header proxy $proxy$request_uri;
proxy_set_header host $proxy_host;
}
}
}
This is the changed part:
set_by_lua_block $proxy {
return "https://proxieddomain.com/"
}
proxy_pass $proxy$request_uri;
I can visit http://localhost/varicent/ and it proxies to https://proxieddomain.com/
But when its javascript requests /api/something etc. it returns content from $proxy (https://proxieddomain.com/) and not from $proxy/api/something (https://proxieddomain.com/api/something).
Do you know why the first non-dynamic solution works without problems?
What should i change to make it work it like before?
Thx
The problem has been in really the domain.
I looked it up through nslookup and changed configuration to use canonical name which is different from the https://proxieddommain.com.
Thank you #IvanShatsky for your tip.

nginx redirection not working inside location directive

I have two location directives both containing conditional redirects.
server {
listen 443 ssl;
ssl_certificate /etc/ssl/cert.pem;
ssl_certificate_key /etc/ssl/cert.key;
server_name services.gixxx.de;
location / {
if (-f $document_root/maintenance.on) {
return 503;
}
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html =404;
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
add_header Cache-Control 'no-cache, must-revalidate, proxy-revalidate, max-age=0';
}
location /api {
if (-f $document_root/maintenance.on) {
return 503;
}
proxy_read_timeout 120;
proxy_connect_timeout 120;
proxy_send_timeout 120;
proxy_pass http://serviceapp;
}
upstream serviceapp {
server serviceapp:3000;
}
When I create a document name maintenance.on on the route folder it works for the first location / { directive but not for location /api { part.
What is going wrong here.
You have no root defined for the second block. You should move the root statement into the outer block and allow it to be inherited by both location blocks.

Nginx reverse proxy returns 404 on static files

Basically I have two local application hosted on 2 different local port.
I'm trying to access http://localhost/admin which is serve via reverse_proxy but I got http://localhost/admin/main.css net::ERR_ABORTED 404 (Not Found).
Ive also tried below (without slash) but I still got the same error.
location /admin{
proxy_pass http://127.0.0.1:8090
....
}
app1.conf
server{
listen 80;
listen [::]:80;
root /var/www/first_app/dist;
index index.html;
access_log /var/log/nginx/first_app.access.log;
error_log /var/log/nginx/first_app.error.log;
location / {
try_files $uri $uri/ /index.html =404;
}
location /admin/{
proxy_pass http://127.0.0.1:8090/
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Scheme $scheme;
client_max_body_size 0;
}
location ~* .(ico|jpg|png|gif|jpeg|css|swf|js|woff)$ {
access_log off;
gzip_static on;
gzip_comp_level 5;
expires 1M;
#add_header Cache-Control private;
add_header Cache-Control public;
}
}
app2.conf
server{
listen 8090;
listen [::]:8090;
root /var/www/second_app/dist;
location /{
try_files $uri /index.html;
}
}
It would be great if someone can explain to me what I'd miss? Thanks much.

NGINX force SSL for all but health check file?

I have a Rails app with an NGINX reverse proxy behind an AWS ELB. I am terminating SSL on the ELB and I have NGINX configured to force any attempt at HTTP to rewrite as HTTPS. This setup works fine, but I'm also serving the site through ECS, and since the ELB health check is on HTTP port 80, when it gets the redirect and returns 301, the ELB health check fails and the instance is deregistered.
How do I set up NGINX to send all but the health check file through HTTPS?
Here is my server block from nginx.conf:
server {
listen 80;
server_name localhost;
root /var/www/html;
location ~ ^elbcheck\.html$ {
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://rails_app;
break;
}
location / {
proxy_redirect off;
proxy_next_upstream error;
if ($http_x_forwarded_proto != "https") {
rewrite ^ https://$host$request_uri? permanent;
}
try_files $uri $uri/ #proxy;
}
location ~* \.(jpg|jpeg|svg|png|gif|ico|css|js|eot|woff|woff2|map)$ {
proxy_cache APP;
proxy_cache_valid 200 1d;
proxy_cache_valid 404 5m;
proxy_ignore_headers "Cache-Control";
expires 1d;
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 https;
add_header X-Cache-Status $upstream_cache_status;
proxy_pass http://rails_app;
}
location #proxy {
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 https;
proxy_pass http://rails_app;
}
}
I had the same problem, and found this answer somewhere on the internet (don't have the source anymore, it was a while ago)
server {
listen 80;
set $redirect_to_https 0;
if ($http_x_forwarded_proto != 'https') {
set $redirect_to_https 1;
}
if ($request_uri = '/status') {
set $redirect_to_https 0;
}
if ($redirect_to_https = 1) {
return 301 https://$host$request_uri;
}
...
}
Found a simple answer that worked great at this post. Here is what #ceejayoz suggested there:
server {
location /elb-status {
access_log off;
return 200;
}
}
Seems to be working--ECS hasn't terminated my service due to failed health checks anymore.

nginx proxy_pass static assets

I have the following nginx configuration
rewrite_log on;
server {
server_name greymarmita.no-ip.org;
listen 80;
rewrite ^(.*) https://$host$1 permanent;
}
server {
server_name greymarmita.no-ip.org;
listen 443 ssl;
error_log /var/log/nginx/main.error;
access_log /var/log/nginx/main.access;
ssl on;
ssl_certificate /etc/ssl/localcerts/autosigned.crt;
ssl_certificate_key /etc/ssl/localcerts/autosigned.key;
root /srv/www;
index index.html /index.html;
location /rasp/ {
proxy_pass http://192.168.2.6:81/;
}
location /cam/ {
proxy_pass http://192.168.2.4:8081;
}
location ^~ /router/ {
proxy_pass http://192.168.2.1/;
}
location /nas/ {
proxy_pass http://192.168.2.13/;
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;
}
}
However when I try to access http://192.168.2.6/nas although the html files are served correctly, files under /web/ are not
GET https://greymarmita.no-ip.org/web/images/login.png 404 (Not Found)
The correct path for these assets should be https://greymarmita.no-ip.org/nas/web/images/login.png
You don't have a location to match that file, try adding this
location / {
try_files $uri $uri/;
}

Resources