aboutsummaryrefslogtreecommitdiffstats
path: root/config/haproxy-devel/haproxy.inc
diff options
context:
space:
mode:
Diffstat (limited to 'config/haproxy-devel/haproxy.inc')
-rw-r--r--config/haproxy-devel/haproxy.inc123
1 files changed, 110 insertions, 13 deletions
diff --git a/config/haproxy-devel/haproxy.inc b/config/haproxy-devel/haproxy.inc
index 89103ef8..0f6de3de 100644
--- a/config/haproxy-devel/haproxy.inc
+++ b/config/haproxy-devel/haproxy.inc
@@ -422,6 +422,9 @@ function write_backend($fd, $name, $pool, $frontend) {
$pool['retries'] = 3;
fwrite ($fd, "\tretries\t\t\t" . $pool['retries'] . "\n");
+ if ($pool['transparent_clientip'])
+ fwrite ($fd, "\tsource 0.0.0.0 usesrc clientip\n");
+
if($pool['stats_enabled']=='yes') {
fwrite ($fd, "\tstats\t\t\tenable\n");
if($pool['stats_uri'])
@@ -505,13 +508,17 @@ function write_backend($fd, $name, $pool, $frontend) {
}
function haproxy_configure() {
+ global $g;
// reload haproxy
- haproxy_writeconf();
+ haproxy_writeconf("{$g['varetc_path']}/haproxy.cfg");
return haproxy_check_run(1);
}
-function haproxy_check_writtenconfig_error(&$messages) {
- $retval = exec("haproxy -c -V -f /var/etc/haproxy.cfg 2>&1", $output, $err);
+function haproxy_check_and_run(&$messages, $reload) {
+ global $g;
+ $configname = "{$g['varetc_path']}/haproxy.cfg";
+ haproxy_writeconf("$configname.new");
+ $retval = exec("haproxy -c -V -f $configname.new 2>&1", $output, $err);
$messages = "";
if ($err > 1)
$messages = "<h2><strong>FATAL ERROR CODE: $err while starting haproxy</strong></h2>";
@@ -523,17 +530,24 @@ function haproxy_check_writtenconfig_error(&$messages) {
foreach($output as $line)
$messages .= "<br/>" . htmlspecialchars($line) . "\n";
}
- return (strstr($retval, "Configuration file is valid"));
+ $ok = strstr($retval, "Configuration file is valid");
+ if ($ok && $reload) {
+ global $haproxy_run_message;
+ exec("mv $configname.new $configname");
+ $ok = haproxy_check_run(1) == 0;
+ $messages = $haproxy_run_message;
+ }
+ return $ok;
}
-function haproxy_writeconf() {
- global $config, $g;
+function haproxy_writeconf($configfile) {
+ global $config;
$a_global = &$config['installedpackages']['haproxy'];
$a_backends = &$config['installedpackages']['haproxy']['ha_backends']['item'];
$a_pools = &$config['installedpackages']['haproxy']['ha_pools']['item'];
- $fd = fopen("{$g['varetc_path']}/haproxy.cfg", "w");
+ $fd = fopen($configfile, "w");
if(is_array($a_global)) {
fwrite ($fd, "global\n");
@@ -541,7 +555,10 @@ function haproxy_writeconf() {
if($a_global['remotesyslog'])
fwrite ($fd, "\tlog\t\t\t{$a_global['remotesyslog']}\t{$a_global['logfacility']}\t{$a_global['loglevel']}\n");
fwrite ($fd, "\tstats socket /tmp/haproxy.socket level admin\n");
- fwrite ($fd, "\tuid\t\t\t80\n");
+
+ if(!use_transparent_clientip_proxying())
+ fwrite ($fd, "\tuid\t\t\t80\n");
+
fwrite ($fd, "\tgid\t\t\t80\n");
// Set numprocs if defined or use system default (#cores)
if($a_global['nbproc'])
@@ -831,13 +848,91 @@ function haproxy_is_running() {
return $running;
}
+
+function haproxy_load_modules() {
+ // On FreeBSD 8 ipfw is needed to allow 'transparent' proxying (getting reply's to a non-local ip to pass back to the client-socket)..
+ // On FreeBSD 9 it is probably possible to do the same with the pf option "divert-reply"
+ mute_kernel_msgs();
+ if (!is_module_loaded("ipfw.ko")) {
+ mwexec("/sbin/kldload ipfw");
+ /* make sure ipfw is not on pfil hooks */
+ mwexec("/sbin/sysctl net.inet.ip.pfil.inbound=\"pf\" net.inet6.ip6.pfil.inbound=\"pf\"" .
+ " net.inet.ip.pfil.outbound=\"pf\" net.inet6.ip6.pfil.outbound=\"pf\"");
+ }
+ /* Activate layer2 filtering */
+ mwexec("/sbin/sysctl net.link.ether.ipfw=1");
+ unmute_kernel_msgs();
+}
+
+function use_transparent_clientip_proxying() {
+ global $config;
+ $a_backends = &$config['installedpackages']['haproxy']['ha_pools']['item'];
+ foreach ($a_backends as $backend) {
+ if ($backend["transparent_clientip"] == 'yes') {
+ return true;
+ break;
+ }
+ }
+ return false;
+}
+
+function load_ipfw_rules() {
+ // On FreeBSD 8 pf does not support "divert-reply" so ipfw is needed.
+ global $g, $config;
+ $ipfw_zone_haproxy = "haproxy";
+
+ $a_backends = &$config['installedpackages']['haproxy']['ha_pools']['item'];
+
+ haproxy_load_modules();
+
+ $transparent_backends = array();
+ foreach ($a_backends as $backend) {
+ if ($backend["transparent_clientip"] != 'yes')
+ continue;
+ $real_if = get_real_interface($backend["transparent_interface"]);
+ $a_servers = &$backend['ha_servers']['item'];
+ foreach($a_servers as $server) {
+ if (is_array($a_servers)) {
+
+ foreach($a_servers as $be) {
+ if (!$be['status'] == "inactive")
+ continue;
+ if (!is_ipaddr($be['address']))
+ continue;
+ $item = array();
+ $item['address'] = $be['address'];
+ $item['port'] = $be['port'];
+ $item['interface'] = $real_if;//"em0";
+ $transparent_backends[] = $item;
+ }
+ }
+ }
+ }
+ mwexec("/usr/local/sbin/ipfw_context -a $ipfw_zone_haproxy", true);
+ mwexec("/usr/local/sbin/ipfw_context -a $ipfw_zone_haproxy -n em0", true);
+ $rulenum = 64000; // why that high? captiveportal.inc also does it...
+ $rules = "flush\n";
+ foreach($transparent_backends as $transparent_be) {
+ $rules .= "add $rulenum fwd localhost tcp from {$transparent_be["address"]} {$transparent_be["port"]} to any in recv {$transparent_be["interface"]}\n";
+ $rulenum++;
+ }
+
+
+ file_put_contents("{$g['tmp_path']}/ipfw_{$ipfw_zone_haproxy}.haproxy.rules", $rules);
+ mwexec("/usr/local/sbin/ipfw_context -s $ipfw_zone_haproxy", true);
+ mwexec("/sbin/ipfw -x $ipfw_zone_haproxy -q {$g['tmp_path']}/ipfw_{$ipfw_zone_haproxy}.haproxy.rules", true);
+}
+
function haproxy_check_run($reload) {
- global $config, $g;
+ global $config, $g, $haproxy_run_message;
$a_global = &$config['installedpackages']['haproxy'];
exec("/usr/bin/limits -n 300014");
+ if(use_transparent_clientip_proxying())
+ load_ipfw_rules();
+
if(isset($a_global['enable'])) {
if (isset($a_global['carpdev'])) {
$status = get_carp_interface_status($a_global['carpdev']);
@@ -856,16 +951,18 @@ function haproxy_check_run($reload) {
return (0);
if (haproxy_is_running()) {
- exec("/usr/local/sbin/haproxy -f /var/etc/haproxy.cfg -p /var/run/haproxy.pid -st `cat /var/run/haproxy.pid`");
+ exec("/usr/local/sbin/haproxy -f /var/etc/haproxy.cfg -p /var/run/haproxy.pid -st `cat /var/run/haproxy.pid` 2>&1", $output, $errcode);
} else {
- exec("/usr/local/sbin/haproxy -f /var/etc/haproxy.cfg -p /var/run/haproxy.pid -D");
+ exec("/usr/local/sbin/haproxy -f /var/etc/haproxy.cfg -p /var/run/haproxy.pid -D 2>&1", $output, $errcode);
}
- return (0);
+ foreach($output as $line)
+ $haproxy_run_message .= "<br/>" . htmlspecialchars($line) . "\n";
+ return ($errcode);
} else {
if ($reload && haproxy_is_running()) {
exec("/bin/pkill -F /var/run/haproxy.pid haproxy");
}
- return (1);
+ return (0);
}
}