diff --git a/net/haproxy/pkg-descr b/net/haproxy/pkg-descr
index 511582ebe..3c0d71c5f 100644
--- a/net/haproxy/pkg-descr
+++ b/net/haproxy/pkg-descr
@@ -16,6 +16,7 @@ Added:
* add config export (#2035)
* add config diff
* guard against broken config by using a staging config file
+* add basic OCSP stapling support (#1430)
Fixed:
* fix maintenance page (python error: 'list' object has no attribute 'strip')
@@ -31,6 +32,7 @@ Changed:
* use new "http-check send" command for HTTP health checks
* change default for spreadChecks from 0 to 2
* no longer overwrite live config file when running a syntax check
+* make restart/reload commands usable in cron jobs
2.26
diff --git a/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/generalSettings.xml b/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/generalSettings.xml
index 78d7ce4b2..5869a62e6 100644
--- a/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/generalSettings.xml
+++ b/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/generalSettings.xml
@@ -21,6 +21,12 @@
checkbox
+
+ haproxy.general.storeOcsp
+
+ checkbox
+
+
haproxy.general.showIntro
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 3cb8e5b2e..89d711a03 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
@@ -16,6 +16,10 @@
0
Y
+
+ 0
+ N
+
1
diff --git a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/exportCerts.php b/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/exportCerts.php
index ea4c086f5..7bfa26819 100755
--- a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/exportCerts.php
+++ b/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/exportCerts.php
@@ -80,7 +80,13 @@ foreach ($configNodes as $key => $value) {
if (!empty((string)$cert->caref)) {
$cert = (array)$cert;
$ca = ca_chain($cert);
+ // append the CA to the certificate data
$pem_content .= "\n" . $ca;
+ // additionally export CA to it's own file,
+ // not required for HAProxy, but makes OCSP handling easier
+ $output_ca_filename = $export_path . $cert_refid . ".issuer";
+ file_put_contents($output_ca_filename, $ca);
+ chmod($output_ca_filename, 0600);
}
}
// generate pem file for individual certs
diff --git a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/setup.sh b/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/setup.sh
index ca8cd48dc..8dc393461 100755
--- a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/setup.sh
+++ b/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/setup.sh
@@ -1,5 +1,9 @@
#!/bin/sh
+if [ -f /etc/rc.conf.d/haproxy ]; then
+. /etc/rc.conf.d/haproxy
+fi
+
# NOTE: Keep /var/haproxy on this list, see GH issue opnsense/plugins #39.
HAPROXY_DIRS="/var/haproxy /var/haproxy/var/run /tmp/haproxy /tmp/haproxy/ssl /tmp/haproxy/lua /tmp/haproxy/errorfiles /tmp/haproxy/mapfiles"
@@ -18,6 +22,11 @@ find /var/haproxy -type d -exec chmod 550 {} \;
/usr/local/opnsense/scripts/OPNsense/HAProxy/exportErrorFiles.php > /dev/null 2>&1
/usr/local/opnsense/scripts/OPNsense/HAProxy/exportMapFiles.php > /dev/null 2>&1
+# update OCSP data
+if [ "${haproxy_ocsp}" == "YES" ]; then
+ /usr/local/opnsense/scripts/OPNsense/HAProxy/updateOcsp.sh > /dev/null 2>&1
+fi
+
# deploy new config
case "$1" in
deploy)
diff --git a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/updateOcsp.sh b/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/updateOcsp.sh
new file mode 100755
index 000000000..12c4c8724
--- /dev/null
+++ b/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/updateOcsp.sh
@@ -0,0 +1,70 @@
+#!/bin/sh
+# This file is based on:
+# https://github.com/acmesh-official/acme.sh/blob/master/deploy/haproxy.sh
+#
+# Copyright (C) 2021 Neil Pang
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+HAPROXY_DIR="/tmp/haproxy/ssl"
+
+for _pem in "$HAPROXY_DIR"/*.pem; do
+ cert_file="$(basename "$_pem")"
+ _issuer="${HAPROXY_DIR}/${cert_file%.pem}.issuer"
+ _ocsp="${_pem}.ocsp"
+ cert_cn="$(openssl x509 -in "$_pem" -noout -text | sed -nE 's/.*Subject:.*CN = ([^,]*)(,.*)?$/\1/p')"
+
+ if [ ! -f "$_issuer" ]; then
+ continue
+ fi
+
+ if [ -r "${_issuer}" ]; then
+ _ocsp_url="$(openssl x509 -noout -ocsp_uri -in "$_pem")"
+ if [ -n "$_ocsp_url" ]; then
+ _ocsp_host="$(echo "$_ocsp_url" | cut -d/ -f3)"
+ subjectdn="$(openssl x509 -in "$_issuer" -subject -noout | cut -d'/' -f2,3,4,5,6,7,8,9,10)"
+ issuerdn="$(openssl x509 -in "$_issuer" -issuer -noout | cut -d'/' -f2,3,4,5,6,7,8,9,10)"
+ if [ "$subjectdn" = "$issuerdn" ]; then
+ _cafile_argument="-CAfile \"${_issuer}\""
+ else
+ _cafile_argument=""
+ fi
+ _openssl_version=$(openssl version | cut -d' ' -f2)
+ _openssl_major=$(echo "${_openssl_version}" | cut -d '.' -f1)
+ _openssl_minor=$(echo "${_openssl_version}" | cut -d '.' -f2)
+ if [ "${_openssl_major}" -eq "1" ] && [ "${_openssl_minor}" -ge "1" ] || [ "${_openssl_major}" -ge "2" ]; then
+ _header_sep="="
+ else
+ _header_sep=" "
+ fi
+
+ _openssl_ocsp_cmd="openssl ocsp \
+ -issuer \"${_issuer}\" \
+ -cert \"${_pem}\" \
+ -url \"${_ocsp_url}\" \
+ -header Host${_header_sep}\"${_ocsp_host}\" \
+ -respout \"${_ocsp}\" \
+ -verify_other \"${_issuer}\" \
+ ${_cafile_argument} \
+ | grep -q \"${_pem}: good\""
+
+ eval "${_openssl_ocsp_cmd}"
+ _ret=$?
+
+ if [ "${_ret}" != "0" ]; then
+ echo "Updating OCSP stapling failed with return code ${_ret}"
+ fi
+ fi
+ fi
+done
diff --git a/net/haproxy/src/opnsense/service/conf/actions.d/actions_haproxy.conf b/net/haproxy/src/opnsense/service/conf/actions.d/actions_haproxy.conf
index 07341474e..1e45bc954 100644
--- a/net/haproxy/src/opnsense/service/conf/actions.d/actions_haproxy.conf
+++ b/net/haproxy/src/opnsense/service/conf/actions.d/actions_haproxy.conf
@@ -20,12 +20,14 @@ message:stopping haproxy
command:/usr/local/opnsense/scripts/OPNsense/HAProxy/setup.sh deploy; /usr/local/opnsense/scripts/OPNsense/HAProxy/rc-wrapper.sh restart
parameters:
type:script
+description:Restart HAProxy service
message:restarting haproxy
[reload]
command:/usr/local/opnsense/scripts/OPNsense/HAProxy/setup.sh deploy; /usr/local/opnsense/scripts/OPNsense/HAProxy/rc-wrapper.sh reload || /usr/local/opnsense/scripts/OPNsense/HAProxy/rc-wrapper.sh restart
parameters:
type:script
+description:Reload HAProxy service
message:reloading haproxy
[configtest]
@@ -119,3 +121,10 @@ parameters:
type:script_output
message:diff haproxy config
+[update_ocsp]
+command:/usr/local/opnsense/scripts/OPNsense/HAProxy/updateOcsp.sh
+parameters:
+type:script_output
+description:Update HAProxy OCSP data
+message:update haproxy ocsp data
+
diff --git a/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/rc.conf.d b/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/rc.conf.d
index 50cee173c..261881284 100644
--- a/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/rc.conf.d
+++ b/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/rc.conf.d
@@ -3,6 +3,11 @@ haproxy_enable=YES
haproxy_var_script="/usr/local/opnsense/scripts/OPNsense/HAProxy/setup.sh"
haproxy_pidfile="/var/run/haproxy.pid"
haproxy_config="/usr/local/etc/haproxy.conf"
+{% if helpers.exists('OPNsense.HAProxy.general.storeOcsp') and OPNsense.HAProxy.general.storeOcsp|default("0") == "1" %}
+haproxy_ocsp=YES
+{% else %}
+haproxy_ocsp=NO
+{% endif %}
{% if helpers.exists('OPNsense.HAProxy.general.gracefulStop') and OPNsense.HAProxy.general.gracefulStop|default("0") == "1" %}
haproxy_hardstop=NO
{% else %}