Connman firewall configuration in general
*****************************************
In general the firewall configuration in connman works as follows:
- Rules are loaded as general, mangle, tethering and service type specific
rules
- Rules are applied only for iptables filter and mangle tables
- Rules are added using managed chains only, no chain management with configs
- Rules are applied to connman-INPUT|FORWARD|OUTPUT chains
- For mangle table rules are applied also to connman-PREROUTING|POSTROUTING
chains
- Rules in General and Mangle sections are applied at start and removed at
shutdown
- Rules in tethering section are enabled/disabled when tethering is on/off
- Rules for service types are enabled/disabled when service goes online/offline
Connman firewall configuration file loading
===========================================
Connman supports firewall configurations for both general (permanent) settings
and for each connected service type. The rules in Mangle section are added to
mangle table only, all the rest are added to filter table. The main
configuration is always as CONFIGDIR/connman/firewall.conf and rest of the
configurations provided by packages or installed by user are searched from
CONFIGDIR/connman/firewall.d/. The configuration files must have *firewall.conf
suffix and the file names must not include other characters than letters or
numbers.
The configuration files from CONFIGDIR/connman/firewall.d/ are read in
alphabetical order after the main CONFIGDIR/connman/firewall.conf is read. If
the file CONFIGDIR/connman/firewall.conf is omitted, then only the firewall
configurations from CONFIGDIR/connman/firewall.d/ are read.
When multiple different rule files are used the POLICY for specific chain is
used from the latest definition of that POLICY in configuration files. The rules
are are appended to the internal list of rules as they are read for both General
section and service & tethering sections. For an example of this refer to
Example1.
The section names in configuration files are case sensitive. Regular key file
format is used.
Connman firewall rule ordering
==============================
Rules from General section in firewall.conf are considered as base rules. These
are kept as last ones in the iptables list to allow exceptions on top of them.
The rules from firewall config files in CONFIGDIR/connman/firewall.d have their
rules from General section set up before the General section rules from
firewall.conf.
When a service that has dynamic rules in any configuration is connected the
rules are inserted on top of the managed chain when the service is in READY
state or tethering is enabled.
Reloading of configurations is half-way supported. Changes in existing files are
not detected as of now (TODO). To make ConnMan detect the changes restart is
required. Adding new or removing old configuration is supported with systemctl
reload command. In case a new config is added the rules are loaded in order to
the internal lists but are not set in correct order into iptables. In such case
service must be re-connected (e.g., WiFi) or ConnMan restarted (General and
Mangle rules) to get the order correct.
Keys in sections
================
The following keys are supported and the generic format is PROTOCOL.CHAIN.TYPE,
where:
- PROTOCOL = IP protocol, either IPv4 or IPv6
- CHAIN = iptables chain name, one of: INPUT, FORWARD, OUTPUT
- TYPE = the key type, RULES for setting rules and POLICY for setting policy
Content for each key must be defined on one line and only the first key in a
group is processed. If the group is any other than Mangle, the rules are added
to filter table.
The keys are:
IPv4.INPUT.RULES = #Rules set into IPv4 INPUT chain.
IPv4.OUTPUT.RULES = #Rules set into IPv4 OUTPUT chain.
IPv4.FORWARD.RULES = #Rules set into IPv4 FORWARD chain.
IPv4.INPUT.POLICY = #Default policy for INPUT chain.
IPv4.OUTPUT.POLICY = #Default policy for OUTPUT chain.
IPv4.FORWARD.POLICY = #Default policy for FORWARD chain.
IPv6.INPUT.RULES = #Rules set into IPv6 INPUT chain.
IPv6.OUTPUT.RULES = #Rules set into IPv6 OUTPUT chain.
IPv6.FORWARD.RULES = #Rules set into IPv6 FORWARD chain.
IPv6.INPUT.POLICY_IPv6 = #Default policy for IPv6 INPUT chain.
IPv6.OUTPUT.POLICY_IPv6 = #Default policy for IPv6 OUTPUT chain.
IPv6.FORWARD.POLICY_IPv6 = #Default policy for IPv6 FORWARD chain.
In addition to the above, in the group Mangle the following keys can be used:
IPv4.PREROUTING.RULES = #Rules set into IPv4 PREROUTING chain.
IPv4.POSTROUTING.RULES = #Rules set into IPv4 POSTROUTING chain.
IPv6.PREROUTING.RULES = #Rules set into IPv6 PREROUTING chain.
IPv6.POSTROUTING.RULES = #Rules set into IPv6 POSTROUTING chain.
RULES and POLICY processing differ from each other. RULES are appended to the
rule list of the section in reading order. But the last POLICY in configuration
files (only allowed in General section) overrules all previous POLICY keys set
for the CHAIN with given PROTOCOL.
Rule formatting and exceptions
==============================
Rules follow iptables rule format in general, with some notable exceptions, for
reference see:
https://www.frozentux.net/iptables-tutorial/iptables-tutorial.html
The most notable exceptions are:
1. -p protocol does NOT imply -m protocol. -p protocol only implies the
protocol in the IP header. So e.g. to add a http port opening, you MUST
use -m tcp:
"IPv4.INPUT.RULES = -p tcp -m tcp --dport 80 -j ACCEPT"
2. The order is stricter - if a match relies on a specific protocol, -p must
be specified before -m on the commandline.
3. No command abbrievations are allowed - it is not possible to use --dest as
short for --destination.
Rules are separated with semicolons (;). All rules for a key must be on one
line.
Used options in rules are checked for their appropriate input values, the
protocol and/or match values are checked as well. If option is not supported or
there are missing/invalid values the rule is ignored. Negations in rules are
supported as with iptables command.
Each rule:
- Must have one target (-j|--jump TARGET) or goto (-g|--goto) which is the
bare minimum of the rule
- E.g., to allow all traffic:
-j ACCEPT
- Can have 1 protocol selector (-p|--protocol protocol)
- E.g., to block all ICMP traffic:
-p icmp -j DROP
- Can have an address specifier for each of traffic directions:
--source/-s, --destination/-d
- E.g. to block all traffic to Google's public DNS servers:
-d 8.8.8.8 -d DROP
- Can have an interface switch for each directions in [General] section:
--in-interface/-i, --out-interface/-o
- Can have match speficiers (-m|--match match), restrictions apply per match.
- E.g., to allow one attempt per second:
-m limit --limit 1/s --limit-burst 1 -j ACCEPT
- Any match that requires a specific set of options must include them after
the -m match for the rule to be approved.
Rules can be commented out with hash tag (#) as first character. Commented rules
are simply ignored. For example:
[General]
IPv4.INPUT.RULES = #-p udp -m udp --dport 23 -j ACCEPT; -p udp -m udp --dport 24 -j ACCEPT
Will discard the first --dport 23 rule and use the second --dport 24 rule.
The targets (-j TARGET) are the same as with default iptables: ACCEPT, DROP,
REJECT, LOG and QUEUE.
Protocols (-p protocol) are the same as with iptables. One can use any protocol
name that is resolvable through /etc/protocols, or use numerical values
directly. As an exception, protocol names "icmpv6", "ipv6-mh", "mh" and "all"
are also allowed.
Following switches are disabled and if a rule contains any of them the rule will
be ignored:
- All chain modifiers are disabled: --append, -A, --delete, -D, --delete-chain,
-X, --flush, -F, --insert, -I, --new-chain, -N, --policy, -P, --rename-chain,
-E, --replace, -R, --zero, -Z
- Destination speficiers for DNAT are disabled: --to-destination,
--from-destination
- Fragment: -f, --fragment
- IP family options: --ipv4, -4, --ipv6, -6
- Interface specifiers are not allowed in tethering or service type sections:
--in-interface, -i, --out-interface, -o
- Any match that is not supported by syntax parser will make the rule invalid.
See the next section for a list of supported matches. Note that ipv6-specific
matches are not supported in ipv4 and vice-versa.
- Any match that is not supported by syntax parser is disabled. See next
section for a list of supported matches. Note that ipv6-specific matches
are not supported in ipv4 and vice-versa.
Match specific options
======================
Currently supported matches are:
- ah
- conntrack
- dccp
- ecn
- esp
- helper
- icmp
- icmp6, icmpv6, ipv6-icmp
- iprange
- limit
- mark
- mh
- multiport
- owner
- pkttype
- rpfilter
- sctp
- tcp
- ttl
- udp
For match-specific options, please see "iptables -m $match --help".
Port matches (--dport and/or --sport) are supported with -m protocol that
supports ports. These are:
- tcp
- udp
- dccp
- sctp
Only one --dport and only one --sport is allowed.
Multiport match requires a protocol that has ports. These are:
- tcp
- udp
- udplite
- dccp
- sctp
Multiport match supports only one option, either --sports, or --dports.
However, it is possible to use multiple -m multiport specifiers to match both
directions, e.g.:
-p tcp -m multiport --dports 80 -m multiport --sports 1024:65535 -j ACCEPT
General section [General]
=========================
General section contains the main static firewall rules. In this section both
RULES and POLICY types are allowed.
RULES are read from each General section and added in sequence. The last POLICY
that is defined for a CHAIN with given PROTOCOL overrules the previous
definitions.
Being static rules the interface specifiers (--in-interface, -i,
--out-interface, -o) are allowed in the General section.
Mangle section [Mangle]
=======================
Mangle section contains rules to be added into mangle table. In this section
only RULES are allowed.
RULES are read from each Mangle section and added in sequence. Changing
Policies is not supported.
Tethering section [tethering]
=============================
The tethering mode configuration is included as builtin feature. When tethering
is enabled a default rules to accept all traffic from the tethering adapter is
used. The rules for tethering can be added later on to be more restrictive.
Tethering rules are applied only for WiFi tethering, i.e., using a hotspot.
For usb tethering the default rules apply regardless of the [tethering] rules
configuration.
The tethering rules must be complete. If there is at least one rule set, no
default rules will be added as they would make these custom rules set in
[tethering] unnecessary by allowing all traffic. Only RULES can be defined in
tethering section.
For example of allowing only DNS and DHCP refer to Example2.
Service type sections
=====================
The service type section supports only RULES type keys. The rules defined in
the service type sections are enabled when a service of that given type becomes
READY or ONLINE and are disabled when the service becomes IDLE, DISCONNECT or
FAILURE.
When a rule is enabled, it will have the interface used by the service added
into the rule. For rules in chain INPUT the interface is added as incoming
interface (-i ). For rules in chains FORWARD and OUTPUT the interface
is added as outgoing interface (-o ).
The service types that are supported (defined by enum connman_service_type in
include/service.h):
- unknown
- system
- ethernet
- wifi
- bluetooth
- cellular
- gps
- vpn
- gadget
- p2p
Examples
========
Here are some examples regarding firewall config use.
Example1: Rule loading
======================
There is main config and three configs, which are processed in order:
1: base firewall.conf - has [General] rules and POLICY set
2: firewall.d/10-firewall.conf - has [wifi] rules
3: firewall.d/20-firewall.conf - has [General] rules
4: firewall.d/30-firewall.conf - has [wifi] and [General] rules
Rules in firewall at ConnMan start:
- Policy from 1
- Rules:
- Rules from 3 [General]
- Rules from 4 [General]
- Rules from 1 [General]
Rules in firewall after enabling WiFi
- Policy from 1
- Rules:
- Rules from 2 [wifi]
- Rules from 4 [wifi]
- Rules from 3 [General]
- Rules from 4 [General]
- Rules from 1 [General]
Example2: Tethering rules to allow only DHCP and DNS
====================================================
For example following rules could be enabled to allow only DHCP and
DNS, into, e.g., /etc/connman/firewall.d/42-tethering-firewall.conf
[tethering]
IPv4.INPUT.RULES = -p udp -m udp --dport 53 -j ACCEPT; -p tcp -m tcp --dport 53 -j ACCEPT; -p udp -m udp --dport 67 -j ACCEPT
IPv6.INPUT.RULES = -p udp -m udp --dport 53 -j ACCEPT; -p tcp -m tcp --dport 53 -j ACCEPT; -p udp -m udp --dport 67 -j ACCEPT