diff options
author | PiBa-NL <pba_2k3@yahoo.com> | 2015-02-02 01:11:17 +0100 |
---|---|---|
committer | PiBa-NL <pba_2k3@yahoo.com> | 2015-02-02 01:11:17 +0100 |
commit | e28f3357fa41438060791f4b339ab079721d64d6 (patch) | |
tree | 395f0249f2bb4922789d133783421174b6fc8f51 /config | |
parent | 90e3a2b3636b8bda325ed66663bba6a6f126762b (diff) | |
download | pfsense-packages-e28f3357fa41438060791f4b339ab079721d64d6.tar.gz pfsense-packages-e28f3357fa41438060791f4b339ab079721d64d6.tar.bz2 pfsense-packages-e28f3357fa41438060791f4b339ab079721d64d6.zip |
haproxy-devel, several improvements / fixes:
-combine certificate acl's with user acl's
-wildcard certificate acl handling
-better handeling of 'transparent' backends when using mixed ipv4 and ipv6, a single defined backend can write 2 backends to the config ipv4 / ipv6
-option to negate a acl
-moved acl definitions above advanced user config in cfg (to allow user config to use already defined acls)
-toggle in frontend overview to easily enable/disable a frontend
Diffstat (limited to 'config')
-rw-r--r-- | config/haproxy-devel/haproxy.inc | 544 | ||||
-rw-r--r-- | config/haproxy-devel/haproxy.xml | 10 | ||||
-rw-r--r-- | config/haproxy-devel/haproxy_listeners.php | 97 | ||||
-rw-r--r-- | config/haproxy-devel/haproxy_listeners_edit.php | 53 | ||||
-rw-r--r-- | config/haproxy-devel/haproxy_pool_edit.php | 2 | ||||
-rw-r--r-- | config/haproxy-devel/haproxy_utils.inc | 26 | ||||
-rw-r--r-- | config/haproxy-devel/pkg/haproxy_upgrade_config.inc | 174 | ||||
-rw-r--r-- | config/haproxy-devel/www/javascript/haproxy_geturl.js | 43 |
8 files changed, 618 insertions, 331 deletions
diff --git a/config/haproxy-devel/haproxy.inc b/config/haproxy-devel/haproxy.inc index 9b758370..e9b0f9e3 100644 --- a/config/haproxy-devel/haproxy.inc +++ b/config/haproxy-devel/haproxy.inc @@ -1,7 +1,7 @@ <?php /* haproxy.inc - Copyright (C) 2013 PiBa-NL + Copyright (C) 2013-2015 PiBa-NL Copyright (C) 2009 Scott Ullrich <sullrich@pfsense.com> Copyright (C) 2008 Remco Hoef All rights reserved. @@ -91,7 +91,7 @@ $a_acltypes["ssl_sni_starts_with"] = array('name' => 'Server Name Indication TLS 'mode' => 'https', 'syntax' => 'req.ssl_sni -m beg -i %1$s', 'advancedoptions' => "tcp-request content accept if { req.ssl_hello_type 1 }"); $a_acltypes["ssl_sni_ends_with"] = array('name' => 'Server Name Indication TLS extension ends with:', 'inspect-delay' => '5', 'mode' => 'https', 'syntax' => 'req.ssl_sni -m end -i %1$s', 'advancedoptions' => "tcp-request content accept if { req.ssl_hello_type 1 }"); -$a_acltypes["ssl_sni_ends_with"] = array('name' => 'Server Name Indication TLS extension regex:', 'inspect-delay' => '5', +$a_acltypes["ssl_sni_regex"] = array('name' => 'Server Name Indication TLS extension regex:', 'inspect-delay' => '5', 'mode' => 'https', 'syntax' => 'req.ssl_sni -m reg -i %1$s', 'advancedoptions' => "tcp-request content accept if { req.ssl_hello_type 1 }"); $a_acltypes["custom"] = array('name' => 'Custom acl:', 'mode' => '', 'syntax' => '%1$s'); @@ -425,140 +425,11 @@ EOD; $static_output .= "HAProxy, update configuration\n"; update_output_window($static_output); - - // make sure the version stays 'comparable' - if (is_arrayset($config,'installedpackages','haproxy') && isset($config['installedpackages']['haproxy']['configversion'])) - $configversion = $config['installedpackages']['haproxy']['configversion']; - else - $configversion = "00.12"; - $static_output .= "HAProxy, from version $configversion\n"; - update_output_window($static_output); - - $writeconfigupdate = false; - if ($configversion < "00.13") { - /* Do XML upgrade from haproxy 0.31 to haproxy-dev */ - if (is_array($config['installedpackages']['haproxy']['ha_servers'])) { - $static_output .= "HAProxy, Do XML upgrade from haproxy 0.31 to haproxy-dev\n"; - update_output_window($static_output); - - /* We have an old config */ - $config['installedpackages']['haproxy']['ha_pools']['item'] = array(); - $a_global = &$config['installedpackages']['haproxy']; - $a_backends = &$config['installedpackages']['haproxy']['ha_backends']['item']; - $a_oldservers = &$config['installedpackages']['haproxy']['ha_servers']['item']; - $a_pools = &$config['installedpackages']['haproxy']['ha_pools']['item']; - - foreach ($a_backends as $id => $be) { - $a_backends[$id]['status'] = 'active'; - } - $id = 0; - foreach ($a_oldservers as $oldserver) { - $pool=$oldserver; - /* make server sub array */ - $server=array(); - $server['name'] = $oldserver['name']; - $server['address'] = $oldserver['address']; - $server['port'] = $oldserver['port']; - $server['weight'] = $oldserver['weight']; - $a_servers=array(); - $a_servers[]=$server; - /* set new pool */ - $pool['name'] = "pool$id"; - $id++; - $pool['ha_servers']['item']=$a_servers; - /* link to frontend */ - foreach ($a_backends as $id => $be) { - if ($a_backends[$id]['name'] == $oldserver['backend']) { - $a_backends[$id]['backend_serverpool'] = $pool['name']; - $pool['monitor_uri'] = $be['monitor_uri']; - unset($a_backends[$id]['monitor_uri']); - break; - } - } - unset($pool['backend']); - unset($pool['address']); - unset($pool['port']); - unset($pool['weight']); - $a_pools[] = $pool; - } - unset($config['installedpackages']['haproxy']['ha_servers']); - $writeconfigupdate = true; - } - - /* XML update to: pkg v1.3 and 'pool' changed to 'backend_serverpool' because 'pool' was added to listtags() in xmlparse.inc */ - if (is_arrayset($config,'installedpackages','haproxy','ha_backends','item',0,'pool')) { - $static_output .= "HAProxy, Do XML upgrade, change to backend_serverpool from pool array\n"; - update_output_window($static_output); - - foreach($config['installedpackages']['haproxy']['ha_backends']['item'] as &$frontend) - { - $backend_serverpool = $frontend['pool'][0]; - $frontend['backend_serverpool'] = $backend_serverpool; - unset($frontend['pool']); - } - $writeconfigupdate = true; - } - //also move setting for existing 2.0 installations as only the new variable is used - if (is_arrayset($config,'installedpackages','haproxy','ha_backends','item',0) && - isset($config['installedpackages']['haproxy']['ha_backends']['item'][0]['pool'])) { - $static_output .= "HAProxy, Do XML upgrade, change to backend_serverpool from pool\n"; - update_output_window($static_output); - foreach($config['installedpackages']['haproxy']['ha_backends']['item'] as &$frontend) - { - $backend_serverpool = $frontend['pool']; - $frontend['backend_serverpool'] = $backend_serverpool; - unset($frontend['pool']); - } - $writeconfigupdate = true; - } - // update config to "haproxy-devel 1.5-dev19 pkg v0.5" - if(is_arrayset($config,'installedpackages','haproxy','ha_backends','item')) { - $static_output .= "HAProxy, Do XML upgrade, update frontend options\n"; - update_output_window($static_output); - foreach ($config['installedpackages']['haproxy']['ha_backends']['item'] as &$bind) { - if($bind['httpclose'] && $bind['httpclose'] == "yes" ) { - $bind['httpclose'] = "httpclose"; - $writeconfigupdate = true; - } - if (!$bind['extaddr']){ - $bind['extaddr'] = "wan_ipv4"; - $writeconfigupdate = true; - } - if ($bind['extaddr'] == "localhost"){ - $bind['extaddr'] = "localhost_ipv4"; - $writeconfigupdate = true; - } - if ($bind['extaddr'] == "any"){ - $bind['extaddr'] = "any_ipv4"; - $writeconfigupdate = true; - } - } - } - } - if ($configversion == "00.12") { - // update config to "haproxy-devel 1.5-dev19 pkg v0.13" - foreach ($config['installedpackages']['haproxy']['ha_backends']['item'] as &$bind) { - if (isset($bind['extaddr'])) { - $new['extaddr'] = $bind['extaddr']; - $new['extaddr_port'] = $bind['port']; - $new['extaddr_ssl'] = $bind['ssloffload']; - $bind['a_extaddr']['item'][] = $new; - } - unset($bind['extaddr']); - unset($bind['port']); - //unset($bind['ssloffload']); - } - $configversion = "00.13"; - } - - $writeconfigupdate = $config['installedpackages']['haproxy']['configversion'] <> $configversion; - if ($writeconfigupdate) { - $config['installedpackages']['haproxy']['configversion'] = $configversion; - $static_output .= "HAProxy, write updated config to version: $configversion\n"; - update_output_window($static_output); - write_config("HAProxy, update xml config version"); - } + // call from external file, so it is surely from the newly downloaded version + // this avoids a problem with php cache that loaded haproxy.inc during uninstalling the old version + require_once('haproxy_upgrade_config.inc'); + haproxy_upgrade_config(); $static_output .= "HAProxy, conf_mount_ro\n"; update_output_window($static_output); @@ -617,6 +488,17 @@ function haproxy_install_cron($should_install) { } } +function haproxy_find_backend($backendname) { + global $config; + $a_backends = &$config['installedpackages']['haproxy']['ha_pools']['item']; + foreach ($a_backends as &$backend) { + if ($backend['name'] == $backendname) { + return $backend; + } + } + return null; +} + function haproxy_find_acl($name) { global $a_acltypes; if($a_acltypes) { @@ -627,7 +509,10 @@ function haproxy_find_acl($name) { } } -function write_backend($configpath, $fd, $name, $pool, $frontend) { +function write_backend($configpath, $fd, $name, $pool, $backendsettings) { + $frontend = $backendsettings['frontend']; + $ipversion = $backendsettings['ipversion']; + if(!is_array($pool['ha_servers']['item']) && !$pool['stats_enabled']=='yes') return; global $a_checktypes, $a_cookiemode, $a_files_cache, $a_error; @@ -784,19 +669,18 @@ function write_backend($configpath, $fd, $name, $pool, $frontend) { $pool['retries'] = 3; fwrite ($fd, "\tretries\t\t\t" . $pool['retries'] . "\n"); - $uses_ipv6 = false; - $ips = get_frontend_ipport($frontend); - foreach($ips as $ip){ - $uses_ipv6 = is_ipaddrv6($ip['addr']); - if ($uses_ipv6) - break; - } - - if ($pool['transparent_clientip']) { - if ($uses_ipv6) - fwrite ($fd, "\tsource ipv6@ usesrc clientip\n"); - else - fwrite ($fd, "\tsource 0.0.0.0 usesrc clientip\n"); + $addrprefix = ""; + $dnsquerytype = "A,AAAA"; + if ($pool['transparent_clientip'] == 'yes') { + if ($ipversion == "ipv6") { + $addrprefix = "ipv6@"; + $dnsquerytype = "AAAA"; + } + if ($ipversion == "ipv4") { + $addrprefix = "ipv4@"; + $dnsquerytype = "A"; + } + fwrite ($fd, "\tsource $addrprefix usesrc clientip\n"); } $uri = $pool['monitor_uri']; @@ -824,8 +708,7 @@ function write_backend($configpath, $fd, $name, $pool, $frontend) { $advanced_txt = ""; } - if ($check_type != 'none') - { + if ($check_type != 'none') { if($pool['checkinter']) $checkinter = " check inter {$pool['checkinter']}"; else @@ -836,8 +719,7 @@ function write_backend($configpath, $fd, $name, $pool, $frontend) { if ($pool['agent_check']) $agentcheck = " agent-check agent-inter {$pool['agent_inter']} agent-port {$pool['agent_port']}"; - if (is_array($a_servers)) - { + if (is_array($a_servers)) { foreach($a_servers as $be) { if ($be['status'] == "inactive") continue; @@ -898,13 +780,37 @@ function write_backend($configpath, $fd, $name, $pool, $frontend) { $maxconn = " maxconn " . $be['maxconn']; } + $servers = array(); if ($be['forwardto'] && $be['forwardto'] != "") { - $server = "/{$be['forwardto']}.socket send-proxy-v2-ssl-cn"; - } else - $server = $be['address'].":" . $be['port']; - - - fwrite ($fd, "\tserver\t\t\t" . $be['name'] . " " . $server . "$ssl$cookie$checkinter$checkport$agentcheck $isbackup$weight$maxconn$cafile$crlfile$verifynone$verifyhost$crtfile{$advanced_txt} {$be['advanced']}\n"); + $servers[] = "/{$be['forwardto']}.socket send-proxy-v2-ssl-cn"; + } else { + if (is_ipaddr($be['address'])) { + $servers[] = $be['address']; + } else if (is_hostname($be['address'])) { + $dnsresult_servers = haproxy_utils::query_dns($be['address'], $dnsquerytype); + foreach($dnsresult_servers as $dnsresult_server){ + $servers[] = $dnsresult_server['data']; + } + } + } + $counter = 0; + foreach($servers as $server) { + if (is_ipaddr($server)) { + // skip ipv4 servers when using transparent client ip with ipv6 backend servers, and vice versa + if ($ipversion == "ipv4" && !is_ipaddrv4($server)) + continue; + if ($ipversion == "ipv6" && !is_ipaddrv6($server)) + continue; + if (isset($be['port'])) + $server = $server . ":" . $be['port']; + } + $servername = $be['name']; + if (count($servers) > 1) { + $servername .= "_" . $counter; + } + fwrite ($fd, "\tserver\t\t\t" . $servername . " " . $server . "$ssl$cookie$checkinter$checkport$agentcheck $isbackup$weight$maxconn$cafile$crlfile$verifynone$verifyhost$crtfile{$advanced_txt} {$be['advanced']}\n"); + $counter++; + } } } fwrite ($fd, "\n"); @@ -1045,7 +951,7 @@ function haproxy_writeconf($configpath) { $localstatsport = $a_global['localstatsport']; if ($localstatsport){ fwrite ($fd, "listen HAProxyLocalStats\n"); - fwrite ($fd, "\tbind 127.0.0.1:$localstatsport\n"); + fwrite ($fd, "\tbind 127.0.0.1:$localstatsport name localstats\n"); fwrite ($fd, "\tmode http\n"); fwrite ($fd, "\tstats enable\n"); if (is_numeric($a_global['localstats_refreshtime'])) @@ -1128,33 +1034,35 @@ function haproxy_writeconf($configpath) { else $frontendinfo = "frontend {$bind['name']}\n"; - $advancedextra = array(); + fwrite ($fd, "{$frontendinfo}"); + $allow_none = false; + $advancedextra = array(); $ca_file = ""; $first = true; if (is_array($bind['clientcert_ca']['item'])){ + $filename = "$configpath/clientca_{$bind['name']}.pem"; foreach($bind['clientcert_ca']['item'] as $ca){ - $filename = "$configpath/clientca_{$bind['name']}.pem"; - haproxy_write_certificate_crt($filename, $ca['cert_ca'], false, !$first); - $first = false; + if (!empty($ca['cert_ca'])){ + haproxy_write_certificate_crt($filename, $ca['cert_ca'], false, !$first); + $first = false; + } else + $allow_none = true; } - $ca_file = " ca-file $filename verify optional"; + $verify = $allow_none ? "verify optional" : "verify required"; + $ca_file = " ca-file $filename $verify"; } $crl_file = ""; $first = true; if (is_array($bind['clientcert_crl']['item'])){ + $filename = "$configpath/clientcrl_{$bind['name']}.pem"; foreach($bind['clientcert_crl']['item'] as $ca){ - $filename = "$configpath/clientcrl_{$bind['name']}.pem"; haproxy_write_certificate_crl($filename, $ca['cert_crl'], !$first); $first = false; } $crl_file = " crl-file $filename"; } - // Prepare ports for processing by splitting - //$portss = "{$bind['port']},"; - //$ports = split(",", $portss); - if($bind['type'] == "http") { // ssl offloading is only possible in http mode. $ssl_info = $bind['ssl_info'].$ca_file.$crl_file; @@ -1164,42 +1072,21 @@ function haproxy_writeconf($configpath) { $advanced_bind = ""; } - fwrite ($fd, "{$frontendinfo}"); - - // Initialize variable - $listenip = ""; - + $useipv4 = false; + $useipv6 = false; // Process and add bind directives for ports - if (isset($bind['a_extaddr'])) { - foreach($bind['a_extaddr']['item'] as $extaddr) { - $a_ip = array(); - if (isset($extaddr['extaddr']) && $extaddr['extaddr'] != "custom") { - $a_ip[] = haproxy_interface_ip($extaddr['extaddr']); - } else { - $iporalias = $extaddr['extaddr_custom']; - $a_ip = haproxy_addressoralias_to_list($iporalias); - } - - if ($extaddr['extaddr_ssl'] == 'yes') - $ssl = $ssl_info; - else - $ssl = ""; - - foreach($a_ip as $ip) { - $portsnumeric = group_ports(haproxy_portoralias_to_list($extaddr['extaddr_port'])); - if (is_array($portsnumeric)) { - foreach($portsnumeric as $portnumeric) { - $portnumeric = str_replace(":","-",$portnumeric); - $listenip .= "\tbind\t\t\t$ip:{$portnumeric} {$ssl} {$advanced_bind} {$extaddr['extaddr_advanced']}\n"; - } - } - } - } + $bindips = get_frontend_bindips($bind); + $listenip = ""; + foreach($bindips as $bindip) { + $ssl = $bindip['extaddr_ssl'] == 'yes' ? $ssl_info : ""; + $listenip .= "\tbind\t\t\t{$bindip['addr']}:{$bindip['port']} name {$bindip['addr']}:{$bindip['port']} {$ssl} {$advanced_bind} {$bindip['extaddr_advanced']}\n"; + $useipv4 |= is_ipaddrv4($bindip['addr']); + $useipv6 |= is_ipaddrv6($bindip['addr']); } fwrite ($fd, "{$listenip}"); if (use_frontend_as_unixsocket($bind['name'])){ - fwrite ($fd, "\tbind /tmp/haproxy_chroot/{$bind['name']}.socket accept-proxy {$ssl_info} {$advanced_bind}\n"); + fwrite ($fd, "\tbind /tmp/haproxy_chroot/{$bind['name']}.socket name unixsocket accept-proxy {$ssl_info} {$advanced_bind}\n"); } // Advanced pass thru @@ -1222,12 +1109,14 @@ function haproxy_writeconf($configpath) { fwrite ($fd, "\tmode\t\t\t" . $backend_type . "\n"); fwrite ($fd, "\tlog\t\t\tglobal\n"); + if ($bind['socket-stats'] == 'yes') + fwrite ($fd, "\toption\t\t\tsocket-stats\n"); if ($bind['dontlognull'] == 'yes') - fwrite ($fd, "\toption\t\t\tdontlognull\n"); + fwrite ($fd, "\toption\t\t\tdontlognull\n"); if ($bind['dontlog-normal'] == 'yes') fwrite ($fd, "\toption\t\t\tdontlog-normal\n"); if ($bind['log-separate-errors'] == 'yes') - fwrite ($fd, "\toption\t\t\tlog-separate-errors\n"); + fwrite ($fd, "\toption\t\t\tlog-separate-errors\n"); if ($bind['log-detailed'] == 'yes'){ if ($backend_type == 'http') fwrite ($fd, "\toption\t\t\thttplog\n"); @@ -1235,8 +1124,7 @@ function haproxy_writeconf($configpath) { fwrite ($fd, "\toption\t\t\ttcplog\n"); } - if ($backend_type == 'http') - { + if ($backend_type == 'http') { if($bind['httpclose'] && $bind['httpclose'] != "none" ) fwrite ($fd, "\toption\t\t\t{$bind['httpclose']}\n"); @@ -1259,25 +1147,41 @@ function haproxy_writeconf($configpath) { // Combine the rest of the frontend configs $default_backend = ""; - $config_usebackend = ""; + $config_acls = ""; + $config_usebackends = ""; + + $transparent_clientip = false; + foreach ($bind['config'] as $frontend) { + $backend = haproxy_find_backend($frontend['backend_serverpool']); + if ($backend["transparent_clientip"] == 'yes') { + $transparent_clientip = true; + break; + } + } + if ($transparent_clientip && $useipv4 && $useipv6) { + // set the src_is_ipv4 acl if needed. + $config_acls .= "\tacl\t\t\tsrc_is_ipv4\tsrc 0.0.0.0/0\n"; + } + $inspectdelay = 0; $i = 0; foreach ($bind['config'] as $frontend) { $a_acl = get_frontend_acls($frontend); - $poolname = $frontend['backend_serverpool'] . "_" . strtolower($bind['type']); - - if (!isset($a_pendingpl[$poolname])) { - $a_pendingpl[$poolname] = array(); - $a_pendingpl[$poolname]['name'] = $poolname; - $a_pendingpl[$poolname]['backend'] = $frontend['backend_serverpool']; - $a_pendingpl[$poolname]['frontend'] = $bind; - } + $backend = haproxy_find_backend($frontend['backend_serverpool']); + $transparent_clientip = $backend["transparent_clientip"] == 'yes'; - // Write this out once, and must be before any backend config text - if (($default_backend == "" || $frontend['secondary'] != 'yes') && count($a_acl) == 0 ) { - $default_backend = $poolname; - } + $ipv = array(); + if ($transparent_clientip) { + if ($useipv4 && $useipv6) { + $ipv["ipv4"]['acl'] = " src_is_ipv4 "; + $ipv["ipv6"]['acl'] = " !src_is_ipv4 "; + } else if ($useipv6) + $ipv["ipv6"]['acl'] = " "; + else + $ipv["ipv4"]['acl'] = " "; + } else + $ipv["ipvANY"]['acl'] = " "; // combine acl's with same name to allow for 'combined checks' to check for example hostname and fileextension together.. $a_acl_combine = array(); @@ -1286,48 +1190,88 @@ function haproxy_writeconf($configpath) { $a_acl_combine[$name][] = $entry['ref']; } - foreach ($a_acl_combine as $a_usebackend) { - $aclnames = ""; - foreach ($a_usebackend as $entry) { - $acl = haproxy_find_acl($entry['expression']); - if (!$acl) - continue; - - // Filter out acls for different modes - if ($acl['mode'] != '' && $acl['mode'] != strtolower($bind['type'])) - continue; - if (($entry['expression'] == "source_ip") && is_alias($entry['value'])) { - $filename = "$configpath/ipalias_{$entry['value']}.lst"; - $listitems = haproxy_hostoralias_to_list($entry['value']); - $fd_alias = fopen("$filename", "w"); - foreach($listitems as $item) - fwrite($fd_alias, $item."\r\n"); - fclose($fd_alias); - $expr = "src -f $filename"; - } else - $expr = sprintf($acl['syntax'],$entry['value'],$poolname); - - $aclname = $i . "_" . $entry['name']; - $aclnames .= $aclname." "; - $config_usebackend .= "\tacl\t\t\t" . $aclname . "\t" . $expr . "\n"; - - if ($acl['inspect-delay'] != '') - $inspectdelay = $acl['inspect-delay']; - - if ($acl['advancedoptions'] != '') - $advancedextra[$acl['syntax']] = $acl['advancedoptions']."\n"; - $i++; + $y = 0; + foreach($ipv as $ipversion => $ipversionoptions) { + $certacls = array(); + $useracls = array(); + $poolname = $frontend['backend_serverpool'] . "_" . strtolower($bind['type'])."_".$ipversion; + if (!isset($a_pendingpl[$poolname])) { + $a_pendingpl[$poolname] = array(); + $a_pendingpl[$poolname]['name'] = $poolname; + $a_pendingpl[$poolname]['backend'] = $frontend['backend_serverpool']; + $a_pendingpl[$poolname]['frontend'] = $bind; + $a_pendingpl[$poolname]['ipversion'] = $ipversion; + } + + // Write this out once, and must be before any backend config text + if (($default_backend == "" || $frontend['secondary'] != 'yes') && count($a_acl) == 0 ) { + $default_backend = $poolname; } - $config_usebackend .= "\tuse_backend\t\t" . $poolname . " if " . $aclnames . "\n"; + + foreach ($a_acl_combine as $a_usebackend) { + $aclnames = ""; + foreach ($a_usebackend as $entry) { + $acl = haproxy_find_acl($entry['expression']); + if (!$acl) + continue; + + // Filter out acls for different modes + if ($acl['mode'] != '' && $acl['mode'] != strtolower($bind['type'])) + continue; + if (($entry['expression'] == "source_ip") && is_alias($entry['value'])) { + $filename = "$configpath/ipalias_{$entry['value']}.lst"; + $listitems = haproxy_hostoralias_to_list($entry['value']); + $fd_alias = fopen("$filename", "w"); + foreach($listitems as $item) + fwrite($fd_alias, $item."\r\n"); + fclose($fd_alias); + $expr = "src -f $filename"; + } else + $expr = sprintf($acl['syntax'],$entry['value'],$poolname); + + $not = $entry['not'] == "yes" ? "!" : ""; + + $aclname = $i . "_" . $entry['name']; + if ($entry['certacl']) + $certacls[] = $aclname . " "; + else + $useracls[$y] .= $not . $aclname . " "; + + $config_acls .= "\tacl\t\t\t" . $aclname . "\t" . $expr . "\n"; + + if ($acl['inspect-delay'] != '') + $inspectdelay = $acl['inspect-delay']; + + if ($acl['advancedoptions'] != '') + $advancedextra[$acl['syntax']] = $acl['advancedoptions']."\n"; + $i++; + } + $y++; + } + + if (count($certacls) == 0) $certacls[] = ""; // add empty item to enter foreach loop at least once. + if (count($useracls) == 0) $useracls[] = ""; // add empty item to enter foreach loop at least once. + $backendacl = ""; + foreach($useracls as $useracl) + foreach($certacls as $certacl) + $backendacl .= "|| {$useracl}{$certacl}{$ipversionoptions['acl']}"; + $backendacl = substr($backendacl, 3); + $config_usebackends .= "\tuse_backend\t\t" . $poolname . " if " . $backendacl . "\n"; + //$config_usebackends .= "\tuse_backend\t\t" . $poolname . " if " . $backendacl . "\n"; } } + if ($inspectdelay > 0) fwrite ($fd, "\ttcp-request inspect-delay\t" . $inspectdelay . "\n"); + + // Write acl's first, so they may be used by advanced text options written by user. + fwrite ($fd, $config_acls); + foreach($advancedextra as $extra) fwrite ($fd, "\t".$extra."\n"); - fwrite ($fd, $config_usebackend); - + // Write backends after advanced options so custom use_backend rules can be applied first. + fwrite ($fd, $config_usebackends); if ($default_backend) fwrite ($fd, "\tdefault_backend\t\t" . $default_backend . "\n"); @@ -1339,7 +1283,7 @@ function haproxy_writeconf($configpath) { foreach ($a_pendingpl as $pending) { foreach ($a_backends as $pool) { if ($pending['backend'] == $pool['name']) { - write_backend($configpath, $fd, $pending['name'], $pool, $pending['frontend']); + write_backend($configpath, $fd, $pending['name'], $pool, $pending); } } } @@ -1721,7 +1665,6 @@ function get_primaryfrontend($frontend) { function get_frontend_ipport($frontend, $userfriendly=false) { $mainfrontend = get_primaryfrontend($frontend); - $newline = ""; $result = array(); if (!is_arrayset($mainfrontend,"a_extaddr","item")) return $result; @@ -1745,6 +1688,42 @@ function get_frontend_ipport($frontend, $userfriendly=false) { return $result; } +function get_frontend_bindips($frontend) { + $mainfrontend = get_primaryfrontend($frontend); + $result = array(); + if (!is_arrayset($mainfrontend,"a_extaddr","item")) + return $result; + foreach($mainfrontend['a_extaddr']['item'] as $extaddr) { + $a_ip = array(); + if (isset($extaddr['extaddr']) && $extaddr['extaddr'] != "custom") { + $a_ip[] = haproxy_interface_ip($extaddr['extaddr']); + } else { + $iporalias = $extaddr['extaddr_custom']; + $a_ip = haproxy_addressoralias_to_list($iporalias); + } + if ($extaddr['extaddr_ssl'] == 'yes') + $ssl = $ssl_info; + else + $ssl = ""; + + foreach($a_ip as $ip) { + $portsnumeric = group_ports(haproxy_portoralias_to_list($extaddr['extaddr_port'])); + if (is_array($portsnumeric)) { + foreach($portsnumeric as $portnumeric) { + $portnumeric = str_replace(":","-",$portnumeric); + $newitem = array(); + $newitem['addr'] = $ip; + $newitem['port'] = $portnumeric; + $newitem['extaddr_ssl'] = $extaddr['extaddr_ssl']; + $newitem['extaddr_advanced'] = $extaddr['extaddr_advanced']; + $result[] = $newitem; + } + } + } + } + return $result; +} + function haproxy_check_config() { global $config; $a_backends = &$config['installedpackages']['haproxy']['ha_backends']['item']; @@ -1828,6 +1807,25 @@ function get_frontend_uses_ssl_only($frontend) { return true; } +function haproxy_get_cert_acl($cert) { + $acl_item = array(); + + $cert_cn = cert_get_cn($cert['crt']); + $descr = haproxy_escape_acl_name($cert['descr']); + unset($cert); + $is_wildcard = substr($cert_cn, 0, 2) == "*."; + $cert_cn_regex = str_replace(".", "\.", $cert_cn); // escape '.' in regex. + $wild_regex = ""; + if ($is_wildcard) { + $cert_cn_regex = "([^\.]*)" . substr($cert_cn_regex, 1);// match only subdomains directly under the wildcard + } + $cert_cn_regex = "^{$cert_cn_regex}(:([0-9]){1,5})?$";// match both with and without port. + + $acl_item['descr'] = "Certificate ACL matches: {$cert_cn}"; + $acl_item['ref'] = array('name' => "{$aclname}_{$descr}",'expression' => 'host_regex', 'value' => $cert_cn_regex, 'certacl' => true); + return $acl_item; +} + function get_frontend_acls($frontend) { $mainfrontend = get_primaryfrontend($frontend); $result = array(); @@ -1842,7 +1840,7 @@ function get_frontend_acls($frontend) { // Filter out acls for different modes if ($acl['mode'] != '' && $acl['mode'] != strtolower($mainfrontend['type'])) continue; - + $not = $entry['not'] == "yes" ? "not " : ""; $acl_item = array(); $acl_item['descr'] = $acl['name'] . ": " . $entry['value']; $acl_item['ref'] = $entry; @@ -1861,44 +1859,14 @@ function get_frontend_acls($frontend) { if (ifset($frontend['ssloffloadacl']) == 'yes' || ifset($frontend['ssloffloadaclnondefault']) == 'yes') { $cert = lookup_cert($frontend['ssloffloadcert']); - $cert_cn = cert_get_cn($cert['crt']); - $descr = haproxy_escape_acl_name($cert['descr']); - unset($cert); - - $acl_item = array(); - if (ifset($frontend['ssloffloadacl']) == 'yes' && ifset($frontend['ssloffloadaclnondefault']) == 'yes') { - $acl_item['descr'] = "Certificate ACL match regex: ^{$cert_cn}(:([0-9]){1,5})?$"; - $acl_item['ref'] = array('name' => "{$aclname}_{$descr}",'expression' => 'host_regex', 'value' => "^{$cert_cn}(:([0-9]){1,5})?$"); - } elseif (ifset($frontend['ssloffloadaclnondefault']) == 'yes') { - $acl_item['descr'] = "Certificate ACL starts with: {$cert_cn}:"; - $acl_item['ref'] = array('name' => "{$aclname}_{$descr}",'expression' => 'host_starts_with', 'value' => $cert_cn.":"); - } else { - $acl_item['descr'] = "Certificate ACL match: {$cert_cn}"; - $acl_item['ref'] = array('name' => "{$aclname}_{$descr}",'expression' => 'host_matches', 'value' => $cert_cn); - } - $result[] = $acl_item; + $result[] = haproxy_get_cert_acl($cert); } - if (ifset($frontend['ssloffloadacladditional']) == 'yes' || ifset($frontend['ssloffloadacladditionalnondefault']) == 'yes') { + if (ifset($frontend['ssloffloadacladditional']) == 'yes') { $certs = $frontend['ha_certificates']['item']; if (is_array($certs)){ 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(); - if (ifset($frontend['ssloffloadacladditional']) == 'yes' && ifset($frontend['ssloffloadacladditionalnondefault']) == 'yes') { - $acl_item['descr'] = "Certificate ACL match regex: ^{$cert_cn}(:([0-9]){1,5})?$"; - $acl_item['ref'] = array('name' => "{$aclname}_{$descr}",'expression' => 'host_regex', 'value' => "^({$cert_cn}(($)|(:.*)))"); - } elseif (ifset($frontend['ssloffloadacladditionalnondefault']) == 'yes') { - $acl_item['descr'] = "Certificate ACL starts with: {$cert_cn}:"; - $acl_item['ref'] = array('name' => "{$aclname}_{$descr}",'expression' => 'host_starts_with', 'value' => $cert_cn.":"); - } else { - $acl_item['descr'] = "Certificate ACL match: {$cert_cn}"; - $acl_item['ref'] = array('name' => "{$aclname}_{$descr}",'expression' => 'host_matches', 'value' => $cert_cn); - } - $result[] = $acl_item; + $result[] = haproxy_get_cert_acl($cert); } } } diff --git a/config/haproxy-devel/haproxy.xml b/config/haproxy-devel/haproxy.xml index da2b4648..27199ee4 100644 --- a/config/haproxy-devel/haproxy.xml +++ b/config/haproxy-devel/haproxy.xml @@ -147,6 +147,16 @@ <chmod>077</chmod> <item>https://packages.pfsense.org/packages/config/haproxy-devel/pkg_haproxy_tabs.inc</item> </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/pkg/</prefix> + <chmod>077</chmod> + <item>https://packages.pfsense.org/packages/config/haproxy-devel/pkg/haproxy_upgrade_config.inc</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/javascript/</prefix> + <chmod>077</chmod> + <item>https://packages.pfsense.org/packages/config/haproxy-devel/www/javascript/haproxy_geturl.js</item> + </additional_files_needed> <custom_delete_php_command> </custom_delete_php_command> <custom_add_php_command> diff --git a/config/haproxy-devel/haproxy_listeners.php b/config/haproxy-devel/haproxy_listeners.php index 301dd253..ef7e01c4 100644 --- a/config/haproxy-devel/haproxy_listeners.php +++ b/config/haproxy-devel/haproxy_listeners.php @@ -3,7 +3,7 @@ /* haproxy_listeners.php part of pfSense (https://www.pfsense.org/) - Copyright (C) 2013 PiBa-NL + Copyright (C) 2013-2015 PiBa-NL Copyright (C) 2009 Scott Ullrich <sullrich@pfsense.com> Copyright (C) 2008 Remco Hoef <remcoverhoef@pfsense.com> All rights reserved. @@ -36,11 +36,34 @@ require_once("certs.inc"); require_once("haproxy_utils.inc"); require_once("pkg_haproxy_tabs.inc"); +$changedesc = "Services: HAProxy: Frontends"; + if (!is_array($config['installedpackages']['haproxy']['ha_backends']['item'])) { $config['installedpackages']['haproxy']['ha_backends']['item'] = array(); } $a_frontend = &$config['installedpackages']['haproxy']['ha_backends']['item']; +if($_GET['action'] == "toggle") { + $id = $_GET['id']; + echo "$id|"; + if (isset($a_frontend[get_frontend_id($id)])) { + $frontent = &$a_frontend[get_frontend_id($id)]; + if ($frontent['status'] != "disabled"){ + $frontent['status'] = 'disabled'; + echo "0|"; + }else{ + $frontent['status'] = 'active'; + echo "1|"; + } + $changedesc .= " set frontend '$id' status to: {$frontent['status']}"; + + touch($d_haproxyconfdirty_path); + write_config($changedesc); + } + echo "ok|"; + exit; +} + if ($_POST) { $pconfig = $_POST; @@ -70,10 +93,6 @@ if ($_GET['act'] == "del") { } } -$pf_version=substr(trim(file_get_contents("/etc/version")),0,3); -if ($pf_version < 2.0) - $one_two = true; - $pgtitle = "Services: HAProxy: Frontends"; include("head.inc"); @@ -81,14 +100,37 @@ include("head.inc"); <body link="#0000CC" vlink="#0000CC" alink="#0000CC"> <?php include("fbegin.inc"); ?> <form action="haproxy_listeners.php" method="post"> -<?php if($one_two): ?> -<p class="pgtitle"><?=$pgtitle?></p> -<?php endif; ?> <?php if ($input_errors) print_input_errors($input_errors); ?> <?php if ($savemsg) print_info_box($savemsg); ?> -<?php if (file_exists($d_haproxyconfdirty_path)): ?> -<?php print_info_box_np("The haproxy configuration has been changed.<br/>You must apply the changes in order for them to take effect.");?><br/> -<?php endif; ?> +<?php +$display_apply = file_exists($d_haproxyconfdirty_path) ? "" : "none"; +echo "<div id='showapplysettings' style='display: {$display_apply};'>"; +print_info_box_np("The haproxy configuration has been changed.<br/>You must apply the changes in order for them to take effect."); +echo "<br/></div>"; +?> +<script type="text/javascript" language="javascript" src="/javascript/haproxy_geturl.js"></script> +<script language="javascript"> +function toggle_on(button, image) { + var item = document.getElementById(button); + item.src = image; +} + +function js_callback(req) { + showapplysettings.style.display = 'block'; + if(req.content != '') { + var itemsplit = req.content.split("|"); + buttonid = itemsplit[0]; + enabled = itemsplit[1]; + if (enabled == 1){ + img = 'pass'; + } else { + img = 'reject'; + } + toggle_on('btn_'+buttonid, './themes/<?=$g['theme'];?>/images/icons/icon_'+img+'.gif'); + } +} +</script> + <table width="100%" border="0" cellpadding="0" cellspacing="0"> <tr><td class="tabnavtbl"> <?php @@ -100,6 +142,7 @@ include("head.inc"); <div id="mainarea"> <table class="tabcont sortable" width="100%" border="0" cellpadding="0" cellspacing="0"> <tr> + <td width="5%" class="listhdrr">On</td> <td width="5%" class="listhdrr">Primary</td> <td width="20%" class="listhdrr">Advanced</td> <td width="20%" class="listhdrr">Name</td> @@ -107,7 +150,7 @@ include("head.inc"); <td width="20%" class="listhdrr">Address</td> <td width="5%" class="listhdrr">Type</td> <td width="10%" class="listhdrr">Backend</td> - <td width="20%" class="listhdrr">Parent</td> + <!--td width="20%" class="listhdrr">Parent</td--> <td width="5%" class="list"></td> </tr> <?php @@ -150,10 +193,22 @@ include("head.inc"); $textgray = $frontend['status'] != 'active' ? " gray" : ""; ?> <tr class="<?=$textgray?>"> - <td class="listlr" style="<?=$frontend['secondary']=='yes'?"visibility:hidden;":""?>" ondblclick="document.location='haproxy_listeners_edit.php?id=<?=$frontendname;?>';"> + <td class="listlr" ondblclick="document.location='haproxy_listeners_edit.php?id=<?=$frontendname;?>';"> + <? + if ($frontend['status']=='disabled'){ + $iconfn = "reject"; + } else { + $iconfn = "pass"; + }?> + <a href='javascript:getURL("?id=<?=$frontendname;?>&action=toggle&", js_callback);'> + <img id="btn_<?=$frontendname;?>" src="./themes/<?= $g['theme']; ?>/images/icons/icon_<?=$iconfn;?>.gif" width="11" height="11" border="0" + title="<?=gettext("click to toggle enable/disable this frontend");?>" alt="icon" /> + </a> + </td> + <td class="listr" style="<?=$frontend['secondary']=='yes'?"visibility:hidden;":""?>" ondblclick="document.location='haproxy_listeners_edit.php?id=<?=$frontendname;?>';"> <?=$frontend['secondary']!='yes'?"yes":"no";?> </td> - <td class="listlr" ondblclick="document.location='haproxy_listeners_edit.php?id=<?=$frontendname;?>';"> + <td class="listr" ondblclick="document.location='haproxy_listeners_edit.php?id=<?=$frontendname;?>';"> <? $acls = get_frontend_acls($frontend); $isaclset = ""; @@ -201,13 +256,13 @@ include("head.inc"); } ?> </td> - <td class="listlr" ondblclick="document.location='haproxy_listeners_edit.php?id=<?=$frontendname;?>';"> + <td class="listr" ondblclick="document.location='haproxy_listeners_edit.php?id=<?=$frontendname;?>';"> <?=$frontend['name'];?> </td> - <td class="listlr" ondblclick="document.location='haproxy_listeners_edit.php?id=<?=$frontendname;?>';"> + <td class="listr" ondblclick="document.location='haproxy_listeners_edit.php?id=<?=$frontendname;?>';"> <?=$frontend['desc'];?> </td> - <td class="listlr" ondblclick="document.location='haproxy_listeners_edit.php?id=<?=$frontendname;?>';"> + <td class="listr" ondblclick="document.location='haproxy_listeners_edit.php?id=<?=$frontendname;?>';"> <? $first = true; foreach($frontend['ipport'] as $addr) { @@ -223,7 +278,7 @@ include("head.inc"); } ?> </td> - <td class="listlr" ondblclick="document.location='haproxy_listeners_edit.php?id=<?=$frontendname;?>';"> + <td class="listr" ondblclick="document.location='haproxy_listeners_edit.php?id=<?=$frontendname;?>';"> <? if ($frontend['type'] == 'http') { $mainfrontend = get_primaryfrontend($frontend); @@ -238,16 +293,16 @@ include("head.inc"); echo $a_frontendmode[$frontend['type']]['shortname']; ?> </td> - <td class="listlr" ondblclick="document.location='haproxy_listeners_edit.php?id=<?=$frontendname;?>';"> + <td class="listr" ondblclick="document.location='haproxy_listeners_edit.php?id=<?=$frontendname;?>';"> <div title='<?=$backend_serverpool_hint;?>'> <a href="haproxy_pool_edit.php?id=<?=$frontend['backend_serverpool']?>"> <?=$frontend['backend_serverpool']?> </a> </div> </td> - <td class="listlr" ondblclick="document.location='haproxy_listeners_edit.php?id=<?=$frontendname;?>';"> + <!--td class="listlr" ondblclick="document.location='haproxy_listeners_edit.php?id=<?=$frontendname;?>';"> <?=$frontend['secondary'] == 'yes' ? $frontend['primary_frontend'] : "";?> - </td> + </td--> <td class="list" nowrap> <table border="0" cellspacing="0" cellpadding="1"> <tr> diff --git a/config/haproxy-devel/haproxy_listeners_edit.php b/config/haproxy-devel/haproxy_listeners_edit.php index a818fcfb..a13eca80 100644 --- a/config/haproxy-devel/haproxy_listeners_edit.php +++ b/config/haproxy-devel/haproxy_listeners_edit.php @@ -6,6 +6,7 @@ Copyright (C) 2009 Scott Ullrich <sullrich@pfsense.com> Copyright (C) 2008 Remco Hoef <remcoverhoef@pfsense.com> Copyright (C) 2013 PiBa-NL merging (some of the) "haproxy-devel" changes from: Marcello Coutinho <marcellocoutinho@gmail.com> + Copyright (C) 2013-2015 PiBa-NL All rights reserved. Redistribution and use in source and binary forms, with or without @@ -71,6 +72,7 @@ global $simplefields; $simplefields = array('name','desc','status','secondary','primary_frontend','type','forwardfor','httpclose','extaddr','backend_serverpool', 'max_connections','client_timeout','port','ssloffloadcert','dcertadv','ssloffload','ssloffloadacl','ssloffloadaclnondefault','advanced_bind', 'ssloffloadacladditional','ssloffloadacladditionalnondefault', + 'socket-stats', 'dontlognull','dontlog-normal','log-separate-errors','log-detailed'); if (isset($_POST['id'])) @@ -103,7 +105,7 @@ $fields_sslCertificates[0]['size']="500px"; $fields_sslCertificates[0]['items']=&$servercerts; $certs_ca = haproxy_get_certificates('ca'); -$ca_none['']['name']="None"; +$ca_none['']['name']="(None), allows for client without a (valid) certificate to connect. Make sure to add appropriate acl's."; $certs_ca = $ca_none + $certs_ca; $fields_caCertificates=array(); $fields_caCertificates[0]['name']="cert_ca"; @@ -114,8 +116,8 @@ $fields_caCertificates[0]['size']="500px"; $fields_caCertificates[0]['items']=&$certs_ca; $certs_crl = haproxy_get_crls(); -$ca_none['']['name']="None"; -$certs_crl = $ca_none + $certs_crl; +//$ca_none['']['name']="None"; +//$certs_crl = $ca_none + $certs_crl; $fields_crlCertificates=array(); $fields_crlCertificates[0]['name']="cert_crl"; $fields_crlCertificates[0]['columnheader']="Certificate revocation lists"; @@ -138,11 +140,17 @@ $fields_aclSelectionList[1]['type']="select"; $fields_aclSelectionList[1]['size']="10"; $fields_aclSelectionList[1]['items']=&$a_acltypes; -$fields_aclSelectionList[2]['name']="value"; -$fields_aclSelectionList[2]['columnheader']="Value"; -$fields_aclSelectionList[2]['colwidth']="35%"; -$fields_aclSelectionList[2]['type']="textbox"; -$fields_aclSelectionList[2]['size']="35"; +$fields_aclSelectionList[2]['name']="not"; +$fields_aclSelectionList[2]['columnheader']="Not"; +$fields_aclSelectionList[2]['colwidth']="5%"; +$fields_aclSelectionList[2]['type']="checkbox"; +$fields_aclSelectionList[2]['size']="5"; + +$fields_aclSelectionList[3]['name']="value"; +$fields_aclSelectionList[3]['columnheader']="Value"; +$fields_aclSelectionList[3]['colwidth']="35%"; +$fields_aclSelectionList[3]['type']="textbox"; +$fields_aclSelectionList[3]['size']="35"; $interfaces = haproxy_get_bindable_interfaces(); $interfaces_custom['custom']['name']="Use custom address:"; @@ -623,6 +631,17 @@ $primaryfrontends = get_haproxy_frontends($excludefrontend); </tr> <tr class="haproxy_primary"><td> </td></tr> <tr class="haproxy_primary"> + <td colspan="2" valign="top" class="listtopic">Stats options</td> + </tr> + <tr class="haproxy_primary" align="left"> + <td width="22%" valign="top" class="vncell">Separate sockets</td> + <td width="78%" class="vtable" colspan="2"> + <input id="socket-stats" name="socket-stats" type="checkbox" value="yes" <?php if ($pconfig['socket-stats']=='yes') echo "checked"; ?> onclick='updatevisibility();' /> + Enable collecting & providing separate statistics for each socket. + </td> + </tr> + <tr class="haproxy_primary"><td> </td></tr> + <tr class="haproxy_primary"> <td colspan="2" valign="top" class="listtopic">Logging options</td> </tr> <tr class="haproxy_primary" align="left"> @@ -684,10 +703,6 @@ $primaryfrontends = get_haproxy_frontends($excludefrontend); The 'forwardfor' option creates an HTTP 'X-Forwarded-For' header which contains the client's IP address. This is useful to let the final web server know what the client address was. (eg for statistics on domains)<br/> - <br/> - It is important to note that as long as HAProxy does not support keep-alive connections, - only the first request of a connection will receive the header. For this reason, - it is important to ensure that option httpclose is set when using this option. </td> </tr> <tr align="left" class="haproxy_mode_http"> @@ -720,7 +735,7 @@ $primaryfrontends = get_haproxy_frontends($excludefrontend); <td> </td> </tr> </table> - <table class="haproxy_mode_http" width="100%" border="0" cellpadding="6" cellspacing="0"> + <table class="haproxy_ssloffloading_enabled" width="100%" border="0" cellpadding="6" cellspacing="0"> <tr> <td colspan="2" valign="top" class="listtopic">SSL Offloading</td> </tr> @@ -735,7 +750,7 @@ $primaryfrontends = get_haproxy_frontends($excludefrontend); <tr align="left" class="haproxy_secondary" > <td width="22%" valign="top" class="vncell">Use Offloading</td> <td width="78%" class="vtable" colspan="2"> - <input id="ssloffload" name="ssloffload" type="checkbox" value="yes" <?php if ($pconfig['ssloffload']=='yes') echo "checked";?> onclick="updatevisibility();" /><strong>Use Offloading</strong> + <input id="ssloffload" name="ssloffload" type="checkbox" value="yes" <?php if ($pconfig['ssloffload']=='yes') echo "checked";?> onclick="updatevisibility();" /><strong>Specify additional certificates for this shared-frontend.</strong> </td> </tr> <tr class="haproxy_ssloffloading_enabled" align="left"> @@ -745,10 +760,9 @@ $primaryfrontends = get_haproxy_frontends($excludefrontend); echo_html_select("ssloffloadcert", $servercerts, $pconfig['ssloffloadcert'], '<b>No Certificates defined.</b> <br/>Create one under <a href="system_certmanager.php">System > Cert Manager</a>.'); ?> <br/> - NOTE: choose the cert to use on this frontend. + Choose the cert to use on this frontend. <br/> - <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 'CN')<br/> - <input id="ssloffloadaclnondefault" name="ssloffloadaclnondefault" type="checkbox" value="yes" <?php if ($pconfig['ssloffloadaclnondefault']=='yes') echo "checked";?> onclick="updatevisibility();" />Add ACL for certificate CommonName for nondefault ports. (host header starts with 'CN:') + <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"> @@ -760,8 +774,7 @@ $primaryfrontends = get_haproxy_frontends($excludefrontend); haproxy_htmllist("tableA_sslCertificates", $a_certificates, $fields_sslCertificates); ?> <br/> - <input id="ssloffloadacladditional" name="ssloffloadacladditional" type="checkbox" value="yes" <?php if ($pconfig['ssloffloadacladditional']=='yes') echo "checked";?> onclick="updatevisibility();" />Add ACL for certificate CommonName. (host header matches 'CN')<br/> - <input id="ssloffloadacladditionalnondefault" name="ssloffloadacladditionalnondefault" type="checkbox" value="yes" <?php if ($pconfig['ssloffloadacladditionalnondefault']=='yes') echo "checked";?> onclick="updatevisibility();" />Add ACL for certificate CommonName for nondefault ports. (host header starts with 'CN:') + <input id="ssloffloadacladditional" name="ssloffloadacladditional" type="checkbox" value="yes" <?php if ($pconfig['ssloffloadacladditional']=='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 haproxy_primary" align="left"> @@ -775,7 +788,7 @@ $primaryfrontends = get_haproxy_frontends($excludefrontend); </tr> <tr class="haproxy_ssloffloading_enabled haproxy_primary"> <td class="vncell" colspan="2"><b>Client certificate verification options, leave this empty if you do not want to ask for a client certificate</b><br/> - The users that visit this site will need to load the client cert signed by the ca's listed below imported into their browser.</td> + The users that visit this site will need to load the client cert signed by one of the ca's listed below imported into their browser.</td> </tr> <tr class="haproxy_ssloffloading_enabled haproxy_primary"> <td width="22%" valign="top" class="vncell">Client verification CA certificates</td> diff --git a/config/haproxy-devel/haproxy_pool_edit.php b/config/haproxy-devel/haproxy_pool_edit.php index 5c7f66b9..5e38b12d 100644 --- a/config/haproxy-devel/haproxy_pool_edit.php +++ b/config/haproxy-devel/haproxy_pool_edit.php @@ -790,7 +790,7 @@ set by the 'retries' parameter.</div> <td width="78%" class="vtable" colspan="2"> <input id="persist_cookie_name" name="persist_cookie_name" type="text" <?if(isset($pconfig['persist_cookie_name'])) echo "value=\"{$pconfig['persist_cookie_name']}\"";?> size="64" /><br/> The string name to track in Set-Cookie and Cookie HTTP headers.<br/> - EXAMPLE: MyLoadBalanceCookie JSESSIONID PHPSESSIONID ASP.NET_SessionId + EXAMPLE: MyLoadBalanceCookie JSESSIONID PHPSESSID ASP.NET_SessionId </td> </tr> <tr class="haproxy_cookie_visible" align="left"> diff --git a/config/haproxy-devel/haproxy_utils.inc b/config/haproxy-devel/haproxy_utils.inc index 08906bb0..4b945c06 100644 --- a/config/haproxy-devel/haproxy_utils.inc +++ b/config/haproxy-devel/haproxy_utils.inc @@ -2,7 +2,7 @@ /* haproxy_utils.php part of pfSense (https://www.pfsense.org/) - Copyright (C) 2013 PiBa-NL + Copyright (C) 2013-2015 PiBa-NL All rights reserved. Redistribution and use in source and binary forms, with or without @@ -35,6 +35,30 @@ require_once("config.inc"); class haproxy_utils { public static $pf_version; + + public function query_dns($host, $querytype="A,AAAA", $dnsserver = "127.0.0.1") { + $result = array(); + $host = trim($host, " \t\n\r\0\x0B[];\"'"); + $host_esc = escapeshellarg($host); + $types = explode(',',$querytype); + 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; + } + } + } + return $result; + } } haproxy_utils::$pf_version = substr(trim(file_get_contents("/etc/version")),0,3); diff --git a/config/haproxy-devel/pkg/haproxy_upgrade_config.inc b/config/haproxy-devel/pkg/haproxy_upgrade_config.inc new file mode 100644 index 00000000..9dd575dd --- /dev/null +++ b/config/haproxy-devel/pkg/haproxy_upgrade_config.inc @@ -0,0 +1,174 @@ +<?php +/* + haproxy.inc + Copyright (C) 2015 PiBa-NL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +require_once("pkg-utils.inc"); + +function haproxy_upgrade_config() { + global $config, $static_output; + // for future config upgrades. + // make sure the version stays 'comparable' + if (is_arrayset($config,'installedpackages','haproxy') && isset($config['installedpackages']['haproxy']['configversion'])) + $configversion = $config['installedpackages']['haproxy']['configversion']; + else + $configversion = "00.12"; + + $static_output .= "HAProxy, from version $configversion\n"; + update_output_window($static_output); + + $writeconfigupdate = false; + if ($configversion < "00.13") { + /* Do XML upgrade from haproxy 0.31 to haproxy-dev */ + if (is_array($config['installedpackages']['haproxy']['ha_servers'])) { + $static_output .= "HAProxy, Do XML upgrade from haproxy 0.31 to haproxy-dev\n"; + update_output_window($static_output); + + /* We have an old config */ + $config['installedpackages']['haproxy']['ha_pools']['item'] = array(); + $a_global = &$config['installedpackages']['haproxy']; + $a_backends = &$config['installedpackages']['haproxy']['ha_backends']['item']; + $a_oldservers = &$config['installedpackages']['haproxy']['ha_servers']['item']; + $a_pools = &$config['installedpackages']['haproxy']['ha_pools']['item']; + + foreach ($a_backends as $id => $be) { + $a_backends[$id]['status'] = 'active'; + } + $id = 0; + foreach ($a_oldservers as $oldserver) { + $pool=$oldserver; + /* make server sub array */ + $server=array(); + $server['name'] = $oldserver['name']; + $server['address'] = $oldserver['address']; + $server['port'] = $oldserver['port']; + $server['weight'] = $oldserver['weight']; + $a_servers=array(); + $a_servers[]=$server; + /* set new pool */ + $pool['name'] = "pool$id"; + $id++; + $pool['ha_servers']['item']=$a_servers; + /* link to frontend */ + foreach ($a_backends as $id => $be) { + if ($a_backends[$id]['name'] == $oldserver['backend']) { + $a_backends[$id]['backend_serverpool'] = $pool['name']; + $pool['monitor_uri'] = $be['monitor_uri']; + unset($a_backends[$id]['monitor_uri']); + break; + } + } + unset($pool['backend']); + unset($pool['address']); + unset($pool['port']); + unset($pool['weight']); + $a_pools[] = $pool; + } + unset($config['installedpackages']['haproxy']['ha_servers']); + $writeconfigupdate = true; + } + + /* XML update to: pkg v1.3 and 'pool' changed to 'backend_serverpool' because 'pool' was added to listtags() in xmlparse.inc */ + if (is_arrayset($config,'installedpackages','haproxy','ha_backends','item',0,'pool')) { + $static_output .= "HAProxy, Do XML upgrade, change to backend_serverpool from pool array\n"; + update_output_window($static_output); + + foreach($config['installedpackages']['haproxy']['ha_backends']['item'] as &$frontend) + { + $backend_serverpool = $frontend['pool'][0]; + $frontend['backend_serverpool'] = $backend_serverpool; + unset($frontend['pool']); + } + $writeconfigupdate = true; + } + //also move setting for existing 2.0 installations as only the new variable is used + if (is_arrayset($config,'installedpackages','haproxy','ha_backends','item',0) && + isset($config['installedpackages']['haproxy']['ha_backends']['item'][0]['pool'])) { + $static_output .= "HAProxy, Do XML upgrade, change to backend_serverpool from pool\n"; + update_output_window($static_output); + foreach($config['installedpackages']['haproxy']['ha_backends']['item'] as &$frontend) + { + $backend_serverpool = $frontend['pool']; + $frontend['backend_serverpool'] = $backend_serverpool; + unset($frontend['pool']); + } + $writeconfigupdate = true; + } + // update config to "haproxy-devel 1.5-dev19 pkg v0.5" + if(is_arrayset($config,'installedpackages','haproxy','ha_backends','item')) { + $static_output .= "HAProxy, Do XML upgrade, update frontend options\n"; + update_output_window($static_output); + foreach ($config['installedpackages']['haproxy']['ha_backends']['item'] as &$bind) { + if($bind['httpclose'] && $bind['httpclose'] == "yes" ) { + $bind['httpclose'] = "httpclose"; + $writeconfigupdate = true; + } + if (!$bind['extaddr']){ + $bind['extaddr'] = "wan_ipv4"; + $writeconfigupdate = true; + } + if ($bind['extaddr'] == "localhost"){ + $bind['extaddr'] = "localhost_ipv4"; + $writeconfigupdate = true; + } + if ($bind['extaddr'] == "any"){ + $bind['extaddr'] = "any_ipv4"; + $writeconfigupdate = true; + } + } + } + } + if ($configversion < "00.13") { + // update config to "haproxy-devel 1.5-dev19 pkg v0.13" + foreach ($config['installedpackages']['haproxy']['ha_backends']['item'] as &$bind) { + if (isset($bind['extaddr'])) { + $new['extaddr'] = $bind['extaddr']; + $new['extaddr_port'] = $bind['port']; + $new['extaddr_ssl'] = $bind['ssloffload']; + $bind['a_extaddr']['item'][] = $new; + } + unset($bind['extaddr']); + unset($bind['port']); + //unset($bind['ssloffload']); + } + $configversion = "00.13"; + } + if ($configversion < "00.16") { + $static_output .= "HAProxy, 00.16\n"; + $static_output .= "HAProxy, NOTICE: Changes to certificate acl's might need adjusting current config accordingly.\n"; + $static_output .= "HAProxy, NOTICE: Certificate acls are now combined with user acls.\n"; + update_output_window($static_output); + $configversion = "00.16"; + } + + $writeconfigupdate = $config['installedpackages']['haproxy']['configversion'] <> $configversion; + if ($writeconfigupdate) { + $config['installedpackages']['haproxy']['configversion'] = $configversion; + $static_output .= "HAProxy, write updated config to version: $configversion\n"; + update_output_window($static_output); + write_config("HAProxy, update xml config version"); + } +} diff --git a/config/haproxy-devel/www/javascript/haproxy_geturl.js b/config/haproxy-devel/www/javascript/haproxy_geturl.js new file mode 100644 index 00000000..5df80646 --- /dev/null +++ b/config/haproxy-devel/www/javascript/haproxy_geturl.js @@ -0,0 +1,43 @@ +/** + * getURL is a proprietary Adobe function, but it's simplicity has made it very + * popular. If getURL is undefined we spin our own by wrapping XMLHttpRequest. + */ +if (typeof getURL == 'undefined') { + getURL = function(url, callback) { + if (!url) + throw 'No URL for getURL'; + + try { + if (typeof callback.operationComplete == 'function') + callback = callback.operationComplete; + } catch (e) {} + if (typeof callback != 'function') + throw 'No callback function for getURL "' + url + '"'; + + var http_request = null; + if (typeof XMLHttpRequest != 'undefined') { + http_request = new XMLHttpRequest(); + } + else if (typeof ActiveXObject != 'undefined') { + try { + http_request = new ActiveXObject('Msxml2.XMLHTTP'); + } catch (e) { + try { + http_request = new ActiveXObject('Microsoft.XMLHTTP'); + } catch (e) {} + } + } + if (!http_request) + throw '<?=gettext("Both getURL and XMLHttpRequest are undefined"); ?>'; + + http_request.onreadystatechange = function() { + if (http_request.readyState == 4) { + callback( { success : true, + content : http_request.responseText, + contentType : http_request.getResponseHeader("Content-Type") } ); + } + } + http_request.open('GET', url, true); + http_request.send(null); + } +} |