aboutsummaryrefslogtreecommitdiffstats
path: root/config/haproxy-devel/haproxy.inc
diff options
context:
space:
mode:
Diffstat (limited to 'config/haproxy-devel/haproxy.inc')
-rw-r--r--config/haproxy-devel/haproxy.inc210
1 files changed, 162 insertions, 48 deletions
diff --git a/config/haproxy-devel/haproxy.inc b/config/haproxy-devel/haproxy.inc
index 273091b3..76b836b6 100644
--- a/config/haproxy-devel/haproxy.inc
+++ b/config/haproxy-devel/haproxy.inc
@@ -158,6 +158,88 @@ $a_sticky_type['stick_rdp_cookie'] = array('name' => 'Stick on RDP-cookie',
'descr' => "Uses a RDP-Cookie send by the mstsc client, note that not all clients send this.",
'cookiedescr' => 'EXAMPLE: msts or mstshash');
+if(!function_exists('group_ports')){
+// function group_ports() is present in pfSense 2.2 in util.inc
+/* create ranges of sequential port numbers (200:215) and remove duplicates */
+function group_ports($ports) {
+ if (!is_array($ports) || empty($ports))
+ return;
+
+ $uniq = array();
+ foreach ($ports as $port) {
+ if (is_portrange($port)) {
+ list($begin, $end) = explode(":", $port);
+ if ($begin > $end) {
+ $aux = $begin;
+ $begin = $end;
+ $end = $aux;
+ }
+ for ($i = $begin; $i <= $end; $i++)
+ if (!in_array($i, $uniq))
+ $uniq[] = $i;
+ } else if (is_port($port)) {
+ if (!in_array($port, $uniq))
+ $uniq[] = $port;
+ }
+ }
+ sort($uniq, SORT_NUMERIC);
+
+ $result = array();
+ foreach ($uniq as $idx => $port) {
+ if ($idx == 0) {
+ $result[] = $port;
+ continue;
+ }
+
+ $last = end($result);
+ if (is_portrange($last))
+ list($begin, $end) = explode(":", $last);
+ else
+ $begin = $end = $last;
+
+ if ($port == ($end+1)) {
+ $end++;
+ $result[count($result)-1] = "{$begin}:{$end}";
+ } else {
+ $result[] = $port;
+ }
+ }
+
+ return $result;
+}
+}
+
+function haproxy_portoralias_to_list($port_or_alias) {
+ // input: a port or aliasname: 80 https MyPortAlias
+ // returns: a array of ports and portranges 80 443 8000:8010
+ global $config;
+ $portresult = array();
+ if (is_alias($port_or_alias)) {
+ if (is_array($config['aliases']['alias'])) {
+ foreach ($config['aliases']['alias'] as $alias) {
+ if ($alias['name'] == $port_or_alias && preg_match("/port/i", $alias['type'])) {
+ $ports = explode(' ',$alias['address']);
+ foreach($ports as $port) {
+ $portresults = haproxy_portoralias_to_list($port);
+ $portresult = array_merge($portresult, $portresults);
+ }
+ return $portresult;
+ }
+ }
+ }
+ } else if (is_portrange($port_or_alias)) {
+ return (array)$port_or_alias;
+ } else if (is_port($port_or_alias)) {
+ if (getservbyname($port_or_alias, "tcp"))
+ return (array)getservbyname($port_or_alias, "tcp");
+ if (getservbyname($port_or_alias, "udp"))
+ return (array)getservbyname($port_or_alias, "udp");
+ return (array)$port_or_alias;
+ }
+ else
+ return null;
+}
+
function haproxy_custom_php_deinstall_command() {
global $static_output;
$static_output .= "HAProxy, running haproxy_custom_php_deinstall_command()\n";
@@ -196,7 +278,7 @@ function haproxy_custom_php_install_command() {
name="haproxy"
rcvar=`set_rcvar`
-command="/usr/local/bin/haproxy"
+command="/usr/pbi/haproxy-devel-`uname -m`/sbin/haproxy"
haproxy_enable=\${haproxy-"YES"}
start_cmd="haproxy_start"
@@ -636,13 +718,11 @@ function write_backend($fd, $name, $pool, $frontend) {
function haproxy_configure() {
global $g;
// reload haproxy
- haproxy_writeconf("{$g['varetc_path']}/haproxy");
return haproxy_check_run(1);
}
function haproxy_check_and_run(&$messages, $reload) {
global $g;
- $configpath = "{$g['varetc_path']}/haproxy";
$testpath = "{$g['varetc_path']}/haproxy_test";
haproxy_writeconf($testpath);
$retval = exec("haproxy -c -V -f $testpath/haproxy.cfg 2>&1", $output, $err);
@@ -660,7 +740,6 @@ function haproxy_check_and_run(&$messages, $reload) {
$ok = strstr($retval, "Configuration file is valid");
if ($ok && $reload) {
global $haproxy_run_message;
- haproxy_writeconf($configpath);
rmdir_recursive($testpath);
$ok = haproxy_check_run(1) == 0;
$messages = $haproxy_run_message;
@@ -734,7 +813,8 @@ function haproxy_writeconf($configpath) {
fwrite ($fd, "\tbind 127.0.0.1:$localstatsport\n");
fwrite ($fd, "\tmode http\n");
fwrite ($fd, "\tstats enable\n");
- fwrite ($fd, "\tstats refresh 10\n");
+ if (is_numeric($a_global['localstats_refreshtime']))
+ fwrite ($fd, "\tstats refresh {$a_global['localstats_refreshtime']}\n");
fwrite ($fd, "\tstats admin if TRUE\n");
fwrite ($fd, "\tstats uri /haproxy_stats.php?haproxystats=1\n");
fwrite ($fd, "\ttimeout client 5000\n");
@@ -841,9 +921,13 @@ function haproxy_writeconf($configpath) {
// Process and add bind directives for ports
$ip = haproxy_interface_ip($bind['extaddr']);
if ($ip){
- foreach($ports as $port) {
- if($port) {
- $listenip .= "\tbind\t\t\t$ip:{$port} {$ssl_info} {$advanced_bind}\n";
+ foreach($ports as $alias_or_port) {
+ if($alias_or_port) {
+ $portsnumeric = group_ports(haproxy_portoralias_to_list($alias_or_port));
+ foreach($portsnumeric as $portnumeric) {
+ $portnumeric = str_replace(":","-",$portnumeric);
+ $listenip .= "\tbind\t\t\t$ip:{$portnumeric} {$ssl_info} {$advanced_bind}\n";
+ }
}
}
}
@@ -899,10 +983,8 @@ function haproxy_writeconf($configpath) {
$default_backend = "";
$i = 0;
foreach ($bind['config'] as $frontend) {
- $a_acl=&$frontend['ha_acls']['item'];
- if(!is_array($a_acl))
- $a_acl=array();
-
+ $a_acl = get_frontend_acls($frontend);
+
$poolname = $frontend['backend_serverpool'] . "_" . strtolower($frontend['type']);
// Create different pools if the svrport is set
@@ -914,31 +996,6 @@ function haproxy_writeconf($configpath) {
$a_pendingpl[$poolname]['name'] = $poolname;
$a_pendingpl[$poolname]['frontend'] = $frontend;
}
-
- if (strtolower($bind['type']) == "http" && $frontend['ssloffload']) {
- $aclname = "SNI_" . $poolname;
- if ($frontend['ssloffloadacl']){
- $cert = lookup_cert($frontend['ssloffloadcert']);
- $cert_cn = cert_get_cn($cert['crt']);
- $descr = haproxy_escape_acl_name($cert['descr']);
- $a_acl[] = array('name' => "{$aclname}_{$descr}",'expression' => 'host_matches', 'value' => $cert_cn);
- unset($cert);
- }
- if ($frontend['ssloffloadacladditional']){
- $certs = $frontend['ha_certificates']['item'];
- if (is_array($certs)){
- if (count($certs) > 0){
- foreach($certs as $certref){
- $cert = lookup_cert($certref['ssl_certificate']);
- $cert_cn = cert_get_cn($cert['crt']);
- $descr = haproxy_escape_acl_name($cert['descr']);
- $a_acl[] = array('name' => "{$aclname}_{$descr}",'expression' => 'host_matches', 'value' => $cert_cn);
- unset($cert);
- }
- }
- }
- }
- }
// Write this out once, and must be before any backend config text
if (($default_backend == "" || $frontend['secondary'] != 'yes') && count($a_acl) == 0 ) {
@@ -948,8 +1005,8 @@ function haproxy_writeconf($configpath) {
// combine acl's with same name to allow for 'combined checks' to check for example hostname and fileextension together..
$a_acl_combine = array();
foreach ($a_acl as $entry) {
- $name = $entry['name'];
- $a_acl_combine[$name][] = $entry;
+ $name = $entry['ref']['name'];
+ $a_acl_combine[$name][] = $entry['ref'];
}
foreach ($a_acl_combine as $a_usebackend) {
@@ -1132,18 +1189,27 @@ function load_ipfw_rules() {
mwexec("/sbin/ipfw -x $ipfw_zone_haproxy -q {$g['tmp_path']}/ipfw_{$ipfw_zone_haproxy}.haproxy.rules", true);
}
+function haproxy_plugin_carp($pluginparams) {
+ // called by pfSense when a CARP interface changes its state (called multiple times when multiple interfaces change state)
+ // $pluginparams['type'] always 'carp'
+ // $pluginparams['event'] either 'rc.carpmaster' or 'rc.carpbackup'
+ // $pluginparams['interface'] contains the affected interface
+ $type = $pluginparams['type'];
+ $event = $pluginparams['event'];
+ $interface = $pluginparams['interface'];
+ haproxy_check_run(0);
+}
+
function haproxy_check_run($reload) {
global $config, $g, $haproxy_run_message;
+ $haproxylock = lock("haproxy", LOCK_EX);
$a_global = &$config['installedpackages']['haproxy'];
$configpath = "{$g['varetc_path']}/haproxy";
-
- if(use_transparent_clientip_proxying()) {
- filter_configure();
- load_ipfw_rules();
- } else
- mwexec("/usr/local/sbin/ipfw_context -d haproxy", true);
+ if ($reload)
+ haproxy_writeconf($configpath);
+
if(isset($a_global['enable'])) {
if (isset($a_global['carpdev'])) {
$status = get_carp_interface_status($a_global['carpdev']);
@@ -1153,15 +1219,25 @@ function haproxy_check_run($reload) {
//exec("/bin/pkill -F /var/run/haproxy.pid haproxy");//doesnt work for multiple pid's in a pidfile
haproxy_kill();
}
+ unlock($haproxylock);
return (0);
} else if (haproxy_is_running() && $reload == 0) {
+ unlock($haproxylock);
return (0);
}
log_error("Starting haproxy on CARP master.");
/* fallthrough */
- } else if ($reload == 0)
+ } else if ($reload == 0){
+ unlock($haproxylock);
return (0);
+ }
+ if(use_transparent_clientip_proxying()) {
+ filter_configure();
+ load_ipfw_rules();
+ } else
+ mwexec("/usr/local/sbin/ipfw_context -d haproxy", true);
+
if (haproxy_is_running()) {
if (isset($a_global['terminate_on_reload']))
$sf_st = "-st";//terminate old process as soon as the new process is listening
@@ -1173,14 +1249,15 @@ function haproxy_check_run($reload) {
}
foreach($output as $line)
$haproxy_run_message .= "<br/>" . htmlspecialchars($line) . "\n";
- return ($errcode);
} else {
if ($reload && haproxy_is_running()) {
//exec("/bin/pkill -F /var/run/haproxy.pid haproxy");//doesnt work for multiple pid's in a pidfile
haproxy_kill();
}
- return (0);
+ $errcode = 0;
}
+ unlock($haproxylock);
+ return ($errcode);
}
function haproxy_kill($killimmediately = true) {
@@ -1337,6 +1414,43 @@ function get_frontend_acls($frontend) {
$result[] = $acl_item;
}
}
+
+ $mainfrontend = get_primaryfrontend($frontend);
+ if (strtolower($mainfrontend['type']) == "http" && $mainfrontend['ssloffload']) {
+ $a_acl = &$frontend['ha_acls']['item'];
+ if(!is_array($a_acl))
+ $a_acl=array();
+
+ $poolname = $frontend['backend_serverpool'] . "_" . strtolower($frontend['type']);
+ $aclname = "SNI_" . $poolname;
+ if ($frontend['ssloffloadacl']){
+ $cert = lookup_cert($frontend['ssloffloadcert']);
+ $cert_cn = cert_get_cn($cert['crt']);
+ $descr = haproxy_escape_acl_name($cert['descr']);
+ unset($cert);
+ $acl_item = array();
+ $acl_item['descr'] = "Certificate ACL ".$cert_cn;
+ $acl_item['ref'] = array('name' => "{$aclname}_{$descr}",'expression' => 'host_matches', 'value' => $cert_cn);
+ $result[] = $acl_item;
+ }
+ if ($frontend['ssloffloadacladditional']){
+ $certs = $frontend['ha_certificates']['item'];
+ if (is_array($certs)){
+ if (count($certs) > 0){
+ foreach($certs as $certref){
+ $cert = lookup_cert($certref['ssl_certificate']);
+ $cert_cn = cert_get_cn($cert['crt']);
+ $descr = haproxy_escape_acl_name($cert['descr']);
+ unset($cert);
+ $acl_item = array();
+ $acl_item['descr'] = "Additional certificate ACLs: ".$cert_cn;
+ $acl_item['ref'] = array('name' => "{$aclname}_{$descr}",'expression' => 'host_matches', 'value' => $cert_cn);
+ $result[] = $acl_item;
+ }
+ }
+ }
+ }
+ }
return $result;
}