HAPROXY add GeoIP capability and run rules inside HAPROXY based on GeoIP

Started by nzkiwi68, November 17, 2023, 05:29:55 AM

Previous topic - Next topic
Firstly, let me credit Brett Merrick for huge assistance. This is not all my own work.

Here's the steps to get GeoIP working inside HAPROXY, not at the firewall rule layer, but inside HAPROXY and still utilising OPNsense GeoIP alias function.

You can write conditions such as:
Condition: Paths starts with /login/
Condition: GeoIP matches Australia

Then write a rule that does things like:
Rule: Only permit login from Australia (Permit http_request if matches "Paths starts with /login/" and "GeoIP matches AU"

Very cool! Any many, many more possibilities for protection, reject excessive error rates or connection rates from certain countries, use Tarpitting on some countries and not others, and so on.

Ok - how:


*****************************************************
ONE: These two files need to get added to the system
*****************************************************

File1
filename: actions_custom.conf
location: /usr/local/opnsense/service/conf/actions.d/

[update]
command:/usr/local/opnsense/scripts/custom/haproxy-alias.sh
parameters:%s
type:script
message:Updating HAProxy Alias %s
description:Update HAProxy Alias


File2
filename: haproxy-alias.sh
location: /usr/local/opnsense/scripts/custom/

#!/bin/csh
if ( $#argv == 0 ) exit 1
configctl filter list table "$1" > "/var/haproxy/$1.lst"
chown 80:80 "/var/haproxy/$1.lst"
exit 0



************************************************************
TWO: Build the GeoIP alias "acl_geoip_au" (for say Australian IP addresses
************************************************************
If you haven't setup for the GeoIP downloads to get the GeoIP databnase list, then follow the OPNsense documentation first:
https://docs.opnsense.org/manual/how-tos/maxmind_geo_ip.html
Normal firewall GeoIP settings
Firewall > Aliases > GeoIP settings

*** make sure to only use ipv4 if you don't have ipv6 ***


*******************************************
THREE: Create the cron job and run it ONCE
*******************************************
Then set to run overnight after midnight sometime ideally running after GeoIP DB update and before HAPROXY reload. You will need an HAPROXY reload to pickup the new GeoIP tables.


************************
FOUR: Now setup a condition
************************
e.g.
Name: GEOIP_AU
Condition type: Source IP matches specified IP (from the drop down list)
Parameters: -f /var/haproxy/acl_geoip_au.lst

(see the acl_geoip_au.lst - that needs to match the firewall GeoIP alias name. In my example the alias name is acl_geoip_au)


*****************************************************************************
FIVE: Go make a rule that uses your condition and attach it a backend or frontend as appropriate
*****************************************************************************

Want more GeoIP ranges?
Start at step two and rinse and repeat for more aliases with different country combinations.
Each aliases needs a CRON job and don't forget you need to run the CRON job once to get the alias ready for HAPROXY to use.



Perhaps these instructions refer to a previous analysis, because I did not understand the need to establish paths that begin with /login/.
In any case, I don't see in the code where you check for /login/

What is the goal you aim to achieve?

Quote from: WhiteTiger on November 18, 2023, 11:16:31 AM
Perhaps these instructions refer to a previous analysis, because I did not understand the need to establish paths that begin with /login/.
In any case, I don't see in the code where you check for /login/

What is the goal you aim to achieve?

No these instructions do not refer to previous analysis or set of instructions.

There is nothing in the code about /login/ - I am merely talking about the concept on using these instructions to satisfy a need to do something like:


  • The URL requested starts with a path, say /login
  • and the request is coming from a GeoIP of Australia
  • Then allow the request, else block the request

In my concept above, you could then allow logins to a website only from Australia IP addresses.

The instruction are for:
How to add GeoIP capability and run rules inside HAPROXY based on GeoIP

Then, how to add the GeoIP capability for HAPROXY starts in my post:
*****************************************************
ONE: These two files need to get added to the system
*****************************************************
... and so on

You do need a high understanding of how HAPROXY works for any of this to make any sense.

Hello,
I have created a GEO alias for France.

But this script does not execute, either in cron or manually via the shell. Impossible to go further in HAProxy...

#!/bin/csh
if ( $#argv == 0 ) exit 1
configctl filter list table "$1" > "/var/haproxy/$1.lst"
chown 80:80 "/var/haproxy/$1.lst"
exit 0


sh haproxy-alias.sh
haproxy-alias.sh: 2: Syntax error: word unexpected (expecting "then")


So in the aliases in /var/haproxy it's impossible to go any further.

Thanks for your help ;-)

lionel

The script needs a parameter, namely the name of the previously created firewall alias.
Also, it is written in csh, not in sh. So, in order to call it, you either hve to "chmod +x" it and call it directly or use "csh script".

@nzkiwi68: It would be better to either call the script haproxy-alias.csh or rewrite it for /bin/sh, which is easy considering its length and complexity.
Intel N100, 4 x I226-V, 16 GByte, 256 GByte NVME, ZTE F6005

1100 down / 800 up, Bufferbloat A+

Merci !

I'm using IPv6, so the export doesn't work.

root@OPNsense:/usr/local/opnsense/scripts/custom # csh haproxy-alias.sh Geo_France
exit: Badly formed number.


If I uncheck IPv6 in the alias it exports IPv6, but the next time I download MaxMind it won't take IPv6...

To use this in HAProxy, don't search for GEO IP but for Source IP matches... and put the name of the list in Source IP, I suppose ?