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.
Current Config
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;
}
What I've tried
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;
}
}
Also Note...
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
Related
I have an nginx config that looks similar to this (simplified):
http {
server {
listen 80 default_server;
location /api {
proxy_pass https://my-bff.azurewebsites.net;
proxy_ssl_server_name on;
}
}
}
Essentially, I have a reverse proxy to an API endpoint that uses https.
Now, I would like to convert this to an upstream group to gain access to keepalive and other features. So I tried this:
http {
upstream bff-app {
server my-bff.azurewebsites.net:443;
}
server {
listen 80 default_server;
location /api {
proxy_pass https:/bff-app;
proxy_ssl_server_name on;
}
}
}
Yet it doesn't work. Clearly I'm missing something.
In summary, how do I correctly do this "conversion" i.e. from url to defined upstream?
I have tried switching between http instead of https in the proxy_pass directive, but that didn't work either.
I was honestly expecting this to be a simple replacement. One upstream for another, but I'm doing something wrong it seems.
Richard Smith pointed me in the right direction.
Essentially, the issue was that the host header was being set to "bff-app" instead of "my-bff.azurewebsites.net" and this caused the remote server to close the connection.
Fixed by specifying header manually like below:
http {
upstream bff-app {
server my-bff.azurewebsites.net:443;
}
server {
listen 80 default_server;
location /api {
proxy_pass https:/bff-app;
proxy_ssl_server_name on;
# Manually set Host header to "my-bff.azurewebsites.net",
# otherwise it will default to "bff-app".
proxy_set_header Host my-bff.azurewebsites.net;
}
}
}
I want to listen port a range, and bind it with reverse proxy with incremental value(10000).
In example, i want to listen and bind it to this values:
example.com:20000 -> http://0.0.0.0:30000
example.com:20010 -> http://0.0.0.0:30010
example.com:20200 -> http://0.0.0.0:30200
my nxing conf:
server {
listen 20000-20200;
server_name example.com;
location / {
proxy_pass http://0.0.0.0:$server_port; ## << I want increment this port with 10000
}
}
How can i do this?
Wow, I didn't know that nginx allows to listen on port range. I didn't find it in documentation, but when I checked it myself, it is really working as expected.
Well, back to the question. Without additional modules nginx doesn't have any built-in mathematics. However, since all you need is the only one digit replacing, you can do it via regex capture group and concatenation of strings:
map $server_port $port {
"~\d(\d{4})" 3$1;
}
server {
listen 20000-20200;
server_name example.com;
location / {
proxy_pass http://0.0.0.0:$port;
}
}
If you're using OpenResty (or build nginx yourself with lua-nginx-module), you can use real mathematics with LUA code within the nginx config:
server {
listen 20000-20200;
server_name example.com;
location / {
set_by_lua_block $port { return ngx.var.server_port + 10000 }
proxy_pass http://0.0.0.0:$port;
}
}
When we enable the RabbitMQ Web Management Console then it is accessible by http://ip:15672.
Instead of this i want to access RabbitMQ managment console by this http://ip/rabitmq by using nginx
I have done changes in the nginx.
server {
listen 80;
server_name _;
location /rabbitmq {
proxy_pass http://localhost:15672;
}
}
but i dont know how to configure path prefix in rabbitnq ?
I suggest you read:
https://github.com/docker-library/rabbitmq/issues/249
In short, you can configure this in the /etc/rabbitmq/rabbitmq.conf by adding the following line:
management.path_prefix = /rabbitmq
If you are running in a docker environment, you will need to modify:
location /rabbitmq {
proxy_pass http://localhost:15672;
}
to
location /rabbitmq {
proxy_pass http://CONTAINERS_HOSTNAME:15672;
}
I'm a bit new to using nginx so I'm likely missing something obvious. I'm trying to create an nginx server that will reverse proxy to a set of web servers that use https.
I've been able to get it to work with one server list this:
server {
listen $PORT;
server_name <nginx server>.herokuapp.com;
location / {
proxy_pass https://<server1>.herokuapp.com;
}
}
However, as soon I try to add in the 'upstream' configuration element it no longer works.
upstream backend {
server <server1>.herokuapp.com;
}
server {
listen $PORT;
server_name <nginx server>.herokuapp.com;
location / {
proxy_pass https://backend;
}
}
I've tried adding in 443, but that also fails.
upstream backend {
server <server1>.herokuapp.com:443;
}
server {
listen $PORT;
server_name <nginx server>.herokuapp.com;
location / {
proxy_pass https://backend;
}
}
Any ideas what I'm doing wrong here?
I am using Nginx reverse proxy with Kubernetes services. Config is following:
events {
}
http {
upstream my-service-3000 {
server my-service:3000;
}
server {
listen 443 ssl;
server_name myserver.net;
ssl_certificate /key.pem;
ssl_certificate_key /key.pem;
location / {
allow myIP;
deny all;
proxy_pass http://my-service-3000;
}
}
server {
...
}
}
It works fine (doing reverse proxy, terminating ssl, changing port, finding Kubernetes service), till the moment I try whitelist only my IP. When I try to access service via https - I got 403 from Nginx. I've tried to move around allow/deny commands, but it do not help. Any suggestions where could be the problem?
Also I am behind proxy by my self - so I am using my external organisation IP.
The whitelisting should be under the http directive, not under the location directive.
http {
allow MyIp;
deny all;
upstream my-service-3000 {
server my-service:3000;
}
server {
listen 443 ssl;
server_name myserver.net;
ssl_certificate /key.pem;
ssl_certificate_key /key.pem;
location / {
proxy_pass http://my-service-3000;
}
}
server {
...
}
}