URL path aliasing for multiple applications in HAProxy - networking

This question is similar to this question, however deals with HAProxy 2.5+.
I'm wanting to have multiple applications have aliased subpaths however I'm having a hard time wrapping my head around how to do it. I'm not wanting configure each application with a individual subpath, instead manage it all through HAProxy. An example of this would be:
example.com/app1 ----> example.com:9090/
example.com/app2 ----> example.com:9091/
etc ...
Below is a simplified HAProxy config of what I want to implement:
frontend http-in
bind :80
option socket-stats
option http-ignore-probes
option forwardfor
acl acl_root path -i /
acl acl_minio path_beg /minio
acl acl_transmission path_beg /transmission
use_backend minio if acl_minio acl_root
use_backend transmission if acl_transmission acl_root
http-request del-header x-forwarded-for
default_backend deny_403
backend deny_403
mode http
option http-server-close
option forwardfor
http-request deny deny_status 400
backend minio
balance roundrobin
option forwardfor
http-request replace-path /minio(.*) /\1
server localsrv 192.168.1.69:9093 check
backend transmission
balance roundrobin
option forwardfor
http-request replace-path /transmission(.*) /\1
server localsrv 192.168.1.69:9091 check
Output of accessing example.com/minio gives this result:
http-in minio/localsrv 0/0/0/1/1 200 1528 - - ---- 1/1/0/0/0 0/0 "GET /minio HTTP/1.1"
http-in deny_403/<NOSRV> 0/-1/-1/-1/0 400 206 - - PR-- 1/1/0/0/3 0/0 "GET /styles/root-styles.css HTTP/1.1"
http-in deny_403/<NOSRV> 0/-1/-1/-1/0 400 206 - - PR-- 2/2/0/0/3 0/0 "GET /static/js/main.069a61a0.js HTTP/1.1"
http-in deny_403/<NOSRV> 0/-1/-1/-1/0 400 206 - - PR-- 1/1/0/0/3 0/0 "GET /static/css/main.90d417ae.css HTTP/1.1"
http-in deny_403/<NOSRV> 0/-1/-1/-1/0 400 206 - - PR-- 3/3/0/0/3 0/0 "GET /images/background.svg HTTP/1.1"
http-in deny_403/<NOSRV> 0/-1/-1/-1/0 400 206 - - PR-- 2/2/0/0/3 0/0 "GET /images/background-wave-orig2.svg HTTP/1.1"
Most of the sites that I've visited use the old reqrep however with newer versions of haproxy you will need to use http-request in the configuration todo the same, however how functionality is diffrent so I'm kinda stuck how to move forward. I can do this in Nginx quite easily but HAProxy is a lot diffrent.

Related

application under Nginx switching IPs, how to make always the same?

I am running application under nginx with configuration:
upstream myup {
server localhost:8833
server localhost:8844
}
server {
listen 80;
server_name: localhost;
location / {
proxy_pass http://myup.com
}
}
This configuration works for me, but when I am watching IP using app in logs, I see the following:
127.0.0.1/ - - - [11/JAN] "GET /info HTTP/1.0" 200
0.0.0.0.0.0.0.1 - - - [11/JAN] "GET /image.css HTTP/1.0" 200
127.0.0.1/ - - - [11/JAN] "GET /script.js HTTP/1.0" 200
0.0.0.0.0.0.0.1 - - - [11/JAN] "GET /logo.svg HTTP/1.0" 200
every second request changes IP between (127.0.0.1, 0.0.0.0.0.0.0.1)
Logs from Nginx there always have IP: 127.0.0.1
Logs from my app without Nginx always have IP: 0.0.0.0.0.0.0.1
How do I manage to work continuously with the same IP as my application depends on it?

nginx forward proxy config is causing "upstream server temporarily disabled while connecting to upstream" error

I want to set up nginx as a forward proxy - much like Squid might work.
This is my server block:
server {
listen 3128;
server_name localhost;
location / {
resolver 8.8.8.8;
proxy_pass http://$http_host$uri$is_args$args;
}
}
This is the curl command I use to test, and it works the first time, maybe even the second time.
curl -s -D - -o /dev/null -x "http://localhost:3128" http://storage.googleapis.com/my.appspot.com/test.jpeg
The corresponding nginx access log is
172.23.0.1 - - [26/Feb/2021:12:38:59 +0000] "GET http://storage.googleapis.com/my.appspot.com/test.jpeg HTTP/1.1" 200 2296040 "-" "curl/7.64.1" "-"
However - on repeated requests, I start getting these errors in my nginx logs (after say the 2nd or 3rd attempt)
2021/02/26 12:39:49 [crit] 31#31: *4 connect() to [2c0f:fb50:4002:804::2010]:80 failed (99: Address not available) while connecting to upstream, client: 172.23.0.1, server: localhost, request: "GET http://storage.googleapis.com/omgimg.appspot.com/test.jpeg HTTP/1.1", upstream: "http://[2c0f:fb50:4002:804::2010]:80/my.appspot.com/test.jpeg", host: "storage.googleapis.com"
2021/02/26 12:39:49 [warn] 31#31: *4 upstream server temporarily disabled while connecting to upstream, client: 172.23.0.1, server: localhost, request: "GET http://storage.googleapis.com/my.appspot.com/test.jpeg HTTP/1.1", upstream: "http://[2c0f:fb50:4002:804::2010]:80/my.appspot.com/test.jpeg", host: "storage.googleapis.com"
What might be causing these issues after just a handful of requests? (curl still fetches the URL fine)
The DNS resolver was resolving to both IPV4 and IPV6 addresses. The IPV6 part seems to be causing an issue with the upstream servers.
Switching it off made those errors disappear.
resolver 8.8.8.8 ipv6=off;

nginx: ignore some requests without proper Host header

In nginx to drop connection I can return 444, however there is a problem with that IMO. It seems that 444 doesn't silently drop the connection, but actually closes it gracefully, as a result tools that all these spammers use will rapidly retry the request:
149.56.28.239 - - [22/Sep/2016:20:33:18 +0200] "PROPFIND /webdav/ HTTP/1.1" 444 0 "-" "WEBDAV Client"
149.56.28.239 - - [22/Sep/2016:20:33:18 +0200] "PROPFIND /webdav/ HTTP/1.1" 444 0 "-" "WEBDAV Client"
is there a way to abort tcp (not gracefully as if my server was suddenly unplugged from the net) so that on the requester end it would continue waiting? Are there any drawbacks/problems with that and is that possible with nginx?
To drop requests without Host header in nginx you use the following config:
server {
listen 80;
return 444;
}
Is there a way to handle some of these requests for example if requested url matches some regex?

Wamp Local Wordpress site: ERR_CONNECTION_REFUSED

I have a live HTTPS wordpress site running. Recently I tried to WAMP it locally to test out some other themes, Git & stuff, but the site wouldn't load, returning ERR_CONNECTION_REFUSED errors.
The live site is hosted by Siteground, running with SSL (HTTPS).
I have set up the database correctly. (I'm sure because it used to return database connection error and then I fixed it)
I used to get Invalid command 'AddOutputFilterByType', 'Header' in Apache error logs. I then turned on the mod_filter and mod_headers in Wamp, and now I still get ERR_CONNECTION_REFUSED error in browser, but the error log does not add new messages.
This is the only local site which wouldn't run. I have other Wamp sites run with no issues.
The only clue for me could be the Apache access log, which is pasted as follows:
127.0.0.1 - - [17/May/2016:16:04:41 +1000] "POST /wp-cron.php?doing_wp_cron=1463465081.0992779731750488281250 HTTP/1.0" 200 -
127.0.0.1 - - [17/May/2016:16:04:28 +1000] "GET / HTTP/1.1" 301 -
127.0.0.1 - - [17/May/2016:16:04:27 +1000] "GET / HTTP/1.1" 301 -
127.0.0.1 - - [17/May/2016:16:04:41 +1000] "POST /wp-cron.php?doing_wp_cron=1463465081.0982780456542968750000 HTTP/1.0" 200 25
127.0.0.1 - - [17/May/2016:16:30:11 +1000] "GET / HTTP/1.1" 200 435
127.0.0.1 - - [17/May/2016:16:30:13 +1000] "GET / HTTP/1.1" 200 435
I have tried to disabled wp-cron but it couldn't fix the problem.
Thanks all in advance.

How to handle "OPTIONS *" request in nginx?

In my environment, I use perlbal to redirect request to nginx. If verify_backend is on. perbal will send a "OPTIONS *" request to nginx, but the nginx response it as a bad request.
According to RFC2616:
If the Request-URI is an asterisk (""), the OPTIONS request is intended to apply to the ?server in general rather than to a specific resource. Since a server's communication options typically depend on the resource, the "" request is only useful as a "ping" or "no-op" type of method; it does nothing beyond allowing the client to test the capabilities of the server. For example, this can be used to test a proxy for HTTP/1.1 compliance (or lack thereof).
I think perlbal is trying to send this kind of request, but nginx can't handle this by default.
When I try to send a request "OPTIONS * HTTP/1.0", I always get "HTTP 400 bad request":
127.0.0.1 - - [18/Feb/2013:03:55:47 +0000] "OPTIONS * HTTP/1.0" 400 172 "-" "-" "-"
but it works on "OPTIONS / HTTP/1.0" option without asterisk requests :
127.0.0.1 - - [18/Feb/2013:04:03:56 +0000] "OPTIONS / HTTP/1.0" 200 0 "-" "-" "-"
How can I configure nginx to let it respond with http return 200 rather than HTTP return 400 ?
I know it's an overkill but one solution is to put HAProxy in front of it to just capture that OPTIONS request and then build your own response in HAProxy:
location * {
if ($request_method = OPTIONS ) {
add_header Content-Length 0;
add_header Content-Type text/plain;
return 200;
}
}
The only way I found to modify the behaviour in this case was to respond to 400 in general:
error_page 400 =200 /empty_reply.html;
You could just send empty responses to everything you cannot handle.
For whoever wants to try to solve this another way, you can simulate this requests with:
curl -X OPTIONS $yourserverip --request-target "*" --http1.1

Resources