Nginx reverse proxy doesn't work as expected - nginx

I have two domains on different nginx(1.15.0) servers (server1 example.com and server2 example.net). I've tried to set up server2 as a reverse proxy with ngx_http_substitutions_filter_module but it doesn't work as expected.
Due to my config, subs_filter directive should replace example.com to example.net but when I type example.net in browser it redirects me to example.com.
nginx.conf
http {
//other settings
.....
include /etc/nginx/sites-enabled/*;
upstream example.com {
server example.com;
}
}
example.net.conf
server {
listen 80;
server_name example.net www.example.net;
rewrite ^/(.*)$ https://example.net/$1 permanent;
}
server {
listen 443 ssl;
server_name example.net;
ssl_certificate /etc/letsencrypt/live/example.net/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.net/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location / {
root html;
try_files $uri #example.com;
}
location #example.com {
include replace.conf;
proxy_pass http://example.com;
proxy_cookie_domain example.com example.net;
proxy_set_header Accept-Encoding "";
proxy_set_header Host example.com;
proxy_redirect http://example.com http://example.net;
}
}
replace.conf
# replace direct links
subs_filter "www.example.com" "example.net" gi;
subs_filter "example.com" "example.net" gi;
Seems like nginx ignores subs_filter directive.
Could someone explain me how can I replace uri properly using ngx_http_substitutions_filter_module? Thank you for advice!

Problem solved.
First of all I removed upstream from nginx.conf:
upstream example.com {
server example.com;
}
Then I changed following lines in example.net.conf:
location / {
...
try_files $uri #static;
}
location #static {
...
proxy_pass https://example.com;
...
...
...
proxy_redirect https://example.com https://example.net;
}
All works fine except login form. Firefox works correctly but Chrome returns error 422. I suppose this is because the login form works on javascript.
Anyway thanks to all!

Related

nginx redirection to index page

I am struggling to implement an automatic nginx redirect from non index pages to my index page, with the exception of /admin
For instance, example.com/test should redirect to example.com, but example.com/admin should not redirect to example.com
This is my current nginx configuration file:
upstream app_server {
server unix:/tmp/mysite.sock;
}
proxy_cache_path /var/www/example.com/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;
server {
listen 80;
server_name www.example.com example.com;
# redirects both www and non-www to https
return 301 https://www.example.com$request_uri;
}
server {
listen 443;
server_name example.com;
return 301 https://www.example.com$request_uri;
}
server {
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
server_name www.example.com;
ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;
charset utf-8;
client_max_body_size 75M;
location /media {
alias /var/www/example.com/media;
}
location /static {
alias /var/www/example.com/static;
}
location / {
proxy_cache my_cache;
include proxy_params;
proxy_pass http://app_server;
proxy_ssl_server_name on;
}
}
I have tried adding a try_files statetement within my location / block, and other things, but none seem to work. Am I missing something?
You are trying to mix proxy_pass with try_files, it won't work within the same location block. You can use named location instead and rewrite any URI that doesn't start with /admin to a root one using negative regex assertion:
location / {
try_files $uri #app;
}
location #app {
rewrite ^(?!/admin) / break;
proxy_cache my_cache;
include proxy_params;
proxy_pass http://app_server;
}
You don't need the separate location /media { ... } or location /static { ... } blocks, because as nginx documentation states:
When location matches the last part of the directive’s value:
location /images/ {
alias /data/w3/images/;
}
it is better to use the root directive instead:
location /images/ {
root /data/w3;
}
Instead you just need to define the common server root (outside of any location blocks):
root /var/www/example.com;
You are also don't need to use the proxy_ssl_server_name directive since you are not proxying your request to the upstream with HTTPS protocol.

Nginx reverse proxy for grafana using dashboard as subpath

I would like to use dashboard as my nginx location for my grafana install.
The problems is grafana uses dashboard in some of it url's like https://example.com/grafana/dashboard/new?orgId=1, where I would like it to be https://example.com/dashboard/dashboard/new?orgId=1 and I think my nginx location is rewriting to https://example.com/dashboard/new?orgId=1.
When I have it setup to use grafana as the subpath it all work as expected;
grafana.ini:
[server]
http_addr = 127.0.0.1
domain = example.com
root_url = %(protocol)s://%(domain)s/grafana/
nginx config:
# Upstream Servers
upstream grafana_server {
server localhost:3000;
}
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
include snippets/ssl-example.com.conf;
include snippets/ssl-params.conf;
root /var/www/example.com/html;
index index.html index.htm;
server_name example.com www.example.com;
location /grafana/ {
proxy_pass http://grafana_server/;
proxy_set_header Host $host;
}
}
But changing it to dashboard and navigating to https://example.com/dashboard/dashboard/new?orgId=1 results in the url been rewritten to https://example.com/dashboard/new?orgId=1
grafana.ini:
[server]
http_addr = 127.0.0.1
domain = example.com
root_url = %(protocol)s://%(domain)s/dashboard/
nginx config:
# Upstream Servers
upstream grafana_server {
server localhost:3000;
}
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
include snippets/ssl-example.com.conf;
include snippets/ssl-params.conf;
root /var/www/example.com/html;
index index.html index.htm;
server_name example.com www.example.com;
location /dashboard/ {
proxy_pass http://grafana_server/;
proxy_set_header Host $host;
}
}
so I have tried a to do a rewrite in the nginx location but can't get it to work as required (really have no clue what to do here)
location ~ (\/dashboard\/) {
proxy_pass http://grafana_server$1;
proxy_set_header Host $host;
}
location ~ /dashboard/ {
rewrite ^ /dashboard/$1;
proxy_pass http://grafana_server;
proxy_set_header Host $host;
}
Any help would be much appreciated.
Regards,
I know this is a bit late - but I stumbled upon the same issue and thought I'd going to share in case somebody else hits this thread:
This isn't an issue with nginx, but with grafana itself.
I could not solve it any other way but renaming the last part of the root_url in something different than /dashboard

nginx as https proxy, but want to intercept one static path for Let's Encrypt /.well-known challenges

There is lots of material about using ngix as a reverse proxy and it is working well for me as a basic proxy for a strange web server app I need to use. I even have redirect on so http gets redirected to https.
server {
listen 80;
server_name <my server>;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name <my server>;
# add Strict-Transport-Security to prevent man in the middle attacks
add_header Strict-Transport-Security "max-age=31536000";
ssl on;
ssl_certificate cert1.crt.pem;
ssl_certificate_key cert1.key.pem;
ssl_session_cache shared:SSL:10m;
location / {
proxy_pass http://localhost:81; # my existing apache instance
proxy_set_header Host $host;
}
Now I have one new wrinkle. I'd like to pick off one particular path and NOT have it get forwarded to the main server app. I need to do this to add in some Let's Encrypt challenge responses. Whenever the incoming url is http:///.well-known/acme-challenge/ then I want to use a static nginx path and NOT fwd to the main server.
Any ideas? I tried adding in a location directory but that wasn't working.
server {
listen 80;
server_name video.maritimeopscorp.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name video.maritimeopscorp.com;
# add Strict-Transport-Security to prevent man in the middle attacks
add_header Strict-Transport-Security "max-age=31536000";
ssl on;
ssl_certificate cert1.crt.pem;
ssl_certificate_key cert1.key.pem;
ssl_session_cache shared:SSL:10m;
location ~ /.well-known {
<I've tried lots of combinations here.>
}
location / {
proxy_pass http://localhost:81; # my existing apache instance
proxy_set_header Host $host;
}
I'd also prefer to get this up into the 80 block rather than the 443 block but little steps first.
Any ideas?
You will need to use a root directive, to inform nginx where the .well-known directory can be found:
server {
listen 80;
server_name video.maritimeopscorp.com;
location / {
return 301 https://$server_name$request_uri;
}
location /.well-known {
root /path/to/enclosing/directory;
}
}
Enclose the return statement inside the default location block, otherwise it will always take precedence.

How to set nginx so that it will show a specific page for IE users?

Below is my nginx config. I want to redirect IE users to a specific page. But if I change "return 403" to "return 301 mysite.com/a_page.html, there will be a redirection loop. How could I fix that?
server {
listen 80;
listen 443 default_server ssl;
server_name mysite.com
ssl_certificate /etc/nginx/ssl/mysite.crt ;
ssl_certificate_key /etc/nginx/ssl/mysite.key
if ($http_user_agent ~ MSIE) {
return 403;
}
if ($scheme = http) {
return 301 https://$server_name$request_uri;
}
client_max_body_size 10M;
location / {
proxy_pass http://localhost:2368/;
proxy_set_header Host $host;
proxy_buffering off;
}
Try to move the condition inside your generic location / {} block, then create a new location block for the redirect target.

multiple Domains without repeat config

How can I serve multiple domains with the same configuration, without copying the server{} rule configuration for every domain?
example.com
example.org
example.de
example.ro
Nginx Config:
upstream example_live {
server 127.0.0.1:8300;
}
server {
listen 80;
server_name example.com example.org example.de example.ro;
access_log /var/log/nginx/example.access.log;
error_log /var/log/nginx/example.error.log;
location / {
proxy_pass http://example_live/VirtualHostBase/http/example.??:80/example/VirtualHostRoot/;
include /etc/nginx/ps.cfg/proxy.conf;
}
include /etc/nginx/cfg/base.conf;
}
in the same server section and using server_name directive to support multiple domains. And seems you already give the answer above.
This works for me, thank you for your Comment
server_name a.com www.a.com
b.org www.b.org
c.net www.c.net;
access_log /var/log/nginx/a.com.access.log;
error_log /var/log/nginx/a.com.error.log;
location / {
rewrite ^(.*)$ /VirtualHostBase/http/$http_host:80/a/VirtualHostRoot$1 break;
proxy_pass http://127.0.0.1:8080;
}

Resources