Conditionally rewrite request url based on referer - Nginx - nginx

What I am trying to achive; is when the request coming from http://<ip>/vault/ui/ (referer in the request header) and it includes the http://<ip>/v1/* endpoint, to be rewriten or redirected to http://<ip>/vault/v1/
can someone please help me to solve this issue?
/etc/nginx/sites-enabled/reverse-proxy.conf
upstream command_center_vault {
server command-center-0.blinchik.io:28200;
}
server {
listen 80;
listen [::]:80;
location /vault/ {
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 Accept-Encoding "";
proxy_pass "http://command_center_vault/vault/";
proxy_redirect /ui/ /vault/ui/;
}
location /vault/v1/ {
proxy_pass "http://command_center_vault/v1/";
}
}
Headers
Update
A little bit more context, the overarching architecture looks as in the picture below.
the configuration of nginx server in the private subnet looks like this:
private subnet nginx
upstream consul_server {
server brain-consul-server-0.blinchik.io:8500;
server brain-consul-server-1.blinchik.io:8500;
server brain-consul-server-2.blinchik.io:8500;
}
upstream vault_server {
server brain-vault-server-0.blinchik.io:8200;
server brain-vault-server-1.blinchik.io:8200;
}
server {
listen 28500;
listen [::]:28500;
location /consul/ {
proxy_pass "http://consul_server";
sub_filter_once off;
sub_filter_types application/javascript text/html;
sub_filter "/v1/" "/consul_v1/";
}
location /consul_v1/ {
proxy_pass "http://consul_server/v1/";
}
}
server {
listen 28200;
listen [::]:28200;
location /vault/ {
proxy_pass "http://vault_server/";
port_in_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;
proxy_set_header Accept-Encoding "";
proxy_redirect /ui/ /vault/ui/;
sub_filter_once off;
sub_filter '<head>' '<head><base href="/vault/">';
sub_filter '"/ui/' '"ui/';
#inspired by this repo https://github.com/Folcky/hashicorp-vault-and-nginx
}
location /v1/ {
proxy_pass "http://vault_server/v1/";
}
}
public subnet nginx
upstream command_center_vault {
server command-center-0.blinchik.io:28200;
}
server {
listen 80;
listen [::]:80;
location /vault/ {
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 Accept-Encoding "";
proxy_pass "http://command_center_vault/vault/";
proxy_redirect /ui/ /vault/ui/;
}
location /vault/v1/ {
proxy_pass "http://command_center_vault/v1/";
}
}
the consul part works fine. if I change in the public subnet configuration the location of /vault/v1/ to /v1/ then it works as well. But the problem that other products that I intend to add it to the reverse proxy (like Nomad) also uses the /v1/ path and in this case there will be a conflict.

I think this one should work (must be placed at the server context outside any locations:
if ($http_referer ~ /vault/ui) {
rewrite ^/v1(/.*) /vault/v1$1 last;
}
You can make regex pattern more strict including //<ip> or https?://<ip> parts.

Related

How to add Cache-Control header in Nginx for a specific folder and every file and folder beneath it?

I want to disable all caching for a specific folder and all it's descendants in my application. The folder has some files in the root and also other subdirectories.
printscreen of my folder in Windows explorer
This is what I tried to far in my nginx configuration file.
I added two map directives and used them in my server directive.
If I check the response headers for any file with curl like so
curl -I http://example.com/api/folder/index.html
I don't see the added Cache-Control header.
This is my nginx file:
events {
}
http {
include /etc/nginx/mime.types;
map $uri $cache_control {
/api/folder/(l|m|r|s)/ "no-cache, no-store, must-revalidate";
}
map $uri $expire {
/api/folder/(l|m|r|s)/ off;
}
upstream api {
server api:80;
}
upstream web {
server web:80;
}
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html;
expires $expire;
add_header Cache-Control $cache_control;
location /api {
rewrite /api/(.*) /$1 break;
proxy_pass http://api;
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;
}
location /swagger {
proxy_pass http://api;
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;
}
location / {
proxy_pass http://web;
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;
}
}
}

Hide port and address with nginx

I've installed a sonarqube and a Jenkins server in one machine, with ports 9000 and 8080 respectively. I'd like to make urls like test_hub.mysite.com/sonar and /jenkins and redirect to machine and port correctly, but maintaining original address test_hub.mysite.com/sonar.
My configuration with nginx is pretty simple:
server {
listen 80;
server_name sonar.mysite.com;
location /sonar/ {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://52.29.xx.xx:9000;
}
}
server {
listen 80;
server_name test_hub.mysite.com;
location / {
# you can use regular exp also
if ($request_uri = /sonar) {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://52.29.xx.xx:9000;
}
if ($request_uri = /jenkins) {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://52.29.xx.xx:8000;
}
}
}
NOTE: Check this link before trying

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 requests for a specific path

Is it possible to pass requests for a specific path to a different upstream server?
Here is my nginx site configuration:
upstream example.org {
server 127.0.0.1:8070;
keepalive 8;
}
server {
listen 0.0.0.0:80;
server_name example.org www.example.org;
access_log /var/log/nginx/example.org.log;
location / {
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_set_header X-NginX-Proxy true;
proxy_pass http://example.org;
proxy_redirect off;
}
}
Currently, requests to this site are redirected to a Node.js instance running on port 8070.
I would like requests to this site that have a path starting with /services to be redirected to another Node.js instance running on port 8080.
Is this possible? And of course -- how so?
Yes, just add another location block:
upstream example.org {
server 127.0.0.1:8070;
keepalive 8;
}
upstream other.example.org {
server 127.0.0.1:8080;
keepalive 8;
}
server {
listen 0.0.0.0:80;
server_name example.org www.example.org;
access_log /var/log/nginx/example.org.log;
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_set_header X-NginX-Proxy true;
proxy_redirect off;
location / {
proxy_pass http://example.org;
}
location /services {
proxy_pass http://other.example.org;
}
}
Note: I extracted all shared proxy directives into the server block so that they are not repeated in each location block. If they would differ between different locations, you would have to move them again into the location blocks...

how to reverse proxy via nginx a specific url?

I have a server running at http://localhost:8080 i want a specific url of this server to be proxied by nginx.
For example, i only want http://localhost:8080/test/(.*) to be reverse proxied to http://localhost/test/(.*).
I'm proxing another server to http://localhost/.
What about just a simple location block?
server {
# ... other stuff
location /test/ {
try_files $uri #testproxy;
}
location #testproxy {
proxy_pass http://127.0.0.1:8080;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Real-IP $remote_addr;
# all your params
}
}
I made it somehow this way and it worked. Thanks for your comment anyway. :)
server {
listen 80;
# ... other stuff
upstream backend1 {
server 127.0.0.1:8080;
}
location /test/ {
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_pass http://backend1/test/;
}
}

Resources