Whitelist allow for specific requests Nginx - nginx

I have a server and there is a Nginx in front. There are many requests which some of them contains special word example:
/posts/men/clouths
I have a whitelist ip file also. I want to write a rule in Nginx that if requests contains "men", only allow the request if requester's ip is in whitelist file.
If requests does not contains "men" allow the request anyway.

Done
http {
## load whitelist
map $remote_addr $deny {
default 0;
include /path/to/whitelist.txt;
}
server{
## check
set $is_white_list 0;
if ($request_uri ~ ".*men.*"){
set $is_white_list 1;
}
if ($deny) {
set $is_white_list 1$is_white_list;
}
if ($is_white_list = 1) {
return 403;
}
##// epg check
}

Related

NGINX Ingress Redirection Based On Domain Name

I have two domain names, each for different applications hosted in a single kubernetes cluster.
Is there a way to configure ingress to redirect to the different apps based on the hostname in the request it receives?
For example:
www.app1.com and www.app2.com point to the same IP address. However, I want www.app1.com to redirect to /appABC while www.app2.com redirect to /appXYZ.
I have attempted to capture the host name and use this to determine the redirect but it doesn't work.
Is what I'm trying to do possible with NGINX?
Yes,it is Possible. You must need to create two configuration files and point them to their respective paths. Please follow this link for more info and refer to this SO also to get further idea on how to use.
After some experimentation, using the NGINX Playground, I was able to come up with this solution.
...
nginx.ingress.kubernetes.io/server-snippet: |
set $is_app1_base 1;
set $is_app2_base 1;
if ($host !~ "^.*app1\.com$" ) {
set $is_app1_base 0;
}
if ($request_uri != "/") {
set $is_app1_base 0;
set $is_app2_base 0;
}
if ($is_app1_base = 1) {
return 301 $scheme://$host/appABC;
}
if ($host !~ "^.*app2\.com$" ) {
set $is_app2_base 0;
}
if ($is_app2_base = 1) {
return 301 $scheme://$host/appXYZ;
}
In case you're wondering why a number of if statements had to be used this way, NGINX is not that great with if statements and logical operations.
Another caveat worth stating here is that all ingresses associated with this NGINX controller will be affected by this server-snippet; Because nginx.ingress.kubernetes.io/server-snippet is a global annotation.

How to bypass nginx proxy a list of IPS

I have an Nginx config with the redirect to holding pages:
location / {
...
if ($setholdingpage = 'True') {
rewrite (^.*$) /holding-page last;
}
proxy_pass $backend;
}
Also, I have a list of IPs that should be whitelisted and not redirected to holding pages. How it's possible to do?
You can use the Nginx geo module to create a variable based upon client IP address, you can specify individual IP addresses or CIDR ranges:
geo $bypassip {
default 0;
64.233.160.0/19 1;
66.102.0.0/20 1;
}
Then override your variable if the IP matches one in your list:
if ($bypassip = 1){
set $setholdingpage False;
}
I use a similar setup to block certain geographic regions but still allow Google crawlers to access my site.
You can make use of the allow deny directives.
If I get you correct the whitelist will be your $setholdingpage variable in some sort?
try this
server {
error_page 403=#holding;
location / {
allow 127.0.0.1;
allow 192.168.1.0/24;
deny all;
proxy_pass http://backend;
}
location /#holding {
root /path/to/your/holding/html;
index holdingv1.html;
}
}
This will send the non-whitelisted IPs to the error-page you specified. The error_page can be in the location as well.
Not tested but this should do the trick.
References:
http://nginx.org/en/docs/http/ngx_http_access_module.html#allow

How to block Nginx requests where http_referer matches requested URL

I am trying to block a webcrawler that uses the requested page as the http_referer, and I can't figure out what variable to compare it to.
e.g.
location / {
if ($the_variable_with_the_current_full_uri = $http_referer) {
return 403;
}
}
The variable has to match protocol, host, and URL, so that internal redirects from http to https don't get blocked.
So if someone requests "https://www.example.com/pages/1" with the $http_referer of "https://www.example.com/pages/1", it should be blocked.
As a secondary question, is it possible block requests on two conditions: where the above check matches, as well as matching a specific user agent string?
The full URL can be constructed by concatenating a number of variables together.
For example:
$scheme://$host$request_uri
The secondary condition could be handled using a map (see this document).
For example:
map $http_user_agent $my_http_referer {
default "";
blahblah $http_referer;
}
server {
...
if ($scheme://$host$request_uri = $my_http_referer) { return 403; }
...
}

Nginx conditionally allow all to react sub-route based on IP

I'm setting up an NGINX server and need to configure it to allow only certain IPs access to the root of a react application, but allow all to a certain subfolder (react route). Basically I need to allow all traffic to /sub/ but only a handful of IPs to the home directory /.
I tried
location /sub/* { allow all;}
location / {
allow x.x.x.x;
deny all;}
but was getting a 403 error when using any other IP address except the 'x.x.x.x'.
What's the correct way to achieve this?
Thanks.
Here is what you can try to do:
map $uri $disallow_by_route {
~^/subroute/ ""; # allow /subroute/... for all
default 1;
}
map $remote_addr $disallow {
x.x.x.x ""; # some allowed IP
y.y.y.y ""; # another allowed IP
default $disallow_by_route;
}
server {
...
location / {
if ($disallow) { return 403; }
...
}
}
However if your allowed pages used some assets (js, css, images etc.) from some other path than /subroute/... this config won't let them to load on restricted IPs. You can try to allow them checking the value of HTTP Referer header with a more complex map blocks chain:
map $http_referer $disallow_by_referer {
# use a regex for your actual domain here
~^https?://example\.com/subroute/ "";
default 1;
}
map $uri $disallow_by_route {
~^/subroute/ "";
# list all the other possible assets extensions (png, gif, svg, webp etc.) here
~\.(?:js|css)$ $disallow_by_referer;
default 1;
}
map $remote_addr $disallow {
x.x.x.x ""; # some allowed IP
y.y.y.y ""; # another allowed IP
default $disallow_by_route;
}
server {
...
location / {
if ($disallow) { return 403; }
...
}
}
Please note that this solution won't work if your server configuration (or react app itself) sets the referer policy to no-referer.

alternative log file in nginx for local requests

How can I redirect access logs to alternative file if requests come from my local network (e.g. 192.168.x.x)?
I've found some hints how I can disable logs based on requester IP, but in my case I want to log these requests to another file so that for development purposes I'd see only my own logs only in that specific file.
The answer is in your referenced pages, you just need to reverse the 1s and the 0s.
This should work:
map $remote_addr $private_ip {
~^192\.168\. 1;
default 0;
}
map $remote_addr $public_local {
~^192\.168\. 0;
default 1;
}
server {
...
# access-private.log for requests from local network
access_log /path/to/access-private.log main if=$private_ip;
# access.log for all other requests
access_log /path/to/access.log main if=$public_ip;
...
}
See this and this for details.
EDIT: Actually the geo directive is more appropriate for mapping a $remote_addr:
geo $private_ip {
192.168.0.0/16 1;
default 0;
}
geo $public_local {
192.168.0.0/16 0;
default 1;
}
See this document for details.

Resources