Skip to content

Commit 00e3d6d

Browse files
committed
Services: Captive Portal: Administration - add "Allow inbound" option to select interfaces which may enter the zone, closes #7161
This may be practical if services in the zone should be accesible from outside the zone or when services need to pass a network which uses a captive portal (users which should be authenticated are in the same network as services need to traverse to reach the internet).
1 parent a86d6e0 commit 00e3d6d

File tree

4 files changed

+54
-1
lines changed

4 files changed

+54
-1
lines changed

src/opnsense/mvc/app/controllers/OPNsense/CaptivePortal/forms/dialogZone.xml

+9
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,15 @@
1717
<type>select_multiple</type>
1818
<help><![CDATA[Select interface(s) to enable for captive portal.]]></help>
1919
</field>
20+
<field>
21+
<id>zone.interfaces_inbound</id>
22+
<label>Allow inbound</label>
23+
<type>select_multiple</type>
24+
<help><![CDATA[
25+
Select interfaces from which to allow inbound (stateful) traffic. This can be convenient if the zone in question
26+
contains machines/servers which should be accessible from other networks attached to this firewall.
27+
]]></help>
28+
</field>
2029
<field>
2130
<id>zone.authservers</id>
2231
<label>Authenticate using</label>

src/opnsense/mvc/app/models/OPNsense/CaptivePortal/CaptivePortal.php

+32
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
namespace OPNsense\CaptivePortal;
3232

3333
use OPNsense\Base\BaseModel;
34+
use OPNsense\Base\Messages\Message;
3435

3536
/**
3637
* Class CaptivePortal
@@ -84,4 +85,35 @@ public function getTemplateByName($name)
8485
$newItem->fileid = uniqid();
8586
return $newItem;
8687
}
88+
/**
89+
* {@inheritdoc}
90+
*/
91+
public function performValidation($validateFullModel = false)
92+
{
93+
$messages = parent::performValidation($validateFullModel);
94+
// validate changed instances
95+
foreach ($this->zones->zone->iterateItems() as $zone) {
96+
if (!$validateFullModel && !$zone->isFieldChanged()) {
97+
continue;
98+
}
99+
$key = $zone->__reference;
100+
if (!empty((string)$zone->interfaces_inbound) && !empty((string)$zone->interfaces)) {
101+
$ifs_inbound = array_filter(explode(',', $zone->interfaces_inbound));
102+
$ifs = array_filter(explode(',', $zone->interfaces));
103+
$overlap = array_intersect($ifs_inbound, $ifs);
104+
if (!empty($overlap)) {
105+
$messages->appendMessage(
106+
new Message(
107+
sprintf(
108+
gettext("Inbound interfaces may not overlap with zone interfaces (%s)"),
109+
implode(',', $overlap)
110+
),
111+
$key . ".interfaces_inbound"
112+
)
113+
);
114+
}
115+
}
116+
}
117+
return $messages;
118+
}
87119
}

src/opnsense/mvc/app/models/OPNsense/CaptivePortal/CaptivePortal.xml

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<model>
22
<mount>//OPNsense/captiveportal</mount>
3-
<version>1.0.1</version>
3+
<version>1.0.2</version>
44
<description>Captive portal application model</description>
55
<items>
66
<zones>
@@ -25,6 +25,12 @@
2525
</filters>
2626
<ValidationMessage>At least one interface must be selected</ValidationMessage>
2727
</interfaces>
28+
<interfaces_inbound type="InterfaceField">
29+
<Multiple>Y</Multiple>
30+
<filters>
31+
<enable>/^(?!0).*$/</enable>
32+
</filters>
33+
</interfaces_inbound>
2834
<authservers type="AuthenticationServerField">
2935
<Multiple>Y</Multiple>
3036
</authservers>

src/opnsense/service/templates/OPNsense/IPFW/ipfw.conf

+6
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,12 @@ add {{loop.index + 1000}} skipto 60000 icmp from any to { 255.255.255.255 or me
116116
{# authenticated clients #}
117117
add {{3000 + item.zoneid|int }} skipto tablearg ip from table({{item.zoneid|int}}) to any via {{item.if}}
118118
add {{3000 + item.zoneid|int }} skipto tablearg ip from any to table({{item.zoneid|int}}) via {{item.if}}
119+
# Allowed traffic heading into this zone #
120+
{% if item.obj.interfaces_inbound|default('') != '' %}
121+
{% for inbound_if in item.obj.interfaces_inbound.split(',') if helpers.physical_interface(inbound_if)%}
122+
add {{3000 + item.zoneid|int }} skipto 60000 ip from any to any recv {{helpers.physical_interface(inbound_if)}} xmit {{item.if}} keep-state
123+
{% endfor %}
124+
{% endif %}
119125
{% endfor %}
120126

121127

0 commit comments

Comments
 (0)