mirror of
https://github.com/netbirdio/plugins.git
synced 2026-05-22 18:44:07 -07:00
net/haproxy: add support for client certificate authentication, closes #426
This commit is contained in:
+33
@@ -128,6 +128,39 @@
|
||||
<type>text</type>
|
||||
<help><![CDATA[Future requests to the domain should use only HTTPS for the specified time (in seconds): 15768000 = 6 months]]></help>
|
||||
</field>
|
||||
<field>
|
||||
<label>Client Certificate Auth</label>
|
||||
<type>header</type>
|
||||
<style>mode_table table_http table_ssl table_ssl_true</style>
|
||||
</field>
|
||||
<field>
|
||||
<id>frontend.ssl_clientAuthEnabled</id>
|
||||
<label>Enable</label>
|
||||
<type>checkbox</type>
|
||||
<help><![CDATA[Enable Client Certificate Authentication.]]></help>
|
||||
</field>
|
||||
<field>
|
||||
<id>frontend.ssl_clientAuthVerify</id>
|
||||
<label>Verification</label>
|
||||
<type>dropdown</type>
|
||||
<help><![CDATA[If set to 'optional' or 'required', client certificate is requested.]]></help>
|
||||
</field>
|
||||
<field>
|
||||
<id>frontend.ssl_clientAuthCAs</id>
|
||||
<label>Certificate Authorities</label>
|
||||
<type>select_multiple</type>
|
||||
<allownew>true</allownew>
|
||||
<help><![CDATA[Select CA certificates to use for client certificate authentication. <br/>To import additional CAs, go to <a href="/system_camanager.php">CA Manager</a>.]]></help>
|
||||
<hint>Type CA name or choose from list.</hint>
|
||||
</field>
|
||||
<field>
|
||||
<id>frontend.ssl_clientAuthCRLs</id>
|
||||
<label>Certificate Revocation Lists</label>
|
||||
<type>select_multiple</type>
|
||||
<allownew>true</allownew>
|
||||
<help><![CDATA[Select CRLs to use for client certificate authentication. <br/>To import additional CRLs, go to <a href="/system_crlmanager.php">CRL Manager</a>.]]></help>
|
||||
<hint>Type CRL name or choose from list.</hint>
|
||||
</field>
|
||||
<field>
|
||||
<label>Tuning Options</label>
|
||||
<type>header</type>
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
<model>
|
||||
<mount>//OPNsense/HAProxy</mount>
|
||||
<version>2.4.0</version>
|
||||
<description>
|
||||
the HAProxy load balancer
|
||||
</description>
|
||||
<version>2.5.0</version>
|
||||
<description>the HAProxy load balancer</description>
|
||||
<items>
|
||||
<general>
|
||||
<enabled type="BooleanField">
|
||||
@@ -406,6 +404,31 @@
|
||||
<ValidationMessage>Please specify a value between 1 and 1000000000.</ValidationMessage>
|
||||
<Required>Y</Required>
|
||||
</ssl_hstsMaxAge>
|
||||
<ssl_clientAuthEnabled type="BooleanField">
|
||||
<default>0</default>
|
||||
<Required>N</Required>
|
||||
</ssl_clientAuthEnabled>
|
||||
<ssl_clientAuthVerify type="OptionField">
|
||||
<Required>N</Required>
|
||||
<default>required</default>
|
||||
<OptionValues>
|
||||
<none>none</none>
|
||||
<optional>optional</optional>
|
||||
<required>required</required>
|
||||
</OptionValues>
|
||||
</ssl_clientAuthVerify>
|
||||
<ssl_clientAuthCAs type="CertificateField">
|
||||
<Required>N</Required>
|
||||
<Type>ca</Type>
|
||||
<Multiple>Y</Multiple>
|
||||
<ValidationMessage>Please select a valid CA from the list.</ValidationMessage>
|
||||
</ssl_clientAuthCAs>
|
||||
<ssl_clientAuthCRLs type="CertificateField">
|
||||
<Required>N</Required>
|
||||
<Type>crl</Type>
|
||||
<Multiple>Y</Multiple>
|
||||
<ValidationMessage>Please select a valid CA from the list.</ValidationMessage>
|
||||
</ssl_clientAuthCRLs>
|
||||
<tuning_maxConnections type="IntegerField">
|
||||
<MinimumValue>1</MinimumValue>
|
||||
<MaximumValue>500000</MaximumValue>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2016 Frank Wall
|
||||
* Copyright (C) 2016-2018 Frank Wall
|
||||
* Copyright (C) 2015 Deciso B.V.
|
||||
*
|
||||
* All rights reserved.
|
||||
@@ -40,7 +40,7 @@ global $config;
|
||||
|
||||
// configure ssl elements
|
||||
$configNodes = [
|
||||
'frontends' => ['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";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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("") != "" %}
|
||||
|
||||
Reference in New Issue
Block a user