aboutsummaryrefslogtreecommitdiffstats
path: root/config
diff options
context:
space:
mode:
authorRenato Botelho <garga@FreeBSD.org>2015-05-28 15:43:35 -0300
committerRenato Botelho <garga@FreeBSD.org>2015-05-28 15:43:35 -0300
commitb8dbf62170c67b477691f8733ada6e67bda0de70 (patch)
tree027e59291fda18952c20e6d64383f4939b9c971d /config
parent901b85305f21a6526b949181bcb7393433044b2d (diff)
parent5c5fd7560c8fa5c01ae862af72a941746301227e (diff)
downloadpfsense-packages-b8dbf62170c67b477691f8733ada6e67bda0de70.tar.gz
pfsense-packages-b8dbf62170c67b477691f8733ada6e67bda0de70.tar.bz2
pfsense-packages-b8dbf62170c67b477691f8733ada6e67bda0de70.zip
Merge pull request #881 from PiBa-NL/haproxy-devel-ocsp
Diffstat (limited to 'config')
-rw-r--r--config/haproxy-devel/pkg/haproxy.inc189
-rw-r--r--config/haproxy-devel/pkg/haproxy_utils.inc41
-rw-r--r--config/haproxy-devel/www/haproxy_listeners_edit.php8
3 files changed, 212 insertions, 26 deletions
diff --git a/config/haproxy-devel/pkg/haproxy.inc b/config/haproxy-devel/pkg/haproxy.inc
index 1e0b28f4..6e07625f 100644
--- a/config/haproxy-devel/pkg/haproxy.inc
+++ b/config/haproxy-devel/pkg/haproxy.inc
@@ -345,10 +345,12 @@ function haproxy_custom_php_deinstall_command() {
update_output_window($static_output);
$static_output .= "HAProxy, deleting haproxy webgui\n";
update_output_window($static_output);
- exec("rm /usr/local/etc/rc.d/haproxy.sh");
+ unlink_if_exists("/usr/local/etc/rc.d/haproxy.sh");
+ unlink_if_exists("/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);
}
@@ -431,7 +433,32 @@ EOD;
$fd = fopen("/usr/local/etc/rc.d/haproxy.sh", "w");
fwrite($fd, $haproxy);
fclose($fd);
- exec("chmod a+rx /usr/local/etc/rc.d/haproxy.sh");
+ chmod("/usr/local/etc/rc.d/haproxy.sh", 0755);
+
+ $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);
+ chmod("/etc/rc.haproxy_ocsp.sh", 0755);
$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..3d841a25 100644
--- a/config/haproxy-devel/pkg/haproxy_utils.inc
+++ b/config/haproxy-devel/pkg/haproxy_utils.inc
@@ -36,26 +36,35 @@ require_once("config.inc");
class haproxy_utils {
public static $pf_version;
- public function query_dns($host, $querytype="A,AAAA", $dnsserver = "127.0.0.1") {
+ public function query_dns($host, $querytype="A,AAAA") {
$result = array();
- $host = trim($host, " \t\n\r\0\x0B[];\"'");
- $host_esc = escapeshellarg($host);
$types = explode(',',$querytype);
+ $recordtypes = 0;
foreach($types as $type){
- $resolved = gethostbyname($host);
- if($resolved) {
- $resolved = array();
- 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);
- foreach($resolved as $item) {
- $newitem = array();
- $newitem["typeid"] = $type;
- $newitem["data"] = $item;
- $result[] = $newitem;
- }
+ switch ($type) {
+ case 'A':
+ $recordtypes += DNS_A;
+ break;
+ case 'AAAA':
+ $recordtypes += DNS_AAAA;
+ break;
+ }
+ }
+ if ($recordtypes == 0)
+ return $result;
+
+ $dnsresult = dns_get_record($host, $recordtypes);
+ foreach($dnsresult as $item) {
+ $newitem["typeid"] = $item['type'];
+ switch ($item['type']) {
+ case 'A':
+ $newitem["data"] = $item['ip'];
+ break;
+ case 'AAAA':
+ $newitem["data"] = $item['ipv6'];
+ break;
}
+ $result[] = $newitem;
}
return $result;
}
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">