I have a situation where we have multiple test environments. Each environment needs to access different versions of a service and we have an NGINX
proxy that sits in-front of these different services. Currently we're using multiple servers to do the proxy. Is there a way I can use NGINX
allow
or deny
to filter which backend the environments connect to based on remote IP
?
The v1
environment has IP
addresses in the 10.0.1.0/24
range, and v2
is only connected to by IP's in 10.0.2.0/24
.
Simplified for brevity.
server {
listen 80;
server_name service.v1.net;
proxy_pass http://10.0.10.56:8081;
}
server {
listen 80;
server_name service.v2.net;
proxy_pass http://10.0.10.56:8082;
}
Clearly this doesn't work.
server {
listen 80;
server_name service.net;
location / {
# v1 proxy
allow 10.0.1.0/24;
deny all;
proxy_pass http://10.0.10.56:8081;
}
location / {
# v2 proxy
allow 10.0.2.0/24;
deny all;
proxy_pass http://10.0.10.56:8082;
}
}
I know this can be done with serving a proxy on different ports and iptables
rules - I'm trying to figure out if NGINX
can do this by itself.
You can use ngx_http_geo_module for that. (Which should just work out of the box). It sets variables depending on the client IP address, which can then be used in an if.
geo $environment {
10.0.1.0/24 v1;
10.0.2.0/24 v2;
}
server {
listen 80;
server_name service.net;
location / {
if ($environment = v1) {
proxy_pass http://10.0.10.56:8081;
}
if ($environment = v2) {
proxy_pass http://10.0.10.56:8082;
}
}
}
All other IPs will see a 404 in this case.
Although this works, be advised that using if within a location block can be very tricky: http://wiki.nginx.org/IfIsEvil