How can I close haproxy frontend connections coming from unknown hosts? - haproxy

Now I am using nginx to close connections from unknown hosts and return 444 "no response"
How do I achieve the same with haproxy which is in front of nginx (saving the extra step between haproxy and nginx)
current nginx config:
server {
# Close connection for unrecognized hosts (444 no response)
listen 80 default_server;
listen [::]:80 default_server;
return 444;
}

This can be achieved using "silent-drop"
acl host_example req.hdr(host) -i example.com
http-request silent-drop if not host_example
https://cbonte.github.io/haproxy-dconv/2.0/configuration.html#4.2-http-request%20silent-drop
https://www.haproxy.com/blog/introduction-to-haproxy-acls/#using-acls-to-block-requests

Ejez you can either accept connections coming from known ip's are block connections of particular ip's in frontend of haproxy.
ref code:
allowed known ip's
acl network_allowed src 20.30.40.50 20.30.40.40
use_backend allowed_backend if network_allowed
or
block certain ip's only
acl is-blocked-ip src 192.0.2.11 192.0.2.12 192.0.2.18
http-request deny if is-blocked-ip
ref:
1.https://blog.sleeplessbeastie.eu/2018/03/26/how-to-block-particular-ip-addresses-on-haproxy/
2.https://raymii.org/s/snippets/haproxy_restrict_specific_urls_to_specific_ip_addresses.html

Related

What is '_' in Nginx listen option?

What is _ in nginx listen option?
I read listen 80 _; in nginx cookbook.
I found server_name _; mean just invalid server_name.
Then what is in listen?
ref https://nginx.org/en/docs/http/ngx_http_core_module.html#server
listen 443 ssl : makes nginx listen on all ipv4 address on the server, on port 443 (0.0.0.0:443)
while
listen [::]:443 ssl : makes nginx listen on all ipv6 address on the server, on port 443 (:::443)
[::]:443 will not make nginx respond on ipv4 by default, unless you specify parameter ipv6only=off :
listen [::]:443 ipv6only=off;
ssl :
The ssl parameter (0.7.14) allows specifying that all connections accepted on this port should work in SSL mode.
http2 :
The http2 parameter (1.9.5) configures the port to accept HTTP/2 connections.
This doesn't mean it accepts only HTTP/2 connections.

HAProxy ACL - Backend resolution

Given this HAProxy configuration:
acl acl-api-qa hdr(host) -i qa.example.com
use_backend backend-api-qa if acl-api-qa
backend backend-api-qa
mode http
balance leastconn
server-template api 10 _api._env=qa.service.consul resolvers consul resolve-prefer ipv4 check
acl acl-api-test hdr(host) -i test.example.com
use_backend backend-api-test if acl-api-test
backend backend-api-test
mode http
balance leastconn
server-template api 10 _api._env=test.service.consul resolvers consul resolve-prefer ipv4 check
Traffic is only getting routed to qa.example.com but test.example.com is a 503: service unavaliable as HAProxy seems to short-circuit when it encounters the first backend and ignores the next set of ACls and backends. Is this an ordering problem? can I not interweave ACLs and backends? Should these be built out as an ACLs section followed by a Backends section?
that appears to be the case? This worked for me:
acl acl-api-test hdr(host) -i test.example.com
acl acl-api-qa hdr(host) -i qa.example.com
use_backend backend-api-test if acl-api-test
use_backend backend-api-qa if acl-api-qa
backend backend-api-test
mode http
balance leastconn
server-template api 10 _api._env=test.service.consul resolvers consul resolve-prefer ipv4 check
backend backend-api-qa
mode http
balance leastconn
server-template api 10 _api._env=qa.service.consul resolvers consul resolve-prefer ipv4 check
but results in a fair bit of duplicated code in my consul template. does HAProxy expect acl, use-backend, and backend to be grouped into distinct groups?

HAProxy not redirecting http to https (ssl)

I'm using HAProxy for load balancing and only want my site to support https. Thus, I'd like to redirect all requests on port 80 to port 443.
How would I do this?
Edit: We'd like to redirect to the same url on https, preserving query params. Thus, http://foo.com/bar would redirect to https://foo.com/bar
frontend httpfront
mode http
bind *:80
redirect scheme https code 301 if !{ ssl_fc }
You need configure frontend for 443 port.
frontend (port 80) -> frontend (port 443) -> backend
Check my example:
frontend httpfront
mode http
bind *:80
redirect scheme https code 301 if !{ ssl_fc }
frontend httpsfront
mode tcp
bind *:443
default_backend app
backend app
mode tcp
balance roundrobin
server server01 10.10.10.11:443 check
server server02 10.10.10.12:443 check

Redirecting requests over 8443 to 443

One of our applications was previously configured to serve SSL from tomcat over port 8443. We're migrating this application to a new environment and switching to using nginx to handle SSL termination rather than tomcat (which will operate over 8080). I would like the ability for folks to be able to connect to the new environment over 8443 but get redirected to 443 (to support anyone's old bookmarks or links).
Currently have rulesets to redirect 80 to 443, and a full ssl_certificate set defined for listening on 443, but no luck trying a variety of methods to listen on 8443 and redirect to itself over 443.
Any suggestions?
Just define a separate server for port 8443, and do a redirect from there. You'd obviously still have to have a proper certificate for your 8443 server, too.
server {
listen 8443 ssl;
server_name example.com;
ssl_...;
return 301 https://example.com$request_uri;
}

haproxy acl not working in https/tcp mode

I am experiencing some problems, it seems I can't get acl's to work in tcp mode, everything works in http mode.
Here is my config.
frontend http *:80
acl http_test_acl path_beg -i /test
use_backend http_test if http_test_acl
default_backend http_default
backend http_test
balance roundrobin
server httptest 10.10.10.10:80 check
backend http_default
balance roundrobin
server httpdefault 10.10.10.10:80 check
############# HTTPS #################
frontend https *:443
mode tcp
acl https_test_acl path_beg -i /test
use_backend https_test if https_test_acl
default_backend https_default
backend https_test
mode tcp
balance roundrobin
server httpstest 10.10.10.10:443 check
backend https_default
mode tcp
balance roundrobin
server httpsdefault 10.10.10.10:443 check
Don't pay attention to ip 10.10.10.10 as I have hidden my orginal one. Could you please let me know why https is not working, http frontend/backend acl rules are working just fine.
cheers
Cause your https servers are in tcp mode (as they should be for ssl), so a layer 7 rule wont work.
for acl to work, disable tcp mode then set up ssl on the servers on your backend(hence the ssl keyword)
frontend https *:443
acl https_test_acl path_beg -i /test
use_backend https_test if https_test_acl
default_backend https_default
backend https_test
balance roundrobin
server httpstest 10.10.10.10:443 ssl check
backend https_default
balance roundrobin
server httpsdefault 10.10.10.10:443 ssl check
Alternatively instead of having to setup ssl on both your backend servers; use private IPS in the backend servers and make sure ports on the backend servers arent open to the world
backend https_test
balance roundrobin
server httpstest some_private_ip:8000 check