Hi,

Here is an rfc about supporting a personal firewall into conman. I
wanted to be clear in the proposal, therefore it's not so short, so take
a bit of time to read.

I tried to keep things simple for dbus api, and make it clear also on
how connman will manage netfilter so it does not become a mess (which is
really easy with iptables...).

Please comment,

Tomasz

---------------------------------------------------------------

Personal Firewall feature
-------------------------

Filtering strategy:
------------------

1 - blocking everything in input when connman starts
2 - Opening default core services ports (and user configured ones) when
service is requested to be connected,
    before it sets up its network. The interface which is in use by the
service should be the only one affected.
3 - closing default core services ports (and user configured ones) when
service is disconnected
4 - opening everything when connman exits

When starting, ConnMan will set some basic rules which, in order, will be:

Note: append and insert are important keywords here since append add the
rule back to the list,
      insert put it on top of the list.

1 - flush/delete/create a chain named 'CONNMAN'
2 - insert into CONNMAN a rule jump to DROP everything (whatever the
interface is)
3 - insert into CONNMAN a rule jump to ACCEPT everything on 'lo' interface
4 - append into INPUT a jump to CONNMAN.

As debugging purpose, it would be possible to ask connman to log the
dropped packet, then it would:

1 - flush/delete/create a chain named 'LOGDROP'
2 - append into LOGDROP a jump to LOG
3 - append into LOGDROP a jump to DROP
4 - in first step 2 'insert into CONNMAN a rule jump to DROP
everything', we should instead do:
    insert into CONNMAN a rule jump to LOGDROP everything

When exiting, it would delete the INPUT jump to CONNMAN, flush/delete
CONNMAN,
and if in debug: flush/delete LOGDROP too.

How to handle service's port opening:
------------------------------------

Note: nothing is told about managing both TCP/UDP ports together or
separately.
Let's discuss about that later.

We have to maintain 2 things
- default core services ports (applied to all services)
- user defined ports (managed per-service, can affect the default ports
to open)

Default core services port (dhcl, avahi...) are applied to all services,
should not be hardcoded,
nor configured through dbus. It would make sense to let the possibility to
configure that depending on the distribution via the profile file. When
packaging connman
it would provide such profile file with such entry:

(If profile file is not present, might be wise to insert some defaults
port in profile.c?)

------ snip ------
[default]
FilterOpenPorts = [a, b, k, m:n]
------ snip ------

Where m:n is a range of ports to be opened, a, b and k are unique port
to be opened.

Note: FilterOpenPorts is a quick proposal, let's figure out a better
name if necessary.

Every service, when instantiated, would inheritate such default setting.
And, when getting connected, would open these ports. And closing it when
getting disconnected.

User defined ports would be "as simple as" maintaining a FilterOpenPorts
Key for the service, if only
the user defines something different than the default list.
So to say, a service will never save the FilterOpenPorts key it got from
default,
unless it got modified (added/removed other ports).

For instance if service wifi_home_psk got some other ports opened by the
user:

------ snip ------
[default]
FilterOpenPorts = [a, b, k, m:n]

[wifi_home_psk]
Type = wifi
Name = home
FilterOpenPorts = [a, k, l, m:n, o, p:q]
(...)

[wifi_work_psk]
Type = wifi
Name = home
(...)
------ snip ------

>From DBus point of view we would have in service-api.txt:

------ snip ------
array{String} FilterOpenPorts [readwrite]
------ snip ------

A technical detail about this service ports to be opened: such port
would be open ONLY for the interface
which is used by this service. So setting put the filter rules for the
service would require that we get
the interface up first, so the service should be aware of which
interface it is working against.

Optional:

What about a "Filter" property on service, which is not going to be
saved (there is no point to save that,
which could lead to a security threat if the user forgot to set it back
to Enabled. So: no saving, always Enabled by default),
and set by default to Enabled, which could be turned Disabled only when
connected, through DBus.
Such property would then insert a rule that accepts everything. Such
rule would be removed if Filter gets back to Enabled.

In service-api.txt it could be:

------ snip ------
boolean Filter [readwrite]
------ snip ------

Here is what service will do when connecting:

1 - flush/delete/create a chain named 'SERVICE-ID'
(chain as the service's id, since we might have multiple service being
instantiated like a vpn etc...)
2 - append into SERVICE-ID a rule to jump to ACCEPT when it targets the
port P on the service's network interface
3 - repeat part 2 for all ports which needs to be opened
4 - insert into CONNMAN a rule to jump to SERVICE-ID

And what it will do while disconnecting:

1 - delete SERVICE-ID jump rule from CONNMAN
2 - flush/delete SERVICE-ID

Specific case when FilterOpenPorts get modified by the user (only when
service is connected):

1 - delete SERVICE-ID jump rule from CONNMAN
2 - flush SERVICE-ID
3 - re-append the rules like in connecting part 2-3
4 - like in connecting part 4

Implementation:
--------------

Here is the operation we should have in iptables.c:

1 - create a new chain
2 - flush a chain
3 - delete a chain
4 - append a rule
5 - insert a rule
6 - delete a rule

Current situation in iptables.c is that we don't get 3, 5 and 6. This
requires to be implemented.

This would probably represent most of the work. The rest is a matter of
implementing the strategy
seen previously so with the right helper functions in main.c and service.c

Questions:
---------

- Should we manage TCP/UDP ports together, or separately? (In such case
we might have:
        FilteOpenPorts.TCP
        FilteOpenPorts.UDP
  Or in the future only?

- This proposal only targets 'filter' table, not 'nat' which is already
maintained in connman,
  in tethering.
      Do we create dedicated chain too for tethering?
      What about port forwarding when tethering is enabled?
      (Imho this should be discussed as a future feature)

- What about private network: As a private network, we might want to
apply specific rules?
  (future stuff too here)

- Current proposal makes the assertion connman would be the only one to
manage netfilter.
  However, its chains makes possible for an external application (such
as FireStarter or whatever) to
  manage its own rules and not messing up connman rules unless it
flushes and deletes connman chains.
  Though it is up to the user to know what he is doing with such
external app, is it necessary to take
  into account such possibility in connman?
  Which means: is there a way to get notified that our chain and rules
got modified?


_______________________________________________
connman mailing list
[email protected]
http://lists.connman.net/listinfo/connman

Reply via email to