Skip to content

Commit

Permalink
cleaned-up route filter-templating
Browse files Browse the repository at this point in the history
  • Loading branch information
ansibleguy committed May 5, 2024
1 parent 62e5ff9 commit ad9ad92
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 66 deletions.
7 changes: 1 addition & 6 deletions ExampleAcme.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,12 +116,7 @@ root@test-ag-haproxy-acme:/# cat /etc/haproxy/conf.d/frontend.cfg
>
> # BACKEND be_test
> acl be_test_domains req.hdr(host) -m str -i app.test.ansibleguy.net
> acl be_test_filter_ip always_true
> acl be_test_filter_not_ip always_false
>
> use_backend be_test if be_test_domains be_test_filter_ip !be_test_filter_not_ip
>
>
> use_backend be_test if be_test_domains
>
> default_backend be_fallback

Expand Down
13 changes: 3 additions & 10 deletions ExampleGeoIP.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,25 +126,18 @@ root@test-ag-haproxy-geoip:/# cat /etc/haproxy/conf.d/frontend.cfg
> http-request capture req.fhdr(User-Agent) len 200
>
> # BACKEND be_test1
> acl be_test1_domains req.hdr(host) -m str -i app1.test.ansibleguy.net acl be_test1_filter_ip always_true
> acl be_test1_filter_not_ip always_false
> acl be_test1_domains req.hdr(host) -m str -i app1.test.ansibleguy.net
> acl be_test1_filter_country var(txn.geoip_country) -m str -i AT
> acl be_test1_filter_not_country always_false
> acl be_test1_filter_asn var(txn.geoip_asn) -m int -i 1337
> acl be_test1_filter_not_asn always_false
>
> use_backend be_test1 if be_test1_domains be_test1_filter_ip !be_test1_filter_not_ip be_test1_filter_asn !be_test1_filter_not_asn be_test1_filter_country !be_test1_filter_not_country
> use_backend be_test1 if be_test1_domains be_test1_filter_asn be_test1_filter_country
>
> # BACKEND be_test2
> acl be_test2_domains req.hdr(host) -m str -i app2.test.ansibleguy.net
> acl be_test2_filter_ip always_true
> acl be_test2_filter_not_ip always_false
> acl be_test2_filter_country always_true
> acl be_test2_filter_not_country var(txn.geoip_country) -m str -i CN RU US
> acl be_test2_filter_asn always_true
> acl be_test2_filter_not_asn var(txn.geoip_asn) -m int -i 100000 120000
>
> use_backend be_test2 if be_test2_domains be_test2_filter_ip !be_test2_filter_not_ip be_test2_filter_asn !be_test2_filter_not_asn be_test2_filter_country !be_test2_filter_not_country
> use_backend be_test2 if be_test2_domains !be_test2_filter_not_asn !be_test2_filter_not_country
>
> default_backend be_fallback

Expand Down
19 changes: 7 additions & 12 deletions ExampleTCP.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ logformat_tcp: "TCP: %ci:%cp [%t] %ft %b/%s %Tw/%Tc/%Tt %B %ts %ac/%fc/%bc/%sc/%
# logformat_http: "HTTP: %ci:%cp [%tr] %ft %b/%s %TR/%Tw/%Tc/%Tr/%Ta %ST %B %CC %CS %tsc %ac/%fc/%bc/%sc/%rc %sq/%bq %hr %hs %{+Q}r"

haproxy:
geoip:
enable: true
token: "<YOUR TOKEN>"

frontends:
fe_mail_smtp:
mode: 'tcp'
Expand Down Expand Up @@ -73,10 +77,7 @@ root@test-ag-haproxy-tcp:/# cat /etc/haproxy/conf.d/frontend.cfg
> log-format "TCP: %ci:%cp [%t] %ft %b/%s %Tw/%Tc/%Tt %B %ts %ac/%fc/%bc/%sc/%rc %sq/%bq"
>
> # BACKEND be_mail_smtp
> acl be_mail_smtp_filter_ip always_true
> acl be_mail_smtp_filter_not_ip always_false
>
> use_backend be_mail_smtp if be_mail_smtp_filter_ip !be_mail_smtp_filter_not_ip
> use_backend be_mail_smtp
>
> frontend fe_mail_imap
> mode tcp
Expand All @@ -103,14 +104,8 @@ root@test-ag-haproxy-tcp:/# cat /etc/haproxy/conf.d/frontend.cfg
> log-format "TCP: %ci:%cp [%t] %ft %b/%s %Tw/%Tc/%Tt %B %ts %ac/%fc/%bc/%sc/%rc %sq/%bq"
>
> # BACKEND be_mail_imap
> acl be_mail_imap_filter_ip always_true
> acl be_mail_imap_filter_not_ip always_false
> acl be_mail_imap_filter_country var(txn.geoip_country) -m str -i SI
> acl be_mail_imap_filter_not_country always_false
> acl be_mail_imap_filter_asn always_true
> acl be_mail_imap_filter_not_asn always_false
>
> use_backend be_mail_imap if be_mail_imap_filter_ip !be_mail_imap_filter_not_ip be_mail_imap_filter_asn !be_mail_imap_filter_not_asn be_mail_imap_filter_country !be_mail_imap_filter_not_country
> acl be_mail_imap_filter_country var(txn.geoip_country) -m str -i SI
> use_backend be_mail_imap if be_mail_imap_filter_country
>
> default_backend be_fallback_tcp
Expand Down
5 changes: 1 addition & 4 deletions ExampleWAF.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,7 @@ root@test-ag-haproxy-waf:/# cat /etc/haproxy/conf.d/frontend.cfg
>
> # BACKEND be_test
> acl be_test_domains req.hdr(host) -m str -i app.test.ansibleguy.net
> acl be_test_filter_ip always_true
> acl be_test_filter_not_ip always_false
>
> use_backend be_test if be_test_domains be_test_filter_ip !be_test_filter_not_ip
> use_backend be_test if be_test_domains
>
> default_backend be_fallback

Expand Down
65 changes: 65 additions & 0 deletions filter_plugins/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ def filters(self):
"is_dict": self.is_dict,
"safe_key": self.safe_key,
"ssl_fingerprint_active": self.ssl_fingerprint_active,
"build_route": self.build_route,
}

@staticmethod
Expand Down Expand Up @@ -43,3 +44,67 @@ def ssl_fingerprint_active(frontends: dict) -> bool:
continue

return False

@staticmethod
def is_truthy(v: (bool, str, int)) -> bool:
return v in [True, 'yes', 'y', 'Yes', 'YES', 'true', 1, '1']

@classmethod
def build_route(cls, fe_cnf: dict, be_cnf: dict, be_name: str) -> list:
lines = []
to_match = []
var_prefix = f'{be_name}_filter'

if fe_cnf['mode'] == 'http' and len(be_cnf['domains']) > 0:
lines.append(
f"acl {var_prefix}_domains req.hdr(host) "
f"-m str -i {' '.join(cls.ensure_list(be_cnf['domains']))}"
)
to_match.append(f'{var_prefix}_domains')

if len(be_cnf['filter_ip']) > 0:
lines.append(f"acl {var_prefix}_ip src {' '.join(cls.ensure_list(be_cnf['filter_ip']))}")
to_match.append(f'{var_prefix}_ip')

if len(be_cnf['filter_not_ip']) > 0:
lines.append(f"acl {var_prefix}_not_ip src {' '.join(cls.ensure_list(be_cnf['filter_not_ip']))}")
to_match.append(f'!{var_prefix}_not_ip')

if cls.is_truthy(fe_cnf['geoip']['enable']):
if cls.is_truthy(fe_cnf['geoip']['country']):
if len(be_cnf['filter_country']) > 0:
lines.append(
f"acl {var_prefix}_country var(txn.geoip_country) "
f"-m str -i {' '.join(cls.ensure_list(be_cnf['filter_country']))}"
)
to_match.append(f'{var_prefix}_country')

if len(be_cnf['filter_not_country']) > 0:
lines.append(
f"acl {var_prefix}_not_country var(txn.geoip_country) "
f"-m str -i {' '.join(cls.ensure_list(be_cnf['filter_not_country']))}"
)
to_match.append(f'!{var_prefix}_not_country')

if cls.is_truthy(fe_cnf['geoip']['asn']):
if len(be_cnf['filter_asn']) > 0:
lines.append(
f"acl {var_prefix}_asn var(txn.geoip_asn) "
f"-m str -i {' '.join(cls.ensure_list(be_cnf['filter_asn']))}"
)
to_match.append(f'{var_prefix}_asn')

if len(be_cnf['filter_not_asn']) > 0:
lines.append(
f"acl {var_prefix}_not_asn var(txn.geoip_asn) "
f"-m str -i {' '.join(cls.ensure_list(be_cnf['filter_not_asn']))}"
)
to_match.append(f'!{var_prefix}_not_asn')

if len(to_match) > 0:
lines.append(f"use_backend {be_name} if {' '.join(to_match)}")

else:
lines.append(f"use_backend {be_name}")

return lines
38 changes: 4 additions & 34 deletions templates/etc/haproxy/conf.d/frontend.cfg.j2
Original file line number Diff line number Diff line change
Expand Up @@ -52,42 +52,12 @@ frontend {{ name }}
{% endif %}
{% for be_name, be_cnf_user in cnf.routes.items() %}
{% set be_cnf = defaults_frontend_route | combine(be_cnf_user, recursive=true) %}
{% set be_route = cnf | build_route(be_cnf, be_name) %}

# BACKEND {{ be_name }}
{% if cnf.mode == 'http' %}
acl {{ be_name }}_domains {% if be_cnf.domains | length > 0 %}req.hdr(host) -m str -i {{ be_cnf.domains | ensure_list | join(' ') }}{% else %}always_true{% endif +%}
{% endif %}
acl {{ be_name }}_filter_ip {% if be_cnf.filter_ip | length > 0 %}src {{ be_cnf.filter_ip | ensure_list | join(' ') }}{% else %}always_true{% endif +%}
acl {{ be_name }}_filter_not_ip {% if be_cnf.filter_not_ip | length > 0 %}src {{ be_cnf.filter_not_ip | ensure_list | join(' ') }}{% else %}always_false{% endif +%}
{% if HAPROXY_CONFIG.geoip.enable | bool and cnf.geoip.enable | bool %}
{% if cnf.geoip.country | bool %}
acl {{ be_name }}_filter_country {% if be_cnf.filter_country | length > 0 %}var(txn.geoip_country) -m str -i {{ be_cnf.filter_country | ensure_list | join(' ') }}{% else %}always_true{% endif +%}
acl {{ be_name }}_filter_not_country {% if be_cnf.filter_not_country | length > 0 %}var(txn.geoip_country) -m str -i {{ be_cnf.filter_not_country | ensure_list | join(' ') }}{% else %}always_false{% endif +%}
{% else %}
acl {{ be_name }}_filter_country always_true
acl {{ be_name }}_filter_not_country always_false
{% endif %}
{% if cnf.geoip.asn | bool %}
acl {{ be_name }}_filter_asn {% if be_cnf.filter_asn | length > 0 %}var(txn.geoip_asn) -m int -i {{ be_cnf.filter_asn | ensure_list | join(' ') }}{% else %}always_true{% endif +%}
acl {{ be_name }}_filter_not_asn {% if be_cnf.filter_not_asn | length > 0 %}var(txn.geoip_asn) -m int -i {{ be_cnf.filter_not_asn | ensure_list | join(' ') }}{% else %}always_false{% endif +%}
{% else %}
acl {{ be_name }}_filter_asn always_true
acl {{ be_name }}_filter_not_asn always_false
{% endif %}

{% if cnf.mode == 'http' %}
use_backend {{ be_name }} if {{ be_name }}_domains {{ be_name }}_filter_ip !{{ be_name }}_filter_not_ip {{ be_name }}_filter_asn !{{ be_name }}_filter_not_asn {{ be_name }}_filter_country !{{ be_name }}_filter_not_country
{% else %}
use_backend {{ be_name }} if {{ be_name }}_filter_ip !{{ be_name }}_filter_not_ip {{ be_name }}_filter_asn !{{ be_name }}_filter_not_asn {{ be_name }}_filter_country !{{ be_name }}_filter_not_country
{% endif %}
{% else %}

{% if cnf.mode == 'http' %}
use_backend {{ be_name }} if {{ be_name }}_domains {{ be_name }}_filter_ip !{{ be_name }}_filter_not_ip
{% else %}
use_backend {{ be_name }} if {{ be_name }}_filter_ip !{{ be_name }}_filter_not_ip
{% endif %}
{% endif %}
{% for line in be_route %}
{{ line }}
{% endfor %}

{% endfor %}

Expand Down

0 comments on commit ad9ad92

Please sign in to comment.