Nginx Reverse proxy to different server - redirect

We're trying to setup a reverse proxy to redirect traffic to an internal network from a DMZ webserver, using nginx.
The traffic comes in on 443, hits an apache page user logs in against an ldap server, then we are redirecting the traffic from apache to nginx (which is listening on 8089). Nginx is then to proxy that traffic back to the internal network.
The apache redirect works, and at least some of the nginx proxy is working. The page on the internal server loads, but all of the resources on the page are double appending the URL. For example:
https ://webserver.us.com ==redirects==> http ://webserver.us.com:8089 ==Nginx Proxy==> http ://internal.server.com:8080/page
http: //internal.server.com/page loads, but all of the resources on the page are trying to load as:
http: //internal.server.com/page/page/resource.
when hitting the internal page directly, they are of course http: //internal.server.com:8080/page/resource
I am sure that there is an error in our setup of the proxy_pass, proxy_redirect and root / location, but I can't figure it out...
Our Nginx.conf is as follows: (FYI this is a solaris server)
worker_processes 1;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 8089;
server_name <internal.server.com>;
access_log /var/opt/csw/nginx/logs/access.log;
error_log /var/opt/csw/nginx/logs/error.log;
root http://<internal.server.com>:8080;
index index.html index.htm;
location / {
proxy_pass http://<internal.server.com>:8080/<page>/;
proxy_redirect http://<internal.server.com>:8080/<page> http://<internal.server.com>:8080/<page>;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}
Whenever we set anything in the "location" parameter other than "/" it returns an nginx 404, and the error log shows:
"/var/opt/csw/nginx//RES_NOT_FOUND"

The client requests webserver.us.com/ which is translated to internal.server.com:8080/page/ through the reverse proxy.
The document specifies resource URIs like /page/resource, so the client requests these as webserver.us.com/page/resource which is translated to internal.server.com:8080/page/page/resource through the reverse proxy.
The simplest solution is to make the reverse proxy transparent. You can add an exact match location to map / to your application's entry point:
location = / {
rewrite ^ /page/ last;
}

Related

URL requested a HTTP redirect, but it could not be followed. - Facebook/Nginx issue

I have used Facebooks sharing debugger to highlight an issue on the website
URL requested a HTTP redirect, but it could not be followed.
https://developers.facebook.com/tools/debug/sharing/?q=https%3A%2F%2Fwww.badgerbookings.com
This is also stopping it accepting the url in the privacy policy when creating an app.
I have researched and made sure to add all OG meta tags. I also "reduced" down the redirects on my nginx to only support a http > https redirect which to me seems pretty standard.
It still produces the error on both the debugger and the Privacy Policy URL.
My Nginx config:
server_tokens off; #Enables or disables emitting nginx version on error pages and in the “Server” response header field
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
server_name _;
return 301 https://www.badgerbookings.com$request_uri;
}
server {
server_name www.badgerbookings.com badgerbookings.com *.badgerbookings.com;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; # allow websockets
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Forwarded-For $remote_addr; # preserve client IP
proxy_set_header Host $http_host;
proxy_set_header X-Forward-Proto http;
proxy_set_header X-Nginx-Proxy true;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/badgerbookings.com-0001/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/badgerbookings.com-0001/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
Go to Facebook Developer's policy page.
Scroll down to this bit:
Privacy Policy
a. Provide a publicly available and easily accessible privacy policy
that explains what data you are collecting and how you will use that
data.
Now run
curl https://badgerbookings.com/terms
Are you looking at an easily accessible privacy policy which is publicly available at that url?
You maybe having IPv6 issues which can be resolved as simple as adding a listen [::]:443 ssl directive in you SSL server block.
If that doesn't fix it, try redirecting with a matching if directive
if ($scheme != "https") {
return 301 https://www.badgerbookings.com$request_uri
}
This is best if you unite both server blocks in one, to avoid more code. Just delete the non-https one and insert port 80 listen directives on the other one as well, with that conditional redirect, this way your code will be even slimmer.

nginx ingress annotations to redirect to authentication and get back headers

I've the below nginx conf file to redirect all the requests (by default) to /auth (of my service) and then get back a response header (foo_id). This header will be forwarded to the original request URI triggered by user. The below works properly with the nginx.
...
location /
{
auth_request /auth;
auth_request_set $foo_id $upstream_http_foo_id;
proxy_pass $request_uri
proxy_set_header X-foo-Token $foo_id;
root html;
index index.html index.htm;
}
location /auth
{
internal;
proxy_pass https://myhost/myservice;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-URI $request_uri;
}
But I need the corresponding ingress rules/annotations that are required to achieve the above use case. I couldn't get the respective auth/proxy-pass related annotations. Kindly help out.
You can use Nginx Ingress Annotations to achieve this goal.
In nutshell:
Assuming, you have an external auth service, which has a Kubernetes service configured.
You need an annotation, which sends auth requests to this service:
nginx.ingress.kubernetes.io/auth-url: http://auth-service.<NameSpace>.svc.cluster.local/auth
Also, you can use nginx.ingress.kubernetes.io/auth-snippet annotation to set your custom configuration for the auth request e.g.
nginx.ingress.kubernetes.io/auth-snippet: |
auth_request_set $foo_id $upstream_http_foo_id;
proxy_pass $request_uri
proxy_set_header X-foo-Token $foo_id;
If you need to return some headers on successful auth, you can use nginx.ingress.kubernetes.io/auth-response-headers:
nginx.ingress.kubernetes.io/auth-response-headers: X-Auth
And, nginx.ingress.kubernetes.io/auth-signin to specify the custom error page

Nginx reverse proxy for HTTPS traffic (through uWSGI socket) and websockets

I have Nginx set up as a reverse proxy for a Flask Application running on uWSGI. The configuration looks like:
server {
listen 80;
server_name subdomain.app.org;
location / {
include uwsgi_params;
uwsgi_pass unix:/home/ubuntu/app/myapp.sock;
}
}
Additionally, I want to access a websocket running on the same machine on port 3232. So I changed the config to:
server {
listen 80;
server_name subdomain.app.org;
location /ws/ {
proxy_pass http://127.0.0.1:3232;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_read_timeout 86400;
}
location / {
include uwsgi_params;
uwsgi_pass unix:/home/ubuntu/app/myapp.sock;
}
}
When I try to access the socket from remote using wscat -c ws://subdomain.app.org/ws I receive error: Error: unexpected server response (301).
Everything works fine when I set the location of the websocket as well as the Flask app to /, but then I cannot access my Flask application anymore.
Any ideas? I undestand that many people before me have asked this but not in connection with a uWSGI socket running. I have spent hours reading stackoverflow posts on this but didn't find anything suitable. Thanks for your help.

502 Bad Gateway when redirecting on nginx

I have a problem with nginx redirection. I work on nginx 1.4.4 and i have two seperate redirects. It should work two ways:
First redirect: Address address1.com redirects to address address2.com ->
Address address2.com redirects to addres2.com:1234 where the application resides.
Second redirect is directly from ddress2.com:
- address2.com redirects to address2.com:1234
Now the problem:
- Redirect from address1.com to address2.com works, but address2.com to address2.com:port doesn't. It ends with 502 Bad Gateway error. Configs and
errors from log are presented below:
Information from error.log:
[error] : *386 connect() failed (111: Connection refused) while connecting to upstream, client: {client ip addr}, server:{server name}, request:
"GET / HTTP/1.1", upstream: "https://127.0.0.1:{port}", host: "{server name}"
Nginx uses many .conf files stored in conf.d location.
address1.conf (This works):
server {
### server port and name ###
listen {ip_addr}:443;
ssl on;
server_name address1.com;
access_log /var/log/nginx/address1.log;
error_log /var/log/nginx/address1-error.log;
ssl_certificate /etc/httpd/ssl/servercert.crt;
ssl_certificate_key /etc/httpd/ssl/private/serverkey.key;
location / {
rewrite ^ $scheme://address2.com redirect;
}}
address2.com conf file (This doesn't):
server {
### server port and name ###
listen {ip_addr}:443;
ssl on;
server_name address2.com;
access_log /var/log/nginx/address2.log;
error_log /var/log/nginx/address2-error.log;
ssl_certificate /etc/httpd/ssl/servercert.crt;
ssl_certificate_key /etc/httpd/ssl/private/serverkey.key;
proxy_read_timeout 180;
location / {
proxy_pass https://127.0.0.1:{port};
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Ssl on;
proxy_set_header X-Forwarded-Protocol $scheme;
proxy_set_header X-Forwarded-HTTPS on;
}}
Funny thing is that I have another application working on the scheme addr3.com -> addr3.com:port and redirection works just perfect. The only
difference between address2.conf and address3.conf is port on which applications work. Each address uses https, Port 443 is open on the firewall.
Hope my description is detailed enough, if not just let me know.
I've been struggling with this problem for couple of days and haven't found any tips or solutions suitable for me.
I'd appreciate any help.
The problem might be with SELinux. Check to see if it running with sestatus. Since some forwarding is working for you, this command might be redundant, but others might require it:
sudo setsebool -P httpd_can_network_connect 1
To enable forwaring for specific ports, which might be your problem, run this command:
sudo semanage port -a -t http_port_t -p tcp 8088
Replace 8088 with the port in question.
The command semanage might not be found. How you install it is distro dependent, but you can most likely google for a solution to that.

Nginx site configuration disabling 301 rewrite for another site

I currently have two enabled site configurations in nginx, let us call them old-site.example and new-site.example. There is no other site configuration active.
old-site.example should 301-redirect to new-site.example. This currently works well as long as the old-site.example configuration is alone. After adding the new-site.example configuration file, it does not redirect anymore.
oldsite.conf:
server {
listen 80;
server_name *.old-site.example;
rewrite_log on;
location / {
return 301 http://www.new-site.example$request_uri;
}
}
newsite.conf:
server {
listen 80;
server_name www.new-site.example;
charset utf-8;
location / {
#forward to application server
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:8080;
}
}
other configuration details:
JBoss AS7 as application server running behind Nginx 1.5.1
This was a DNS related error, sorry everyone.
Background: The ISP of the client managed to "smart redirect" the domain instead of using DNS. They basically scraped the new site on their servers and returned it via the old domain. I'm speechless.
If you ever have a problem like this, check DNS resolution before second-guessing your config.