Skip to content

Commit

Permalink
basic geoip implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
ansibleguy committed May 2, 2024
1 parent 1ad2374 commit fec8a9b
Show file tree
Hide file tree
Showing 18 changed files with 552 additions and 19 deletions.
97 changes: 93 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

# Ansible Role - HAProxy Community

**WARNING**: The role is still in early development! **DO NOT TRY TO USE IN PRODUCTION**!

Role to deploy HAProxy (*Focus on the Community Version*)

<a href='https://ko-fi.com/ansible0guy' target='_blank'><img height='35' style='border:0px;height:46px;' src='https://az743702.vo.msecnd.net/cdn/kofi3.png?v=0' border='0' alt='Buy me a coffee' />
Expand Down Expand Up @@ -56,6 +58,7 @@ ansible-galaxy install -r requirements.yml
* **Default opt-ins**:
* Frontend
* Redirect non SSL traffic to SSL if in HTTP mode
* Logging User-Agent
* Backend
* Basic Check (*httpchk if in http mode*)

Expand All @@ -64,7 +67,7 @@ ansible-galaxy install -r requirements.yml
* Stats http listener
* Frontend
* [ACME/LetsEncrypt](https://www.haproxy.com/blog/haproxy-and-let-s-encrypt) (*yet to be implemented*)
* [GeoIP Lookups](https://github.com/superstes/haproxy-geoip) (*yet to be implemented..*)
* [GeoIP Lookups](https://github.com/superstes/haproxy-geoip)


## Info
Expand All @@ -80,10 +83,64 @@ ansible-galaxy install -r requirements.yml
* **Warning:** Not every setting/variable you provide will be checked for validity. Bad config might break the role!


* **Warning:** If you use the auto-provisioned GeoIP databases - make sure your product follows their license agreement:

* **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*)

**Attribution**: `<p>IP address data powered by <a href="https://ipinfo.io">IPinfo</a></p>`

* **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*)

**Attribution**: `This product includes GeoLite2 data created by MaxMind, available from <a href="https://www.maxmind.com">https://www.maxmind.com</a>.`


* **Info**: If you want to self-manage the databases - the role will assume they are placed at `/var/local/lib/geoip` and be named `asn.mmdb` & `country.mmdb`.


* **Info**: For GeoIP Tokens you will have to create a free account:

* **IPInfo**: [Login/Register](https://ipinfo.io/login)
* **MaxMind**: [Login/Register](https://www.maxmind.com/en/account/login) - Set the `token` to `<ACCOUNT>:<LICENSE>`


* **Info**: You can test the [GeoIP Lookup Microservice](https://github.com/superstes/haproxy-geoip) manually by using curl: `curl 'http://127.0.0.1:10069/?lookup=country&ip=1.1.1.1'`


* **Info**: You can easily filter access to backends by using the `filter` and `filter_not` settings:

`filter_ip`, `filter_not_ip`, `filter_country`, `filter_not_country`, `filter_asn`, `filter_not_asn`


## Usage

### Config

**Minimal example**

```yaml
haproxy:
frontends:
fe_web:
bind: ['[::]:80 v4v6', '[::]:443 v4v6 ssl']
acme: true
acme_domains: ['app.template.ansibleguy.net']

route:
be_intern:
filter_ip: '10.0.0.0/8'
filter_not_ip: '10.100.0.0/24'

default_backend: 'be_fallback'

backends:
be_intern:


be_fallback:
lines:
default: 'http-request redirect code 301 location https://github.com/ansibleguy'
```
Define the config as needed:
```yaml
Expand All @@ -99,20 +156,43 @@ haproxy:
fe_web:
bind: ['[::]:80 v4v6', '[::]:443 v4v6 ssl']
acme: true
acme_domains: ['app.template.ansibleguy.net'] # domains from routes will also be added

# map hostnames to backends
backend_map:
be_app01: ['app01.template.ansibleguy.net', 'hello.template.ansibleguy.net']
route:
be_app01:
domains: ['app01.template.ansibleguy.net', 'hello.template.ansibleguy.net']

# define raw config sections/lines to add
lines:
section1:
- ...

default_backend: 'be_fallback'

fe_dbs:
mode: 'tcp'
default_backend: 'be_db'

fe_restricted:
bind: ['[::]:80 v4v6', '[::]:443 v4v6 ssl']
acme: true

geoip:
enable: true

backends:
be_app01:
filter_country: ['AT', 'DE', 'CH']
# filter_ip: ['10.0.0.0/8']
domains: ['app01.template.ansibleguy.net', 'hello.template.ansibleguy.net']

# define raw config sections/lines to add
lines:
section1:
- ...

default_backend: 'be_fallback'

backends:
be_app01:
servers:
Expand All @@ -135,6 +215,15 @@ haproxy:
- 'mysql-1 10.0.0.1:3306'
- 'mysql-2 10.0.0.2:3306'

be_fallback:
lines:
default: 'http-request redirect code 301 location https://github.com/ansibleguy'

geoip:
enable: true
provider: 'ipinfo' # or 'maxmind'
token: '<YOUR-TOKEN>'

# define globals/defaults as key/value pairs (multi-value lists usable)
global:
ca-base: '/etc/ssl/certs'
Expand Down
34 changes: 34 additions & 0 deletions defaults/main/0_hardcoded.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,45 @@
---

cpu_arch: "{{ 'amd64' if ansible_architecture == 'x86_64' else ansible_architecture }}"

HAPROXY_HC:
valid_versions: ['2.6', '2.7', '2.8', '2.9']
path:
config: '/etc/haproxy/conf.d'
acme: '/etc/ssl/haproxy_acme'
map: '/etc/haproxy/map'
lua: '/etc/haproxy/lua'
geoip_bin: '/usr/local/bin/geoip-lookup'
geoip_bin_src: "geoip-lookup-linux-{{ cpu_arch }}-CGO0"
geoip_update_script: '/usr/local/bin/geoip-db-update.sh'
geoip_db: '/var/local/lib/geoip'
map_geoip_country: '/etc/haproxy/map/geoip_country.map'
map_geoip_asn: '/etc/haproxy/map/geoip_asn.map'
map_geoip_as_name: '/etc/haproxy/map/geoip_as_name.map'

user: 'haproxy'
group: 'haproxy'

url:
geoip_bin: "https://github.com/superstes/geoip-lookup-service/releases/download/1.0/geoip-lookup-linux-{{ cpu_arch }}-CGO0.tar.gz"
geoip_ipinfo_country: "https://ipinfo.io/data/free/country.mmdb?token="
geoip_ipinfo_asn: "https://ipinfo.io/data/free/asn.mmdb?token="
geoip_maxmind_country: "https://download.maxmind.com/geoip/databases/GeoLite2-ASN/download?suffix=tar.gz"
geoip_maxmind_asn: "https://download.maxmind.com/geoip/databases/GeoLite2-ASN/download?suffix=tar.gz"

valid_geoip_providers: ['ipinfo', 'maxmind']
geoip_lookup_port: 10069
user_geoip: 'haproxy-geoip'
service_geoip_lookup: 'haproxy-geoip-lookup'
service_geoip_update: 'haproxy-geoip-update'
geoip_update_timer: 'Mon *-*-* 01:00:00'

Check failure on line 35 in defaults/main/0_hardcoded.yml

View workflow job for this annotation

GitHub Actions / build

35:23 [colons] too many spaces after colon
geoip_lookup_filters:
ipinfo:
country: 'country'
asn: 'asn'
as_name: 'name'

maxmind:
country: 'country.iso_code'
asn: 'autonomous_system_number'
as_name: 'autonomous_system_organization'
35 changes: 33 additions & 2 deletions defaults/main/1_main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

no_prompts: false
debug: false
force_update: false

# default config => is overwritten by provided config
defaults_haproxy:
Expand All @@ -20,6 +21,12 @@ defaults_haproxy:
pwd: 'monitor'
realm: 'Authorized Personal Only'

geoip:
enable: false
manage_db: true
provider: 'ipinfo'
token:

global:
log:
- '/dev/log local0'
Expand Down Expand Up @@ -59,14 +66,38 @@ defaults_frontend:
# ssl with custom cert: ':443 ssl crt /etc/ssl/haproxy/site.pem'
acme: false
ssl_redirect: true
log:
user_agent: true

geoip:
enable: false
country: true
asn: true
asn_name: false

lines: {} # raw config lines to add - section to lines mapping to make resulting config human-readable

backend_map: {} # hostname to backend mapping
# backend_name: ['hostname1', 'hostname2']
route: {}
# backend_name:
# domains: ['hostname1', 'hostname2']
# filter_country: ['AT', 'DE', 'CH']
# filter_not_country: []
# filter_asn: [13335]
# filter_not_asn: []
# filter_ip: ['10.0.0.0/8']
# filter_not_ip: []

default_backend:

defaults_frontend_route:
domains: []
filter_country: []
filter_not_country: []
filter_asn: []
filter_not_asn: []
filter_ip: []
filter_not_ip: []

defaults_backend:
mode: 'http'
balance: 'leastconn'
Expand Down
2 changes: 1 addition & 1 deletion tasks/debian/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
group: 'haproxy'
mode: 0640
loop:
- 'frontend'
- 'backend'
- 'frontend'
- 'stats'
notify: haproxy-reload
Loading

0 comments on commit fec8a9b

Please sign in to comment.