aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPiBa-NL <pba_2k3@yahoo.com>2015-05-24 17:50:51 +0200
committerPiBa-NL <pba_2k3@yahoo.com>2015-05-24 17:50:51 +0200
commit7fa9bacd55f24141ba030cce6140c0423c9a3ed6 (patch)
treeda7775155b34f3e076e548c0a55f0115cb8ccec3
parent5be0199960c6d8fe85d1e4085e26316b504a91cd (diff)
downloadpfsense-packages-7fa9bacd55f24141ba030cce6140c0423c9a3ed6.tar.gz
pfsense-packages-7fa9bacd55f24141ba030cce6140c0423c9a3ed6.tar.bz2
pfsense-packages-7fa9bacd55f24141ba030cce6140c0423c9a3ed6.zip
haproxy-devel, new functionality SSL OCSP stapling for haproxy
-fix server dns resolving in case a CNAME is used.
-rw-r--r--config/haproxy-devel/pkg/haproxy.inc185
-rw-r--r--config/haproxy-devel/pkg/haproxy_utils.inc2
-rw-r--r--config/haproxy-devel/www/haproxy_listeners_edit.php8
-rw-r--r--pkg_config.10.xml4
4 files changed, 188 insertions, 11 deletions
diff --git a/config/haproxy-devel/pkg/haproxy.inc b/config/haproxy-devel/pkg/haproxy.inc
index 1e0b28f4..0c8ae4d6 100644
--- a/config/haproxy-devel/pkg/haproxy.inc
+++ b/config/haproxy-devel/pkg/haproxy.inc
@@ -346,9 +346,11 @@ function haproxy_custom_php_deinstall_command() {
$static_output .= "HAProxy, deleting haproxy webgui\n";
update_output_window($static_output);
exec("rm /usr/local/etc/rc.d/haproxy.sh");
+ exec("rm /etc/rc.haproxy_ocsp.sh");
$static_output .= "HAProxy, installing cron job if needed\n";
update_output_window($static_output);
haproxy_install_cron(false);
+ haproxy_install_cronjob(false, '/etc/rc.haproxy_ocsp.sh');
$static_output .= "HAProxy, running haproxy_custom_php_deinstall_command() DONE\n";
update_output_window($static_output);
}
@@ -433,6 +435,31 @@ EOD;
fclose($fd);
exec("chmod a+rx /usr/local/etc/rc.d/haproxy.sh");
+ $haproxy_ocsp = <<<EOD
+#!/usr/local/bin/php -f
+
+<?php
+
+/*
+ Updates haproxy OCSP responses.
+*/
+
+require_once("globals.inc");
+require_once("functions.inc");
+require_once("haproxy.inc");
+require_once("haproxy_socketinfo.inc");
+haproxy_updateocsp();
+
+?>
+
+EOD;
+ // removing the \r prevents the "No input file specified." error..
+ $haproxy_ocsp = str_replace("\r\n","\n", $haproxy_ocsp);
+ $fd = fopen("/etc/rc.haproxy_ocsp.sh", "w");
+ fwrite($fd, $haproxy_ocsp);
+ fclose($fd);
+ exec("chmod a+rx /etc/rc.haproxy_ocsp.sh");
+
$static_output .= "HAProxy, update configuration\n";
update_output_window($static_output);
@@ -453,6 +480,51 @@ EOD;
update_output_window($static_output);
}
+function haproxy_install_cronjob($should_install, $script, $interval = 60, $parameters = "") {
+ global $config, $g;
+ if($g['booting']==true)
+ return;
+ $is_installed = false;
+ if(!$config['cron']['item'])
+ return;
+ $x=0;
+ foreach($config['cron']['item'] as $item) {
+ if(strstr($item['command'], $script)) {
+ $is_installed = true;
+ break;
+ }
+ $x++;
+ }
+ switch($should_install) {
+ case true:
+ if(!$is_installed) {
+ $cron_item = array();
+ $cron_item['minute'] = "*/{$interval}";
+ $cron_item['hour'] = "*";
+ $cron_item['mday'] = "*";
+ $cron_item['month'] = "*";
+ $cron_item['wday'] = "*";
+ $cron_item['who'] = "root";
+ $cron_item['command'] = "$script $parameters";
+ $config['cron']['item'][] = $cron_item;
+ parse_config(true);
+ write_config("haproxy, install cron job");
+ configure_cron();
+ }
+ break;
+ case false:
+ if($is_installed == true) {
+ if($x > 0) {
+ unset($config['cron']['item'][$x]);
+ parse_config(true);
+ write_config("haproxy, remove cron job");
+ }
+ configure_cron();
+ }
+ break;
+ }
+}
+
function haproxy_install_cron($should_install) {
global $config, $g;
if($g['booting']==true)
@@ -903,6 +975,85 @@ function haproxy_write_certificate_fullchain($filename, $certid, $append = false
unset($cert);
}
+function haproxy_write_certificate_issuer($filename, $certid) {
+ $cert = haproxy_lookup_cert($certid);
+ $certchaincontent = ca_chain($cert);
+ if ($certchaincontent != "") {
+ $certcontent .= "\r\n" . $certchaincontent;
+ }
+ unset($certchaincontent);
+ file_put_contents($filename, $certcontent, 0);
+ unset($certcontent);
+ unset($cert);
+}
+
+function haproxy_uses_ocsp() {
+ global $config;
+ $a_frontends = &$config['installedpackages']['haproxy']['ha_backends']['item'];
+ if (!is_array($a_frontends))
+ return false;
+
+ $configpath = "{$g['varetc_path']}/haproxy";
+ foreach ($a_frontends as $frontend) {
+ if ($frontend['sslocsp'] == 'yes') {
+ return true;
+ }
+ }
+ return false;
+}
+
+function haproxy_getocspurl($filename) {
+ return exec("openssl x509 -noout -ocsp_uri -in $filename", $output, $err);
+}
+
+function haproxy_updateocsp_one($socketupdate, $filename, $name) {
+ if (file_exists("{$filename}.ocsp")) {
+ // If the .ocsp file exists we want to use ocsp
+ syslog(LOG_NOTICE, "HAProxy Retrieving OCSP for frontend {$name}.. ");
+ $ocsp_url = haproxy_getocspurl($filename);
+ $ocsp_host = parse_url($ocsp_url, PHP_URL_HOST);
+ if (empty($ocsp_url)) {
+ // If cert does not have a ocsp_uri, it cannot be updated..
+ syslog(LOG_ERR, "HAProxy OCSP ERROR Cert does not have a ocsp_uri");
+ } else {
+ $retval = exec("openssl ocsp -issuer {$filename}.issuer -verify_other {$filename}.issuer -cert {$filename} -url {$ocsp_url} -header Host {$ocsp_host} -respout {$filename}.ocsp 2>&1", $output, $err);
+ if ($socketupdate) {
+ $ocspresponse = base64_encode(file_get_contents("{$filename}.ocsp"));
+ $r = haproxy_socket_command("set ssl ocsp-response $ocspresponse");
+ if ($r[0] == "OCSP Response updated!\n")
+ syslog(LOG_NOTICE, "HAProxy OCSP socket update successful for frontend {$name}..result: ".$retval);
+ else {
+ syslog(LOG_ERR, "HAProxy OCSP ERROR while performing haproxy socket update OCSP response for: {$name}");
+ }
+ } else {
+ syslog(LOG_NOTICE, "HAProxy Retrieving OCSP for frontend {$name}..result: ".$retval);
+ }
+ }
+ }
+}
+
+function haproxy_updateocsp($socketupdate = true) {
+ global $config, $g;
+ $a_frontends = &$config['installedpackages']['haproxy']['ha_backends']['item'];
+ if (!is_array($a_frontends))
+ return true;
+
+ $configpath = "{$g['varetc_path']}/haproxy";
+ foreach ($a_frontends as $frontend) {
+ $filename = "$configpath/{$frontend['name']}.pem";
+ haproxy_updateocsp_one($socketupdate, $filename, $frontend['name']);
+
+ $subfolder = "$configpath/{$frontend['name']}";
+ $certs = $frontend['ha_certificates']['item'];
+ if (is_array($certs)){
+ foreach($certs as $cert){
+ $filename = "$subfolder/{$cert['ssl_certificate']}.pem";
+ haproxy_updateocsp_one($socketupdate, $filename, $frontend['name']);
+ }
+ }
+ }
+}
+
function haproxy_writeconf($configpath) {
global $config;
global $aliastable;
@@ -999,14 +1150,29 @@ function haproxy_writeconf($configpath) {
//ssl crt ./server.pem ca-file ./ca.crt verify optional crt-ignore-err all crl-file ./ca_crl.pem
$filename = "$configpath/{$frontend['name']}.pem";
$ssl_crt = " crt $filename";
+
haproxy_write_certificate_fullchain($filename, $frontend['ssloffloadcert']);
+ if ($frontend['sslocsp'] == 'yes') {
+ if (!empty(haproxy_getocspurl($filename))) {
+ haproxy_write_certificate_issuer($filename . ".issuer", $frontend['ssloffloadcert']);
+ touch($filename . ".ocsp");
+ }
+ }
+
$subfolder = "$configpath/{$frontend['name']}";
$certs = $frontend['ha_certificates']['item'];
if (is_array($certs)){
if (count($certs) > 0){
@mkdir($subfolder, 0755, true);
foreach($certs as $cert){
- haproxy_write_certificate_fullchain("$subfolder/{$cert['ssl_certificate']}.pem", $cert['ssl_certificate']);
+ $filenamefoldercert = "$subfolder/{$cert['ssl_certificate']}.pem";
+ haproxy_write_certificate_fullchain($filenamefoldercert, $cert['ssl_certificate']);
+ if ($frontend['sslocsp'] == 'yes') {
+ if (!empty(haproxy_getocspurl($filenamefoldercert))) {
+ haproxy_write_certificate_issuer($filenamefoldercert . ".issuer", $cert['ssl_certificate']);
+ touch($filenamefoldercert . ".ocsp");
+ }
+ }
}
$ssl_crt .= " crt $subfolder";
}
@@ -1350,11 +1516,6 @@ function haproxy_writeconf($configpath) {
haproxy_do_xmlrpc_sync();
}
}
-
- if (isset($a_global['carpdev']))
- haproxy_install_cron(true);
- else
- haproxy_install_cron(false);
}
function haproxy_is_running() {
@@ -1566,8 +1727,18 @@ function haproxy_check_run($reload) {
$a_global = &$config['installedpackages']['haproxy'];
$configpath = "{$g['varetc_path']}/haproxy";
- if ($reload)
+ if ($reload) {
haproxy_writeconf($configpath);
+ haproxy_updateocsp(false);
+
+ if (isset($a_global['carpdev']))
+ haproxy_install_cron(true);
+ else
+ haproxy_install_cron(false);
+
+ $useocsp = haproxy_uses_ocsp();
+ haproxy_install_cronjob($useocsp, '/etc/rc.haproxy_ocsp.sh', 120);
+ }
if(isset($a_global['enable'])) {
if (isset($a_global['carpdev'])) {
diff --git a/config/haproxy-devel/pkg/haproxy_utils.inc b/config/haproxy-devel/pkg/haproxy_utils.inc
index d8c4faf4..08065abc 100644
--- a/config/haproxy-devel/pkg/haproxy_utils.inc
+++ b/config/haproxy-devel/pkg/haproxy_utils.inc
@@ -48,7 +48,7 @@ class haproxy_utils {
if (haproxy_utils::$pf_version < '2.2')
exec("/usr/bin/dig {$host_esc} $type @$dnsserver | /usr/bin/grep {$host_esc} | /usr/bin/grep -v ';' | /usr/bin/awk '{ print $5 }'", $resolved);
else
- exec("/usr/bin/drill {$host_esc} $type @$dnsserver | /usr/bin/grep {$host_esc} | /usr/bin/grep -v ';' | /usr/bin/awk '{ print $5 }'", $resolved);
+ exec("/usr/bin/drill {$host_esc} $type @$dnsserver | /usr/bin/awk '{ if($1!=\";;\" && $4==\"{$type}\") print $5 }'", $resolved);
foreach($resolved as $item) {
$newitem = array();
$newitem["typeid"] = $type;
diff --git a/config/haproxy-devel/www/haproxy_listeners_edit.php b/config/haproxy-devel/www/haproxy_listeners_edit.php
index d8841c33..5b726d08 100644
--- a/config/haproxy-devel/www/haproxy_listeners_edit.php
+++ b/config/haproxy-devel/www/haproxy_listeners_edit.php
@@ -71,7 +71,7 @@ uasort($a_pools, haproxy_compareByName);
global $simplefields;
$simplefields = array('name','desc','status','secondary','primary_frontend','type','forwardfor','httpclose','extaddr','backend_serverpool',
'max_connections','client_timeout','port','advanced_bind',
- 'ssloffloadcert','dcertadv','ssloffload','ssloffloadacl','ssloffloadacladditional','sslclientcert-none','sslclientcert-invalid',
+ 'ssloffloadcert','dcertadv','ssloffload','ssloffloadacl','ssloffloadacladditional','sslclientcert-none','sslclientcert-invalid','sslocsp',
'socket-stats',
'dontlognull','dontlog-normal','log-separate-errors','log-detailed');
@@ -787,6 +787,12 @@ $primaryfrontends = get_haproxy_frontends($excludefrontend);
<input id="ssloffloadacl" name="ssloffloadacl" type="checkbox" value="yes" <?php if ($pconfig['ssloffloadacl']=='yes') echo "checked";?> onclick="updatevisibility();" />Add ACL for certificate CommonName. (host header matches the 'CN' of the certificate)<br/>
</td>
</tr>
+ <tr class="haproxy_ssloffloading_enabled" align="left">
+ <td width="22%" valign="top" class="vncell">OCSP</td>
+ <td width="78%" class="vtable" colspan="2">
+ <input id="sslocsp" name="sslocsp" type="checkbox" value="yes" <?php if ($pconfig['sslocsp']=='yes') echo "checked";?> onclick="updatevisibility();" />Load certificate ocsp responses for easy certificate validation by the client.<br/>
+ </td>
+ </tr>
<tr class="haproxy_ssloffloading_enabled">
<td width="22%" valign="top" class="vncell">Additional certificates</td>
<td width="78%" class="vtable" colspan="2" valign="top">
diff --git a/pkg_config.10.xml b/pkg_config.10.xml
index 7f4e7b6d..95043bc3 100644
--- a/pkg_config.10.xml
+++ b/pkg_config.10.xml
@@ -172,7 +172,7 @@
Supports ACLs for smart backend switching.]]></descr>
<website>http://haproxy.1wt.eu/</website>
<category>Services</category>
- <version>0.23</version>
+ <version>0.24</version>
<status>Release</status>
<required_version>2.2</required_version>
<config_file>https://packages.pfsense.org/packages/config/haproxy-devel/haproxy.xml</config_file>
@@ -184,7 +184,7 @@
<build_pbi>
<ports_before>security/openssl</ports_before>
<custom_name>haproxy-devel</custom_name>
- <port>net/haproxy</port>
+ <port>net/haproxy-devel</port>
</build_pbi>
<build_options>WITH_OPENSSL_PORT=yes;haproxy_UNSET_FORCE=DPCRE;haproxy_SET_FORCE=OPENSSL SPCRE</build_options>
</package>