opnsense / plugins

OPNsense plugin collection
https://opnsense.org/
BSD 2-Clause "Simplified" License
812 stars 596 forks source link

net/haproxy: Add support for map_reg #3641

Open LeaderbotX400 opened 8 months ago

LeaderbotX400 commented 8 months ago

Important notices Before you add a new report, we ask you kindly to acknowledge the following:

Is your feature request related to a problem? Please describe. I run lots of services internally, such as things like the arr suite. which while its not hard it is mildly annoyning to have to copy out the map entry for each one. This, to me feels to cramped/clogged compared to `^[a-z]arr MEDIARR_backend`

sonarr MEDIARR_backend
radarr MEDIARR_backend
liarr MEDIARR_backend
etc.....

Describe the solution you'd like

I would like an option to use map_reg instead of map_dom in the rules

Describe alternatives you've considered

The alternative to this is just manually copy-pasting the same line repeatedly. Which, while is do able is more work than I would like to put in.

Additional context

I am just using HAProxy in front of traefik which is why my backends overlap

fraenki commented 8 months ago

@LeaderbotX400 Sounds like a valuable addition. Could you please provide an haproxy.conf snippet that shows how to use map_reg? Thanks :)

LeaderbotX400 commented 8 months ago

@fraenki

patterns.map

^[a-z]*arr\.mydomain\.tld MEDIARR_backend

HAproxy.conf

frontend internal
  bind :80
  use_backend %[req.hdr(host),map_reg(/patterns.map)]

Reference

doktornotor commented 7 months ago

Ok, I have a request so that we don't step on each others PRs and produce conflicts. Can you add one for this as well? @LeaderbotX400

use_backend %[req.ssl_sni,lower,map(/tmp/haproxy/mapfiles/mapfile.txt,backend-dummy)]

This is for using maps to select backend with SNI (tcp mode). Tested (the configuration, not the sample code below) and it is working great, super useful. Something like this (only the core part, not a complete patch}

--- HAProxy.xml.orig    2023-12-11 18:55:03.766258000 +0100
+++ HAProxy.xml 2023-12-11 18:54:45.467077000 +0100
@@ -2162,6 +2162,7 @@
                         <use_backend>Use specified Backend Pool</use_backend>
                         <use_server>Override server in Backend Pool</use_server>
                         <map_use_backend>Map domains to backend pools using a map file</map_use_backend>
+                        <map_use_backend_sni>Map domains to backend pools using SNI map file</map_use_backend_sni>
                         <fcgi_pass_header>FastCGI pass-header</fcgi_pass_header>
                         <fcgi_set_param>FastCGI set-param</fcgi_set_param>
                         <http-request_allow>http-request allow</http-request_allow>
@@ -2469,6 +2470,30 @@
                     <Multiple>N</Multiple>
                     <Required>N</Required>
                 </map_use_backend_default>
+                <map_use_backend_sni_file type="ModelRelationField">
+                    <Model>
+                        <template>
+                            <source>OPNsense.HAProxy.HAProxy</source>
+                            <items>mapfiles.mapfile</items>
+                            <display>name</display>
+                        </template>
+                    </Model>
+                    <ValidationMessage>Related map file item not found</ValidationMessage>
+                    <Multiple>N</Multiple>
+                    <Required>N</Required>
+                </map_use_backend_sni_file>
+                <map_use_backend_sni_default type="ModelRelationField">
+                    <Model>
+                        <template>
+                            <source>OPNsense.HAProxy.HAProxy</source>
+                            <items>backends.backend</items>
+                            <display>name</display>
+                        </template>
+                    </Model>
+                    <ValidationMessage>Related backend pool item not found</ValidationMessage>
+                    <Multiple>N</Multiple>
+                    <Required>N</Required>
+                </map_use_backend_sni_default>
             </action>
         </actions>
         <luas>
--- haproxy.conf.orig   2023-12-11 18:34:23.146555000 +0100
+++ haproxy.conf        2023-12-11 18:41:24.852977000 +0100
@@ -465,6 +465,24 @@
 {%             set action_enabled = '0' %}
     # ERROR: missing parameters
 {%           endif %}
+{%         elif action_data.type == 'map_use_backend_sni' %}
+{#           # First get the map file path #}
+{%           if action_data.map_use_backend_file|default("") != "" %}
+{%             set mapfile_data = helpers.getUUID(action_data.map_use_backend_file) %}
+{%             set mapfile_path = '/tmp/haproxy/mapfiles/' ~ mapfile_data.id ~ '.txt' %}
+{#             # Check if a default backend is specified #}
+{%             if action_data.map_use_backend_default|default("") != "" %}
+{%               set defaultbackend_data = helpers.getUUID(action_data.map_use_backend_default) %}
+{%               set defaultbackend_option = ',' ~ defaultbackend_data.name %}
+{%             else %}
+{%               set defaultbackend_option = '' %}
+{%             endif %}
+{#             # Finally add map file to config #}
+{%             do action_options.append('use_backend %[req.ssl_sni,lower,map(' ~ mapfile_path ~ defaultbackend_option ~ ')]') %}
+{%           else %}
+{%             set action_enabled = '0' %}
+    # ERROR: missing parameters
+{%           endif %}
 {%         elif action_data.type == 'fcgi_pass_header' %}
 {%           if action_data.fcgi_pass_header|default('') != '' %}
 {%             do action_options.append('pass-header ' ~ action_data.fcgi_pass_header) %}
figadore commented 4 months ago

I was hoping to be able to use map_beg. I know map_reg would cover my use case as well, but maybe it should be more generic and just allow you to pick your map function? This request is partially due to the complexity of regular expressions, some users may appreciate being able to use something simpler and not deal with edge cases where the . in a regex actually matches any character, rather than a literal period

fraenki commented 4 months ago

I wasn't able to work on this, but if someone wants to step in: please submit a pull request.

figadore commented 1 month ago

@fraenki it seems nobody is working on this at the moment. I'm not familiar with this repo, how would one go about getting started (assuming this change would be an easy first contribution)?