This commit is contained in:
seth0r 2023-04-19 22:50:14 +02:00 committed by GitHub
commit 8f4d85851b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 172 additions and 0 deletions

View File

@ -0,0 +1,58 @@
Client Isolation Support
========================
Normally every client is a wireless network can communicate
with any other client in the network.
Client Isolation is a security feature which prevents
Client-to-Client communication.
There are two different modes to isolate traffic, which can be
selected by the ``mesh.isolate`` setting in the site or domain
configuration.
Full Client Isolation Mode
--------------------------
In the full isolation mode all traffic between wireless and
wired clients is prevented. The Clients are only able to access
the Gateway and the Internet.
This mode may not be very useful in a Freifunk context.
It can be activated by setting ``mesh.isolate`` to ``all`` in the
site or domain configuration.
::
{
mesh = {
isolate = 'all'
},
-- more domain specific config follows below
}
Wireless Client Isolation Mode
------------------------------
In the wireless isolation mode only wireless clients are isolated
from other wireless clients. Communication where a wired client is
involved is not prevented. So every client can access any wired
client and every wired client can access all of the clients, only
wireless clients can not access other wireless clients.
This mode may be more useful in a Freifunk context, but is still
not as ``frei`` as without any isolation.
It can be activated by setting ``mesh.isolate`` to ``wireless``
in the site or domain configuration.
::
{
mesh = {
isolate = 'wireless'
},
-- more domain specific config follows below
}

View File

@ -31,6 +31,7 @@ Several Freifunk communities in Germany use Gluon as the foundation of their Fre
features/authorized-keys
features/roles
features/vpn
features/client-isolation
.. toctree::
:caption: Developer Documentation

View File

@ -0,0 +1,40 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=gluon-client-isolation
include ../gluon.mk
define Package/gluon-client-isolation
TITLE:=Support for client isolation over batman-adv
DEPENDS:=+gluon-core +gluon-ebtables gluon-mesh-batman-adv
endef
define Package/gluon-client-isolation/description
This package provides client isolation in a batman-adv
bridged layer 2 network.
To use it, mesh.isolate must be set in the site or
domain configuration.
When it is set to wireless, wireless clients are isolated from
other wireless clients, wireless to wired, wired to wireless
and wire to wired traffic is not affected in this mode.
When it is set to all, wired traffic is also isolated.
To isolate the clients connected to the same wireless interface,
it sets the isolate option in the wireless configuration for
the client and owe wifi interfaces.
To extend the isolation the ap_isolation and isolation_mark
options are set for the gluon_bat0 network interface.
A new filter chain ISOLATED is added to ebtables, through which
all traffic of br-client is routed.
Depending the value of mesh.isolate, the traffic is marked when
it arrives from the interfaces to isolate and batman-adv
restores the mark for isolated traffic from other nodes.
The marked traffic will not be forwarded to isolated interfaces.
endef
$(eval $(call BuildPackageGluon,gluon-client-isolation))

View File

@ -0,0 +1 @@
chain('ISOLATED', 'ACCEPT')

View File

@ -0,0 +1,12 @@
local isolate = require('gluon.site').mesh.isolate("none")
if isolate == "all" then
for _,dev in ipairs({ 'eth0', 'eth1', 'client0', 'client1', 'owe0', 'owe1' }) do
rule('ISOLATED -i ' .. dev .. ' -j mark --mark-or 0x10 --mark-target CONTINUE')
end
end
if isolate == "wireless" then
for _,dev in ipairs({ 'client0', 'client1', 'owe0', 'owe1' }) do
rule('ISOLATED -i ' .. dev .. ' -j mark --mark-or 0x10 --mark-target CONTINUE')
end
end

View File

@ -0,0 +1,12 @@
local isolate = require('gluon.site').mesh.isolate("none")
if isolate == "all" then
for _,dev in ipairs({ 'eth0', 'eth1', 'client0', 'client1', 'owe0', 'owe1' }) do
rule('ISOLATED -o ' .. dev .. ' --mark 0x10/0x10 -j DROP')
end
end
if isolate == "wireless" then
for _,dev in ipairs({ 'client0', 'client1', 'owe0', 'owe1' }) do
rule('ISOLATED -o ' .. dev .. ' --mark 0x10/0x10 -j DROP')
end
end

View File

@ -0,0 +1 @@
rule('FORWARD --logical-in br-client -j ISOLATED')

View File

@ -0,0 +1,38 @@
#!/usr/bin/lua
local site = require 'gluon.site'
local wireless = require 'gluon.wireless'
local isolate = site.mesh.isolate("none")
local uci = require('simple-uci').cursor()
wireless.foreach_radio(uci, function(radio)
local radio_name = radio['.name']
local vif = 'client_' .. radio_name
if uci:get('wireless', vif) then
uci:delete('wireless', vif, 'isolate')
if isolate == "all" or isolate == "wireless" then
uci:set('wireless', vif, 'isolate', '1')
end
end
vif = 'owe_' .. radio_name
if uci:get('wireless', vif) then
uci:delete('wireless', vif, 'isolate')
if isolate == "all" or isolate == "wireless" then
uci:set('wireless', vif, 'isolate', '1')
end
end
end)
uci:save('wireless')
uci:delete('network', 'gluon_bat0', 'ap_isolation')
uci:delete('network', 'gluon_bat0', 'isolation_mark')
if isolate == "all" or isolate == "wireless" then
uci:set('network', 'gluon_bat0', 'ap_isolation', '1')
uci:set('network', 'gluon_bat0', 'isolation_mark', '0x10/0x10')
end
uci:save('network')

View File

@ -10,6 +10,8 @@ proto_gluon_bat0_init_config() {
renew_handler=1
proto_config_add_string 'gw_mode'
proto_config_add_boolean 'ap_isolation:bool'
proto_config_add_string 'isolation_mark'
}
lookup_site() {
@ -40,7 +42,11 @@ proto_gluon_bat0_setup() {
local routing_algo="$(lookup_site 'mesh.batman_adv.routing_algo' 'BATMAN_IV')"
local gw_mode
local ap_isolation
local isolation_mark
json_get_vars gw_mode
json_get_vars ap_isolation
json_get_vars isolation_mark
batctl routing_algo "$routing_algo"
batctl interface create
@ -48,6 +54,9 @@ proto_gluon_bat0_setup() {
batctl orig_interval 5000
batctl hop_penalty "$(lookup_uci 'gluon.mesh_batman_adv.hop_penalty' 15)"
batctl noflood_mark 0x4/0x4
[ -n "$ap_isolation" ] && batctl ap_isolation "$ap_isolation"
[ -n "$isolation_mark" ] && batctl isolation_mark "$isolation_mark"
case "$gw_mode" in
server)