Hi Darren and all,

As part of the Visual Panels project,

http://opensolaris.org/os/project/vpanels

we're proposing a generic firewall framework for Solaris. The framework utilizes IPfilter to provide a simple mechanism to configure a firewall on Solaris systems.

The firewall framework is functionally complete on which the Visual Panels project will provide a panel, a configuration UI. Attached is the current firewall framework design which I'm soliciting feedback by next Monday, August 25th.

Thanks in advance,
-tony
1. Introduction

   This document describes a framework that simplifies system and service
   firewall configuration. Currently, Solaris has IPfilter which allows user to
   set up system and service firewall policies.

   IPfilter uses a set of ipf rules from which it determines whether an IP
   packet should be allowed in or out of the system. Although ipf rule syntax
   is fairly simple and straightforward, it still demands good understanding of
   networking and security concepts, a non-trivial learning curve for 'casual'
   Solaris users. Moreover, the task of creating and testing ipf rules are
   mostly manual and can become a management burden in systems where large
   number of rules are used.

   The proposed framework aims to simplify user model by allowing users to
   express firewall policy at system and service level. Given the user defined
   firewall policy, the framework generates a set of IPfilter rules to enforce
   the desired system behavior. Users specify system and service firewall
   policies that allow or disallow network traffic from certain hosts, subnets,
   and interface(s). The policies can be translated into a set of active ipf
   rules to enforce the specified firewall policies.

   It's important to note the proposed framework isn't a full IPfilter
   configuration tool, thus it won't generate every possible IPfilter
   configuration. However, users can specified a custom ipf rule set to be used
   if the framework can't provide the desired IPfilter configuration.

2. Design

   Model:   The proposed firewall framework provides a simple mechanism to
   restrict incoming network traffic to a Solaris machine. Network traffic is
   normally from remote servers and clients to local clients and servers(local
   network services), respectively. Other types of network traffic include
   broadcasts and ICMP messages. The goal of any firewall is to block unwanted
   incoming network traffic and/or restrict access to certain source(s) while
   allow local client programs to work seamlessly.

   A three layer approach with different precedence levels helps us achieve the
   desired behaviors.

        Global Default - default system-wide policy. This policy is
        automatically inherited by all services unless services modify their
        firewall policy.

        Network Services - higher precedence than Global Default. A service's
        policy allows/disallows traffic to its specific ports, regardless of
        Global Default policy.

        Global Override - another system-wide policy that takes precedence over
        the needs of specific services in Network Services layer.

                Global Override
                      |
                      |
                Network Services
                      |
                      |
                Global Default

   A firewall policy includes a firewall mode and an optional set of network
   sources. Network sources are IP addresses, subnets, and local network
   interfaces, from which a system can receive incoming traffic. The basic set
   of firewall modes are:

        None - no firewall, allow all incoming traffic

        Allow All Except - allow all incoming traffic but deny traffic from
        specified source(s).

        Deny All Except  - deny all incoming traffic but allow from specified
        source(s)

   Layers in Detail:   The first system-wide layer, Global Default, defines a
   firewall policy that applies to *any* incoming traffic, e.g. allowing or
   blocking all traffic from an IP address. This makes it simple to have a
   policy that blocks all incoming traffic or all incoming traffic from
   unwanted source(s).

   The Network Services layer contains firewall policies for local programs
   that provide service to remote clients, e.g. telnetd, sshd, and httpd. Each
   of these programs, a network service, has its own firewall policy that
   controls access to its service. Initially, a service's policy is set to
   inherit Global Default policy, a "Use Global Default" mode. This makes it
   simple to set a single policy, at the Global Default layer, that can be
   inherited by all services. When a service's policy is different from Global
   Default policy, the service's policy has higher precedence.  If Global
   Default policy is set to block all traffic from a subnet, the SSH service
   could be configured to allow access from certain hosts in that subnet. The
   set of all policies for all network services comprises the Network Service
   layer.

   The second sytem-wide layer, Global Override, has a firewall policy that
   also applies to any incoming network traffic. This policy has highest
   precedence and overrides policies in other layers, specifically overriding
   the needs of network services. The example is when it's desirable block
   known malicious source(s) regardless of services' policies.

   User Interaction:   This framework leverages IPfilter functionality and is
   only active when svc:/network/ipfilter is enabled. Similarly, a network
   service's firewall policy is only active when that service is enabled. A
   system with an active firewall has IPfilter rules for each running/enabled
   network service and for system-wide policy(s) with firewall mode other than
   "None". User's enabling and disabling action for a service corresponds to
   firewall policy activation and deactivation for that service. A user changes
   firewall settings by modifying a service and/or system-wide firewall policy.

   At a high level, the firewall framework composes of policy configuration and
   a mechanism to generate ipfilter rules from the policy and applying those
   rules to get the desired IPfilter configuration. A quick summary of the
   design:

        - system-wide policy(s) are stored in network/ipfilter

        - network services' policies are stored in each SMF service

        - firewall is only activated when network/ipfilter is enabled.

        - enabling/disabling a network service activates/deactivates a
          service's firewall policy

        - changing a global or per-service firewall policy results in an update
          to the system's firewall rules

3. Configuration

   Customizable configuration:   Firewall policies comprising a mode and two
   lists of network sources, strings, are stored as SMF properties. A
   per-service firewall policy allows each SMF network service to store its
   policy as a property group. Thus, the Network Services layer is made up of
   all SMF network services and their corresponding firewall policies. A new
   per-service property group, firewall_config, is used to store its firewall
   policy. The system-wide policies, Global Default and Global Override, are
   stored as separate property groups, firewall_config and firewall_config_ovr,
   respectively, in svc:/network/ipfilter since this service controls firewall
   activation for the entire system.

   A policy is stored in a property group, firewall_config or
   firewall_config_ovr, with the following properties and values:

        policy -  "none", "allow_all_except", "deny_all_except"

        allow_except_list - a list of IP addresses and network interface names

        deny_except_list - similar to allow_except list property

        For individual services only:

                policy - can also be set to "use_global"

        For the Global Default only:

                policy - can also be set to "custom"

                custom_policy_file - if policy is "custom", a file path

                client{N} - protocol and port(s) tuple in the form
                "{tcp | udp}:{PORT | PORT-PORT}"

   "none" policy mode: no access restriction. For a global policy, this mode
   allows all incoming traffic. For a service policy, this mode allows all
   incoming traffic to its service.

   "allow_all_except" policy mode: more restrictive than "none". This mode
   allows incoming traffic from all sources except those specified in the
   "allow_except_list" property.

   "deny_all_except" policy mode: most restrictive mode. This mode blocks
   incoming traffic from all sources except those specified in the
   "deny_except_list" property.

   "allow_except_list" property: a multi-value property listing sources to be
   blocked when the policy is "allow_all_except". The syntax for possible
   values are:

        host:           host:IP                 "host:192.168.84.14"
        subnet:         network:IP/netmask      "network:129.168.1.5/24"
        interface:      if:interface_name       "if:e1000g0"

   "deny_except_list" property: a multi-value property listing sources that are
   allowed access when the policy is "deny_all_except". Possible values are the
   same as allow_all_except property.

   "use_global" policy mode: This mode is only valid for policies in Network
   Services layer. Services with "use_global" policy mode inherits the Global
   Default firewall policy.

   "custom" policy mode:   Users preferring to use a custom ipfilter
   configuration, e.g. existing ipfilter configuration or configurations that
   can't be provided by the framework can choose the custom policy. This Global
   Default only policy mode allows users to supply a text file containing the
   complete set of ipfilter rules. When "custom" mode is selected, the
   specified set of ipfilter rules is *complete* and the framework will not
   generate additional ipfilter rules. The Global Default policy property group
   has an additional custom_policy_file property to store the complete file
   path.

   "client" properties:   Only Global Default policy has these optional
   properties. A non-service client requiring allowance of its incoming traffic
   can request the firewall to allow traffic to its communication ports. This
   per client property contains value of the form

        "{tcp | udp}:{PORT | PORT-PORT}"

   The properties are stored in firewall_config property group in
   network/ipfilter.

   Initially, system-wide policies are set to "none" and network services'
   policies are set to "use_global". Enabling network/ipfilter activates the
   firewall with an empty set of ipfilter rules, since system-wide policy is
   "none" and all services inherit that policy. This behavior is compatible
   with prior systems when network/ipfilter is initially enabled. To configure
   a more restrictive policy, user needs to modify policy(s) for network
   services or a system-wide policy.

   Static configuration:   Network services may need additional information to
   help translate a firewall policy into IPfilter rules. Additionally, some
   services may require a mechanism to generate and supply their own rules to
   the framework. An optional per-service property group, firewall_context,
   provides the necessary service information and allows custom rule
   generation. The Implementation section will explain how these properties are
   consumed but brief definitions are provided here.

        - firewall_context/name, IANA name for non-inetd service, equivalent to
          inetd/name property 

        - firewall_context/isrpc, a boolean property where a "true" value
          indicates an RPC service, equivalent to inetd/isrpc property. This
          property adds contextual information for non-inetd RPC services but
          doesn't affect the meaning of firewall_context/name property.

        - firewall_context/ipf_method, a command, normally a script that
          generates ipf rules for a service. The framework does not generate
          rules for services with this property definition but expect these
          services to provide their own rules.

          A service's ipf_method specifies a command that takes an additional
          argument, its own fmri and generates the service's firewall rules and
          output the rules to stdout. To generate rules for a service with
          ipf_method property, the framework execs the command specified in
          ipf_method, passing the service fmri as the additional argument and
          stores the rules for that service by redirecting the command output,
          the rules, to the service's rule file. Because an ipf_method is
          exec'ed from the context of either network/ipfilter start or refresh
          method process, it inherits the execution context and runs as root.

4. Implementation

   The implementation consists of additions of SMF property groups to store
   firewall configuration, network/ipfilter modifications to activate,
   deactivate firewall settings, a new daemon to monitor and update per-service
   firewall setting, and a mechanism to generate ipfilter rules given a
   firewall policy.

   Configuration store:   The above Confguration section described in detail
   firewall policy and other information are stored as SMF property groups. 

   network/ipfilter:   The SMF network/ipfilter service drives the rule
   generation process as the firewall active and inactive states are directly
   tied to network/ipfilter service's enabled state. network/ipfilter start
   method is modified to read the system-wide firewall policies and each
   enabled service's firewall policy, generate and load all the rules. The
   refresh method also performs the same steps as a complete regeneration is
   necessary. The existing stop method disables IPfilter, unloading all the
   rules, doesn't need any modification.

   svc.ipfd: The above process sets up and tears down the entire system's
   firewall configuration.  However, it's necessary to be able to react to
   changes in the system's configuration and do so in an incremental fashion. A
   service's firewall policy is activated when it's enabled, deactivated when
   it's disabled, and updated when its configuration property group is
   modified.

   In order to configure the firewall for individual services, we need to know
   when a service is enabled or disabled, or when its configuration has changed
   and invoke the rule generation process to carry out the service's firewall
   policy. We will implement this by introducing a new deamon,
   /lib/svc/bin/svc.ipfd, that monitors the repository for relevant changes.
   This daemon is started by the network/ipfilter service.

   Rules Generation:   IPfilter rules generation uses the firewall policy to
   create the appropriate ipf rules that allow or disallow network packets from
   specified network source(s). The configuration the firewall framework
   permits the user to express can be mapped into a subset of the IPfilter
   language. Configuration in system-wide layers map to rules of the form:

        {block|pass} in from SOURCE to DESTINATION
        {block|pass} on INTERFACE to DESTINATION

   where DESTINATION is the local machine. Note that for system-wide layers, we
   do not specify a port. In contrast, a service's configuration will map to
   rules of the form:

        {block|pass} in from SOURCE to DESTINATION on port = PORT
        {block|pass} on INTERFACE to DESTINATION on port = PORT

   where PORT is the service's port. A firewall policy configuration is a set
   of block and pass rules on the same destination and (optionally) port.

   IPfiler rules are order sensitive so some planning is necessary to correctly
   implement a firewall policy. For a policy configuration, there is a primary
   rule to allow or deny all and zero or more exception rules to deny or allow
   specific source(s). The exception rules by definition will have higher
   priority. Thus, exception rules are always on top of primary rule and the
   "quick" keyword is added to tell IPfilter to take action on the first
   matched rule.

   To clarify the ordering discussion, let's see some examples of how rules can
   be generated from different policies.  The network service of interest is
   network/ssh whose sshd listens on port 22.

        - "None" or no firewall policy simply allows all incoming packets
          destined to port 22 with the rule

                "pass in log quick from any to any port = 22"

        - "Allow All Except" policy with the 1.2.3.4 address in the
          allow_except_list will generate the following rules:

                "block in log quick from 1.2.3.4 to any port = 22"
                "pass in log quick from any to any port = 22"

        - "Deny All Except" policy with the 1.2.3.4 address in the
          deny_except_list will generate the following rules:

                "pass in log quick from 1.2.3.4 to any port = 22"
                "block in log quick from any to any port = 22"

   The Global Default policy has a boilerplate rule

        pass out log quick all keep state

   which allows incoming traffic if communication session is locally initiated.
   This rule allows most client programs to carry out their communication and
   is generated when Global Default policy isn't "none".

   Starting the firewall:   Firewall activation is done by enabling
   network/ipfilter whose start method is modified to do the following:

        - create Global Default rules based on its firewall policy

        - create network services' rules for enabled services with firewall
          policy

        - create Global Override rules based on its firewall policy

        - load rules from Global Default, Network Services, and Global
          Override, in that order

   Since the start method sets up the system firewall configuration, it also
   configures the system firewall on boot and whenever network/ipfilter is
   refreshed.

   Partial update:   While the system is running, the set of IPfilter rules
   need to change as services get enabled or disabled, or when a policy is
   modified. We want to update the IPfilter rules without reloading all the
   rules. Network services are independent of each other so we can add and
   remove each service's rules as needed. Global Override rules are reloaded
   whenever there's an update to the rules in Network Services layer to
   maintain their highest priority in the system rule set.

   A change in system-wide policy will cause regeneration and reloading of
   rules from all three layers. While not the most efficient approach, this
   complete regeneration takes care of all policy inheritance and rule
   ordering. In practice, it's reasonable because most policy changes happen at
   the service policy level and system-wide policies are seldom changed.

   Each policy has its rules stored in a separate and temporary file whose
   content is loaded or unload by IPfilter to activate or deactivate the
   policy. An update to the policy requires unloading the stored rule(s) and
   regenerate and load the new rule(s).
   
   Continuing the network/ssh service example, let's say the user would like to
   add the IP address "1.2.3.10" to the deny_except_list, thus policy mode is
   "Deny All Except", the following steps will take place:

        - Global Override rules stored in its rule file are unloaded

        - Unloading service's current rules which are

                "pass in log quick from 1.2.3.4 to any port = 22"
                "block in quick from any to any port = 22"

        - Generating new rules 

                "pass in log quick from 1.2.3.10 to any port = 22"
                "pass in log quick from 1.2.3.4 to any port = 22"
                "block in quick from any to any port = 22"

        - service's updated rule set above is loaded to enforce its new policy

        - Global Override rules stored in its rule file are reloaded

   Complicated services:  Some services have rules that can't be generated by
   the proposed model and require another mechanism. network/ftp uses both port
   21 and 20 so its configuration will need rules that specify each port.
   Moreover, client programs such as nis/client, network/autofs, and
   network/ntp requires the system to allow their communication with remote
   servers when a system-wide policy is "Deny All Except".

   A service whose rules can't be generated by the framework can provide a
   script that generate its IPfilter rules and outputs the rules to stdout. The
   firewall_context/ipf_method property contains the script's path and
   argument, similar to SMF method properties. During rule generation, the
   service's script is invoked with the service FMRI as an additional argument
   and the expected output is redirected that service's rule file. The file can
   be loaded as if it were generated by the framework.

   Example: network/ftp and firewall_context/ipf_method

        - policy mode is "Deny All Except" with an empty except list

        - ipf_method is "firewall_context/ipf_method astring
          /lib/svc/method/svc-ftp\ ipfilter"

        - script is invoked as "/lib/svc/method/svc-ftp ipfilter
          network/ftp:default >>/var/run/ipfilter/ftp.ipf"

        - the resulting content of /var/run/ipfilter/ftp.ipf is 

                block in log quick proto tcp from any to any port = 21
                block in log quick proto tcp from any to any port = 20

   The example shows the 'script' defined as an SMF 'ipfilter' method, thus
   potentially small modification to existing service's method script.

   Example: network/ntp running as a client, ntp.conf specifies the server
   129.144.134.19 and multicastclient group 224.0.1.1. Its ipf_method script
   generates the following rules:

        pass in quick from 129.144.134.19 to any port = 123
        pass in log quick from any to 224.0.1.1

   Non-service client software:   We also need to allow non-SMF client programs
   such as BitTorrent & video conferencing peers/servers to carry out their
   communication, allowing incoming traffic to certain local ports. A
   firewall_config/client property value in the form
   "{tcp | udp}:{PORT | PORT-PORT}" can generate rules

        pass in quick proto {tcp | udp} from any to any port = PORT
        pass in quick proto {tcp | udp} from any to any port = port range

   which should be sufficient to support these client programs. 

   RPC services:   These services are problematic because they may use
   dynamically chosen ports and clients may also require access to rpbind,
   (network/rpc service). Initially, network/rpc and all RPC services inherit
   the same Global Default policy so there isn't a conflict. But if an RPC
   service's policy is modified, it is important to note the policy for
   network/rpc, unless it is less restrictive than the RPC service's, some
   clients may not be able to access the RPC service as intended.

   For a service, the value of inetd/isrpc or firewall_context/isrpc property,
   or the lack of those properties indicates whether a service is an RPC
   service. For RPC services, the framework queries rpcbind to get their port
   information.

5. Putting it all together

   Some simple but more complete examples to show the entire system firewall
   configuration and the interactions of IPfilter rules at all three layers.
   Each example building on previous examples, briefly describes the firewall
   policy(s) and show the resulting firewall configuration, rule set.

   Example 1 - Global Default policy is "None", all network services' policies
   are "use_global", and Global Override policy is "None". This is the initial
   configuration which corresponds to the initial empty ipf.conf file, thus an
   empty set of IPfilter rules.

   Example 2 - set a strict system-wide policy by changing Global Default
   policy to "Deny All Except". This policy generates rules for Global Default
   system-wide policy and any enabled network services. In this case, the only
   enabled network service is network/ssh which by default inherits Global
   Default policy. The resulting firewall configuration blocks all incoming
   traffic:

        block in log quick from any to any port = 22
        block in log quick from all

   Example 3 - resume normal operation for network/ssh by changing its policy
   to "Allow All Except" and enable network/ftp service. This new policy
   generates a different set of rules for network/ssh and network/ftp policy is
   activated. Below is the new firewall configuration with a less than useful
   network/ftp service since it doesn't allow any connection.

        block in log quick from any to any port = 20
        block in log quick from any to any port = 21
        pass in log quick from any to any port = 22
        block in log quick from all

   Example 4 - restrict network/ftp access to two IP addresses "10.253.195.57"
   and "10.253.195.60" by setting policy mode to "Deny All Except" and
   deny_except_list to contain the two IP address. This new policy generates
   set of rules for network/ftp and results in the below firewall configuration

        pass in log quick from 10.253.195.60 to any port = 21
        pass in log quick from 10.253.195.60 to any port = 20
        pass in log quick from 10.253.195.57 to any port = 21
        pass in log quick from 10.253.195.57 to any port = 20
        block in log quick from any to any port = 20
        block in log quick from any to any port = 21
        pass in log quick from any to any port = 22
        block in log quick from all

   Example 5 - a malicious host, "10.253.195.66", is discovered which no
   service should accept incoming traffic. This is accomplished by changing
   system-wide Global Override policy from "None" to "Allow All Except" and set
   its allow_all_except list to contain "10.253.195.66". The below new firewall
   configuration blocks all incoming packets from 10.253.195.66

        block in log quick from 10.253.195.66 to any
        pass in log quick from 10.253.195.60 to any port = 21
        pass in log quick from 10.253.195.60 to any port = 20
        pass in log quick from 10.253.195.57 to any port = 21
        pass in log quick from 10.253.195.57 to any port = 20
        block in log quick from any to any port = 20
        block in log quick from any to any port = 21
        pass in log quick from any to any port = 22
        block in log quick from all
_______________________________________________
networking-discuss mailing list
[email protected]

Reply via email to