Description Language for Security Policy and Topology

Overview

Policies

Network Objects

Service Definitions

Groups

Service Groups

Detailed description of network objects

The topology is built from networks and routers. A router and a network are connected by an interface. Networks may have any number of hosts, which are located inside the network.

Routers may be managed or unmanaged. For a managed router, NetSPoC generates access control lists which control what traffic can pass this router and what traffic is blocked. The whole topology is partitioned into different security domains by managed routers.

Special network objects called 'any' objects and 'every' objects may be defined which denote all network objects inside a security domain.

General syntax

All network objects and groups have a typed name like <type>:<name>.

<name> is build from one ore more alphanumerical characters together with hyphen and underscore. The current locale settings are used, i.e. accented characters are allowed for european locale settings.

<ip-adr> denotes an IP address. Currently NetSPoC handles IP v4 addresses n.n.n.n with 0 <= n <= 255

<interface_name> may contain any characters, even interspersed whitespace. Currently characters from [;,=] are not allowed, since we use them as delimiters.

<int> is an integer

Meta symbols in syntax definitions below:

Network Definition

Syntax

  network:<name> = {
     {{
         [ route_hint; ]
	 [ subnet_of = network:<name>; ]
         ip = <ip-adr>; mask = <ip-adr>;
	 <network NAT definition> *
         <host definition> *
     |
         unnumbered
     }}
  }

  <network NAT definition> ::=
         nat:<name> = { 
	  ip = <ip-adr>; 
	  [ mask = <ip-adr>; ] 
	  [ dynamic; ]
	  [ subnet_of = network:<name>; ] 
	 }

Host definition

Syntax

  <host definition> ::=
        host:<name> = {   
	 {{
	   ip = <ip-adr>, ...;
         |
           range = <ip-adr> - <ip-adr>;
	 }}
           <NAT definition> *
        }

  <NAT definition> ::=
        nat:<name> = { ip = <ip-adr>; }

Router definition

Syntax

  <router definition> ::=
  router:<name> = {
     {{
        managed [ = {{ full | secondary }} ] ;
        model = <name>;
	[ no_group_code; ]
	<interface definition> *
     |
        [ model = <name>; ]
        {{ <interface definition> | <short interface definition> }} *
     }}
  }

Interface definition

Syntax

  <interface definition> ::= 
    interface:<name> = {
         {{ ip = <ip-adr>, ...; | unnumbered; }}
         <NAT definition> *
         [ <NAT binding> ]
	 [ virtual = <ip-adr> ]
         [ hardware = <interface_name>; ]
	 [ routing = {{ EIGRP | OSPF }}; ]
	 [ reroute_permit = network:<name>, ...; ]
         [ disabled ; ]
    }

  <short interface definition> ::=
    interface:<name>;
 
  <NAT definition> ::=
         nat:<name> = { ip = <ip-adr>; }
  <NAT binding> ::=
         nat = <name>;

'Every' object definition

Syntax

 every:<name> = { link = {{ network:<name>; | router:<name>; }} }

'Any' object definition

Syntax

 any:<name> = { link = {{ network:<name>; |  router:<name>; }} }

Referencing network objects

Syntax

 <network object> ::=
 {{
   host:<name> 
 | network:<name> 
 | interface:<name>.<name> 
 | interface:<name>.[auto]; 
 | interface:<name>.[all]; 
 | interface:[managed].[auto]; 
 | interface:[managed].[all]; 
 | interface:[all].[auto]; 
 | interface:[all].[all]; 
 | any:<name> 
 | any:[all]; 
 | any:[local];
 | every:<name>
 | group:<name> 
 }}

Groups of network objects

Syntax

 group:<name> = <network object list>;

with

 <network object list> :== <network object>, ...

Services

Syntax

 service:<name> = 
 {{
   ip 
 | tcp [<range> ->] <range>
 | udp [<range> ->] <range>
 | icmp [<int_1>[/<int_2>]] 
 | proto <int> 
 }} ;

with

 <range> ::= [<int_1>[-<int_2>]]

tcp, udp

icmp

protocol

Groups of services

Syntax

  servicegroup:<name> = <service list>;

with

  <service list> ::= <service>, ...
  <service> ::= {{ service:<name> | servicegroup:<name> }}

Policies

Syntax

  policy:<name> = {
     [ <description> ]
     user = <network object list>;
     <policy_rule> * 
  }

with

  <policy_rule> ::=
  {{ permit | deny }}
        src = <policy_object>;
        dst = <policy_object>;
        srv = <service list>;
  <policy_object> ::= {{ user | <network object list> }}
  <description> ::= description = any text up to end of line

Path restrictions

Syntax

 pathrestriction:<name> = 
  [ <description> ]
  <interface list> ;

  <interface list> ::= interface:<name>.<name>, ...
  <description> ::= description = any text up to end of line

Global NAT definition

Syntax

 nat:<name> = { 
 ip = <ip-adr>; 
 mask = <ip-adr>; 
 dynamic;
 [ subnet_of = network:<name>; ] 
}
A global NAT definition may be used as a shortcut for applying multiple identical dynamic NAT definitions to all networks in some area. See network address translation for details.

Network address translation (NAT)

Network address translation occurs at routers. At one side of a router, a network object is visible with its original IP address; at another side of the router this address is translated to another address.

Currently, NetSPoC supports static and dynamic NAT for whole networks.

For static NAT, the translated address uses the same netmask as the original network. The translation is automatically applied to all host and interface definitions of the translated network. A separate NAT definition for hosts or interfaces is not possible in this case.

For dynamic NAT, the translated address may use a different netmask than the original network. Typically a smaller network is used for translation. IP addresses are translated dynamically, hence hosts and interfaces of this network are not visible from outside. But a dynamic translation of a network may be augmented with static translations for single hosts or interfaces of this network.

Syntax for NAT is divided into two parts:

  1. A NAT definition denominates the alternate IP address of an network object.
  2. A NAT binding applies a set of NAT definitions to an interface.

Example

Network "extern" has bad IP addresses, which are not usable at network "intern". At router "r_ext" static NAT occurs. The NAT definition and NAT binding tells NetSPoC, that and where NAT occurs.
Hosts "extern_www" and "extern_mail" are visible with addresses 10.7.128.10 and 10.7.128.25 from "intern".
network:extern = {
 ip = 128.1.2.0; mask = 255.255.255.0;
 # static NAT definition
 nat:bad128 = { ip = 10.7.128.0; }
 host:extern_www = { ip = 128.1.2.10; }
 host:extern_mail = { ip = 128.1.2.25; }
}

router:r_ext = {
 interface:extern;
 interface:intern = {
  ip = 10.1.1.1;
  # NAT binding
  nat = bad128;
 }
}

network:intern = { ip = 10.1.1.0; mask = 255.255.255.0; }
All NAT definitions with the same name establish a set of NAT definitions. A set of NAT definition is effective behind that interface where the NAT binding with the same name occurs. We are defining behind an interface as that part of the topology which is seen when looking from the router to that interface.

Multiple NAT definitions may be given for a single network. These are bound to different interfaces to make different NAT definitions effective at different parts of the topology.

For dynamic NAT, multiple networks may use identical NAT definitions. This is used to masquerade multiple networks to a single address space.

A global NAT definition may be used as a shortcut for applying multiple identical dynamic NAT definitions to all networks located before that interface where the NAT binding with this name occurs.

NetSPoC needs to know about NAT for different reasons:

  1. When generating ACLs for an interface it must use those IP addresses which are visible in the area of this interface.
  2. The same is true when generating static routing entries.
  3. For some types of devices NetSPoC is able to actually generate the NAT translation rules. This is currently true for PIX firewalls.

Secondary packet filters

In a given topology we may get chains of managed packet filters on the path from src to dst. Each packet filter is a "full" packet filter by default, which does full filtering for each rule again and again.
A secondary packet filter has simpler rules for permitted traffic which gets further filtering by a full packet filter. In this case it allows any IP packets from the src network to the dst network. This simple filtering assures that the traffic comes from the right src and goes to the right dst.
A secondary packet filter is declared by the attribute "managed = secondary". This may be useful if a router has not enough memory for storing a complete set of filter rules and most of the packets get fully filtered already by some other managed device.

Routing

Static and dynamic routing

From its knowledge about the topology, NetSPoC generates static routing entries for each managed device. If an interface of a device has an attribute "routing=<routing protocol>", no static routing entries are generated for networks behind that interface.

Routing entries are only generated for network objects, which are used in some rule. I.e. no routing entries are generated for unused parts of the topology. Even for network objects which are only used as source of a rule, routing entries are generated, since stateful packet filters implicitly allow answer packets back to the source. If an 'any' object is used in a rule, routing entries for all networks part of this 'any' object are generated.

Default route

A default route may be defined for a topology by placing a network with IP address and mask equal 0.0.0.0. Such a network must have an attribute "route_hint".

Alternatively, NetSPoC can automatically define a default route for each managed device as a means to reduce the number of static routing entries.

Optimization

Multiple routing entries for networks which are in a subnet relation, are replaced by a single routing entry.

Rerouting inside of security domains

Internal traffic which flows inside a security domain isn't filtered at all. Sometimes an interface X of a managed (filtering) router is used as a default route for traffic which normally flows inside a security domain. This would cause internal traffic to be routed to X, which would deny this traffic.

NetSPoC is prepared to handle this case by defining an attribute 'reroute_permit' for a managed interface. Value of this attribute is a list of networks, for which any internal traffic should be allowed.

Example

router:x is managed, router:y is unmanaged.
router:x -- network:a -- router:y -- network:b

network:a and network:b are inside one security domain, since router:y isn't managed. If traffic from network:a to network:b is routed via router:x and router:y, router:x would deny this traffic. Use "reroute_permit = network:b" at "interface:x.a" to permit any incoming traffic to network:b.

Virtual IP addresses

A unique virtual IP address is defined at two or more interfaces, where a redundancy protocol like HSRP or VRRP is enabled.

Disabling part of the topology

An interface may be explicitly marked as disabled. This implicitly marks all network objects as disabled, that are lying behind this interface. We are defining behind an interface as that part of the topology which is seen when looking from the router to that interface. All occurrences of disabled network objects in groups and rules are silently discarded.

Handling of 'any' objects

The meaning of 'any' is different in a NetSPoC rule from that in an ACL. For NetSPoC, any:X means "any network object of the security domain where any:X is located". For an ACL which filters incoming traffic of an interface, any (i.e. 0.0.0.0/0.0.0.0) means "any network object beyond the interface where the ACL is applied to".

as source:
any data object connected directly or indirectly with this interface.
as destination:
any data object lying behind the router where the interface belongs to.

PIX security levels

PIX firewalls have a security level associated with each interface. We don't want to expand our syntax to state them explicitly, but instead we try to derive the level from the interface name:

It is not necessary the find the exact level; what we need to know is the relation of the security levels to each other.

Automatic deletion of redundant rules

Fully implemented, but documentation has to be done ...

Generated Code

Supported devices

Copyright (c) 2005, Heinz Knutzen heinzknutzen@users.berlios.de