From 7b9b5ac6b297792f2c61f09eb5b33133c75a2cc1 Mon Sep 17 00:00:00 2001 From: PiBa-NL Date: Sun, 30 Nov 2014 20:53:42 +0100 Subject: haproxy-devel, remove old listen ip:port configuration, add conversion code. --- config/haproxy-devel/haproxy.inc | 405 +++++++++++++++++++++++++-------------- 1 file changed, 257 insertions(+), 148 deletions(-) (limited to 'config/haproxy-devel/haproxy.inc') diff --git a/config/haproxy-devel/haproxy.inc b/config/haproxy-devel/haproxy.inc index 930fd4e9..5b56595a 100644 --- a/config/haproxy-devel/haproxy.inc +++ b/config/haproxy-devel/haproxy.inc @@ -38,6 +38,13 @@ require_once("haproxy_xmlrpcsyncclient.inc"); $d_haproxyconfdirty_path = $g['varrun_path'] . "/haproxy.conf.dirty"; +global $a_frontendmode; +$a_frontendmode = array(); +$a_frontendmode['http'] = array('name' => "http / https(offloading)", 'shortname' => "http/https"); +$a_frontendmode['https'] = array('name' => "ssl / https(TCP mode)", 'shortname' => "ssl/https"); +$a_frontendmode['tcp'] = array('name' => "tcp", 'shortname' => "tcp"); +$a_frontendmode['health'] = array('name' => "health", 'shortname' => "health"); + global $a_acltypes; $a_acltypes = array(); $a_acltypes["host_starts_with"] = array('name' => 'Host starts with:', @@ -84,6 +91,8 @@ $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', + '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'); @@ -237,10 +246,11 @@ function group_ports($ports) { return $result; } } - + function haproxy_portoralias_to_list($port_or_alias) { // input: a port or aliasname: 80 https MyPortAlias // returns: a array of ports and portranges 80 443 8000:8010 + global $aliastable; $portresult = array(); if (alias_get_type($port_or_alias) == "port") { @@ -253,15 +263,39 @@ function haproxy_portoralias_to_list($port_or_alias) { return $portresult; } else if (is_portrange($port_or_alias)) { return (array)$port_or_alias; - } else if (is_port($port_or_alias)) { - if (getservbyname($port_or_alias, "tcp")) - return (array)getservbyname($port_or_alias, "tcp"); - if (getservbyname($port_or_alias, "udp")) - return (array)getservbyname($port_or_alias, "udp"); - return (array)$port_or_alias; + } else { + $ports = explode(",", $port_or_alias); + foreach($ports as $port){ + if (is_port($port)) { + if (getservbyname($port, "tcp")) + $port = getservbyname($port, "tcp"); + if (getservbyname($port, "udp")) + $port = getservbyname($port, "udp"); + $portresult[] = $port; + } + } + return $portresult; + } +} +function haproxy_addressoralias_to_list($address_or_alias) { + global $aliastable; + $result = array(); + $alias_type = alias_get_type($address_or_alias); + if (!empty($alias_type)) { + $alias = $aliastable[$address_or_alias]; + if ($alias_type == "url") { + $result = explode(' ',$alias); + } else + if ($alias_type == "network") { + //$result = explode(' ',$alias); + } else + if ($alias_type == "host") { + $result = explode(' ',$alias); + } + } else { + $result[] = $address_or_alias; } - else - return null; + return $result; } function haproxy_hostoralias_to_list($host_or_alias) { @@ -365,107 +399,136 @@ EOD; $static_output .= "HAProxy, update configuration\n"; update_output_window($static_output); - $writeconfigupdate = false; - /* 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); + // make sure the version stays 'comparable' + if (is_arrayset($config,'installedpackages','haproxy')) + $configversion = $config['installedpackages']['haproxy']['configversion']; + else + $configversion = "00.12"; - /* 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']; + $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; + $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($pool['backend']); - unset($pool['address']); - unset($pool['port']); - unset($pool['weight']); - $a_pools[] = $pool; + unset($config['installedpackages']['haproxy']['ha_servers']); + $writeconfigupdate = true; } - 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']); + + /* 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; } - $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']); + //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; + } + } } - $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); + 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($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 (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) { - $static_output .= "HAProxy, write updated config\n"; + $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"); } @@ -875,6 +938,9 @@ function haproxy_write_certificate_fullchain($filename, $certid, $append = false function haproxy_writeconf($configpath) { global $config; + global $aliastable; + if (!isset($aliastable)) + alias_make_table($config); $chroot_dir = "/tmp/haproxy_chroot"; // can contain socket to forward connection from backend to frontend. "/var/empty" make_dirs($chroot_dir); @@ -951,7 +1017,8 @@ function haproxy_writeconf($configpath) { if(!$frontend['backend_serverpool']) continue; $primaryfrontend = get_primaryfrontend($frontend); - $bname = get_frontend_ipport($frontend); + + $bname = $primaryfrontend['name']; if (!is_array($a_bind[$bname])) { $a_bind[$bname] = array(); $a_bind[$bname] = $primaryfrontend; @@ -959,12 +1026,14 @@ function haproxy_writeconf($configpath) { } //check ssl info - if (strtolower($primaryfrontend['type']) == "http" && $frontend['ssloffload']){ + $ssl = get_frontend_uses_ssl($frontend); + + if ($ssl) { //ssl crt ./server.pem ca-file ./ca.crt verify optional crt-ignore-err all crl-file ./ca_crl.pem - $filename = "$configpath/{$frontend['name']}.{$frontend['port']}.pem"; + $filename = "$configpath/{$frontend['name']}.pem"; $ssl_crt = " crt $filename"; haproxy_write_certificate_fullchain($filename, $frontend['ssloffloadcert']); - $subfolder = "$configpath/{$frontend['name']}.{$frontend['port']}"; + $subfolder = "$configpath/{$frontend['name']}"; $certs = $frontend['ha_certificates']['item']; if (is_array($certs)){ if (count($certs) > 0){ @@ -1032,8 +1101,8 @@ function haproxy_writeconf($configpath) { } // Prepare ports for processing by splitting - $portss = "{$bind['port']},"; - $ports = split(",", $portss); + //$portss = "{$bind['port']},"; + //$ports = split(",", $portss); if($bind['type'] == "http") { // ssl offloading is only possible in http mode. @@ -1043,41 +1112,36 @@ function haproxy_writeconf($configpath) { $ssl_info = ""; $advanced_bind = ""; } + + fwrite ($fd, "{$frontendinfo}"); + // Initialize variable $listenip = ""; // Process and add bind directives for ports - $ip = haproxy_interface_ip($bind['extaddr']); - if ($ip){ - foreach($ports as $alias_or_port) { - if($alias_or_port) { - $portsnumeric = group_ports(haproxy_portoralias_to_list($alias_or_port)); - foreach($portsnumeric as $portnumeric) { - $portnumeric = str_replace(":","-",$portnumeric); - $listenip .= "\tbind\t\t\t$ip:{$portnumeric} {$ssl_info} {$advanced_bind}\n"; - } - } - } - } - - fwrite ($fd, "{$frontendinfo}"); - if (isset($bind['a_extaddr'])) { foreach($bind['a_extaddr']['item'] as $extaddr) { - if (isset($extaddr['extaddr']) && $extaddr['extaddr'] != "") { - $ip = haproxy_interface_ip($extaddr['extaddr']); - } else - $ip = $extaddr['extaddr_custom']; + $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 = ""; - $portsnumeric = group_ports(haproxy_portoralias_to_list($extaddr['extaddr_port'])); - foreach($portsnumeric as $portnumeric) { - $portnumeric = str_replace(":","-",$portnumeric); - $listenip .= "\tbind\t\t\t$ip:{$portnumeric} {$ssl} {$advanced_bind} {$extaddr['extaddr_advanced']}\n"; + 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"; + } + } } } } @@ -1127,10 +1191,9 @@ function haproxy_writeconf($configpath) { if($bind['forwardfor']) { fwrite ($fd, "\toption\t\t\tforwardfor\n"); - if($bind['ssloffload'] == "yes") - fwrite ($fd, "\treqadd X-Forwarded-Proto:\ https\n"); - else - fwrite ($fd, "\treqadd X-Forwarded-Proto:\ http\n"); + fwrite ($fd, "\tacl https ssl_fc\n"); + fwrite ($fd, "\treqadd X-Forwarded-Proto:\ http if !https\n"); + fwrite ($fd, "\treqadd X-Forwarded-Proto:\ https if https\n"); } } @@ -1413,8 +1476,7 @@ function haproxy_plugin_certificates($pluginparams) { $result['certificatelist'] = array(); // return a array of used certificates. foreach($config['installedpackages']['haproxy']['ha_backends']['item'] as &$frontend) { - $mainfrontend = get_primaryfrontend($frontend); - if (strtolower($mainfrontend['type']) == "http" && $mainfrontend['ssloffload']) { + if (get_frontend_uses_ssl($frontend)) { if ($frontend['ssloffloadacl']){ $item = array(); $cert = $frontend['ssloffloadcert']; @@ -1602,12 +1664,30 @@ function get_primaryfrontend($frontend) { return $mainfrontend; } -function get_frontend_ipport($frontend,$userfriendly=false) { +function get_frontend_ipport($frontend, $userfriendly=false) { $mainfrontend = get_primaryfrontend($frontend); - $result = haproxy_interface_ip($mainfrontend['extaddr'], $userfriendly); - if ($userfriendly and is_ipaddrv6($result)) - $result = "[{$result}]"; - return $result . ":" . $mainfrontend['port']; + $newline = ""; + $result = array(); + if (!isset($mainfrontend)) + return $result; + foreach($mainfrontend['a_extaddr']['item'] as $extaddr) { + if ($extaddr['extaddr'] == 'custom'){ + $addr = $extaddr['extaddr_custom']; + } else { + $addr = haproxy_interface_ip($extaddr['extaddr'], $userfriendly); + } + if ($userfriendly and is_ipaddrv6($addr)) + $addr = "[{$addr}]"; + + $port = $extaddr['extaddr_port']; + $newitem = array(); + $newitem['addr'] = $addr; + $newitem['port'] = $port; + $newitem['ssl'] = $extaddr['extaddr_ssl']; + $result[$addr.$port] = $newitem; + } + ksort($result); + return $result; } function haproxy_check_config() { @@ -1620,17 +1700,20 @@ function haproxy_check_config() { foreach($a_backends as $frontend) { if (($frontend['status'] != 'active') || ($frontend['secondary'] == 'yes')) continue; - $ipport = get_frontend_ipport($frontend); - if (isset($activefrontends[$ipport])) - $issues['P_'.$ipport] = "Multiple primary frontends with IP:Port \"$ipport\""; - else - $activefrontends[$ipport] = true; + $ipports = get_frontend_ipport($frontend); + foreach($ipports as $ipport) { + $id = "{$ipport['addr']}:{$ipport['port']}"; + if (isset($activefrontends[$id])) + $issues['P_'.$id] = "Multiple primary frontends with IP:Port \"$id\""; + else + $activefrontends[$id] = true; + } } foreach($a_backends as $frontend) { if (($frontend['status'] != 'active') || ($frontend['secondary'] != 'yes')) continue; - $ipport = get_frontend_ipport($frontend); - if (!isset($activefrontends[$ipport])) + $mainfrontend = get_primaryfrontend($frontend); + if (!isset($mainfrontend)) $issues['S_'.$frontend['name']] = "Secondary frontend \"{$frontend['name']}\" without active primary frontend."; } foreach ($issues as $item) @@ -1649,17 +1732,43 @@ function get_haproxy_frontends($excludeitem="") { if ($frontend['name'] == $excludeitem) continue; - $serveradress = "{$frontend['extaddr']}:{$frontend['port']}"; - $result[$frontend['name']]['name'] = "{$frontend['name']} - {$frontend['type']} ({$serveradress})"; + $serveraddress = get_frontend_ipport($frontend, true); + $serveradresstext = null; + foreach($serveraddress as $addr) { + $serveradresstext .=($serveradresstext == null ? "" : ", ") . "{$addr['addr']}:{$addr['port']}"; + } + $result[$frontend['name']]['name'] = "{$frontend['name']} - {$frontend['type']} ({$serveradresstext})"; $result[$frontend['name']]['ref'] = &$frontend; } uasort($result, haproxy_compareByName); return $result; } -function generate_cert_acl($crt, $defaultport, $nondefaultport){ - // The host header send by a browser will contain the portnumber when a nondefault port is used for the server side. +function get_frontend_uses_ssl($frontend) { + $mainfrontend = get_primaryfrontend($frontend); + $ssl = false; + if (is_arrayset($mainfrontend,'a_extaddr','item')) { + foreach($mainfrontend['a_extaddr']['item'] as $extaddr) { + if ($extaddr['extaddr_ssl'] == 'yes') { + $ssl = true; + break; + } + } + } + if ($mainfrontend['name'] != $frontend['name']) + $ssl = $ssl && $frontend['ssloffload'] == 'yes'; + return $ssl; +} +function get_frontend_uses_ssl_only($frontend) { + $mainfrontend = get_primaryfrontend($frontend); + if (is_arrayset($mainfrontend,'a_extaddr','item')) { + foreach($mainfrontend['a_extaddr']['item'] as $extaddr) { + if ($extaddr['extaddr_ssl'] != 'yes') + return false; + } + } + return true; } function get_frontend_acls($frontend) { @@ -1685,7 +1794,7 @@ function get_frontend_acls($frontend) { } } - if (strtolower($mainfrontend['type']) == "http" && $mainfrontend['ssloffload']) { + if (get_frontend_uses_ssl($frontend)) { $a_acl = &$frontend['ha_acls']['item']; if(!is_array($a_acl)) $a_acl=array(); -- cgit v1.2.3