Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added: ap_isolation option for bat0 #2714

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions docs/features/client-isolation.rst
Original file line number Diff line number Diff line change
@@ -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
}
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
40 changes: 40 additions & 0 deletions package/gluon-client-isolation/Makefile
Original file line number Diff line number Diff line change
@@ -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))
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
chain('ISOLATED', 'ACCEPT')
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
rule('FORWARD --logical-in br-client -j ISOLATED')
Original file line number Diff line number Diff line change
@@ -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')
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -40,14 +42,21 @@ 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

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)
Expand Down