Commit 06455569 authored by Łukasz Nowak's avatar Łukasz Nowak

XXX caddy-frontend: Fix host matching in Haproxy

By using regular expressions, matching exact host names up to the optional
port and putting wildcard matches in the end, the Haproxy acl rules will allow
to direct request to correct backend.

XXX: Think about a good test.
parent 6bedc76b
Pipeline #11523 passed with stage
in 0 seconds
......@@ -54,7 +54,7 @@ md5sum = 266f175dbdfc588af7a86b0b1884fe73
[template-backend-haproxy-configuration]
_update_hash_filename_ = templates/backend-haproxy.cfg.in
md5sum = 68a7758ca8f8b544ba9bc756824be3d3
md5sum = eaf7491f628e72c877c31588e62eeb89
[template-log-access]
_update_hash_filename_ = templates/template-log-access.conf.in
......
......@@ -14,32 +14,46 @@ defaults
timeout connect {{ configuration['backend-connect-timeout'] }}s
retries {{ configuration['backend-connect-retries'] }}
{%- macro frontend_entry(slave_instance, scheme) %}
{%- macro frontend_entry(slave_instance, scheme, wildcard) %}
{#- wildcard switch allows to put dangerous entries in the end, as haproxy parses with first match #}
{%- set host_list = (slave_instance.get('server-alias') or '').split() %}
{%- if slave_instance.get('custom_domain') not in host_list %}
{%- do host_list.append(slave_instance.get('custom_domain')) %}
{%- endif %}
{%- set matched = {'count': 0} %}
{%- for host in host_list %}
{%- if host.startswith('*.') %}
{#- hdr_sub has to be used, as anyway something.example.com shall match *.example.com[:port], with optional port #}
acl is_{{ slave_instance['slave_reference'] }} hdr_sub(host) -i {{ host[2:] }}
{%- else %}
acl is_{{ slave_instance['slave_reference'] }} hdr_dom(host) -i {{ host }}
{#- Match up to the end or optional port (starting with ':') #}
{#- Please note that this matching is quite sensitive to changes and hard to test, so avoid needless changes #}
{%- if wildcard and host.startswith('*.') %}
{%- do matched.__setitem__('count', matched['count'] + 1) %}
# match wildcard {{ host }}
acl is_{{ slave_instance['slave_reference'] }} hdr_reg(host) -i {{ host[2:] }}($|:.*)
{%- elif not wildcard and not host.startswith('*.') %}
{%- do matched.__setitem__('count', matched['count'] + 1) %}
acl is_{{ slave_instance['slave_reference'] }} hdr_reg(host) -i ^{{ host }}($|:.*)
{%- endif %}
{%- endfor %}
{%- if matched['count'] > 0 %}
use_backend {{ slave_instance['slave_reference'] }}-{{ scheme }} if is_{{ slave_instance['slave_reference'] }}
{%- endif %}
{%- endmacro %}
frontend http-backend
bind {{ configuration['local-ipv4'] }}:{{ configuration['http-port'] }}
{%- for slave_instance in backend_slave_list %}
{{ frontend_entry(slave_instance, 'http') }}
{{ frontend_entry(slave_instance, 'http', False) }}
{%- endfor %}
{%- for slave_instance in backend_slave_list %}
{{ frontend_entry(slave_instance, 'http', True) }}
{%- endfor %}
frontend https-backend
bind {{ configuration['local-ipv4'] }}:{{ configuration['https-port'] }}
{%- for slave_instance in backend_slave_list %}
{{ frontend_entry(slave_instance, 'https') }}
{{ frontend_entry(slave_instance, 'https', False) }}
{%- endfor %}
{%- for slave_instance in backend_slave_list %}
{{ frontend_entry(slave_instance, 'https', True) }}
{%- endfor %}
{%- for slave_instance in backend_slave_list %}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment