mirror of
https://github.com/netbirdio/plugins.git
synced 2026-05-22 18:44:07 -07:00
Merge pull request #31 from fraenki/haproxy_25
net/haproxy: SSL fixes & more – version 1.4
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
PLUGIN_NAME= haproxy
|
||||
PLUGIN_VERSION= 1.3
|
||||
PLUGIN_REVISION= 1
|
||||
PLUGIN_VERSION= 1.4
|
||||
PLUGIN_COMMENT= Reliable, high performance TCP/HTTP load balancer
|
||||
PLUGIN_DEPENDS= haproxy
|
||||
PLUGIN_MAINTAINER= opnsense@moov.de
|
||||
|
||||
@@ -26,6 +26,13 @@
|
||||
<help><![CDATA[Configure listen addresses for this frontend, i.e. 127.0.0.1:8080 or www.example.com:443. Use TAB key to complete typing a listen address.]]></help>
|
||||
<hint>Enter address:port here. Finish with TAB.</hint>
|
||||
</field>
|
||||
<field>
|
||||
<id>frontend.bindOptions</id>
|
||||
<label>Advanced Bind Options</label>
|
||||
<type>text</type>
|
||||
<help><![CDATA[A list of parameters that will be appended to every Listen Address line.<br/>Example: accept-proxy npn http/1.1<br/><div class="text-info"><b>NOTE:</b> The syntax will not be checked, use at your own risk!</div>]]></help>
|
||||
<advanced>true</advanced>
|
||||
</field>
|
||||
<field>
|
||||
<id>frontend.mode</id>
|
||||
<label>Type</label>
|
||||
|
||||
@@ -37,6 +37,35 @@
|
||||
<type>checkbox</type>
|
||||
<help><![CDATA[Enable or disable SSL communication with this server.]]></help>
|
||||
</field>
|
||||
<field>
|
||||
<id>server.sslVerify</id>
|
||||
<label>Verify SSL Certificate</label>
|
||||
<type>checkbox</type>
|
||||
<help><![CDATA[If disabled, server certificate is not verified. Otherwise the certificate provided by the server is verified using CAs and optional CRLs. <b>Please note that this setting can be overriden by the global configuration.</b><br/><div class="text-info"><b>NOTE:</b> 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.</div>]]></help>
|
||||
</field>
|
||||
<field>
|
||||
<id>server.sslCA</id>
|
||||
<label>SSL Verify CA</label>
|
||||
<type>dropdown</type>
|
||||
<help><![CDATA[This certificate authority will be used to verify server's certificate. <br/>To import additional CAs, go to <a href="/system_certmanager.php">Certificate Manager</a>.]]></help>
|
||||
<hint>Type CA name or choose from list.</hint>
|
||||
</field>
|
||||
<field>
|
||||
<id>server.sslCRL</id>
|
||||
<label>SSL Verify CRL</label>
|
||||
<type>dropdown</type>
|
||||
<help><![CDATA[This certificate revocation list will be used to verify server's certificate. <br/>To import additional CRLs, go to <a href="/system_certmanager.php">Certificate Manager</a>.]]></help>
|
||||
<hint>Type CRL name or choose from list.</hint>
|
||||
<advanced>true</advanced>
|
||||
</field>
|
||||
<field>
|
||||
<id>server.sslClientCertificate</id>
|
||||
<label>SSL Client Certificate</label>
|
||||
<type>dropdown</type>
|
||||
<help><![CDATA[This certificate will be sent if the server send a client certificate request.<br/>To import additional certificates, go to <a href="/system_certmanager.php">Certificate Manager</a>.]]></help>
|
||||
<hint>Type certificate name or choose from list.</hint>
|
||||
<advanced>true</advanced>
|
||||
</field>
|
||||
<field>
|
||||
<id>server.weight</id>
|
||||
<label>Weight</label>
|
||||
|
||||
@@ -37,6 +37,13 @@
|
||||
<type>text</type>
|
||||
<help><![CDATA[Sets the maximum number of concurrent connections per HAProxy process.<br/><div class="text-info"><b>NOTE:</b> HAProxy will not be able to allocate enough memory if you set this value too high. Consider raising the settings for kern.maxfiles and kern.maxfilesperproc if you need to specify a non-default value.</div>]]></help>
|
||||
</field>
|
||||
<field>
|
||||
<id>haproxy.general.tuning.sslServerVerify</id>
|
||||
<label>Verify SSL Server Certificates</label>
|
||||
<type>dropdown</type>
|
||||
<help><![CDATA[This enforces a certain behavior for SSL verify on servers, ignoring per-server settings. If set to 'enforce verify', server certificates are verified. If set to 'disable verify', server certificates are not verified. The default is 'no preference' to only use per-server configurations and not enforce a global default for all servers.]]></help>
|
||||
<advanced>true</advanced>
|
||||
</field>
|
||||
<field>
|
||||
<id>haproxy.general.tuning.maxDHSize</id>
|
||||
<label>Maximum SSL DH Size</label>
|
||||
|
||||
@@ -27,6 +27,15 @@
|
||||
<ValidationMessage>Please specify a value between 1 and 128.</ValidationMessage>
|
||||
<Required>Y</Required>
|
||||
</nbproc>
|
||||
<sslServerVerify type="OptionField">
|
||||
<Required>Y</Required>
|
||||
<default>ignore</default>
|
||||
<OptionValues>
|
||||
<ignore>no preference [default]</ignore>
|
||||
<required>enforce verify</required>
|
||||
<none>disable verify</none>
|
||||
</OptionValues>
|
||||
</sslServerVerify>
|
||||
<maxDHSize type="IntegerField">
|
||||
<default>1024</default>
|
||||
<MinimumValue>1024</MinimumValue>
|
||||
@@ -243,6 +252,9 @@
|
||||
<ChangeCase>lower</ChangeCase>
|
||||
<ValidationMessage>Please provide a valid listen address, i.e. 127.0.0.1:8080 or www.example.com:443. Port range as start-end, i.e. 127.0.0.1:1220-1240.</ValidationMessage>
|
||||
</bind>
|
||||
<bindOptions type="TextField">
|
||||
<Required>N</Required>
|
||||
</bindOptions>
|
||||
<mode type="OptionField">
|
||||
<Required>Y</Required>
|
||||
<default>http</default>
|
||||
@@ -558,13 +570,31 @@
|
||||
<active>active [default]</active>
|
||||
<backup>backup</backup>
|
||||
<disabled>disabled</disabled>
|
||||
<inactive>inactive</inactive>
|
||||
</OptionValues>
|
||||
</mode>
|
||||
<ssl type="BooleanField">
|
||||
<default>0</default>
|
||||
<Required>Y</Required>
|
||||
</ssl>
|
||||
<sslVerify type="BooleanField">
|
||||
<default>1</default>
|
||||
<Required>Y</Required>
|
||||
</sslVerify>
|
||||
<sslCA type="CertificateField">
|
||||
<Required>N</Required>
|
||||
<Type>ca</Type>
|
||||
<ValidationMessage>Please select a valid CA from the list.</ValidationMessage>
|
||||
</sslCA>
|
||||
<sslCRL type="CertificateField">
|
||||
<Required>N</Required>
|
||||
<Type>crl</Type>
|
||||
<ValidationMessage>Please select a valid CRL from the list.</ValidationMessage>
|
||||
</sslCRL>
|
||||
<sslClientCertificate type="CertificateField">
|
||||
<Required>N</Required>
|
||||
<Type>cert</Type>
|
||||
<ValidationMessage>Please select a valid certificate from the list.</ValidationMessage>
|
||||
</sslClientCertificate>
|
||||
<weight type="IntegerField">
|
||||
<MinimumValue>0</MinimumValue>
|
||||
<MaximumValue>256</MaximumValue>
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: opnsense-haproxy
|
||||
version: 1.2
|
||||
version: 1.4
|
||||
origin: opnsense/haproxy
|
||||
comment: load balancer
|
||||
desc: Reliable, high performance TCP/HTTP load balancer
|
||||
|
||||
@@ -43,7 +43,12 @@
|
||||
{% for acl in action_data.linkedAcls.split(",") %}
|
||||
{% set acl_data = helpers.getUUID(acl) %}
|
||||
{% set acl_enabled = '1' %}
|
||||
{% do action_acls.append('acl_' ~ acl_data.id) %}
|
||||
{# # first check if this ACL condition should be negated #}
|
||||
{% if acl_data.negate|default("") == '1' %}
|
||||
{% do action_acls.append('!acl_' ~ acl_data.id) if acl_data.negate|default("") == '1' %}
|
||||
{% else %}
|
||||
{% do action_acls.append('acl_' ~ acl_data.id) %}
|
||||
{% endif %}
|
||||
{# # check if this ACL was already defined in this scope #}
|
||||
{% if acl_data.id in acls_seen %}
|
||||
{# # DEBUG: ignoring duplicate ACL {{acl_data.name}} #}
|
||||
@@ -456,6 +461,11 @@ global
|
||||
{% if helpers.exists('OPNsense.HAProxy.general.tuning.maxDHSize') %}
|
||||
tune.ssl.default-dh-param {{OPNsense.HAProxy.general.tuning.maxDHSize}}
|
||||
{% endif %}
|
||||
{% if helpers.exists('OPNsense.HAProxy.general.tuning.sslServerVerify') %}
|
||||
{% if OPNsense.HAProxy.general.tuning.sslServerVerify|default("") != 'ignore' %}
|
||||
ssl-server-verify {{OPNsense.HAProxy.general.tuning.sslServerVerify}}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if OPNsense.HAProxy.general.tuning.spreadChecks|default("") != "" %}
|
||||
spread-checks {{OPNsense.HAProxy.general.tuning.spreadChecks}}
|
||||
{% endif %}
|
||||
@@ -554,7 +564,7 @@ frontend {{frontend.name}}
|
||||
{# # bind/listen configuration #}
|
||||
{% if frontend.bind|default("") != "" %}
|
||||
{% for bind in frontend.bind.split(",") %}
|
||||
bind {{bind}} name {{bind}} {% if frontend.ssl_enabled == '1' and ssl_certs|default("") != "" %}ssl {{ ssl_options }}{{ssl_certs|join(' ')}} {% endif %}
|
||||
bind {{bind}} name {{bind}} {% if frontend.bindOptions|default("") != "" %}{{ frontend.bindOptions }} {% endif %}{% if frontend.ssl_enabled == '1' and ssl_certs|default("") != "" %}ssl {{ ssl_options }}{{ssl_certs|join(' ')}} {% endif %}
|
||||
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
@@ -778,7 +788,40 @@ backend {{backend.name}}
|
||||
{# # server weight #}
|
||||
{% 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" %}
|
||||
{% if server_data.mode|default("") != 'active' %}
|
||||
{% do server_options.append(server_data.mode) %}
|
||||
{% endif %}
|
||||
{# # 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 #}
|
||||
|
||||
Reference in New Issue
Block a user