On Fri, Feb 24, 2023 at 12:33 AM Willy Tarreau <w...@1wt.eu> wrote:
>
> On Fri, Feb 24, 2023 at 05:39:13AM +0000, Robin H. Johnson wrote:
> > On Thu, Feb 23, 2023 at 06:48:14PM -0700, Bryan Arenal wrote:
> > > Hi there,
> > >
> > > I'm seeing some traffic from what appears to be bad actors and am
> > > wanting to block them.  I see this in the existing config but being
> > > new to haproxy, it doesn't seem like it's configured correctly but I'm
> > > not sure:
> > >
> > > frontend main
> > >         bind :80
> > >         acl bad_ip src
> > >         acl bad_ip_proxy hdr_ip(X-Forwarded-For)
> > Off the top of my head, this should probably be:
> > acl bad_ip src -f /etc/haproxy/blocklist.lst
> > acl bad_ip_proxy hdr_ip(X-Forwarded-For) -f /etc/haproxy/blocklist.lst
> >
> > >         tcp-request connection reject if bad_ip || bad_ip_proxy
> > I'm not sure offhand about the processing order for the header case.
> >
> > You might need BOTH:
> > tcp-request connection reject if bad_ip || bad_ip_proxy
> > http-request connection reject if bad_ip || bad_ip_proxy
>
> In fact the tcp-request rule will not consider the bad_ip_proxy ACL since
> it relies on header extraction that is not possible at this step. Indeed,
> You'd need to deal with this using the http-request rule. I would also
> suggest that if the IP is blocked at the TCP level then it's not needed
> to evaluate it again at the HTTP layer. This would give:
>
>   tcp-request connection reject if bad_ip
>   http-request reject if bad_ip_proxy
>
> > Depending on the scale of the traffic, the one problem you'll have here is
> > that HAProxy still has to process the problematic requests.
>
> In fact it depends. For example if it's a POST with a heavy body, a "deny"
> rule will return a 403 and will drain the rest of the body in order to try
> to recover the connection, but a "reject" rule will instantly break the
> connection, which instantly stops any processing.
>
> > In that case I suggest writing a feedback loop that adds the bad IP to an 
> > ipset
> > set, to block the traffic before it gets to HAProxy, for some period of 
> > time.
> > The trigger for the loop can either be a tail on the logfile, or using some
> > variation of the set* functionality (set-acl, set-map, set-mark) and 
> > exporting
> > the data to ipset.
>
> I used to proceed like this a very long time ago, and found that it was
> not always convenient due to the lack of observability (i.e. "is that rule
> still needed or has the attack stopped?"). Given the performance of most
> machines nowadays, I *tend* to prefer only blocking using the ACLs in TCP
> rules (that's still very fast). However you're right, sometimes it can be
> required to block IPs at the packet level, particularly for multi-protocol
> attacks that span over many ports.
>
> By the way, if attacks come from a small to medium sized set of clients,
> the "tarpit" and "silent-drop" actions can be more effective because they
> consume resources on the client by keeping the connection open. But *do not*
> do that if there is a firewall or NAT box between the net and your LB or
> it might not find this funny. For silent-drop there's a new "rst-ttl"
> option that allows to send a reset with a limited TTL that only the
> firewall/NAT box will see. This one might be considered as an option.

Thank you both VERY much for your help -- I really appreciate it.
That makes total sense that you'd have to use http-request rather than
tcp-request since you've got to evaluate the headers.

And would this work to reject any request that has the
'X-Forwarded-For' header?

  acl is-forwarded hdr_sub(x-forwarded-for)
  http-request reject if is-forwarded

How resource intensive do you think this would this be?

Thanks again!

Reply via email to