HAProxy SSL Redirect Loop - http

I'm using HAProxy for load balancing the traffics. It works perfect for HTTP request but however it shows this webpage has a redirect loop on HTTPS. How to solve this looping?

Your httpsclient backend isn't being used in your current config (all traffic is going to the http backend because its set to default and you have no rules that would map it to a specified backend) try mapping a rule like this maybe:
acl http_80 dst_port 80
acl https_443 dst_port 443
use_backend httpclient if http_80
use_backend httpsclient if http_443
(add this at the bottom of your frontend params, just above your first backend)

Related

In a reverse proxy server + Python HTTPS Server, who should handle SSL Certificates for HTTPS connections?

Suppose I want to use a combination of NGinX (probably another since it doesn't proxy HTTP/2 requests) and Hypercorn. As both can handle SSL certificate files, I wonder who is the best suited to do this for an HTTPS request. It is important to me that Hypercorn could listen to 443 port and I'm not sure it can do that without specifying certfile and keyfile parameters.
Well, that depend what you want to do.
The simpliest solution is to configure both to use SSL.
Nginx will receive the request, decipher it, process it, send it to Hypercom on port 443 as an HTTPS Client. Hypercom will get the request as any normal HTTPS client.
If your goal is security : go with both
If your goal is just to not
have hypercom expose directly, you can configure it to not use SSL
Nginx support by default proxying request to an HTTPS upstream so that's the best solution I think. However, you might need to play with setting http-header for hypercom to correctly understand who's the client by playing with X-Forwarded-For, X-Forwarded-Host and any headers that might be needed by Hypercom.

NGINX Forwarding a request

I have an NGINX Server set up, I'd like to take a request and forward it to another application on a TCP port.
Let's say I have the following JSON payload
{
"someKey1": 1234,
"someKey2": "a string"
}
This is sent inside query parameters like the following
https://mywebsite.com?payload=%7B%0A%20%22someKey1%22%3A%201234%2C%0A%20%22someKey2%22%3A%20%22a%20string%22%0A%7D
Is there a way to forward that JSON payload to TCP port 1234 natively with NGINX?
Additionally, can I do any pre-processing of the above payload prior to it being forwarded to TCP port 1234. For example, I'd like to covert the above JSON to
someKey1=1234,someKey2="a string"
And then forward this data to TCP port 1234
I understang I'd have to create some sort of REST endpoint using something like springboot to do this, but I'd really like to try and accomplish the above natively with NGINX if possible.
Nginx's primary purpose is HTTP server/proxy.
It can be scripted via ngx_http_lua_module, but for your task it is much simpler to make an app/microservice that will listen HTTP and forward your custom protocol, or modify your app that listens mentioned port to understand HTTP.
When your endpoint talks HTTP - nginx can then be used for routing:
location /some_path/ {
proxy_pass http://localhost:1234/;
}
location /some_other_path/ {
proxy_pass http://localhost:1235/;
}
NGINX is simple web-server, which accepts HTTP requests and forwards them to configured location (may be application server, or any other web-server), and responds back on HTTP to the requester. Data can't be processed inside NGINX.
You can configure forwarding rules in default file under sites-available directory in NGINX installation directory.
Here is the nice tutorial of NGINX configuration which might help you.

Redirect HTTPS request to HTTP (varnish) and then backend server HTTPS

My current configuration is like this :
1. Nginx listening on Port 8080 and 443
2. Varnish listening to port 80
Currently, when requests are made through HTTP they are delivered through the varnish, but when requests are made through HTTPS varnish doesn't deliver them.
My goal is to put varnish between Client and Nginx web server ( or make varnish work with port 443 )
Reading through articles and answer on StackOverflow, I tried to setup reverse proxy 443 to 80 ( or 8080 maybe ?)
I followed these article(s) :
https://www.smashingmagazine.com/2015/09/https-everywhere-with-nginx-varnish-apache/
https://serverfault.com/questions/835887/redirect-http-to-https-using-varnish-4-1
Problem is that when I try to set these up, I get 502 bad request error, and sometimes the default Nginx page.
PS: I'm trying to set this up using virtual server block, not default server.
PS2: I also need to deliver the final web page through HTTPS weather the request made through HTTP or HTTPS ( but I get too many redirects error )
PS3: I'm using Cloudflare
The basic concept is to sandwich varnish between an entity handling SSL and a back-end server working on port 8080 or whatever you choose.
Here's the traffic flow:
user 443 > front-end proxy for SSL offloading 443 > Varnish 80 > nginx 8080.
Now your options for Front end proxy are:
1.A Load balancer supporting SSL termination / offloading.
2.Nginx or apache working as a proxy to receive traffic on 443 and forward that on port 80 to Varnish.
Error 502 means your Varnish is having issues connecting your backend, please check varnish.vcl

haproxy: get the host name

I am trying to get the requester host/ip as it comes to haproxy node.
My haproxy config is as below:
frontend www-http
bind *:9000
http-request redirect location https://%fi:9143
frontend www-https
bind *:9143 ssl crt /root/keys.pem
reqadd X-Forwarded-Proto:\ https
default_backend www-backend
backend www-backend
balance roundrobin
cookie SERVERID insert indirect nocache
server server1 1.1.1.1:9080 cookie server1 weight 1 maxconn 1024 check
So here, if any http request comes, then I need to forward to https.
Now request may come either with ip address or hostname in fully qualified form, like
http://10.10.10.10:9000
this needs to be forwarded to https://10.10.10.10:9143
Again, the request may come hostname in fully qualified form, like
http://myhost.domain.com:9000
this needs to be forwarded to https://myhost.domain.com:9143
basically 10.10.10.10 and myhost.domain.com is same system.
Now with the above haproxy configuration, I am not able to get the below, as it is %fi (frontend_ip), so it is redirecting to https://10.10.10.10:9143
So my question is how I can get the haproxy node's ip/host as it comes to haproxy.
I tried below options, which did not work:
http-request redirect location https://%f:9143
http-request redirect location https://%[req.hdr(Host)]:9143
from https://www.haproxy.com/doc/aloha/7.0/haproxy/log_format_rules.html
See How do I set a dynamic variable in HAProxy? for additional details, but using that as a base, here is what should work for you:
frontend www-http
bind *:9000
# Redirect user from http port to https port
http-request set-var(req.hostname) req.hdr(Host),field(1,:),lower
http-request redirect code 301 location https://%[var(req.hostname)]:9143 if !{ ssl_fc }
frontend www-https
bind *:9143 ssl crt /root/keys.pem
reqadd X-Forwarded-Proto:\ https
default_backend www-backend
backend www-backend
balance roundrobin
cookie SERVERID insert indirect nocache
server server1 1.1.1.1:9080 cookie server1 weight 1 maxconn 1024 check
My situation was a little different as I was only looking to redirect a stats UI URL so I didn't have to go update each stats URL in our internal documentation. Here is what worked for my situation (in case it helps someone else):
userlist stats-auth
group admin users adminuser
group readonly users readonlyuser
# Passwords created via mkpasswd -m sha-512 PASSWORD_HERE
user adminuser password NOT_REAL_PASSWORD
user readonlyuser password NOT_REAL_PASSWORD
listen stats
# Used just for the initial connection before we redirect the user to https
bind *:4711
# Combined file containing server, intermediate and root CA certs along
# with the private key for the server cert.
bind *:4712 ssl crt /etc/ssl/private/my-site-name_combined_cert_bundle_with_key.pem
option dontlognull
mode http
option httplog
# Redirect user from http port to https port
http-request set-var(req.hostname) req.hdr(Host),field(1,:),lower
http-request redirect code 301 location https://%[var(req.hostname)]:4712/ if !{ ssl_fc }
acl AUTH http_auth(stats-auth)
acl AUTH_ADMIN http_auth_group(stats-auth) admin
stats enable
# The only "site" for using these ports is the admin UI, so use '/' as
# the base path instead of requiring something like '/haproxy_stats' or
# '/stats' in order to display the UI.
stats uri /
# Force a login if not already authenticated
stats http-request auth unless AUTH
# Allow administrator functionality if user logged in using admin creds
# (there are separate read-only username and password pairs)
stats admin if AUTH_ADMIN
I left out the frontend and backend config as those are much longer/detailed.
You can get the Source address through the src var.
Haproxy holds the requester IP under this , and can be used in acl's and other places.
For logging use it in the following manner : %[src]
Check out these links : src and fetching-samples(under layer 4)

haproxy + nginx get client ip behind anonymous proxy

I'm creating an application, where frontend is Haproxy and nginx.
Do you know a way to get client IP address if navigates behind anonymous proxy with HAproxy ?
My actual configuration for haproxy use "option forwardfor", but I get anonymous proxy IP instead real client IP in nginx logs (using $http_x_forwarded_for var)
frontend general_frontend
bind 111.111.111.111:80
default_backend nginx_farm_backend
backend nginx_farm_backend
balance roundrobin
option abortonclose
option forwardfor
http-check disable-on-404
http-check expect string nginx
option httpchk GET /index.html HTTP/1.0
# - Nodes
server nginx-server-1 222.222.222.222:8080 check on-error mark-down observe layer7 error-limit 1
server nginx-server-1 333.333.333.333:8080 check on-error mark-down observe layer7 error-limit 1
Thank you
Do you Using $remote_addr var for nginx log format?

Resources