Project

General

Profile

Download (7.55 KB) Statistics
| Branch: | Tag: | Revision:
1 cb7d18d5 Renato Botelho
#!/usr/local/bin/php-cgi -f
2 ae75bcb4 Scott Ullrich
<?php
3
/*
4 ac24dc24 Renato Botelho
 * rc.carpmaster
5
 *
6
 * part of pfSense (https://www.pfsense.org)
7 38809d47 Renato Botelho do Couto
 * Copyright (c) 2004-2013 BSD Perimeter
8
 * Copyright (c) 2013-2016 Electric Sheep Fencing
9 8f2f85c3 Luiz Otavio O Souza
 * Copyright (c) 2014-2022 Rubicon Communications, LLC (Netgate)
10 ac24dc24 Renato Botelho
 * All rights reserved.
11
 *
12 b12ea3fb Renato Botelho
 * Licensed under the Apache License, Version 2.0 (the "License");
13
 * you may not use this file except in compliance with the License.
14
 * You may obtain a copy of the License at
15 ac24dc24 Renato Botelho
 *
16 b12ea3fb Renato Botelho
 * http://www.apache.org/licenses/LICENSE-2.0
17 ac24dc24 Renato Botelho
 *
18 b12ea3fb Renato Botelho
 * Unless required by applicable law or agreed to in writing, software
19
 * distributed under the License is distributed on an "AS IS" BASIS,
20
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21
 * See the License for the specific language governing permissions and
22
 * limitations under the License.
23 ac24dc24 Renato Botelho
 */
24 ae75bcb4 Scott Ullrich
25
require_once("functions.inc");
26
require_once("config.inc");
27
require_once("notices.inc");
28 9ea0cb90 jim-p
require_once("openvpn.inc");
29 6ae26227 Viktor G
require_once("ipsec.inc");
30 e3449857 PiBa-NL
require_once("interfaces.inc");
31 0eae38cd Augustin-FL
require_once("captiveportal.inc");
32 ae75bcb4 Scott Ullrich
33 7de4474e Luiz Otavio O Souza
if (isset($_GET['interface'])) {
34 815f1f77 Ermal
	$argument = $_GET['interface'];
35 e173dd74 Phil Davis
} else {
36 815f1f77 Ermal
	$argument = str_replace("\n", "", $argv[1]);
37 e173dd74 Phil Davis
}
38 de9df940 jim-p
$argument = ltrim($argument, '$');
39 e173dd74 Phil Davis
if (!strstr($argument, "@")) {
40 10e58a70 Chris Buechler
	log_error("CARP master event triggered from wrong source {$argument}");
41 7de4474e Luiz Otavio O Souza
	exit;
42 e173dd74 Phil Davis
}
43 77411fa7 Ermal
44
list($vhid, $iface) = explode("@", $argument);
45
46
$friendly = convert_real_interface_to_friendly_interface_name($iface);
47 34cd5348 Chris Buechler
$friendly_descr = convert_friendly_interface_to_friendly_descr($friendly);
48
$vips = link_interface_to_vips($friendly, '', $vhid);
49 7de4474e Luiz Otavio O Souza
if (!is_array($vips)) {
50
	log_error("CARP master event triggered from wrong source {$argument} - no associated VIPs");
51
	exit;
52
}
53 34cd5348 Chris Buechler
foreach ($vips as $vip) {
54 7de4474e Luiz Otavio O Souza
	$notificationmsg = sprintf('HA cluster member "(%1$s@%2$s): (%3$s)" has resumed CARP state "MASTER" for vhid %4$s',
55 3e798da2 jim-p
					$vip['subnet'], $iface, $friendly_descr, $vhid);
56 ae75bcb4 Scott Ullrich
57 02fcba75 Viktor G
	notify_all_remote($notificationmsg);
58 34cd5348 Chris Buechler
	log_error($notificationmsg);
59
}
60 a9a74b49 Luiz Souza
restart_ppp_interfaces_using_interfaces($vips);
61 ae75bcb4 Scott Ullrich
62 9ea0cb90 jim-p
/* Start OpenVPN clients running on this VIP, since they should be in the stopped state while the VIP is CARP Backup. */
63
global $config;
64 43a9b03d PiBa-NL
$a_groups = return_gateway_groups_array(true);
65 3e798da2 jim-p
66
foreach (array('server', 'client') as $mode) {
67
	foreach (config_get_path("openvpn/openvpn-{$mode}", []) as $settings) {
68
		if (empty($settings)) {
69 d20dd658 Chris Buechler
			continue;
70
		}
71 f003f8db jim-p
		if (substr($settings['interface'], 0, 4) == '_vip') {
72
			$openvpn_vip = $settings['interface'];
73
		} else if (is_array($a_groups[$settings['interface']])) {
74
			// interface is a gateway group, check CARP VIP
75 3e798da2 jim-p
			$vip = array_get_path($a_groups, "{$settings['interface']}/0/vip");
76
			if (substr($vip, 0, 4) == '_vip') {
77
				$openvpn_vip = $vip;
78 f003f8db jim-p
			}
79
		} else {
80 3e798da2 jim-p
			// this OpenVPN instance not on a CARP VIP
81 f003f8db jim-p
			continue;
82
		}
83 7de4474e Luiz Otavio O Souza
		foreach ($vips as $vip) {
84 f003f8db jim-p
			if ($openvpn_vip == "_vip{$vip['uniqid']}") {
85 3e798da2 jim-p
				log_error("Starting OpenVPN {$mode} instance on {$friendly_descr} because of transition to CARP master.");
86
				openvpn_restart($mode, $settings);
87 7de4474e Luiz Otavio O Souza
			}
88 e173dd74 Phil Davis
		}
89
	}
90 52b5a223 Renato Botelho
}
91 3e798da2 jim-p
92
foreach (config_get_path("ipsec/phase1", []) as $ph1ent) {
93
	if (empty($ph1ent)) {
94
		continue;
95
	}
96
	if ((substr($ph1ent['interface'], 0, 4) == '_vip') && (in_array($ph1ent['interface'], $vips))) {
97
		log_error("Reconfiguring IPsec because of transition to CARP master.");
98
		ipsec_configure();
99
		break;
100 6ae26227 Viktor G
	}
101
}
102 52b5a223 Renato Botelho
103 fcac6e87 Chris Buechler
/* Reconfigure radvd when necessary */
104 3e798da2 jim-p
$rafound = false;
105
foreach (config_get_path("dhcpdv6", []) as $dhcpv6if => $dhcpv6ifconf) {
106
	if (empty($dhcpv6ifconf)) {
107
		continue;
108 fcac6e87 Chris Buechler
	}
109 3e798da2 jim-p
	foreach ($vips as $vip) {
110
		if ($dhcpv6ifconf['rainterface'] == "_vip{$vip['uniqid']}") {
111
			log_error("Starting radvd instance on {$friendly_descr} because of transition to CARP master.");
112
			$rafound = true;
113
		}
114 fcac6e87 Chris Buechler
	}
115
}
116 3e798da2 jim-p
if ($rafound) {
117
	services_radvd_configure();
118
}
119 fcac6e87 Chris Buechler
120 30169caa Viktor G
/* Reconfigure DHCP Relay when necessary */
121 3e798da2 jim-p
if (config_path_enabled('dhcrelay') &&
122
    (config_get_path('dhcrelay/carpstatusvip') == "_vip{$vip['uniqid']}")) {
123 30169caa Viktor G
	log_error("Starting DHCP Relay service because of transition to CARP master.");
124
	services_dhcrelay_configure();
125
}
126
127
/* Reconfigure DHCPv6 Relay when necessary */
128 3e798da2 jim-p
if (config_path_enabled('dhcrelay6') &&
129
    (config_get_path('dhcrelay6/carpstatusvip') == "_vip{$vip['uniqid']}")) {
130 30169caa Viktor G
	log_error("Starting DHCPv6 Relay service because of transition to CARP master.");
131
	services_dhcrelay6_configure();
132
}
133
134 0eae38cd Augustin-FL
/* Reconfigure captive portal when necessary :
135
   If we are the primary node, and we are switching back from backup to master : Get user list from the backup node */
136 3e798da2 jim-p
if (!empty(config_get_path('captiveportal')) &&
137
    !empty(config_get_path('hasync/synchronizetoip')) &&
138
    !empty(config_get_path('hasync/synchronizecaptiveportal'))) {
139
	$xmlrpc_username = config_get_path('hasync/username');
140
	if (empty($xmlrpc_username)) {
141 0eae38cd Augustin-FL
		$xmlrpc_username = "admin";
142
	}
143 3e798da2 jim-p
	$xmlrpc_port = config_get_path('system/webgui/port');
144 fef846ce jim-p
	if (empty($xmlrpc_port)) {
145 3e798da2 jim-p
		if (config_get_path('system/webgui/protocol') == "http") {
146 0eae38cd Augustin-FL
			$xmlrpc_port = "80";
147
		} else {
148
			$xmlrpc_port = "443";
149
		}
150
	}
151
152 3e798da2 jim-p
	foreach (array_keys(config_get_path('captiveportal')) as $cpzone) {
153 0eae38cd Augustin-FL
		$rpc_client = new pfsense_xmlrpc_client();
154 3e798da2 jim-p
		$rpc_client->setConnectionData(config_get_path('hasync/synchronizetoip'), $xmlrpc_port, $xmlrpc_username, config_get_path('hasync/password'));
155 0eae38cd Augustin-FL
		$resp = $rpc_client->xmlrpc_method('captive_portal_sync', array('op' => 'get_databases', 'zone' => $cpzone));
156
157 3e798da2 jim-p
		if (is_array($resp) || !empty($resp)) { // $resp will be an array only if the communication was successful
158 0eae38cd Augustin-FL
			// Contains array of connected users (will be stored in SQLite DB)
159
			$connected_users = unserialize(base64_decode($resp['connected_users']));
160
			// Contains array of active vouchers (will be stored in active vouchers db)
161
			$active_vouchers = unserialize(base64_decode($resp['active_vouchers']));
162
			// Contain bitmask of both in use and expired vouchers (will be stored in "used vouchers" db)
163
			$expired_vouchers = unserialize(base64_decode($resp['expired_vouchers']));
164 a81a6edc Viktor G
			// Contains array of usedmacs (will be stored in usedmacs db)
165
			$usedmacs = unserialize(base64_decode($resp['usedmacs']));
166 0eae38cd Augustin-FL
167
			$cpdb = captiveportal_read_db();
168
			$unsetindexes = array_column($cpdb, 5);
169
			if (!empty($unsetindexes)) {
170
				captiveportal_remove_entries($unsetindexes, true); // true: prevent carp loop
171
			}
172
			captiveportal_free_dnrules();
173
174 3e798da2 jim-p
			foreach ($connected_users as $user) {
175
				if (!is_array($user) || empty($user)) {
176
					continue;
177
				}
178 0eae38cd Augustin-FL
				$pipeno = captiveportal_get_next_dn_ruleno('auth');
179
				$attributes = array();
180
				$attributes['allow_time'] = $user['allow_time'];
181
				$attributes['session_timeout'] = $user['session_timeout'];
182
				$attributes['idle_timeout'] = $user['idle_timeout'];
183
				$attributes['session_terminate_time'] = $user['session_terminate_time'];
184
				$attributes['interim_interval'] = $user['interim_interval'];
185
				$attributes['maxbytes'] = $user['traffic_quota'];
186
187
				portal_allow($user['ip'], $user['mac'], $user['username'], base64_decode($user['bpassword']), null,
188
				    $attributes, $pipeno, $user['authmethod'], $user['context'], $user['sessionid'], true);
189
			}
190
			foreach ($expired_vouchers as $roll => $vdb) {
191
				voucher_write_used_db($roll, $vdb);
192
			}
193
			foreach ($active_vouchers as $roll => $vouchers) {
194
				voucher_write_active_db($roll, $vouchers);
195
			}
196 a81a6edc Viktor G
			captiveportal_write_usedmacs_db($usedmacs); 
197 0eae38cd Augustin-FL
		}
198 a81a6edc Viktor G
		captiveportal_syslog(sprintf(gettext('Connected users, used vouchers and used MACs have been synchronized from %1$s'), $config['hasync']['synchronizetoip']));
199 0eae38cd Augustin-FL
	}
200
}
201 f1fcc3ce Renato Botelho do Couto
openlog("", LOG_PID, LOG_LOCAL0);
202 eaee3af6 PiBa-NL
$pluginparams = array();
203
$pluginparams['type'] = 'carp';
204
$pluginparams['event'] = 'rc.carpmaster';
205 eda14265 jim-p
$pluginparams['interface'] = $argument;
206 331166a8 PiBa-NL
pkg_call_plugins('plugin_carp', $pluginparams);
207 eaee3af6 PiBa-NL
208 34cd5348 Chris Buechler
?>