Actions
Feature #13784
closedOption to completely block MAC addresses in Captive Portal
Added by Marcos M almost 2 years ago. Updated about 1 year ago.
Start date:
Due date:
% Done:
0%
Estimated time:
Plus Target Version:
Release Notes:
Default
Description
Currently, blocked MAC addresses are still able to access services on the firewall itself such as DNS and NTP. Add an optional action to completely block the MAC address.
Updated by Marcos M almost 2 years ago
- Status changed from New to Pull Request Review
https://gitlab.netgate.com/pfSense/pfSense/-/merge_requests/994
A new "reject" action is now available which retains the previous behavior, and the "block" action now blocks the MAC address entirely. Configuration upgrades will migrate the "block" action to "reject".
Updated by Jim Pingle almost 2 years ago
- Target version set to 2.7.0
- Plus Target Version set to 23.05
Updated by Jim Pingle over 1 year ago
- Plus Target Version changed from 23.05 to 23.09
Updated by Marcos M over 1 year ago
- Target version changed from 2.7.0 to CE-Next
Updated by Jim Pingle about 1 year ago
- Plus Target Version changed from 23.09 to 24.01
Updated by Marcos M about 1 year ago
- Status changed from Pull Request Review to Rejected
- Target version deleted (
CE-Next) - Plus Target Version deleted (
24.01)
Now that L2 filtering is possible in the GUI (see #14308), this is no longer needed. Below is the diff for this MR for future reference.
diff --git a/src/etc/inc/captiveportal.inc b/src/etc/inc/captiveportal.inc index 8fe88dc8b0..98f897ad12 100644 --- a/src/etc/inc/captiveportal.inc +++ b/src/etc/inc/captiveportal.inc @@ -1022,8 +1022,8 @@ function captiveportal_passthrumac_delete_entry($macent) { if (!empty($pipes)) { captiveportal_pipes_delete($pipes); } - } else { - /* no rules on passthru block */ + } elseif ($macent['action'] == 'reject') { + /* no rules on passthru reject */ return; } @@ -2358,7 +2358,7 @@ function captiveportal_write_usedmacs_db($usedmacs) { unlock($cpumaclck); } -function captiveportal_blocked_mac($mac) { +function captiveportal_rejected_mac($mac) { global $cpzone; if (empty($mac) || !is_macaddr($mac)) { @@ -2370,7 +2370,7 @@ function captiveportal_blocked_mac($mac) { } foreach (config_get_path("captiveportal/{$cpzone}/passthrumac", []) as $passthrumac) { - if (($passthrumac['action'] == 'block') && + if (($passthrumac['action'] == 'reject') && ($passthrumac['mac'] == strtolower($mac))) { return true; } @@ -2777,18 +2777,9 @@ function captiveportal_pipes_delete($pipes) { function captiveportal_ether_configure_entry($hostent, $anchor, $user_auth = false) { global $cpzone; - if (($hostent['action'] == 'block') && ($anchor == 'passthrumac')) { - return; - } - $cpzoneprefix = CPPREFIX . config_get_path("captiveportal/{$cpzone}/zoneid"); if ($anchor == 'passthrumac') { $tag = $cpzoneprefix . '_auth'; - } else { - $tag = $cpzoneprefix . '_' . $anchor; - } - - if ($anchor == 'passthrumac') { list($pipeup, $pipedown) = captiveportal_pipe_configure($hostent, 'pipe_mac', $user_auth); $host = str_replace("/", "_", str_replace(":", "", $hostent['mac'])); $l3from = ''; @@ -2796,6 +2787,7 @@ function captiveportal_ether_configure_entry($hostent, $anchor, $user_auth = fal $macfrom = "from {$hostent['mac']}"; $macto = "to {$hostent['mac']}"; } else { + $tag = $cpzoneprefix . '_' . $anchor; list($pipeup, $pipedown) = captiveportal_pipe_configure($hostent, 'auth', $user_auth); $host = $hostent['ip'] . '_32'; $l3from = "l3 from {$hostent['ip']}"; @@ -2813,8 +2805,16 @@ function captiveportal_ether_configure_entry($hostent, $anchor, $user_auth = fal } } - $rules = "ether pass in quick {$macfrom} {$l3from} tag {$tag} dnpipe {$pipeup}\n"; - $rules .= "ether pass out quick {$macto} {$l3to} tag {$tag} dnpipe {$pipedown}\n"; + if ($hostent['action'] == 'pass') { + $rules = "ether pass in quick {$macfrom} {$l3from} tag {$tag} dnpipe {$pipeup}\n"; + $rules .= "ether pass out quick {$macto} {$l3to} tag {$tag} dnpipe {$pipedown}\n"; + } elseif ($anchor == 'passthrumac' && ($hostent['action'] == 'block' && + !config_path_enabled("captiveportal/{$cpzone}", 'nomacfilter'))) { + $rules = "ether block in quick {$macfrom} l3 all\n"; + $rules .= "ether block out quick {$macto} l3 all\n"; + } else { + return; + } captiveportal_load_pfctl("{$cpzoneprefix}_{$anchor}", $host, $rules); } diff --git a/src/etc/inc/upgrade_config.inc b/src/etc/inc/upgrade_config.inc index 1d49d24c06..314fe862c1 100644 --- a/src/etc/inc/upgrade_config.inc +++ b/src/etc/inc/upgrade_config.inc @@ -6680,6 +6680,18 @@ function upgrade_226_to_227() { function upgrade_227_to_228() { global $config; + /* Captive Portal blocked MAC addresses can now be fully blocked. + * The previous "block" behavior is now "reject". */ + if (is_array($config['captiveportal'])) { + foreach ($config['captiveportal'] as & $zone) { + foreach ($zone['passthrumac'] as & $emac) { + if (isset($emac['action']) && $emac['action'] == 'block') { + $emac['action'] = 'reject'; + } + } + } + } + $any_removed = false; /* We no longer support 3des, blowfish, cast128 or md5 and sha1 * authentication for IPSec. */ diff --git a/src/usr/local/captiveportal/index.php b/src/usr/local/captiveportal/index.php index f598e06d95..d6730012ee 100644 --- a/src/usr/local/captiveportal/index.php +++ b/src/usr/local/captiveportal/index.php @@ -178,15 +178,15 @@ if ($_POST['logout_id']) { header("Location: index.php?zone=" . $cpzone); ob_flush(); return; -} elseif (($_POST['accept'] || $cpcfg['auth_method'] === 'radmac' || !empty($cpcfg['blockedmacsurl'])) && !isset($cpcfg['nomacfilter']) && $clientmac && captiveportal_blocked_mac($clientmac)) { - captiveportal_logportalauth($clientmac, $clientmac, $clientip, "Blocked MAC address"); - if (!empty($cpcfg['blockedmacsurl'])) { - portal_reply_page($cpcfg['blockedmacsurl'], "redir"); +} elseif (($_POST['accept'] || $cpcfg['auth_method'] === 'radmac' || !empty($cpcfg['rejectedmacsurl'])) && !isset($cpcfg['nomacfilter']) && $clientmac && captiveportal_rejected_mac($clientmac)) { + captiveportal_logportalauth($clientmac, $clientmac, $clientip, "Rejected MAC address"); + if (!empty($cpcfg['rejectedmacsurl'])) { + portal_reply_page($cpcfg['rejectedmacsurl'], "redir"); } else { if ($cpcfg['auth_method'] === 'radmac') { - echo gettext("This MAC address has been blocked"); + echo gettext("This MAC address has been rejected"); } else { - portal_reply_page($redirurl, "error", "This MAC address has been blocked", $clientmac, $clientip); + portal_reply_page($redirurl, "error", "This MAC address has been rejected", $clientmac, $clientip); } } } elseif (portal_consume_passthrough_credit($clientmac)) { diff --git a/src/usr/local/www/services_captiveportal.php b/src/usr/local/www/services_captiveportal.php index 8aaadab143..2de3e0ad1a 100644 --- a/src/usr/local/www/services_captiveportal.php +++ b/src/usr/local/www/services_captiveportal.php @@ -134,7 +134,7 @@ $pconfig['reauthenticateacct'] = config_get_path("captiveportal/{$cpzone}/reauth $pconfig['httpslogin_enable'] = config_path_enabled("captiveportal/{$cpzone}", 'httpslogin'); $pconfig['httpsname'] = config_get_path("captiveportal/{$cpzone}/httpsname"); $pconfig['preauthurl'] = strtolower(config_get_path("captiveportal/{$cpzone}/preauthurl")); -$pconfig['blockedmacsurl'] = strtolower(config_get_path("captiveportal/{$cpzone}/blockedmacsurl")); +$pconfig['rejectedmacsurl'] = strtolower(config_get_path("captiveportal/{$cpzone}/rejectedmacsurl")); $pconfig['certref'] = config_get_path("captiveportal/{$cpzone}/certref"); $pconfig['nohttpsforwards'] = config_path_enabled("captiveportal/{$cpzone}", 'nohttpsforwards'); $pconfig['logoutwin_enable'] = config_path_enabled("captiveportal/{$cpzone}", 'logoutwin_enable'); @@ -317,8 +317,8 @@ if ($_POST['save']) { if (!empty($_POST['redirurl']) && !is_URL($_POST['redirurl'])) { $input_errors[] = gettext("After authentication Redirection URL contents must be a valid URL"); } - if (!empty($_POST['blockedmacsurl']) && !is_URL($_POST['blockedmacsurl'])) { - $input_errors[] = gettext("Blocked MAC address redirect URL contents must be a valid URL"); + if (!empty($_POST['rejectedmacsurl']) && !is_URL($_POST['rejectedmacsurl'])) { + $input_errors[] = gettext("Rejected MAC address redirect URL contents must be a valid URL"); } if (!$input_errors) { @@ -374,7 +374,7 @@ if ($_POST['save']) { } $newcp['httpsname'] = $_POST['httpsname']; $newcp['preauthurl'] = $_POST['preauthurl']; - $newcp['blockedmacsurl'] = $_POST['blockedmacsurl']; + $newcp['rejectedmacsurl'] = $_POST['rejectedmacsurl']; if ((isset($newcp['nomacfilter']) ^ isset($_POST['nomacfilter'])) || (isset($newcp['peruserbw']) ^ isset($_POST['peruserbw'])) || (isset($newcp['bwdefaultdn']) && ($newcp['bwdefaultdn'] != $_POST['peruserbw'])) || @@ -661,11 +661,11 @@ $section->addInput(new Form_Input( ))->setHelp('Set a forced redirection URL. Clients will be redirected to this URL instead of the one they initially tried to access after they\'ve authenticated.'); $section->addInput(new Form_Input( - 'blockedmacsurl', - 'Blocked MAC address redirect URL', + 'rejectedmacsurl', + 'Rejected MAC address redirect URL', 'text', - $pconfig['blockedmacsurl'] -))->setHelp('Blocked MAC addresses will be redirected to this URL when attempting access.'); + $pconfig['rejectedmacsurl'] +))->setHelp('Rejected MAC addresses will be redirected to this URL when attempting access.'); if (captiveportal_xmlrpc_sync_get_details($tmpsyncip, $tmpport, $tmpusername, $tmppassword)) { $section->addInput(new Form_Checkbox( @@ -1235,7 +1235,7 @@ events.push(function() { hideCheckbox('logoutwin_enable', hide); hideInput('preauthurl', hide); hideInput('redirurl', hide); - hideInput('blockedmacsurl', hide); + hideInput('rejectedmacsurl', hide); hideInput('noconcurrentlogins', hide); hideCheckbox('preservedb', hide); hideCheckbox('preservedb_disabled', hide); diff --git a/src/usr/local/www/services_captiveportal_mac.php b/src/usr/local/www/services_captiveportal_mac.php index bc523c7bd6..600a8f6569 100644 --- a/src/usr/local/www/services_captiveportal_mac.php +++ b/src/usr/local/www/services_captiveportal_mac.php @@ -59,7 +59,8 @@ $pglinks = array("", "services_captiveportal_zones.php", "services_captiveportal $shortcut_section = "captiveportal"; $actsmbl = array('pass' => '<i class="fa fa-check text-success"></i> ' . gettext("Pass"), - 'block' => '<i class="fa fa-times text-danger"></i> ' . gettext("Block")); + 'block' => '<i class="fa fa-times text-danger"></i> ' . gettext("Block"), + 'reject' => '<i class="fa fa-hand-stop-o text-warning"></i> ' . gettext("Reject")); if ($_POST['act'] == "del") { if ($a_passthrumacs[$_POST['id']]) { diff --git a/src/usr/local/www/services_captiveportal_mac_edit.php b/src/usr/local/www/services_captiveportal_mac_edit.php index e26a7ce400..479c346e11 100644 --- a/src/usr/local/www/services_captiveportal_mac_edit.php +++ b/src/usr/local/www/services_captiveportal_mac_edit.php @@ -201,8 +201,9 @@ $section->addInput(new Form_Select( 'action', '*Action', strtolower($pconfig['action']), - array('pass' => gettext('Pass'), 'block' => gettext('Block')) -))->setHelp('Choose what to do with packets coming from this MAC address.'); + array('pass' => gettext('Pass'), 'block' => gettext('Block'), 'reject' => gettext('Reject')) +))->setHelp('Choose what to do with packets coming from this MAC address. The "Reject" action allows ' . + 'access to the Captive Portal and denies access when attempting to authenticate.'); $macaddress = new Form_Input( 'mac',
Actions