Nginx as a forward proxy - nginx

I am trying to configure nginx as a forward proxy and establish persistent connection between the nginx and the upstream server. When I set
server {
location / {
proxy_pass http://$http_host$request_uri;
proxy_http_version 1.1;
proxy_set_header Connection "";
...
}
}
in the location context, it has no effect until I have a upstream module that has keepalive directive in it. Is it mandatory to specify the upstream module with keepalive directive?
If I do that way,
http
{
upstream up {
server $http_host;
keepalive 20;
}
server {
proxy_pass http://up$request_uri;
}
}
I get the error host not found in upstream "$http_host". Looks like the server directive is not using it as variable but merely looking for a server named $http_host? I tried finding hints in online resources but couldn't get help. I need someone to point me how this goes wrong?

Related

NGINX Proxy pass to external site that has internal redirect

i'm trying to configure an nginx proxy that hide an internal site via the proxy pass but without success.
the config i used is
location /internal1/ {
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 15;
proxy_read_timeout 180;
proxy_pass http://internal1/;
}
upstream internal1 {
server a.b.c.d:80;
}
the problem is that when i try to reach the a.b.c.d site it redirect to a login page that sould be http://a.b.c.d/login and after i login it redirect at another page http://a.b.c.d/device/config . with the proxy it redirect to http://mysite/login and http://mysite/device/config
that make the proxy do not work and show me resource not found and i couldn not see any of the pages.
If i change the proxy_pass value to http://a.b.c.d/login/ it show the login page at http://mysite/internal1 and after i login it show no resource found because it try to reach http://mysite/device/config.
someone have some suggestion on how to configure it in the proper way?
thanks for all the answer
EDIT:
sorry for the late answer but i got very busy in the meanwhile, anyway that solution work for 1 device but now all my device connected go only that device "internal" page and i cannot differentiate between more cause nginx do not support the same location in multiple config ( all device have ip/page1 )
location /page1/
{
proxy_pass mysite/internal1/page1;
proxy_redirect off;
proxy_set_header Host $host;
}
EDIT2:
unlucky it's not possible to expose all device to internet directly. the solution i found is:
create a custom DNS subdomain and then create a different nginx server block for every device with his own location and future redirect/proxy ecc...
If you want to expose the web UI of all your devices that live in the internal network to be accessible through Internet - then you will have to create a subdomain (and a corresponding virtual host config) for each device.
Suppose that the domain that points to your nginX is mydevices.net and that you have 2 devices - on 192.168.2.10 and 192.168.2.20
Then your nginX config will look like this:
server {
listen 80;
server_name dev1.mydevices.net;
location / {
proxy_pass internal1;
proxy_redirect default;
}
}
upstream internal1 {
server 192.168.2.10;
}
server {
listen 80;
server_name dev2.mydevices.net;
location / {
proxy_pass internal2;
proxy_redirect default;
}
}
upstream internal2 {
server 192.168.2.20;
}

With NGINX upstreams, is it possible to proxy pass to both HTTP and HTTPS backends in the same upstream?

Suppose I want to proxy some portion of my traffic to a remote backend instead of the local listener on the server. For example:
upstream backends {
server 127.0.0.1:8080 weight=20; # local process (HTTP)
server other-remote-backend.company-internal.com:443; # remote server (HTTPS)
}
location / {
# ...other stuff...
proxy_pass http://backends;
}
In the above configuration, every 20 or so requests NGINX will try to route to http://other-remote-backend.company-internal.com:443 which is only listening for SSL.
Is there a way for the upstream to define its own protocol scheme? Right now this seems undoable without changing the local listener process to be SSL as well (which is a less than desirable change to make).
Thanks
As is the usual case, I've figured out my own problem and its quite obvious. If you're trying to accomplish the above the trick is quite simple.
First create a new NGINX Virtual Host that listens on HTTP and proxy_passes to your remote HTTPS backend like so:
/etc/nginx/sites-available/remote_proxy
upstream remote {
server other-remote-backend.company-internal.com:443;
}
server {
# other-remote-backend.company-internal.com:443;
listen 8181;
server_name my_original_server_name;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass https://remote;
}
}
You can now use just http for your upstreams in the original configuration listening on 443:
/etc/nginx/sites-available/default
upstream backends {
server 127.0.0.1:8080 weight=20; # local process (HTTP)
server 127.0.0.1:8181 # local nginx proxying to HTTPS remote
}
location / {
# ...other stuff...
proxy_pass http://backends;
}
Now just enable your new site and restart
$ ln -s /etc/nginx/sites-available/remote_proxy /etc/nginx/sites-enabled/ && systemctl restart nginx

Nginx configuration issue - getting 404

I trying to configure Nginx to serve as a HTTP Load Balancer. Just for sake of prove of concept, I configured my nginx to redirect to ordinary http website (www.nationalrail.co.uk).
This is how my nginx configuration looks like:
http {
upstream stream_backend {
server www.nationalrail.co.uk:80;
}
server {
listen 80;
error_log /home/ubuntu/logs/error.log debug;
location / {
proxy_pass http://stream_backend;
}
}
}
However, when I going to my Nginx url (say, loadbalancer.com) - I receiving "404 - not found" error.
What do I miss?
Have you tried like this ?
http {
server {
server_name loadbalancer.com;
location / {
proxy_pass http://www.nationalrail.co.uk;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
}
I discovered that the issue was due to http redirects. Redirects shall be explicitly handled inside Nginx, otherwise it doesn't works as expected.

nginx - Forward requests to another proxy

So, I have a third party proxy (probably under squid) which will only accept connections from one of my IP's, but I need to be able to access it from a variety of IPs.
So I'm trying to put a nginx to forward requests to this proxy. I know nginx can forward request like this:
location / {
proxy_pass http://$http_host$uri$is_args$args;
}
This would work if I needed nginx to forward requests directly to the target site, but I need it to pass it to proxy X first. I tried this:
upstream myproxy {
server X.X.X.X:8080;
}
location / {
proxy_pass http://myproxy$uri$is_args$args; // also tried: http://myproxy$http_host$uri$is_args$args
}
But I get "(104) Connection reset by peer". I guess because nginx is proxying like this:
GET /index.html HTTP/1.1
Host: www.targetdomain.com.br
But I need it to proxy like this:
GET http://www.targetdomain.com.br/index.html HTTP/1.1
I found out that this works:
http {
# resolver 8.8.8.8; # Needed if you use a hostname for the proxy
server_name ~(?<subdomain>.+)\.domain\.com$;
server {
listen 80;
location / {
proxy_redirect off;
proxy_set_header Host $subdomain;
proxy_set_header X-Forwarded-Host $http_host;
proxy_pass "http://X.X.X.X:8080$request_uri";
}
}
}
You need to use resolver if X.X.X.X is a hostname and not an IP.
Check https://github.com/kawanet/nginx-forward-proxy/blob/master/etc/nginx.conf for more tricks.
EDIT: also check nginx server_name wildcard or catch-all and http://nginx.org/en/docs/http/ngx_http_core_module.html#var_server_name

Tornado WebSocket Server without proxy

I have a tornado websocket server that works fine on my local machine. but when I deploy it to a web server and run it with supervisord I cant connect with javascript websockets.
I have tried to open the port in firewall but doesnt work.
I also tried to use a proxy with nginx (and the tcp module)
tcp {
upstream websockets {
server abc.de.efg.hij:23581;
check interval=3000 rise=2 fall=5 timeout=1000;
}
server {
listen abc.de.efg.hij:45645;
server_name _;
tcp_nodelay on;
proxy_pass websockets;
}
}
but also doesnt work.
whats wrong here?
You need to add an extra 'location' section for the websocket to make sure the upgrade headers are passed correctly:
location /YOUR_SOCKET_ENDPOINT/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
Docs are here: http://nginx.org/en/docs/http/websocket.html

Resources