diff options
Diffstat (limited to 'config/haproxy-devel')
-rw-r--r-- | config/haproxy-devel/haproxy.xml | 48 | ||||
-rw-r--r-- | config/haproxy-devel/pkg/haproxy.inc (renamed from config/haproxy-devel/haproxy.inc) | 657 | ||||
-rw-r--r-- | config/haproxy-devel/pkg/haproxy_htmllist.inc (renamed from config/haproxy-devel/haproxy_htmllist.inc) | 0 | ||||
-rw-r--r-- | config/haproxy-devel/pkg/haproxy_socketinfo.inc (renamed from config/haproxy-devel/haproxy_socketinfo.inc) | 0 | ||||
-rw-r--r-- | config/haproxy-devel/pkg/haproxy_upgrade_config.inc | 204 | ||||
-rw-r--r-- | config/haproxy-devel/pkg/haproxy_utils.inc (renamed from config/haproxy-devel/haproxy_utils.inc) | 28 | ||||
-rw-r--r-- | config/haproxy-devel/pkg/haproxy_xmlrpcsyncclient.inc (renamed from config/haproxy-devel/haproxy_xmlrpcsyncclient.inc) | 0 | ||||
-rw-r--r-- | config/haproxy-devel/pkg/pkg_haproxy_tabs.inc (renamed from config/haproxy-devel/pkg_haproxy_tabs.inc) | 0 | ||||
-rw-r--r-- | config/haproxy-devel/www/haproxy_files.php (renamed from config/haproxy-devel/haproxy_files.php) | 0 | ||||
-rw-r--r--[-rwxr-xr-x] | config/haproxy-devel/www/haproxy_global.php (renamed from config/haproxy-devel/haproxy_global.php) | 30 | ||||
-rw-r--r-- | config/haproxy-devel/www/haproxy_listeners.php (renamed from config/haproxy-devel/haproxy_listeners.php) | 103 | ||||
-rw-r--r-- | config/haproxy-devel/www/haproxy_listeners_edit.php (renamed from config/haproxy-devel/haproxy_listeners_edit.php) | 137 | ||||
-rw-r--r-- | config/haproxy-devel/www/haproxy_pool_edit.php (renamed from config/haproxy-devel/haproxy_pool_edit.php) | 2 | ||||
-rw-r--r-- | config/haproxy-devel/www/haproxy_pools.php (renamed from config/haproxy-devel/haproxy_pools.php) | 0 | ||||
-rw-r--r-- | config/haproxy-devel/www/haproxy_stats.php (renamed from config/haproxy-devel/haproxy_stats.php) | 0 | ||||
-rw-r--r-- | config/haproxy-devel/www/haproxy_templates.php (renamed from config/haproxy-devel/haproxy_templates.php) | 0 | ||||
-rw-r--r-- | config/haproxy-devel/www/javascript/haproxy_geturl.js | 43 | ||||
-rw-r--r--[-rwxr-xr-x] | config/haproxy-devel/www/shortcuts/pkg_haproxy.inc (renamed from config/haproxy-devel/pkg_haproxy.inc) | 0 | ||||
-rw-r--r-- | config/haproxy-devel/www/widgets/widgets/haproxy.widget.php (renamed from config/haproxy-devel/haproxy.widget.php) | 0 |
19 files changed, 831 insertions, 421 deletions
diff --git a/config/haproxy-devel/haproxy.xml b/config/haproxy-devel/haproxy.xml index da2b4648..e057bfb2 100644 --- a/config/haproxy-devel/haproxy.xml +++ b/config/haproxy-devel/haproxy.xml @@ -52,6 +52,12 @@ <section>Services</section> <url>/haproxy_listeners.php</url> </menu> + <menu> + <name>HAProxy Stats</name> + <tooltiptext>Stats of HAProxy</tooltiptext> + <section>Status</section> + <url>/haproxy_stats.php?haproxystats=1</url> + </menu> <service> <name>HAProxy</name> <rcfile>haproxy.sh</rcfile> @@ -70,82 +76,92 @@ <additional_files_needed> <prefix>/usr/local/pkg/</prefix> <chmod>077</chmod> - <item>https://packages.pfsense.org/packages/config/haproxy-devel/haproxy.inc</item> + <item>https://packages.pfsense.org/packages/config/haproxy-devel/pkg/haproxy.inc</item> </additional_files_needed> <additional_files_needed> <prefix>/usr/local/www/</prefix> <chmod>077</chmod> - <item>https://packages.pfsense.org/packages/config/haproxy-devel/haproxy_listeners.php</item> + <item>https://packages.pfsense.org/packages/config/haproxy-devel/www/haproxy_listeners.php</item> </additional_files_needed> <additional_files_needed> <prefix>/usr/local/www/</prefix> <chmod>077</chmod> - <item>https://packages.pfsense.org/packages/config/haproxy-devel/haproxy_listeners_edit.php</item> + <item>https://packages.pfsense.org/packages/config/haproxy-devel/www/haproxy_listeners_edit.php</item> </additional_files_needed> <additional_files_needed> <prefix>/usr/local/www/</prefix> <chmod>077</chmod> - <item>https://packages.pfsense.org/packages/config/haproxy-devel/haproxy_global.php</item> + <item>https://packages.pfsense.org/packages/config/haproxy-devel/www/haproxy_global.php</item> </additional_files_needed> <additional_files_needed> <prefix>/usr/local/www/</prefix> <chmod>077</chmod> - <item>https://packages.pfsense.org/packages/config/haproxy-devel/haproxy_files.php</item> + <item>https://packages.pfsense.org/packages/config/haproxy-devel/www/haproxy_files.php</item> </additional_files_needed> <additional_files_needed> <prefix>/usr/local/www/</prefix> <chmod>077</chmod> - <item>https://packages.pfsense.org/packages/config/haproxy-devel/haproxy_pools.php</item> + <item>https://packages.pfsense.org/packages/config/haproxy-devel/www/haproxy_pools.php</item> </additional_files_needed> <additional_files_needed> <prefix>/usr/local/www/</prefix> <chmod>077</chmod> - <item>https://packages.pfsense.org/packages/config/haproxy-devel/haproxy_pool_edit.php</item> + <item>https://packages.pfsense.org/packages/config/haproxy-devel/www/haproxy_pool_edit.php</item> </additional_files_needed> <additional_files_needed> <prefix>/usr/local/www/</prefix> <chmod>077</chmod> - <item>https://packages.pfsense.org/packages/config/haproxy-devel/haproxy_stats.php</item> + <item>https://packages.pfsense.org/packages/config/haproxy-devel/www/haproxy_stats.php</item> </additional_files_needed> <additional_files_needed> <prefix>/usr/local/www/</prefix> <chmod>077</chmod> - <item>https://packages.pfsense.org/packages/config/haproxy-devel/haproxy_templates.php</item> + <item>https://packages.pfsense.org/packages/config/haproxy-devel/www/haproxy_templates.php</item> </additional_files_needed> <additional_files_needed> <prefix>/usr/local/pkg/</prefix> <chmod>077</chmod> - <item>https://packages.pfsense.org/packages/config/haproxy-devel/haproxy_socketinfo.inc</item> + <item>https://packages.pfsense.org/packages/config/haproxy-devel/pkg/haproxy_socketinfo.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/haproxy_xmlrpcsyncclient.inc</item> + <item>https://packages.pfsense.org/packages/config/haproxy-devel/pkg/haproxy_xmlrpcsyncclient.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/haproxy_htmllist.inc</item> + <item>https://packages.pfsense.org/packages/config/haproxy-devel/pkg/haproxy_htmllist.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/haproxy_utils.inc</item> + <item>https://packages.pfsense.org/packages/config/haproxy-devel/pkg/haproxy_utils.inc</item> </additional_files_needed> <additional_files_needed> <prefix>/usr/local/www/widgets/widgets/</prefix> <chmod>077</chmod> - <item>https://packages.pfsense.org/packages/config/haproxy-devel/haproxy.widget.php</item> + <item>https://packages.pfsense.org/packages/config/haproxy-devel/www/widgets/widgets/haproxy.widget.php</item> </additional_files_needed> <additional_files_needed> <prefix>/usr/local/www/shortcuts/</prefix> <chmod>0755</chmod> - <item>https://packages.pfsense.org/packages/config/haproxy-devel/pkg_haproxy.inc</item> + <item>https://packages.pfsense.org/packages/config/haproxy-devel/www/shortcuts/pkg_haproxy.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_tabs.inc</item> + <item>https://packages.pfsense.org/packages/config/haproxy-devel/pkg/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> diff --git a/config/haproxy-devel/haproxy.inc b/config/haproxy-devel/pkg/haproxy.inc index 9b758370..135f2d4f 100644 --- a/config/haproxy-devel/haproxy.inc +++ b/config/haproxy-devel/pkg/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. @@ -68,12 +68,12 @@ $a_acltypes["path_regex"] = array('name' => 'Path regex:', $a_acltypes["path_contains"] = array('name' => 'Path contains:', 'mode' => 'http', 'syntax' => 'path_dir -i %1$s'); $a_acltypes["ssl_c_verify_code"] = array('name' => 'SSL Client certificate verify error result:', - 'mode' => 'http', 'syntax' => 'ssl_fc_has_crt ssl_c_verify %1$s'); + 'mode' => 'http', 'syntax' => 'ssl_c_verify %1$s', 'require_client_cert' => '1'); // ssl_c_verify result codes: https://www.openssl.org/docs/apps/verify.html#DIAGNOSTICS $a_acltypes["ssl_c_verify"] = array('name' => 'SSL Client certificate valid.', - 'mode' => 'http', 'syntax' => 'ssl_fc_has_crt ssl_c_verify 0 '); + 'mode' => 'http', 'syntax' => 'ssl_c_verify 0', 'novalue' => '1', 'require_client_cert' => '1'); $a_acltypes["ssl_c_ca_commonname"] = array('name' => 'SSL Client issued by CA common-name:', - 'mode' => 'http', 'syntax' => 'ssl_c_i_dn(CN) %1$s'); + 'mode' => 'http', 'syntax' => 'ssl_c_i_dn(CN) %1$s', 'require_client_cert' => '1'); $a_acltypes["source_ip"] = array('name' => 'Source IP matches IP or Alias:', 'mode' => '', 'syntax' => 'src %1$s'); $a_acltypes["backendservercount"] = array('name' => 'Minimum count usable servers:', @@ -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'); @@ -151,9 +151,13 @@ $a_closetypes['forceclose'] = array('name' => 'forceclose', 'syntax' => 'forcecl global $a_servermodes; $a_servermodes = array(); $a_servermodes["active"]['name'] = "active"; +$a_servermodes["active"]['sign'] = ""; $a_servermodes["backup"]['name'] = "backup"; +$a_servermodes["backup"]['sign'] = "*"; $a_servermodes["disabled"]['name'] = "disabled"; +$a_servermodes["disabled"]['sign'] = "?"; $a_servermodes["inactive"]['name'] = "inactive"; +$a_servermodes["inactive"]['sign'] = "-"; // http://www.exceliance.fr/sites/default/files/biblio/aloha_load_balancer_haproxy_cookie_persistence_methods_memo.pdf global $a_cookiemode; @@ -370,7 +374,7 @@ function haproxy_custom_php_install_command() { . /etc/rc.subr name="haproxy" -rcvar=`set_rcvar` +rcvar="\${name}_enable" command="/usr/pbi/haproxy-devel-`uname -m`/sbin/haproxy" haproxy_enable=\${haproxy-"YES"} @@ -425,140 +429,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); @@ -597,7 +472,7 @@ function haproxy_install_cron($should_install) { $cron_item['month'] = "*"; $cron_item['wday'] = "*"; $cron_item['who'] = "root"; - $cron_item['command'] = "/usr/local/etc/rc.d/haproxy.sh check"; + $cron_item['command'] = "/usr/local/etc/rc.d/haproxy.sh onecheck"; $config['cron']['item'][] = $cron_item; parse_config(true); write_config("haproxy, install cron CARP job"); @@ -617,6 +492,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 +513,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 +673,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 +712,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 +723,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 +784,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 +955,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,88 +1038,53 @@ function haproxy_writeconf($configpath) { else $frontendinfo = "frontend {$bind['name']}\n"; - $advancedextra = array(); + fwrite ($fd, "{$frontendinfo}"); + $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; + } } - $ca_file = " ca-file $filename verify optional"; + $verify = $bind['sslclientcert-none'] == 'yes' ? "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"; } + $advanced_bind = $bind['advanced_bind']; + $ssl_info = $bind['ssl_info']; + $ssl_info .= $ca_file . $crl_file; + if ($bind['sslclientcert-invalid']) + $ssl_info .= " crt-ignore-err all"; - // 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; - $advanced_bind = $bind['advanced_bind']; - } else { - $ssl_info = ""; - $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"); - } - - // Advanced pass thru - if($bind['advanced']) { - $advanced = explode("\n", base64_decode($bind['advanced'])); - foreach($advanced as $adv_line) { - if ($adv_line != "") { - fwrite($fd, "\t" . str_replace("\r", "", $adv_line) . "\n"); - } - } + fwrite ($fd, "\tbind /tmp/haproxy_chroot/{$bind['name']}.socket name unixsocket accept-proxy {$ssl_info} {$advanced_bind}\n"); } // https is an alias for tcp for clarity purposes @@ -1222,12 +1097,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 +1112,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"); @@ -1256,78 +1132,187 @@ function haproxy_writeconf($configpath) { fwrite ($fd, "\ttimeout client\t\t" . $bind['client_timeout'] . "\n"); + + // Advanced pass thru + if($bind['advanced']) { + $advanced = explode("\n", base64_decode($bind['advanced'])); + foreach($advanced as $adv_line) { + if ($adv_line != "") { + fwrite($fd, "\t" . str_replace("\r", "", $adv_line) . "\n"); + } + } + } // Combine the rest of the frontend configs $default_backend = ""; - $config_usebackend = ""; + $config_acls = ""; + $config_usebackends = ""; + $config_usedefaultbackends = ""; + + $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; + $acllist = array(); + $acl_newid = 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; - } + $allowfordefaultbackend = true; + $ipv = array(); + if ($transparent_clientip) { + if ($useipv4 && $useipv6) { + $ipv["ipv4"]['acl'] = " src_is_ipv4 "; + $ipv["ipv6"]['acl'] = " !src_is_ipv4 "; + $allowfordefaultbackend = false; // transparent backend must always match client-ip which is ipv4 v.s. ipv6 specific so there cannot be a default. + } 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(); foreach ($a_acl as $entry) { $name = $entry['ref']['name']; - $a_acl_combine[$name][] = $entry['ref']; + + $acl = array(); + $acl['ref'] = $entry['ref']; + $acltype = haproxy_find_acl($entry['ref']['expression']); + $acl['acltype'] = $acltype; + if (!isset($acltype)) + continue; + $a_acl_combine[$name][] = $acl; + + if (isset($acltype['require_client_cert'])){ + $acl = array(); + $acl['ref']['expression'] = "ssl_c_used"; + $acl['acltype']['syntax'] = "ssl_c_used"; + $acl['acltype']['novalue'] = 1; + $a_acl_combine[$name][] = $acl; + } } - 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"; + $certacl = ""; + $y = 0; + foreach($ipv as $ipversion => $ipversionoptions) { + $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; + } + $canbedefaultbackend = false; + // Write this out once, and must be before any backend config text + if (($default_backend == "" || $frontend['secondary'] != 'yes') && count($a_acl) == 0 ) { + $canbedefaultbackend = true; + if ($allowfordefaultbackend) + $default_backend = $poolname; + } + + foreach ($a_acl_combine as $a_usebackend) { + $aclnames = ""; + foreach ($a_usebackend as $entry2) { + $entry = $entry2['ref']; + $acl = $entry2['acltype']; + + // 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" ? "!" : ""; + + unset($aclkey); + foreach($acllist as $aclid => $aclitem) { + if ($aclitem['expr'] == $expr) { + $aclkey = $aclid; + } + } + if (isset($aclkey)) { + $aclname = $acllist[$aclkey]['aclname']; + } else { + $aclkey = $acl_newid++; + if ($entry['certacl']) { + $aclname = "aclcrt_".$frontend['name']; + $certacl = $aclname; + } else { + $aclname = "aclusr_{$entry['expression']}"; + if (!isset($acl['novalue'])) + $aclname .= "_{$entry['value']}"; + $aclname = haproxy_escape_acl_name($aclname); + $i++; + } + $acllist[$aclkey]['aclname'] = $aclname; + $acllist[$aclkey]['expr'] = $expr; + $config_acls .= "\tacl\t\t\t" . $aclname . "\t" . $expr . "\n"; + } + if (!isset($entry['certacl'])) + $useracls[$y] .= $not . $aclname . " "; + + if ($acl['inspect-delay'] != '') + $inspectdelay = $acl['inspect-delay']; + + if ($acl['advancedoptions'] != '') + $advancedextra[$acl['syntax']] = $acl['advancedoptions']."\n"; + } + $y++; + } + + $systemacl = trim("{$certacl}{$ipversionoptions['acl']}"); + if (!empty($systemacl) && count($useracls) == 0) $useracls[] = ""; // add empty item to enter foreach loop at least once when a system acl is pressent. + foreach($useracls as $useracl) { + $backendacl = ""; + $backendacl .= "|| {$useracl}{$systemacl}"; + $backendacl = substr($backendacl, 3); + if ($canbedefaultbackend) { + // makes sure these come last even though systemacl's might have been added. + $config_usedefaultbackends .= "\tuse_backend\t\t" . $poolname . " if " . $backendacl . "\n"; } 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++; + $config_usebackends .= "\tuse_backend\t\t" . $poolname . " if " . $backendacl . "\n"; } - $config_usebackend .= "\tuse_backend\t\t" . $poolname . " if " . $aclnames . "\n"; } } + if ($inspectdelay > 0) - fwrite ($fd, "\ttcp-request inspect-delay\t" . $inspectdelay . "\n"); + fwrite ($fd, "\ttcp-request inspect-delay\t" . $inspectdelay . "s\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); + fwrite ($fd, $config_usedefaultbackends); if ($default_backend) fwrite ($fd, "\tdefault_backend\t\t" . $default_backend . "\n"); @@ -1339,7 +1324,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); } } } @@ -1552,6 +1537,22 @@ function haproxy_plugin_certificates($pluginparams) { return $result; } +function haproxy_carpipismaster($ip) { + global $config; + foreach($config['virtualip']['vip'] as $carp) { + if ($carp['mode'] != "carp") + continue; + $ipaddress = $carp['subnet']; + if ($ipaddress != $ip) + continue; + + $carp_int = "{$carp['interface']}_vip{$carp['vhid']}"; + $status = get_carp_interface_status($carp_int); + return ($status == "MASTER"); + } + return null; +} + function haproxy_check_run($reload) { global $config, $g, $haproxy_run_message; @@ -1564,8 +1565,8 @@ function haproxy_check_run($reload) { if(isset($a_global['enable'])) { if (isset($a_global['carpdev'])) { - $status = get_carp_interface_status($a_global['carpdev']); - if ($status != "MASTER") { + $status = haproxy_carpipismaster($a_global['carpdev']); + if (!$status) { if (haproxy_is_running()) { log_error("Stopping haproxy on CARP backup."); //exec("/bin/pkill -F /var/run/haproxy.pid haproxy");//doesnt work for multiple pid's in a pidfile @@ -1721,7 +1722,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 +1745,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 +1864,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,9 +1897,9 @@ 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['descr'] = $acl['name'] . " " . (isset($acl['novalue']) ? "" : $not . $entry['value']); $acl_item['ref'] = $entry; $result[] = $acl_item; @@ -1861,44 +1916,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_htmllist.inc b/config/haproxy-devel/pkg/haproxy_htmllist.inc index f873028e..f873028e 100644 --- a/config/haproxy-devel/haproxy_htmllist.inc +++ b/config/haproxy-devel/pkg/haproxy_htmllist.inc diff --git a/config/haproxy-devel/haproxy_socketinfo.inc b/config/haproxy-devel/pkg/haproxy_socketinfo.inc index cbfb131b..cbfb131b 100644 --- a/config/haproxy-devel/haproxy_socketinfo.inc +++ b/config/haproxy-devel/pkg/haproxy_socketinfo.inc 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..c1c951df --- /dev/null +++ b/config/haproxy-devel/pkg/haproxy_upgrade_config.inc @@ -0,0 +1,204 @@ +<?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"; + } + if ($configversion < "00.17") { + $static_output .= "HAProxy, 00.17\n"; + update_output_window($static_output); + // remove 'none' ca-cert, and set checkbox to allow for no certificate instead. + foreach ($config['installedpackages']['haproxy']['ha_backends']['item'] as &$bind) { + $list = array(); + foreach ($bind['clientcert_ca']['item'] as $ca){ + if (empty($ca['cert_ca'])) + $bind['sslclientcert-none'] = 'yes'; + else + $list[] = $ca; + } + $bind['clientcert_ca']['item'] = $list; + } + $configversion = "00.17"; + } + if ($configversion < "00.19") { + update_output_window($static_output); + $carpint = $config['installedpackages']['haproxy']['carpdev']; + if (is_arrayset($config, 'virtualip', 'vip') && is_arrayset($config, 'installedpackages', 'haproxy')) { + foreach($config['virtualip']['vip'] as $carp) { + $carp_int = "{$carp['interface']}_vip{$carp['vhid']}"; + if ($carp_int == $carpint) { + $config['installedpackages']['haproxy']['carpdev'] = $carp['subnet']; + break; + } + } + } + $configversion = "00.19"; + } + + $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/haproxy_utils.inc b/config/haproxy-devel/pkg/haproxy_utils.inc index 08906bb0..d8c4faf4 100644 --- a/config/haproxy-devel/haproxy_utils.inc +++ b/config/haproxy-devel/pkg/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); @@ -330,7 +354,7 @@ function haproxy_get_certificates($type = 'server,user', $get_includeWebCert=fal $ok |= stristr($type,',user,') && $purpose['server'] != 'Yes'; if (!$ok) continue; - if ($get_includeWebCert == false && is_webgui_cert($cert['refid'])) + if ($get_includeWebCert == false && $cert['descr'] == "webConfigurator default") continue; $certificates[$cert['refid']]['name'] = haproxy_get_certificate_descriptivename($cert); } diff --git a/config/haproxy-devel/haproxy_xmlrpcsyncclient.inc b/config/haproxy-devel/pkg/haproxy_xmlrpcsyncclient.inc index 699dffd1..699dffd1 100644 --- a/config/haproxy-devel/haproxy_xmlrpcsyncclient.inc +++ b/config/haproxy-devel/pkg/haproxy_xmlrpcsyncclient.inc diff --git a/config/haproxy-devel/pkg_haproxy_tabs.inc b/config/haproxy-devel/pkg/pkg_haproxy_tabs.inc index a74ee20a..a74ee20a 100644 --- a/config/haproxy-devel/pkg_haproxy_tabs.inc +++ b/config/haproxy-devel/pkg/pkg_haproxy_tabs.inc diff --git a/config/haproxy-devel/haproxy_files.php b/config/haproxy-devel/www/haproxy_files.php index 4946a7be..4946a7be 100644 --- a/config/haproxy-devel/haproxy_files.php +++ b/config/haproxy-devel/www/haproxy_files.php diff --git a/config/haproxy-devel/haproxy_global.php b/config/haproxy-devel/www/haproxy_global.php index cad3795a..978d778d 100755..100644 --- a/config/haproxy-devel/haproxy_global.php +++ b/config/haproxy-devel/www/haproxy_global.php @@ -191,7 +191,7 @@ function enable_change(enable_change) { <table cellpadding="0" cellspacing="0"> <tr> <td> - <input name="maxconn" type="text" class="formfld" id="maxconn" size="5" <?if ($pconfig['enable']!='yes') echo "enabled=\"false\"";?> value="<?=htmlspecialchars($pconfig['maxconn']);?>" /> per Backend. + <input name="maxconn" type="text" class="formfld" id="maxconn" size="5" <?if ($pconfig['enable']!='yes') echo "enabled=\"false\"";?> value="<?=htmlspecialchars($pconfig['maxconn']);?>" /> per process. </td> </tr> </table> @@ -253,7 +253,7 @@ function enable_change(enable_change) { <input name="nbproc" type="text" class="formfld" id="nbproc" size="18" value="<?=htmlspecialchars($pconfig['nbproc']);?>" /> <br/> Defaults to 1 if left blank (<?php echo trim(`/sbin/sysctl kern.smp.cpus | cut -d" " -f2`); ?> CPU core(s) detected).<br/> - Note : Consider leaving this value empty or 1 because in multi-process mode (nbproc > 1) memory is not shared between the processes, which could result in random behaviours for several options like ACL's, sticky connections and some others.<br/> + Note : Consider leaving this value empty or 1 because in multi-process mode (nbproc > 1) memory is not shared between the processes, which could result in random behaviours for several options like ACL's, sticky connections, stats pages, admin maintenance options and some others.<br/> For more information about the <b>"nbproc"</b> option please see <b><a href='http://cbonte.github.io/haproxy-dconv/configuration-1.5.html#nbproc' target='_blank'>HAProxy Documentation</a> </b> </td> </tr> @@ -271,26 +271,12 @@ function enable_change(enable_change) { Carp monitor </td> <td class="vtable"> - <select name="carpdev" class="formfld"> - <option value="disabled" <?php if (!isset($pconfig['carpdev'])) echo "selected"; ?>> - disabled - </option> - <?php - if(is_array($config['virtualip']['vip'])) { - foreach($config['virtualip']['vip'] as $carp): - if ($carp['mode'] != "carp") continue; - $ipaddress = $carp['subnet']; - $carp_int = trim(find_carp_interface($ipaddress)); - ?> - <option value="<?=$carp_int;?>" - <?php if (isset($pconfig['carpdev']) && $carp_int == $pconfig['carpdev']) echo "selected"; ?>> - <?=$carp_int;?> (<?=$ipaddress;?>) - </option> - <?php - endforeach; - } - ?> - </select> + <?php + $vipinterfaces = array(); + $vipinterfaces[] = array('ip' => '', 'name' => 'Disabled'); + $vipinterfaces += haproxy_get_bindable_interfaces($ipv="ipv4,ipv6", $interfacetype="carp"); + echo_html_select('carpdev',$vipinterfaces, $pconfig['carpdev'],"No carp interfaces pressent"); + ?> <br/> Monitor carp interface and only run haproxy on the firewall which is MASTER. </td> diff --git a/config/haproxy-devel/haproxy_listeners.php b/config/haproxy-devel/www/haproxy_listeners.php index 301dd253..db1f3ff2 100644 --- a/config/haproxy-devel/haproxy_listeners.php +++ b/config/haproxy-devel/www/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 = ""; @@ -192,22 +247,24 @@ include("head.inc"); $backend_serverpool_hint = gettext("Servers in pool:"); if (is_array($servers)){ foreach($servers as $server){ + $srvstatus = $server['status']; + $status = $a_servermodes[$srvstatus]['sign']; if (isset($server['forwardto']) && $server['forwardto'] != "") - $backend_serverpool_hint .= "\n[".$server['forwardto']."]"; + $backend_serverpool_hint .= "\n{$status}[{$server['forwardto']}]"; else - $backend_serverpool_hint .= "\n".$server['address'].":".$server['port']; + $backend_serverpool_hint .= "\n{$status}{$server['address']}:{$server['port']}"; } } } ?> </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 +280,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 +295,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/www/haproxy_listeners_edit.php index a818fcfb..d8841c33 100644 --- a/config/haproxy-devel/haproxy_listeners_edit.php +++ b/config/haproxy-devel/www/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 @@ -69,8 +70,9 @@ 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','ssloffloadcert','dcertadv','ssloffload','ssloffloadacl','ssloffloadaclnondefault','advanced_bind', - 'ssloffloadacladditional','ssloffloadacladditionalnondefault', + 'max_connections','client_timeout','port','advanced_bind', + 'ssloffloadcert','dcertadv','ssloffload','ssloffloadacl','ssloffloadacladditional','sslclientcert-none','sslclientcert-invalid', + 'socket-stats', 'dontlognull','dontlog-normal','log-separate-errors','log-detailed'); if (isset($_POST['id'])) @@ -103,8 +105,6 @@ $fields_sslCertificates[0]['size']="500px"; $fields_sslCertificates[0]['items']=&$servercerts; $certs_ca = haproxy_get_certificates('ca'); -$ca_none['']['name']="None"; -$certs_ca = $ca_none + $certs_ca; $fields_caCertificates=array(); $fields_caCertificates[0]['name']="cert_ca"; $fields_caCertificates[0]['columnheader']="Certificates authorities"; @@ -114,8 +114,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 +138,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:"; @@ -240,9 +246,9 @@ if ($_POST) { $a_certificates = haproxy_htmllist_get_values($fields_sslCertificates); $pconfig['a_certificates'] = $a_certificates; $a_clientcert_ca = haproxy_htmllist_get_values($fields_caCertificates); - $pconfig['a_clientcert_ca'] = $a_clientcert_ca; + $pconfig['clientcert_ca'] = $a_clientcert_ca; $a_clientcert_crl = haproxy_htmllist_get_values($fields_crlCertificates); - $pconfig['a_clientcert_crl'] = $a_clientcert_crl; + $pconfig['clientcert_crl'] = $a_clientcert_crl; $a_acl = haproxy_htmllist_get_values($fields_aclSelectionList); $pconfig['a_acl'] = $a_acl; @@ -254,17 +260,31 @@ if ($_POST) { foreach($a_acl as $acl) { $acl_name = $acl['name']; $acl_value = $acl['value']; - + + $acltype = haproxy_find_acl($acl['expression']); if (preg_match("/[^a-zA-Z0-9\.\-_]/", $acl_name)) $input_errors[] = "The field 'Name' contains invalid characters."; - if (!preg_match("/.{1,}/", $acl_value)) - $input_errors[] = "The field 'Value' is required."; + if (!isset($acltype['novalue'])) + if (!preg_match("/.{1,}/", $acl_value)) + $input_errors[] = "The field 'Value' is required."; if (!preg_match("/.{2,}/", $acl_name)) $input_errors[] = "The field 'Name' is required with at least 2 characters."; } - + foreach($a_extaddr as $extaddr) { + $ports = explode(",",$extaddr['extaddr_port']); + foreach($ports as $port){ + if ($port && !is_numeric($port) && !is_portoralias($port)) + $input_errors[] = "The field 'Port' value '".htmlspecialchars($port)."' is not a number or alias thereof."; + } + + if ($extaddr['extaddr'] == 'custom') { + $extaddr_custom = $extaddr['extaddr_custom']; + if (empty($extaddr_custom) || (!is_ipaddroralias($extaddr_custom))) + $input_errors[] = sprintf(gettext("%s is not a valid source IP address or alias."),$extaddr_custom); + } + } if (!$input_errors) { $backend = array(); if(isset($id) && $a_backend[$id]) @@ -323,6 +343,7 @@ $primaryfrontends = get_haproxy_frontends($excludefrontend); ?> <style type="text/css"> .haproxy_mode_http{display:none;} + .haproxy_ssloffloading_show{display:none;} .haproxy_ssloffloading_enabled{display:none;} .haproxy_primary{} .haproxy_secondary{display:none;} @@ -392,22 +413,31 @@ $primaryfrontends = get_haproxy_frontends($excludefrontend); function updatevisibility() { d = document; ssl = false; + sslshow = false; ssloffload = d.getElementById("ssloffload"); - for (i = 0; i < 99; i++) { - customEdit = document.getElementById("extaddr_ssl"+i); - if (customEdit && customEdit.checked) - ssl = true; - } - var type; + var primary; var secondary = d.getElementById("secondary"); - var primary_frontend = d.getElementById("primary_frontend"); + var primary_frontend = d.getElementById("primary_frontend"); if ((secondary !== null) && (secondary.checked)) { - type = primaryfrontends[primary_frontend.value]['ref']['type']; - ssl = ssloffload.checked; - } else + primary = primaryfrontends[primary_frontend.value]; + type = primary['ref']['type']; + for (i = 0; i < 99; i++) { + if (primary['ref']['a_extaddr']['item'][i] && primary['ref']['a_extaddr']['item'][i]['extaddr_ssl'] == 'yes') + sslshow = true;//ssloffload.checked; + ssl = ssloffload.checked; + } + } else { type = d.getElementById("type").value; + for (i = 0; i < 99; i++) { + customEdit = document.getElementById("extaddr_ssl"+i); + if (customEdit && customEdit.checked) + sslshow = true; + } + ssl = sslshow; + } + setCSSdisplay(".haproxy_ssloffloading_show", sslshow); setCSSdisplay(".haproxy_ssloffloading_enabled", ssl); setCSSdisplay(".haproxy_mode_http", type == "http"); if (secondary !== null) { @@ -623,6 +653,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 +725,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 +757,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_show" width="100%" border="0" cellpadding="6" cellspacing="0"> <tr> <td colspan="2" valign="top" class="listtopic">SSL Offloading</td> </tr> @@ -735,7 +772,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 +782,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 +796,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"> @@ -774,8 +809,26 @@ $primaryfrontends = get_haproxy_frontends($excludefrontend); </td> </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> + <td class="vncell" colspan="2"><b>Client certificate verification options, leave all these options 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 one of the ca's listed below imported into their browser.</td> + </tr> + <tr class="haproxy_ssloffloading_enabled haproxy_primary" align="left"> + <td width="22%" valign="top" class="vncell">Without client cert</td> + <td width="78%" class="vtable" colspan="2"> + <input id="sslclientcert-none" name="sslclientcert-none" type="checkbox" value="yes" <?php if ($pconfig['sslclientcert-none']=='yes') echo "checked"; ?> onclick='updatevisibility();' /> + Allows clients without a certificate to connect. + <div>Make sure to add appropriate acl's to check for presence of a user certificate where needed.</div> + </td> + </tr> + <tr class="haproxy_ssloffloading_enabled haproxy_primary" align="left"> + <td width="22%" valign="top" class="vncell">Allow invalid cert</td> + <td width="78%" class="vtable" colspan="2"> + <input id="sslclientcert-invalid" name="sslclientcert-invalid" type="checkbox" value="yes" <?php if ($pconfig['sslclientcert-invalid']=='yes') echo "checked"; ?> onclick='updatevisibility();' /> + Allows client with a invalid/expired/revoked or otherwise wrong certificate to connect. + <div>Make sure to add appropriate acl's to check for valid certificates and verify errors using codes from the following list. + <a target="_blank" href="https://www.openssl.org/docs/apps/verify.html#DIAGNOSTICS">https://www.openssl.org/docs/apps/verify.html#DIAGNOSTICS</a></div> + + </td> </tr> <tr class="haproxy_ssloffloading_enabled haproxy_primary"> <td width="22%" valign="top" class="vncell">Client verification CA certificates</td> @@ -823,7 +876,9 @@ $primaryfrontends = get_haproxy_frontends($excludefrontend); <br/> <script type="text/javascript"> <? - phparray_to_javascriptarray($primaryfrontends,"primaryfrontends",Array('/*','/*/name','/*/ref','/*/ref/type','/*/ref/ssloffload')); + phparray_to_javascriptarray($primaryfrontends,"primaryfrontends",Array('/*', + '/*/name','/*/ref','/*/ref/type','/*/ref/a_extaddr','/*/ref/a_extaddr/item','/*/ref/a_extaddr/item/*', + '/*/ref/a_extaddr/item/*/extaddr_ssl')); phparray_to_javascriptarray($a_closetypes,"closetypes",Array('/*','/*/name','/*/descr')); phparray_to_javascriptarray($fields_sslCertificates,"fields_sslCertificates",Array('/*','/*/name','/*/type','/*/size','/*/items','/*/items/*','/*/items/*/*','/*/items/*/*/name')); phparray_to_javascriptarray($fields_caCertificates,"fields_ca",Array('/*','/*/name','/*/type','/*/size','/*/items','/*/items/*','/*/items/*/*','/*/items/*/*/name')); diff --git a/config/haproxy-devel/haproxy_pool_edit.php b/config/haproxy-devel/www/haproxy_pool_edit.php index 5c7f66b9..5e38b12d 100644 --- a/config/haproxy-devel/haproxy_pool_edit.php +++ b/config/haproxy-devel/www/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_pools.php b/config/haproxy-devel/www/haproxy_pools.php index 92235933..92235933 100644 --- a/config/haproxy-devel/haproxy_pools.php +++ b/config/haproxy-devel/www/haproxy_pools.php diff --git a/config/haproxy-devel/haproxy_stats.php b/config/haproxy-devel/www/haproxy_stats.php index 302793b6..302793b6 100644 --- a/config/haproxy-devel/haproxy_stats.php +++ b/config/haproxy-devel/www/haproxy_stats.php diff --git a/config/haproxy-devel/haproxy_templates.php b/config/haproxy-devel/www/haproxy_templates.php index 478c83a3..478c83a3 100644 --- a/config/haproxy-devel/haproxy_templates.php +++ b/config/haproxy-devel/www/haproxy_templates.php 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); + } +} diff --git a/config/haproxy-devel/pkg_haproxy.inc b/config/haproxy-devel/www/shortcuts/pkg_haproxy.inc index 1e5c75c2..1e5c75c2 100755..100644 --- a/config/haproxy-devel/pkg_haproxy.inc +++ b/config/haproxy-devel/www/shortcuts/pkg_haproxy.inc diff --git a/config/haproxy-devel/haproxy.widget.php b/config/haproxy-devel/www/widgets/widgets/haproxy.widget.php index 5d664e81..5d664e81 100644 --- a/config/haproxy-devel/haproxy.widget.php +++ b/config/haproxy-devel/www/widgets/widgets/haproxy.widget.php |