Security:Nether

From Tizen Wiki
(Redirected from Security/Tizen 3.X Nether)
Jump to: navigation, search

Introduction

Nether is an application firewall for the Tizen 3.0 OS.

It can enforce the http://tizen.org/privilege/internet privilege on per application basis. Nether relies on Cynara as it's security policy backend, and can be dynamically reconfigured.

Basic data flow for nether is illustrated below:

Nether.jpg

Nether uses the libnetfilter_queue and the NETLINK interface to make it's decisions about packets, this mechanism is implemented in the kernel via the netfilter NFQUEUE module.

Additional patches required to get the security context information from the packets, have been sent and accepted in the mainstream (both kernel and netfilter).

Prerequisites

REQUIRED

Nether requires some specific kernel options to be set:

CONFIG_NETFILTER_XT_TARGET_NFQUEUE
CONFIG_NETFILTER_XT_MARK
CONFIG_NETWORK_SECMARK
CONFIG_IP_NF_TARGET_REJECT
CONFIG_NETFILTER_XT_TARGET_AUDIT

Theese options need to be enabled in the kernel, also the command iptables-restore needs to be available in the system for setting the correct rules by nether on start.

The only required libaray for nether is the libnetfilter_queue package and it's development headers and libraries. The source package is availabe on the netfilter page: http://www.netfilter.org/projects/libnetfilter_queue/index.html

OPTIONAL

- Cynara - if any of the policy backends is to be the Cynara backend, the development packages for cynara need to be installed (cynara-client-async)

- libsystemd-journal - if you want nether to log errors and warning into the system journal, you need this library, otherwise the only available logging backends will be FILE, SYSLOG, STDERR

- audit - If you want nether to control auditing on/off when starting you need the development headers nad libraries (without those, you need to enable auditing on your own, so that the iptables AUDIT target works)

- boost - is optional for the logging backend

Build

Download the nether sources from github or tizen.org:

https://github.com/Samsung/nether.git
https://review.tizen.org/gerrit/p/platform/core/security/nether.git

Nether uses cmake for building. Just run cmake in the source directory, to specify the installation prefix set the CMAKE_INSTALL_PREFIX variable during cmake.

[root@localhost:~/nether]# cmake -DCMAKE_INSTALL_PREFIX=/usr .
-- The C compiler identification is GNU 4.9.0
-- The CXX compiler identification is GNU 4.9.0
-- Check for working C compiler: /bin/cc
-- Check for working C compiler: /bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /bin/c++
-- Check for working CXX compiler: /bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Found PkgConfig: /bin/pkg-config (found version "0.28") 
-- checking for module 'libnetfilter_queue'
--   found libnetfilter_queue, version 1.0.2
-- checking for module 'cynara-client-async'
--   found cynara-client-async, version 0.8.0
-- checking for module 'libsystemd-journal'
--   found libsystemd-journal, version 219
-- Could NOT find Boost
-- Installing config files
-- Configuring done
-- Generating done
-- Build files have been written to: /root/nether

Usage

Usage:nether [OPTIONS]

  -d,--daemon				Run as daemon in the background (default:no)
  -x,--no-rules				Don't load iptables rules on start (default:no)
  -c,--copy-packets			Copy entire packets, needed to read TCP/IP information (default:no)
  -I,--interface-info			Get interface info for every packet (default:no)
  -R,--relaxed				Run in relaxed mode, instrad of deny do ACCEPT_LOG(default:no)
  -l,--log=<backend>			Set logging backend STDERR,SYSLOG(default:stderr)
  -L,--log-args=<arguments>		Set logging backend arguments
  -V,--verdict=<verdict>		What verdict to cast when policy backend is not available
					ACCEPT,ALLOW_LOG,DENY (default:ALLOW_LOG)
  -p,--primary-backend=<module>		Primary policy backend
					CYNARA,FILE,NONE (defualt:cynara)
  -P,--primary-backend-args=<arguments>	Primary policy backend arguments
  -b,--backup-backend=<module>		Backup policy backend
					CYNARA,FILE,NONE (defualt:file)
  -B,--backup-backend-args=<arguments>	Backup policy backend arguments (default:/etc/nether/nether.policy)
  -q,--queue-num=<queue number>		NFQUEUE queue number to use for receiving packets (default:0)
  -m,--mark-deny=<mark>			Packet mark to use for DENY verdicts (default:3)
  -M,--mark-allow-log=<mark>		Packet mark to use for ALLOW_LOG verdicts (default:4)
  -a,--enable-audit			Enable the auditing subsystem (default: no)
  -r,--rules-path=<path>		Path to iptables rules file (default:/etc/nether/nether.rules)
  -i,--iptables-restore-path=<path>	Path to iptables-restore command (default:/usr/sbin/iptables-restore)
  -h,--help				show help information

Backend arguments:

cynara

(multiple parameters should be seperated with ';')

policy=<file> specifies a path to a file that defines cynara policy details, it can contain multiple privileges and special packet markings for them, this way you can can poke holes in your security policy.

cache-size=<number> size of the cynara cache to allocate (this unit is defined by cynara not by nether)

privname=<privilege> the name of the privilege to check in cynara, this is hard coded in nether but can be altered on the command line, this will only have affect in case a policy file is not defined, if a policy file exists the first privilege in that file is considered the default privilege

file

There is just one argument that is the path to the location of the policy file.

Details:

-x - by default nether loads iptables rules needed for nethet to catch packets it should make descisions about, the default set of rules can be found in CMAKE_INSTALL_PREFIX/etc/nether/nether.rules. Default rules catch first packets of each TCP/IP connection and ignore all traffic on the loopback interface. If you wish to change the default set of rules, edit this file. Or set the rules on your own and start nether with this option

-c - by default nether does not receive the entire network packet, it's not needed to get the meta information about a packet (UID/GID and the security context of each packet). But if you policy backend needs more information about the network specifc part of a packet, setting this option will provide TCP/IP information to the backend (destination and source interface if available, destination and source IP address, destination and source PORT if the protocol is TCP/UDP). This option is used to gain more performance if the policy backend does not require network information.

-I - same as -c but for network interface information

-R - this is a special mode where nether will work as usual (perform security checks against it's defined policy backends), but regardless of the response it will always ACCEPT all packets. This can be used for testing purposes.

-L - log backend arguments, the only backend that accepts options is the FILE backend, the option for it is the log file path.

-V - this is the fallback verdict that will be used in case ALL policy backends fail, or are unable to make decisions about a certain packet (due to lack of specific information or due to some type mismatch)

-p - set's the primary policy backend to use

-P - set's the primary backend args, currently two backends use this option The FILE backend uses this option for the file path where the policy is kept, by default this is set to ${CMAKE_INSTALL_DIR}/etc/nether/nether.policy The CYNARA backend uses this option to set the cache size that the client side will use, the size is in CYNARA specific units, the format is cache-size=NUM where NUM is the cache size, other options might appear in this field in the future

-b,-B - same as -p -P but for the backup policy backend

-q - This is the queue number that nether will accept packets from, the queue number is by default 0 and you can set it to a different number by editing your iptables rules. This number must match the queue number set by iptables.

-m,-M - iptables use theese values to mark packets as ACCEPT,DENY after nether made a decision about them. Those numbers must match the numbers set by iptables rules (by default they are 0x3 for DENY and 0x4 for ALLOW_LOG)

-a - if audit headers are available, nether will activate auditing on start

-r - the path to the default set of rules nether should apply on start, by default this is set to ${CMAKE_INSTALL_DIR}/etc/nether/nether.rules

-i - the path to the iptables-restore program, it's needed to set the initial nether rules. No api is provided by netfilter to set the rules. iptables-restore is a preferred way to restore rules in the system.

Poking holes in cynara policy

In order to exclude some traffic from the cynara policy, you can define custom privileges and paths they should take inside iptables. This is done by specifying a custom cynara.policy file with privilege|mark pairs. If a defined privilege gets a ALLOW response the packet that was beeing matched gets marked with the defined mark. Using the initial nether.rules you can add custom rules for those matched packets and do whatever you want with them.

There is one example debug privilege defined in the cynara.policy as an example, it doesn't do anything but if an application has this privilege and cynara returns ALLOW for it the traffic will pass. This means that an application does not need the default internet privilege. You can define as many privilege|mark pairs as you wish, all entries will be processed until at least one returns ALLOW, in case all return DENY the traffic will be blocked.

Performance analysis

Performance tests have been made using the Odroid U3 target with the TV image (latest image downloaded from download.tizen.org on 2015-10-06), build information below:

TZ_BUILD_RELEASE_NAME="Tizen3/TV"
TZ_BUILD_VERSION=3.0
TZ_BUILD_FULLVER=3.0.0

TZ_BUILD_PROFILE=tv
TZ_BUILD_PROJECT=Tizen:TV
TZ_BUILD_VENDOR=tizen
TZ_BUILD_REPO=arm-wayland
TZ_BUILD_ARCH=arm

TZ_BUILD_ID=tizen-tv_20151006.3
TZ_BUILD_DATE=20151006_083438
TZ_BUILD_TIME=08:34:38
TZ_BUILD_TS=1444120478

TZ_BUILD_URL=http://download.tizen.org
TZ_BUILD_SNAPSHOT_URL=${TZ_BUILD_URL}/snapshots/tizen/tv/
TZ_BUILD_DAILY_URL=${TZ_BUILD_URL}/releases/daily/tizen/tv/
TZ_BUILD_WEEKLY_URL=${TZ_BUILD_URL}/releases/weekly/tizen/tv/
TZ_BUILD_MILESTONE_URL=${TZ_BUILD_URL}/releases/milestone/tizen/tv/

TZ_BUILD_WITH_MESA=1
TZ_BUILD_WITH_WAYLAND=1
TZ_BUILD_WITH_RDP=1
TZ_BUILD_WITH_X=
TZ_BUILD_WITH_EMULATOR=

On the Odroid tests have been made with both the "ab" utility (part of the apache http package) and a special program written to test the preformance of the connect() function (included in the nether sources repository)

Test 1

Connections: 1000
Concurrency: 5
Security context: constant
Nether: disabled

Time taken for tests:   1.233 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      3539000 bytes
HTML transferred:       3297000 bytes
Requests per second:    811.21 [#/sec] (mean)
Time per request:       6.164 [ms] (mean)
Time per request:       1.233 [ms] (mean, across all concurrent requests)
Transfer rate:          2803.59 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        1    3   0.6      3       6
Processing:     2    3   0.7      3       6
Waiting:        0    3   0.4      3       4
Total:          4    6   0.9      6      10

Percentage of the requests served within a certain time (ms)
  50%      6
  66%      6
  75%      6
  80%      7
  90%      7
  95%      8
  98%      9
  99%      9
 100%     10 (longest request)

Test 2

Connections: 1000
Concurrency: 5
Security context: constant
Nether: enabled

Time taken for tests:   1.341 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      3539000 bytes
HTML transferred:       3297000 bytes
Requests per second:    745.56 [#/sec] (mean)
Time per request:       6.706 [ms] (mean)
Time per request:       1.341 [ms] (mean, across all concurrent requests)
Transfer rate:          2576.70 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        1    3   0.8      3       6
Processing:     2    4   1.0      3       7
Waiting:        0    3   0.7      3       6
Total:          4    7   1.1      6      10
WARNING: The median and mean for the processing time are not within a normal deviation
        These results are probably not that reliable.

Percentage of the requests served within a certain time (ms)
  50%      6
  66%      7
  75%      7
  80%      8
  90%      8
  95%      9
  98%      9
  99%      9
 100%     10 (longest request)
Test 3

Connections: 1000
Concurrency: 1
Security context: different on every connection
Nether: disabled

Average over 100 samples 0.7668 ms
Average over 100 samples 0.7633 ms
Average over 100 samples 0.7536 ms
Average over 100 samples 0.7315 ms
Average over 100 samples 0.7027 ms
Average over 100 samples 0.6853 ms
Average over 100 samples 0.7189 ms
Average over 100 samples 0.7951 ms
Average over 100 samples 0.7866 ms
Test 4

Connections: 1000
Concurrency: 1
Security context: different on every connection
Nether: enabled

Average over 100 samples 0.9053 ms
Average over 100 samples 0.8879 ms
Average over 100 samples 0.8953 ms
Average over 100 samples 0.8671 ms
Average over 100 samples 0.8127 ms
Average over 100 samples 0.7880 ms
Average over 100 samples 0.7862 ms
Average over 100 samples 0.7824 ms
Average over 100 samples 0.7410 ms
Test 5

Connections: 1000
Concurrency: 1
Security context: random on every connection
Nether: enabled

Average over 100 samples 0.8072 ms
Average over 100 samples 0.7964 ms
Average over 100 samples 0.8089 ms
Average over 100 samples 0.8191 ms
Average over 100 samples 0.8298 ms
Average over 100 samples 0.8230 ms
Average over 100 samples 0.8120 ms
Average over 100 samples 0.7999 ms
Average over 100 samples 0.7952 ms