Project

General

Profile

Download (13.8 KB) Statistics
| Branch: | Tag: | Revision:
1 b0ae75c5 Bill Marquette
<?php
2
/* $Id$ */
3
/*
4
	firewall_virtual_ip.php
5 c7281770 Chris Buechler
	part of pfSense (https://www.pfsense.org/)
6 b0ae75c5 Bill Marquette
7
	Copyright (C) 2005 Bill Marquette <bill.marquette@gmail.com>.
8 ce77a9c4 Phil Davis
	Copyright (C) 2013-2015 Electric Sheep Fencing, LP
9 b0ae75c5 Bill Marquette
	All rights reserved.
10
11
	Includes code from m0n0wall which is:
12
	Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
13
	All rights reserved.
14
15
	Includes code from pfSense which is:
16
	Copyright (C) 2004-2005 Scott Ullrich <geekgod@pfsense.com>.
17
	All rights reserved.
18
19
	Redistribution and use in source and binary forms, with or without
20
	modification, are permitted provided that the following conditions are met:
21
22
	1. Redistributions of source code must retain the above copyright notice,
23
	   this list of conditions and the following disclaimer.
24
25
	2. Redistributions in binary form must reproduce the above copyright
26
	   notice, this list of conditions and the following disclaimer in the
27
	   documentation and/or other materials provided with the distribution.
28
29
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
30
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
31
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
33
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38
	POSSIBILITY OF SUCH DAMAGE.
39
*/
40 7ac5a4cb Scott Ullrich
/*
41
	pfSense_BUILDER_BINARIES:	/sbin/ifconfig
42
	pfSense_MODULE:	interfaces
43
*/
44 b0ae75c5 Bill Marquette
45 6b07c15a Matthew Grooms
##|+PRIV
46
##|*IDENT=page-firewall-virtualipaddresses
47
##|*NAME=Firewall: Virtual IP Addresses page
48
##|*DESCR=Allow access to the 'Firewall: Virtual IP Addresses' page.
49
##|*MATCH=firewall_virtual_ip.php*
50
##|-PRIV
51
52 b0ae75c5 Bill Marquette
require("guiconfig.inc");
53 7a927e67 Scott Ullrich
require_once("functions.inc");
54
require_once("filter.inc");
55
require_once("shaper.inc");
56 b0ae75c5 Bill Marquette
57
if (!is_array($config['virtualip']['vip'])) {
58
	$config['virtualip']['vip'] = array();
59
}
60
$a_vip = &$config['virtualip']['vip'];
61
62
if ($_POST) {
63
	$pconfig = $_POST;
64
65
	if ($_POST['apply']) {
66 6e4c8e92 Ermal LUÇI
		$check_carp = false;
67 68071477 Ermal
		if (file_exists("{$g['tmp_path']}/.firewall_virtual_ip.apply")) {
68 760b1df9 Phil Davis
			$toapplylist = unserialize(file_get_contents("{$g['tmp_path']}/.firewall_virtual_ip.apply"));
69 68071477 Ermal
			foreach ($toapplylist as $vid => $ovip) {
70 760b1df9 Phil Davis
				if (!empty($ovip)) {
71 68071477 Ermal
					interface_vip_bring_down($ovip);
72 760b1df9 Phil Davis
				}
73 68071477 Ermal
				if ($a_vip[$vid]) {
74 760b1df9 Phil Davis
					switch ($a_vip[$vid]['mode']) {
75
						case "ipalias":
76
							interface_ipalias_configure($a_vip[$vid]);
77
							break;
78
						case "proxyarp":
79
							interface_proxyarp_configure($a_vip[$vid]['interface']);
80
							break;
81
						case "carp":
82
							$check_carp = true;
83
							interface_carp_configure($a_vip[$vid]);
84
							break;
85
						default:
86
							break;
87 68071477 Ermal
					}
88 760b1df9 Phil Davis
				}
89
			}
90 68071477 Ermal
			@unlink("{$g['tmp_path']}/.firewall_virtual_ip.apply");
91
		}
92 6e4c8e92 Ermal LUÇI
		/* Before changing check #4633 */
93 760b1df9 Phil Davis
		if ($check_carp === true && !get_carp_status()) {
94
			set_single_sysctl("net.inet.carp.allow", "1");
95
		}
96 6e4c8e92 Ermal LUÇI
97 b0ae75c5 Bill Marquette
		$retval = 0;
98 920b3bb0 Scott Ullrich
		$retval |= filter_configure();
99 b0ae75c5 Bill Marquette
		$savemsg = get_std_save_message($retval);
100 abcb2bed Ermal Lu?i
101 a368a026 Ermal Lu?i
		clear_subsystem_dirty('vip');
102 b0ae75c5 Bill Marquette
	}
103
}
104
105
if ($_GET['act'] == "del") {
106
	if ($a_vip[$_GET['id']]) {
107
		/* make sure no inbound NAT mappings reference this entry */
108
		if (is_array($config['nat']['rule'])) {
109
			foreach ($config['nat']['rule'] as $rule) {
110 93e485e3 Renato Botelho
				if($rule['destination']['address'] <> "") {
111 3504e10b Renato Botelho
					if ($rule['destination']['address'] == $a_vip[$_GET['id']]['subnet']) {
112 3e2a70d9 Rafael Lucas
						$input_errors[] = gettext("This entry cannot be deleted because it is still referenced by at least one NAT mapping.");
113 7c99b15c Scott Ullrich
						break;
114
					}
115 b0ae75c5 Bill Marquette
				}
116
			}
117
		}
118
119 52856a80 Phil Davis
		/* make sure no OpenVPN server or client references this entry */
120
		$openvpn_types_a = array("openvpn-server" => gettext("server"), "openvpn-client" => gettext("client"));
121
		foreach ($openvpn_types_a as $openvpn_type => $openvpn_type_text) {
122
			if (is_array($config['openvpn'][$openvpn_type])) {
123
				foreach ($config['openvpn'][$openvpn_type] as $openvpn) {
124
					if ($openvpn['ipaddr'] <> "") {
125
						if ($openvpn['ipaddr'] == $a_vip[$_GET['id']]['subnet']) {
126
							if (strlen($openvpn['description'])) {
127
								$openvpn_desc = $openvpn['description'];
128
							} else {
129
								$openvpn_desc = $openvpn['ipaddr'] . ":" . $openvpn['local_port'];
130
							}
131
							$input_errors[] = sprintf(gettext("This entry cannot be deleted because it is still referenced by OpenVPN %s %s."), $openvpn_type_text, $openvpn_desc);
132
							break;
133
						}
134
					}
135
				}
136
			}
137
		}
138
139 ff9f40d5 Renato Botelho
		if (is_ipaddrv6($a_vip[$_GET['id']]['subnet'])) {
140
			$is_ipv6 = true;
141 55705b33 Renato Botelho
			$subnet = gen_subnetv6($a_vip[$_GET['id']]['subnet'], $a_vip[$_GET['id']]['subnet_bits']);
142 ba47a890 Renato Botelho
			$if_subnet_bits = get_interface_subnetv6($a_vip[$_GET['id']]['interface']);
143
			$if_subnet = gen_subnetv6(get_interface_ipv6($a_vip[$_GET['id']]['interface']), $if_subnet_bits);
144 ff9f40d5 Renato Botelho
		} else {
145
			$is_ipv6 = false;
146 55705b33 Renato Botelho
			$subnet = gen_subnet($a_vip[$_GET['id']]['subnet'], $a_vip[$_GET['id']]['subnet_bits']);
147 ba47a890 Renato Botelho
			$if_subnet_bits = get_interface_subnet($a_vip[$_GET['id']]['interface']);
148
			$if_subnet = gen_subnet(get_interface_ip($a_vip[$_GET['id']]['interface']), $if_subnet_bits);
149 ff9f40d5 Renato Botelho
		}
150 55705b33 Renato Botelho
151
		$subnet .= "/" . $a_vip[$_GET['id']]['subnet_bits'];
152 ff9f40d5 Renato Botelho
		$if_subnet .= "/" . $if_subnet_bits;
153 55705b33 Renato Botelho
154 760b1df9 Phil Davis
		if (is_array($config['gateways']['gateway_item'])) {
155 55705b33 Renato Botelho
			foreach($config['gateways']['gateway_item'] as $gateway) {
156 760b1df9 Phil Davis
				if ($a_vip[$_GET['id']]['interface'] != $gateway['interface']) {
157 55705b33 Renato Botelho
					continue;
158 760b1df9 Phil Davis
				}
159
				if ($is_ipv6 && $gateway['ipprotocol'] == 'inet') {
160 55705b33 Renato Botelho
					continue;
161 760b1df9 Phil Davis
				}
162
				if (!$is_ipv6 && $gateway['ipprotocol'] == 'inet6') {
163 55705b33 Renato Botelho
					continue;
164 760b1df9 Phil Davis
				}
165
				if (ip_in_subnet($gateway['gateway'], $if_subnet)) {
166 ff9f40d5 Renato Botelho
					continue;
167 760b1df9 Phil Davis
				}
168 55705b33 Renato Botelho
169
				if (ip_in_subnet($gateway['gateway'], $subnet)) {
170
					$input_errors[] = gettext("This entry cannot be deleted because it is still referenced by at least one Gateway.");
171
					break;
172
				}
173
			}
174 760b1df9 Phil Davis
		}
175 55705b33 Renato Botelho
176 e8471084 Ermal
		if ($a_vip[$_GET['id']]['mode'] == "ipalias") {
177 a9fc108f PiBa-NL
			$subnet = gen_subnet($a_vip[$_GET['id']]['subnet'], $a_vip[$_GET['id']]['subnet_bits']) . "/" . $a_vip[$_GET['id']]['subnet_bits'];
178
			$found_if = false;
179 b030e035 Renato Botelho
			$found_carp = false;
180
			$found_other_alias = false;
181
182 760b1df9 Phil Davis
			if ($subnet == $if_subnet) {
183 a9fc108f PiBa-NL
				$found_if = true;
184 760b1df9 Phil Davis
			}
185
186 e19b7d1e Ermal
			$vipiface = $a_vip[$_GET['id']]['interface'];
187 b030e035 Renato Botelho
			foreach ($a_vip as $vip_id => $vip) {
188 760b1df9 Phil Davis
				if ($vip_id == $_GET['id']) {
189 b030e035 Renato Botelho
					continue;
190 760b1df9 Phil Davis
				}
191 b030e035 Renato Botelho
192 760b1df9 Phil Davis
				if ($vip['interface'] == $vipiface && ip_in_subnet($vip['subnet'], $subnet)) {
193
					if ($vip['mode'] == "carp") {
194 b030e035 Renato Botelho
						$found_carp = true;
195 760b1df9 Phil Davis
					} else if ($vip['mode'] == "ipalias") {
196 b030e035 Renato Botelho
						$found_other_alias = true;
197 760b1df9 Phil Davis
					}
198
				}
199 e19b7d1e Ermal
			}
200 b030e035 Renato Botelho
201 760b1df9 Phil Davis
			if ($found_carp === true && $found_other_alias === false && $found_if === false) {
202 b030e035 Renato Botelho
				$input_errors[] = gettext("This entry cannot be deleted because it is still referenced by a CARP IP with the description") . " {$vip['descr']}.";
203 760b1df9 Phil Davis
			}
204 5063f1df Ermal
		} else if ($a_vip[$_GET['id']]['mode'] == "carp") {
205
			$vipiface = "{$a_vip[$_GET['id']]['interface']}_vip{$a_vip[$_GET['id']]['vhid']}";
206
			foreach ($a_vip as $vip) {
207 760b1df9 Phil Davis
				if ($vipiface == $vip['interface'] && $vip['mode'] == "ipalias") {
208 5063f1df Ermal
					$input_errors[] = gettext("This entry cannot be deleted because it is still referenced by an IP alias entry with the description") . " {$vip['descr']}.";
209 760b1df9 Phil Davis
				}
210 5063f1df Ermal
			}
211 e19b7d1e Ermal
		}
212 760b1df9 Phil Davis
213 b0ae75c5 Bill Marquette
		if (!$input_errors) {
214 760b1df9 Phil Davis
			if (!session_id()) {
215 4111fcf5 Ermal
				session_start();
216 760b1df9 Phil Davis
			}
217 3a343d73 jim-p
			$user = getUserEntry($_SESSION['Username']);
218
			if (is_array($user) && userHasPrivilege($user, "user-config-readonly")) {
219
				header("Location: firewall_virtual_ip.php");
220
				exit;
221
			}
222 4111fcf5 Ermal
			session_commit();
223 3a343d73 jim-p
224 1ba7a81b Ermal Lu?i
			// Special case since every proxyarp vip is handled by the same daemon.
225
			if ($a_vip[$_GET['id']]['mode'] == "proxyarp") {
226 e8471084 Ermal
				$viface = $a_vip[$_GET['id']]['interface'];
227 1ba7a81b Ermal Lu?i
				unset($a_vip[$_GET['id']]);
228 e8471084 Ermal
				interface_proxyarp_configure($viface);
229 1ba7a81b Ermal Lu?i
			} else {
230
				interface_vip_bring_down($a_vip[$_GET['id']]);
231
				unset($a_vip[$_GET['id']]);
232
			}
233 760b1df9 Phil Davis
			if (count($config['virtualip']['vip']) == 0) {
234 ed65eb04 Ermal Lu?i
				unset($config['virtualip']['vip']);
235 760b1df9 Phil Davis
			}
236 b0ae75c5 Bill Marquette
			write_config();
237 406abd6e Rafael Lucas
			header("Location: firewall_virtual_ip.php");
238 b0ae75c5 Bill Marquette
			exit;
239
		}
240
	}
241 760b1df9 Phil Davis
} else if ($_GET['changes'] == "mods" && is_numericint($_GET['id'])) {
242 abcb2bed Ermal Lu?i
	$id = $_GET['id'];
243 760b1df9 Phil Davis
}
244 b0ae75c5 Bill Marquette
245 3e2a70d9 Rafael Lucas
$pgtitle = array(gettext("Firewall"),gettext("Virtual IP Addresses"));
246 b0ae75c5 Bill Marquette
include("head.inc");
247
248
?>
249
<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
250
<?php include("fbegin.inc"); ?>
251
<form action="firewall_virtual_ip.php" method="post">
252 760b1df9 Phil Davis
<?php
253
	if ($input_errors) {
254 b760a120 Scott Ullrich
		print_input_errors($input_errors);
255 760b1df9 Phil Davis
	} else if ($savemsg) {
256
		print_info_box($savemsg);
257
	} else if (is_subsystem_dirty('vip')) {
258 8cd558b6 ayvis
		print_info_box_np(gettext("The VIP configuration has been changed.")."<br />".gettext("You must apply the changes in order for them to take effect."));
259 760b1df9 Phil Davis
	}
260 b760a120 Scott Ullrich
?>
261 8cd558b6 ayvis
<br />
262 3bfe618a Colin Fleming
<table width="100%" border="0" cellpadding="0" cellspacing="0" summary="virtual ip">
263 760b1df9 Phil Davis
	<tr><td class="tabnavtbl">
264
	<?php
265
		/* active tabs */
266
		$tab_array = array();
267
		$tab_array[] = array(gettext("Virtual IPs"), true, "firewall_virtual_ip.php");
268
		$tab_array[] = array(gettext("CARP Settings"), false, "system_hasync.php");
269
		display_top_tabs($tab_array);
270
	?>
271
	</td></tr>
272
	<tr>
273
		<td><input type="hidden" id="id" name="id" value="<?php echo htmlspecialchars($id); ?>" /></td>
274
	</tr>
275
	<tr>
276
		<td>
277
			<div id="mainarea">
278
				<table class="tabcont sortable" width="100%" border="0" cellpadding="0" cellspacing="0" summary="main area">
279
					<tr>
280
						<td width="30%" class="listhdrr"><?=gettext("Virtual IP address");?></td>
281
						<td width="10%" class="listhdrr"><?=gettext("Interface");?></td>
282
						<td width="10%" class="listhdrr"><?=gettext("Type");?></td>
283
						<td width="40%" class="listhdr"><?=gettext("Description");?></td>
284
						<td width="10%" class="list">
285
							<table border="0" cellspacing="0" cellpadding="1" summary="edit">
286
								<tr>
287
									<td width="17"></td>
288
									<td valign="middle"><a href="firewall_virtual_ip_edit.php"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" width="17" height="17" border="0" alt="edit" /></a></td>
289
								</tr>
290
							</table>
291
						</td>
292
					</tr>
293
					<?php
294
						$interfaces = get_configured_interface_with_descr(false, true);
295
						$carplist = get_configured_carp_interface_list();
296
						foreach ($carplist as $cif => $carpip) {
297
							$interfaces[$cif] = $carpip." (".get_vip_descr($carpip).")";
298
						}
299
						$interfaces['lo0'] = "Localhost";
300
						$i = 0;
301
						foreach ($a_vip as $vipent):
302
							if($vipent['subnet'] <> "" or $vipent['range'] <> "" or $vipent['subnet_bits'] <> "" or (isset($vipent['range']['from']) && $vipent['range']['from'] <> "")):
303
					?>
304
					<tr>
305
						<td class="listlr" ondblclick="document.location='firewall_virtual_ip_edit.php?id=<?=$i;?>';">
306
						<?php
307
							if (($vipent['type'] == "single") || ($vipent['type'] == "network")) {
308
								if($vipent['subnet_bits']) {
309 2db680e1 Scott Ullrich
									echo "{$vipent['subnet']}/{$vipent['subnet_bits']}";
310 760b1df9 Phil Davis
								}
311
							}
312
							if ($vipent['type'] == "range") {
313 b0ae75c5 Bill Marquette
								echo "{$vipent['range']['from']}-{$vipent['range']['to']}";
314 760b1df9 Phil Davis
							}
315
							if($vipent['mode'] == "carp") {
316
								echo " (vhid {$vipent['vhid']})";
317
							}
318
						?>
319
						</td>
320
						<td class="listr" ondblclick="document.location='firewall_virtual_ip_edit.php?id=<?=$i;?>';">
321
							<?=htmlspecialchars($interfaces[$vipent['interface']]);?>&nbsp;
322
						</td>
323
						<td class="listr" align="center" ondblclick="document.location='firewall_virtual_ip_edit.php?id=<?=$i;?>';">
324
							<?php if($vipent['mode'] == "proxyarp") echo "<img src='./themes/".$g['theme']."/images/icons/icon_parp.gif' title='Proxy ARP' alt='proxy arp' />"; elseif($vipent['mode'] == "carp") echo "<img src='./themes/".$g['theme']."/images/icons/icon_carp.gif' title='CARP' alt='carp' />"; elseif($vipent['mode'] == "other") echo "<img src='./themes/".$g['theme']."/images/icons/icon_other.gif' title='Other' alt='other' />"; elseif($vipent['mode'] == "ipalias") echo "<img src='./themes/".$g['theme']."/images/icons/icon_ifalias.gif' title='IP Alias' alt='ip alias' />";?>
325
						</td>
326
						<td class="listbg" ondblclick="document.location='firewall_virtual_ip_edit.php?id=<?=$i;?>';">
327
							<?=htmlspecialchars($vipent['descr']);?>&nbsp;
328
						</td>
329
						<td class="list nowrap">
330
							<table border="0" cellspacing="0" cellpadding="1" summary="icons">
331
								<tr>
332
									<td valign="middle"><a href="firewall_virtual_ip_edit.php?id=<?=$i;?>"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_e.gif" width="17" height="17" border="0" alt="edit" /></a></td>
333
									<td valign="middle"><a href="firewall_virtual_ip.php?act=del&amp;id=<?=$i;?>" onclick="return confirm('<?=gettext('Do you really want to delete this entry?');?>')"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" width="17" height="17" border="0" alt="delete" /></a></td>
334
								</tr>
335
							</table>
336
						</td>
337
					</tr>
338
					<?php
339
							endif;
340
							$i++;
341
						endforeach;
342 b0ae75c5 Bill Marquette
					?>
343 760b1df9 Phil Davis
				<tfoot>
344
					<tr>
345
						<td class="list" colspan="4"></td>
346
						<td class="list">
347
							<table border="0" cellspacing="0" cellpadding="1" summary="edit">
348
								<tr>
349
									<td width="17"></td>
350
									<td valign="middle"><a href="firewall_virtual_ip_edit.php"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" width="17" height="17" border="0" alt="edit" /></a></td>
351
								</tr>
352
							</table>
353
						</td>
354
					</tr>
355
					<tr>
356
						<td colspan="5">
357
							<p>
358
								<span class="vexpl"><span class="red"><strong><?=gettext("Note:");?><br /></strong></span>
359
								<?=gettext("The virtual IP addresses defined on this page may be used in");?><a href="firewall_nat.php"> <?=gettext("NAT"); ?> </a><?=gettext("mappings.");?><br />
360
								<?=gettext("You can check the status of your CARP Virtual IPs and interfaces ");?><a href="carp_status.php"><?=gettext("here");?></a>.</span>
361
							</p>
362
						</td>
363
					</tr>
364
				</tfoot>
365
				</table>
366
			</div><!-- div:mainarea -->
367
		</td>
368
	</tr>
369
</table>
370
</form>
371 b0ae75c5 Bill Marquette
<?php include("fend.inc"); ?>
372
</body>
373
</html>