{"id":23889565,"url":"https://github.com/o-x-l/haproxy-geoip","last_synced_at":"2025-12-14T22:47:22.836Z","repository":{"id":208127709,"uuid":"720872182","full_name":"O-X-L/haproxy-geoip","owner":"O-X-L","description":"HAProxy (community) GeoIP Lookups","archived":false,"fork":false,"pushed_at":"2024-09-18T16:28:05.000Z","size":68,"stargazers_count":8,"open_issues_count":1,"forks_count":5,"subscribers_count":1,"default_branch":"latest","last_synced_at":"2025-04-10T06:05:27.701Z","etag":null,"topics":["asn","asn-lookup","country","country-codes","geoip","geoip-lookup","haproxy","haproxy-configuration","ipinfo","maxmind","maxmind-geoip"],"latest_commit_sha":null,"homepage":"https://docs.o-x-l.com/proxy/reverse_haproxy.html","language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/O-X-L.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-11-19T21:05:45.000Z","updated_at":"2025-02-06T16:32:07.000Z","dependencies_parsed_at":"2023-11-24T23:22:06.661Z","dependency_job_id":"0c84b611-6f28-4082-b115-2880c75a0192","html_url":"https://github.com/O-X-L/haproxy-geoip","commit_stats":null,"previous_names":["superstes/haproxy-geoip-lua","superstes/haproxy-geoip","o-x-l/haproxy-geoip"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/O-X-L/haproxy-geoip","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/O-X-L%2Fhaproxy-geoip","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/O-X-L%2Fhaproxy-geoip/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/O-X-L%2Fhaproxy-geoip/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/O-X-L%2Fhaproxy-geoip/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/O-X-L","download_url":"https://codeload.github.com/O-X-L/haproxy-geoip/tar.gz/refs/heads/latest","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/O-X-L%2Fhaproxy-geoip/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273983576,"owners_count":25202188,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-06T02:00:13.247Z","response_time":2576,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asn","asn-lookup","country","country-codes","geoip","geoip-lookup","haproxy","haproxy-configuration","ipinfo","maxmind","maxmind-geoip"],"created_at":"2025-01-04T10:09:50.757Z","updated_at":"2025-12-14T22:47:22.828Z","avatar_url":"https://github.com/O-X-L.png","language":"Lua","funding_links":[],"categories":[],"sub_categories":[],"readme":"# HAProxy - GeoIP Lookups\n\n\u003cp align=\"center\"\u003e\n    \u003ca title=\"Support this Project (Donate, Support-Licenses)\" href=\"https://shop.oxl.app/collections/open-source\"\u003e\n        \u003cimg src=\"https://files.oxl.at/img/badge-oss-support.svg\" alt=\"Support Badge (Donate, Support-Licenses)\"/\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\n----\n\n[![Lint Python](https://github.com/O-X-L/haproxy-geoip/actions/workflows/lint_python.yml/badge.svg?branch=latest)](https://github.com/O-X-L/haproxy-geoip/actions/workflows/lint_python.yml)\n[![Integration Tests](https://github.com/O-X-L/haproxy-geoip/actions/workflows/test.yml/badge.svg?branch=latest)](https://github.com/O-X-L/haproxy-geoip/actions/workflows/test.yml)\n\n\nThis is an example on how to use GeoIP lookups in combination with HAProxy.\n\nData linking requests to its origin country and ASN/ISP can be very useful when dealing with application-level attacks.\n\nThis allows you also to handle requests from specific countries and ASNs (p.e. datacenters/hosting providers) differently than others.\n\nNOTE: This functionality is covered by the [HAProxy Enterprise Maxmind-Module](https://www.haproxy.com/documentation/hapee/latest/load-balancing/geolocation/maxmind/)! Only use this implementation if you are limited to the community edition.\n\n----\n\n## Topology\n\nYou can implement this in two ways:\n\n* Use a custom backend-service to do this lookups\n \n   [Go-based binary](https://github.com/O-X-L/geoip-lookup-service/releases/tag/1.0)\n\n   [Python3-based](https://github.com/O-X-L/haproxy-geoip/tree/latest/backend)\n\n* UNTESTED: Use the [resty-maxminddb LUA library](https://raw.githubusercontent.com/anjia0532/lua-resty-maxminddb/master/lib/resty/maxminddb.lua) to query the MMDB databases directly from LUA\n\n----\n\n### Lookup via Backend\n\n1. Request hits HAProxy\n\n2. HAProxy calls LUA script to delegate GeoIP-database lookup\n\n3. LUA calls a minimal web-service on localhost that queries the GeoIP-database(s)\n\n   You can either use a [Go-based](https://github.com/O-X-L/geoip-lookup-service) or [Python3-based](https://github.com/O-X-L/haproxy-geoip/tree/latest/backend) HTTP-Server as backend\n\n\u003cimg src=\"https://raw.githubusercontent.com/O-X-L/haproxy-geoip/latest/topology.svg\" width=300\u003e\n\n\n### Lookup via Library\n\n1. Request hits HAProxy\n\n2. HAProxy calls LUA script for querying the GeoIP-database(s)\n\n\n----\n\n### GeoIP\n\nYou will have to download some MMDB GeoIP databases.\n\n* **IPInfo**: [Information](https://ipinfo.io/products/free-ip-database), [CC4 License](https://creativecommons.org/licenses/by-sa/4.0/) (*allows for commercial usage - you need to add an attribution*)\n\n    **Attribution**: `\u003cp\u003eIP address data powered by \u003ca href=\"https://ipinfo.io\"\u003eIPinfo\u003c/a\u003e\u003c/p\u003e`\n\n* **MaxMind**: [Information](https://dev.maxmind.com/geoip/geolite2-free-geolocation-data), [EULA](https://www.maxmind.com/en/geolite2/eula) (*allows for limited commercial usage - you need to add an attribution*)\n\n    **Attribution**: `This product includes GeoLite2 data created by MaxMind, available from \u003ca href=\"https://www.maxmind.com\"\u003ehttps://www.maxmind.com\u003c/a\u003e.`\n\n----\n\n## Setup\n\n* Add the LUA script to your system\n* Install and set up the GeoIP lookup-backend of your choice\n\n## Config\n\n* Load the LUA module by adding lua-load `/etc/haproxy/lua/geoip_lookup.lua` in the global section\n* Execute the LUA script on HTTP requests:\n\n  * In HTTP mode\n\n    ```\n    # country\n    http-request lua.lookup_geoip_country\n    # asn\n    http-request lua.lookup_geoip_asn\n    ```\n\n  * In TCP mode\n\n    ```\n    # country\n    tcp-request content lua.lookup_geoip_country\n    # asn\n    tcp-request content lua.lookup_geoip_asn\n    ```\n\n* Log the data:\n\n  * In HTTP mode\n\n    ```\n    http-request capture var(txn.geoip_asn) len 10\n    http-request capture var(txn.geoip_country) len 2\n    ```\n\n  * In TCP mode\n\n    ```\n    tcp-request content capture var(txn.geoip_asn) len 10\n    tcp-request content capture var(txn.geoip_country) len 2\n    ```\n\nYou can also check out the configuration example: `haproxy_example.cfg`\n\n----\n\n### Cache-Map\n\nYou will have to decide if you want to use [HAProxy Maps](https://www.haproxy.com/blog/introduction-to-haproxy-maps) to cache Lookup results.\n\nThis can speed up the lookup for IPs that have already connected to your server.\n\nIt will also use more memory.\n\nSee also: `haproxy_example.cfg - test_country_cachemap`\n\nThe speed-improvements as seen by running the test-script are: `first: 0.03, second: 0.00`\n\nBy utilizing [HAProxy's ipmask](https://www.haproxy.com/blog/ip-masking-in-haproxy) (`src,ipmask(24,48)`) feature we are able to reduce the needed entries inside the map to the minimal subnets that are announced on public BGP.  \n\n----\n\n### Lookup\n\n#### via Go-Backend\n\nDownload the binary for you system from [the releases](https://github.com/O-X-L/geoip-lookup-service/releases).\n\n[Read the documentation](https://github.com/O-X-L/geoip-lookup-service) on how to use it.\n\nYou need to use the `lua/geoip_lookup_w_backend.lua` script.\n\nIt is recommended to start Go-Backend with `-plain` command line argument to get the variable in plain text format.\n\n----\n\n#### via Python-Backend\n\nTo query the MMDB databases, you will have to install the [maxminddb python-module](https://github.com/maxmind/MaxMind-DB-Reader-python):\n\n```bash\npython3 -m pip install maxminddb\n```\n\nYou will have to update the paths to your database-files in the `backend/geoip_lookup_backend.py` file!\n\nYou need to use the `lua/geoip_lookup_w_backend.lua` script.\n\n----\n\n#### via Library\n\nWARNING: UNTESTED\n\nTo query the MMDB databases, you will have to install the [resty-maxminddb LUA library](https://raw.githubusercontent.com/anjia0532/lua-resty-maxminddb/master/lib/resty/maxminddb.lua) and its dependencies.\n\nYou need to use the `lua/geoip_lookup_w_lib.lua` script.\n\n----\n\n## Run\n\n### With Go-Backend\n```bash\n# start the web-service\n./geoip-lookup \u0026\n# initialize the haproxy map(s)\ntouch /tmp/haproxy_geoip_country.map\n# start haproxy\nhaproxy -W -f haproxy_example.cfg\n```\n\n### With Python-Backend\n```bash\n# start the web-service\npython3 backend/geoip_lookup.py \u0026\n# initialize the haproxy map(s)\ntouch /tmp/haproxy_geoip_country.map\n# start haproxy\nhaproxy -W -f haproxy_example.cfg\n```\n\n\n### With LUA-Library\n\n```bash\n# initialize the haproxy map(s)\ntouch /tmp/haproxy_geoip_country.map\n# start haproxy\nhaproxy -W -f haproxy_example.cfg\n```\n\n----\n\n## Testing\n\nYou will have to copy some GeoIP databases to `/tmp`:\n\n* '/tmp/maxmind_country.mmdb'\n* '/tmp/maxmind_asn.mmdb'\n* '/tmp/ipinfo_country.mmdb'\n* '/tmp/ipinfo_asn.mmdb'\n\nAt least IPInfo OR MaxMind databases need to exist!\n\n```bash\ncd test\nbash test.sh\n\u003e\n\u003e CLEANUP\n\u003e\n\u003e WARN: UNABLE TO TEST MaxMind databases as they are missing!\n\u003e\n\u003e STARTING HAPROXY\n\u003e\n\u003e TESTING with PYTHON-BACKEND\n\u003e LINKING IPInfo databases\n\u003e 127.0.0.1 - - [22/Nov/2023 21:21:00] \"GET /?lookup=country\u0026ip=1.1.1.1 HTTP/1.1\" 200 -\n\u003e 127.0.0.1 - - [22/Nov/2023 21:21:00] \"GET /?lookup=continent\u0026ip=1.1.1.1 HTTP/1.1\" 200 -\n\u003e 127.0.0.1 - - [22/Nov/2023 21:21:00] \"GET /?lookup=asn\u0026ip=1.1.1.1 HTTP/1.1\" 200 -\n\u003e 127.0.0.1 - - [22/Nov/2023 21:21:00] \"GET /?lookup=asname\u0026ip=1.1.1.1 HTTP/1.1\" 200 -\n\u003e REQUEST TIMES: 0.01 =\u003e 0.00 (cached)\n\u003e\n\u003e STOPPING HAPROXY\n\u003e\n\u003e FINISHED - exiting\n```\n\nFeel free to [contribute more test-cases](https://github.com/O-X-L/haproxy-geoip/blob/latest/test/requests.sh)!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fo-x-l%2Fhaproxy-geoip","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fo-x-l%2Fhaproxy-geoip","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fo-x-l%2Fhaproxy-geoip/lists"}