Syntax for IF Statement in nginx - nginx

I have two different server_name in nginx.conf file:
First one as:
server_name ~^(?<subdomain>.+)\.nithinveer\.com$;
location /
{
proxy_pass http://192.168.6.190/Profiles/$subdomain/default.aspx$request_uri/;
access_log /var/log/nginx/true.log;
}
Another one as
server_name ~^(?<subdomain>.+)\.nithinveer\.com\.(?<extension>)$;
location /extension
{
proxy_pass http://192.168.6.190;
access_log /var/log/nginx/false.log;
}
Now the thing is I want to use both the server_name based on the in the server_name. If there is no extension with the server_name it should go to first location. If there is an extension, it should go to second location.
But while running the nginx, it is not moving into the second server_name
Can anyone please find some solution for this...?
I thought a solution as(may be wrong).
server_name ~^(?<subdomain>.+)\.nithinveer\.com\.(?<extension>.+)$;
if($<extension> == NULL)
{
location /
{
proxy_pass http://192.168.6.190/Profiles/$subdomain/default.aspx$request_uri/;
access_log /var/log/nginx/true.log;
}
}
else
{ location /
{
proxy_pass http://192.168.6.190;
access_log /var/log/nginx/false.log;
}
But the syntax with the if statement throws an error.

There's no else directive in nginx.
Also, you don't need to duplicate the location either.
try this:
server {
server_name ~^(?<subdomain>.+).nithinveer\.com(?<extension>\..+)$;
location / {
This will match hosts terminating with ".com"
if ($extension = "")
{
proxy_pass http://192.168.6.190/Profiles/$subdomain/default.aspx$request_uri/;
access_log /var/log/nginx/true.log;
}
This will match hosts with something after ".com", e.g: "foo.nithinveer.com.me", the $extension will be ".me"
if ($extension != "")
{
proxy_pass http://192.168.6.190;
access_log /var/log/nginx/false.log;
}
}
}
Also, consider that if is evil.
This is the version with a safe usage of it:
server_name ~^(?<subdomain>.+).nithinveer\.com(?<extension>\..+)$;
location / {
error_page 418 = #with_extension;
#This will match hosts with something after ".com",
# e.g: "foo.nithinveer.com.me", the $extension will be ".me"
if ($extension != "")
{
return 418;
}
# This will match hosts terminating with ".com"
proxy_pass http://192.168.6.190/Profiles/$subdomain/default.aspx$request_uri/;
access_log /var/log/nginx/true.log;
}
location #with_extension {
proxy_pass http://192.168.6.190;
access_log /var/log/nginx/false.log;
}

Related

Nginx using the wrong location block

I have the following nginx configuration:
upstream front {
server localhost:4000;
}
upstream back {
server localhost:8000;
}
server {
server_name my_domain.com;
listen 80;
location ~ /api($|/.*) {
rewrite ^/api($|/.*) /VirtualHostBase/http/my_domain.com:80/Intk/VirtualHostRoot/_vh_api$1 break;
proxy_pass http://back;
}
location ~ / {
add_header Cache-Control "public";
expires +1m;
proxy_pass http://front;
}
location ~ /orgs/.+$ {
return 301 http://my_domain.com/orgs;
}
location ~* manage_ {
deny all;
}
location ~ \.php$ {
return 410;
access_log off;
}
location ~ ^/(wp-admin|wp-content) {
return 410;
access_log off;
}
location = /nginx_stub_status {
stub_status on;
allow 127.0.0.1;
deny all;
}
}
server {
server_name www.my_domain.com;
listen 80;
access_log off;
return 301 http://my_domain.com$request_uri;
}
I cannot understand what is wrong with it, specifically with the 3rd location block.
If I write my_domain.com/orgs/some-org, shouldn't it redirect to my_domain.org/orgs?
It's not doing that, it acts as if that location block wasn't there.
From my understanding, nginx should fulfill the request with the most specific match possible, and it should be the one in the 3rd location block.
http://example.com/orgs will be matched by location ~ / {} instead of location ~ /orgs/.+$ {}. Consider placing rewrite outside of location block, and use location / {} (non-regex without ~) as your fallback.
server {
rewrite ~ ^/orgs/.+ /orgs permanent;
# fallback
location / {
}
}

Nginx reverse proxy to multiple sites on different locations

Is it possible to configure nginx reverse proxy where http://localhost/a/ leads to 1 site and http://localhost/b/ to another? I tried this config:
server {
listen 80;
server_name localhost;
location /a/ {
proxy_pass http://apache.org/;
}
location /b/ {
proxy_pass http://www.gnu.org/;
}
it almost works, but all the links returned by web pages are missing /a/ or /b/ prefix so it can't load any pictures, styles and etc. For example link http://localhost/css/styles.css is not working, but http://localhost/a/css/styles.css is working.
Is there a directive that will append all links on page with suitable prefix? Or there is different approach to put a websites on separate locations?
#ivan-shatsky, Thank you very much.
Just wanted to add working config if some1 else needs.
map $http_referer $prefix {
~https?://[^/]+/a/ a;
default b;
}
server {
listen 80;
server_name localhost;
location / {
try_files /dev/null #$prefix;
}
location /a/ {
proxy_pass http://apache.org/;
}
location #a {
proxy_pass http://apache.org;
}
location /b/ {
proxy_pass http://www.gnu.org/;
}
location #b {
proxy_pass http://www.gnu.org;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}```

Nginx location domain.ltd regex

i need rewrite for domain whois for example http://domainname.ltd/example.com must be call http://domainname.ltd/whois.php?d=example.com
i try location examples but not working.
you can do it like this:
server {
listen 80;
server_name test.com;
location = /whois.php {
proxy_pass http://your_origin_host.com
}
location ~ \/(.*) {
set $domain_query $1;
set $args "d=${domain_query}";
rewrite ^ /whois.php last;
}
}

How can I set a range of remote IP addresses without passing a list?

I have this server block:
server {
server_name doamin.tld;
set $maintenance on;
if ($remote_addr ~ (127.0.0.1|10.1.1.10)) {
set $maintenance off;
}
if ($maintenance = on) {
return 503;
}
error_page 503 #maintenance;
location #maintenance {
root /var/www/html/global;
rewrite ^(.*)$ /holding-page.html break;
}
root html;
access_log logs/doamin.tld.access.log;
error_log logs/doamin.tld.error.log;
include ../conf/default.d/location.conf;
}
What is the correct way to pass a list to the $remote_addr instead of coding it like (127.0.0.1| etc...)?
Use the nginx map directive to set the $maintenance value according to the $remote_addr:
map $remote_addr $maintenance {
default on;
127.0.0.1 off;
10.1.1.10 off;
10.*.1.* off;
}
server {
server_name doamin.tld;
if ($maintenance = on) {
return 503;
}
# ... your code ...
}
Take a look at the include directive if you want to take the IPs list in a separate file.

How to exact match a nginx location?

I am configuring a nginx revser proxy. The result should be when user type http://10.21.169.13/mini, then the request should be proxy_pass to 192.168.1.56:5000. Here is the nginx config:
server {
listen 80;
server_name 10.21.169.13;
location = /mini {
proxy_pass http://192.168.1.65:5000;
include /etc/nginx/proxy_params;
}
}
The above location block never worked with http://10.21.169.13/mini. The only location block worked is:
server {
listen 80;
server_name 10.21.169.13;
location / {
proxy_pass http://192.168.1.65:5000;
include /etc/nginx/proxy_params;
}
}
But the above config also match http://10.21.169.13 request which is too board.
What location block will only match 'http://10.21.169.13/mini` and no more?
UPDATE: tried and failed with the following:
location /mini {
proxy_pass http://192.168.1.65:5000;
include /etc/nginx/proxy_params;
}
location /mini/ {
proxy_pass http://192.168.1.65:5000;
include /etc/nginx/proxy_params;
}
The error is request not found.
Try this out:
server {
listen 80;
server_name 10.21.169.13;
# root /usr/share/nginx/html;
# index index.html index.htm;
location / {
# add something here to handle the root
# try_files $uri $uri/ /index.html;
}
location /mini {
proxy_pass http://192.168.1.65:5000;
include /etc/nginx/proxy_params;
}
}
Let me know if that works for you.

Resources