diff --git a/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogFrontend.xml b/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogFrontend.xml index da3c7d2a0..af4f53a11 100644 --- a/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogFrontend.xml +++ b/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogFrontend.xml @@ -128,6 +128,39 @@ text + + + header + + + + frontend.ssl_clientAuthEnabled + + checkbox + + + + frontend.ssl_clientAuthVerify + + dropdown + + + + frontend.ssl_clientAuthCAs + + select_multiple + true + To import additional CAs, go to CA Manager.]]> + Type CA name or choose from list. + + + frontend.ssl_clientAuthCRLs + + select_multiple + true + To import additional CRLs, go to CRL Manager.]]> + Type CRL name or choose from list. + header diff --git a/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/HAProxy.xml b/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/HAProxy.xml index 566a97e6c..3ada067d2 100644 --- a/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/HAProxy.xml +++ b/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/HAProxy.xml @@ -1,9 +1,7 @@ //OPNsense/HAProxy - 2.4.0 - - the HAProxy load balancer - + 2.5.0 + the HAProxy load balancer @@ -406,6 +404,31 @@ Please specify a value between 1 and 1000000000. Y + + 0 + N + + + N + required + + none + optional + required + + + + N + ca + Y + Please select a valid CA from the list. + + + N + crl + Y + Please select a valid CA from the list. + 1 500000 diff --git a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/exportCerts.php b/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/exportCerts.php index ca577f177..61b74b1ac 100755 --- a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/exportCerts.php +++ b/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/exportCerts.php @@ -2,7 +2,7 @@ ['ssl_certificates'], + 'frontends' => ['ssl_certificates', 'ssl_clientAuthCAs', 'ssl_clientAuthCRLs'], 'servers' => ['sslCA', 'sslCRL', 'sslClientCertificate'], ]; $certTypes = ['cert', 'ca', 'crl']; @@ -51,19 +51,20 @@ foreach ($configNodes as $key => $value) { // lookup all config nodes if (isset($configObj->OPNsense->HAProxy->$key)) { foreach ($configObj->OPNsense->HAProxy->$key->children() as $child) { - // generate a crt-list for every child node - $crtlist = array(); - $crtlist_filename = "/var/etc/haproxy/ssl/" . (string)$child->id . ".crtlist"; // search in all matching child elements for ssl data foreach ($configNodes[$key] as $sslchild) { if (isset($child->$sslchild)) { - // multiple comma-separated values are possible - $certs = explode(',', $child->$sslchild); - foreach ($certs as $cert_refid) { - // if the element has a cert attached, search for its contents - if ($cert_refid != "") { - // check all known cert types - foreach ($certTypes as $type) { + // generate a list for every known cert type + foreach ($certTypes as $type) { + // every child node needs its own set of lists + $crtlist = array(); + $crtlist_filename = "/var/etc/haproxy/ssl/" . (string)$child->id . "." . $type . "list"; + + // multiple comma-separated values are possible + $certs = explode(',', $child->$sslchild); + foreach ($certs as $cert_refid) { + // if the element has a cert attached, search for its contents + if ($cert_refid != "") { // search for cert (type) in config foreach ($configObj->$type as $cert) { if ($cert_refid == (string)$cert->refid) { @@ -83,37 +84,44 @@ foreach ($configNodes as $key => $value) { $pem_content .= "\n" . $ca; } } - // generate pem file - $output_pem_filename = "/var/etc/haproxy/ssl/" . $cert_refid . ".pem"; - file_put_contents($output_pem_filename, $pem_content); - chmod($output_pem_filename, 0600); - echo "exported $type to " . $output_pem_filename . "\n"; - // add pem file to crt-list - $crtlist[] = $output_pem_filename; + // generate pem file for individual certs + // (only supported for type "cert") + if ($type == cert) { + $output_pem_filename = "/var/etc/haproxy/ssl/" . $cert_refid . ".pem"; + file_put_contents($output_pem_filename, $pem_content); + chmod($output_pem_filename, 0600); + echo "exported $type to " . $output_pem_filename . "\n"; + // add pem file to crt-list + $crtlist[] = $output_pem_filename; + } else { + // All other types do not support list files. + // Add cert content directly to the list file. + $crtlist[] = $pem_content; + } } } } } - } - // generate crt-list file - // (this makes only sense for frontends) - if ($key == 'frontends') { - // ignore if crt-list is empty - if (empty($crtlist)) { - continue; + // generate list file + // (only supported for frontends) + if ($key == 'frontends') { + // ignore if list is empty + if (empty($crtlist)) { + continue; + } + // check if a default certificate is configured + if (($type == cert) and isset($child->ssl_default_certificate) and (string)$child->ssl_default_certificate != "") { + $default_cert = (string)$child->ssl_default_certificate; + $default_cert_filename = "/var/etc/haproxy/ssl/" . $default_cert . ".pem"; + // ensure default certificate is the first entry on the list + unset($crtlist[$default_cert]); + array_unshift($crtlist, $default_cert_filename); + } + $crtlist_content = implode("\n", $crtlist) . "\n"; + file_put_contents($crtlist_filename, $crtlist_content); + chmod($crtlist_filename, 0600); + echo "exported $type list to " . $crtlist_filename . "\n"; } - // check if a default certificate is configured - if (isset($child->ssl_default_certificate) and (string)$child->ssl_default_certificate != "") { - $default_cert = (string)$child->ssl_default_certificate; - $default_cert_filename = "/var/etc/haproxy/ssl/" . $default_cert . ".pem"; - // ensure default certificate is the first entry on the list - unset($crtlist[$default_cert]); - array_unshift($crtlist, $default_cert_filename); - } - $crtlist_content = implode("\n", $crtlist) . "\n"; - file_put_contents($crtlist_filename, $crtlist_content); - chmod($crtlist_filename, 0600); - echo "exported crt-list to " . $crtlist_filename . "\n"; } } } diff --git a/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf b/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf index 5ed67d2c2..cd7968dea 100644 --- a/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf +++ b/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf @@ -791,6 +791,23 @@ frontend {{frontend.name}} http-response set-header Strict-Transport-Security "{{ hsts_options|join('') }}" {% endif %} {% endif %} +{# # configure client certificate authentication #} +{% if frontend.ssl_clientAuthEnabled == '1' %} +{# # check for CAs (required) #} +{% if frontend.ssl_clientAuthCAs|default("") != "" %} +{# # NOTE: CA lists are generated by exportCerts.php #} +{% do ssl_options.append('ca-file /var/etc/haproxy/ssl/' ~ frontend.id ~ '.calist') %} +{# # check for verification mode #} +{% if frontend.ssl_clientAuthVerify|default("") != "" %} +{% do ssl_options.append('verify ' ~ frontend.ssl_clientAuthVerify) %} +{% endif %} +{# # check for CRL #} +{% if frontend.ssl_clientAuthCRLs|default("") != "" %} +{# # NOTE: CRL lists are generated by exportCerts.php #} +{% do ssl_options.append('crl-file /var/etc/haproxy/ssl/' ~ frontend.id ~ '.crllist') %} +{% endif %} +{% endif %} +{% endif %} {% endif %} {# # bind/listen configuration #} {% if frontend.bind|default("") != "" %}