diff --git a/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogServer.xml b/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogServer.xml index 7fceff403..bfa340571 100644 --- a/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogServer.xml +++ b/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogServer.xml @@ -37,6 +37,35 @@ checkbox + + server.sslVerify + + checkbox + Please note that this setting can be overriden by the global configuration.
NOTE: It is critically important to verify server certificates when using SSL to connect to servers, otherwise the communication is prone to trivial man-in-the-middle attacks rendering SSL totally useless.
]]>
+
+ + server.sslCA + + dropdown + To import additional CAs, go to Certificate Manager.]]> + Type CA name or choose from list. + + + server.sslCRL + + dropdown + To import additional CRLs, go to Certificate Manager.]]> + Type CRL name or choose from list. + true + + + server.sslClientCertificate + + dropdown + To import additional certificates, go to Certificate Manager.]]> + Type certificate name or choose from list. + true + server.weight 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 2d5b966df..5beeab7a7 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 @@ -574,6 +574,25 @@ 0 Y + + 1 + Y + + + N + ca + Please select a valid CA from the list. + + + N + crl + Please select a valid CRL from the list. + + + N + cert + Please select a valid certificate from the list. + 0 256 diff --git a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/exportCerts.php b/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/exportCerts.php index 96f03ee43..02e70a1f7 100755 --- a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/exportCerts.php +++ b/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/exportCerts.php @@ -37,27 +37,51 @@ require_once("legacy_bindings.inc"); use OPNsense\Core\Config; global $config; -// traverse HAProxy frontends +// configure ssl elements +$configNodes = [ + 'frontends' => ['ssl_certificates'], + 'servers' => ['sslCA', 'sslCRL', 'sslClientCertificate'], +]; +$certTypes = ['cert', 'ca', 'crl']; + +// traverse HAProxy configuration $configObj = Config::getInstance()->object(); -if (isset($configObj->OPNsense->HAProxy->frontends)) { - foreach ($configObj->OPNsense->HAProxy->frontends->children() as $frontend) { - if (!isset($frontend->ssl_enabled)) { - continue; - } - // multiple comma-separated values are possible - $certs = explode(',', $frontend->ssl_certificates); - foreach ($certs as $cert_refid) { - // if the frontend has a cert attached, search for its contents - if ($cert_refid != "") { - foreach ($configObj->cert as $cert) { - if ($cert_refid == (string)$cert->refid) { - // generate cert pem file - $pem_content = str_replace("\n\n", "\n", str_replace("\r", "", base64_decode((string)$cert->crt))); - $pem_content .= "\n" . str_replace("\n\n", "\n", str_replace("\r", "", base64_decode((string)$cert->prv))); - $output_pem_filename = "/var/etc/haproxy/ssl/" . $cert_refid . ".pem" ; - file_put_contents($output_pem_filename, $pem_content); - chmod($output_pem_filename, 0600); - echo "certificate exported to " . $output_pem_filename . "\n"; +foreach ($configNodes as $key => $value) { + // lookup all config nodes + if (isset($configObj->OPNsense->HAProxy->$key)) { + foreach ($configObj->OPNsense->HAProxy->$key->children() as $child) { + // 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) { + // search for cert (type) in config + foreach ($configObj->$type as $cert) { + if ($cert_refid == (string)$cert->refid) { + $pem_content = ''; + // CRLs require special export + if ( $type == 'crl' ) { + $crl =& lookup_crl($cert_refid); + crl_update($crl); + $pem_content = base64_decode($crl['text']); + } else { + $pem_content = str_replace("\n\n", "\n", str_replace("\r", "", base64_decode((string)$cert->crt))); + $pem_content .= "\n" . str_replace("\n\n", "\n", str_replace("\r", "", base64_decode((string)$cert->prv))); + } + // 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"; + } + } + } + } } } } 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 aa0e31d8f..92ca36ba1 100644 --- a/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf +++ b/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf @@ -457,7 +457,7 @@ global tune.ssl.default-dh-param {{OPNsense.HAProxy.general.tuning.maxDHSize}} {% endif %} {% if helpers.exists('OPNsense.HAProxy.general.tuning.sslServerVerify') %} -{% if OPNsense.HAProxy.general.tuning.spreadChecks|default("") != 'ignore' %} +{% if OPNsense.HAProxy.general.tuning.sslServerVerify|default("") != 'ignore' %} ssl-server-verify {{OPNsense.HAProxy.general.tuning.sslServerVerify}} {% endif %} {% endif %} @@ -784,8 +784,37 @@ backend {{backend.name}} {% do server_options.append('weight ' ~ server_data.weight) if server_data.weight|default("") != "" %} {# # server role/mode #} {% do server_options.append(server_data.mode) if server_data.mode|default("") != "active" %} -{# # server ssl support #} -{% do server_options.append('ssl ') if server_data.ssl|default("") == '1' %} +{# # server ssl communication #} +{% if server_data.ssl|default("") == '1' %} +{% do server_options.append('ssl') %} +{# # get status of ssl verification #} +{% set ssl_verify_enabled = '0' %} +{% if helpers.exists('OPNsense.HAProxy.general.tuning.sslServerVerify') and OPNsense.HAProxy.general.tuning.sslServerVerify|default("") != 'ignore' %} +{# # NOTE: Global parameter overrides per-server configuration. #} +{% set ssl_verify_enabled = '1' if OPNsense.HAProxy.general.tuning.sslServerVerify|default("") == 'required' %} +{% elif server_data.sslVerify|default("") == '1' %} +{% set ssl_verify_enabled = '1' %} +{% endif %} +{# # configure ssl verification #} +{% if ssl_verify_enabled == '1' %} +{# # enable SSL verification #} +{% do server_options.append('verify required') %} +{# # check for SSL CA #} +{% if server_data.sslCA|default("") != "" %} +{% do server_options.append('ca-file /var/etc/haproxy/ssl/' ~ server_data.sslCA ~ '.pem') %} +{% endif %} +{# # check for SSL CRL #} +{% if server_data.sslCRL|default("") != "" %} +{% do server_options.append('crl-file /var/etc/haproxy/ssl/' ~ server_data.sslCRL ~ '.pem') %} +{% endif %} +{# # check for SSL client cert #} +{% if server_data.sslClientCertificate|default("") != "" %} +{% do server_options.append('crt /var/etc/haproxy/ssl/' ~ server_data.sslClientCertificate ~ '.pem') %} +{% endif %} +{% else %} +{% do server_options.append('verify none') %} +{% endif %} +{% endif %} {# # source address #} {% if backend.source|default("") != "" %} {# # prefer backend configuration #}