| Validator Configuration File Format |
| =================================== |
| |
| You can set up a ``Validator`` via a configuration file. Next, we will |
| show you how to write a configuration file. |
| |
| The configuration file consists of **rules** and **trust-anchors** that |
| will be used in validation. **Rules** tell the validator how to validate |
| a packet, while **trust-anchors** tell the validator which certificates |
| are valid immediately. Here is an example of configuration file |
| containing two rules. |
| |
| :: |
| |
| rule |
| { |
| id "Simple Rule" |
| for data |
| filter |
| { |
| type name |
| name /localhost/example |
| relation is-prefix-of |
| } |
| checker |
| { |
| type customized |
| sig-type rsa-sha256 |
| key-locator |
| { |
| type name |
| name /ndn/edu/ucla/KEY/yingdi/ksk-1234/ID-CERT |
| relation equal |
| } |
| } |
| } |
| rule |
| { |
| id "Testbed Validation Rule" |
| for data |
| checker |
| { |
| type hierarchical |
| sig-type rsa-sha256 |
| } |
| } |
| trust-anchor |
| { |
| type file |
| file-name "testbed-trust-anchor.cert" |
| } |
| |
| - \ **ATTENTION: The order of rules MATTERS!**\ |
| |
| A rule can be broken into two parts: |
| |
| - The first part is to qualify packets to which the rule can be |
| applied; |
| - The second part is to check whether further validation process is |
| necessary. |
| |
| When receiving a packet, the validator will apply rules in the |
| configuration file one-by-one against the packet, until finding a rule |
| that the packet qualifies for. And the second part of the matched rule |
| will be used to check the validity of the packet. If the packet cannot |
| qualify for any rules, it is treated as an invalid packet. Once a packet |
| has been matched by a rule, the rest rules will not be applied against |
| the packet. Therefore, you should always put the most specific rule to |
| the top, otherwise it will become useless. |
| |
| In the example configuration, the first rule indicates that all the data |
| packets under the name prefix "/localhost/example" must be signed by a |
| key whose certificate name is |
| "/ndn/edu/ucla/KEY/yingdi/ksk-1234/ID-CERT". If a packet does not have a |
| name under prefix "/localhost/example", validator will skip the first |
| rule and apply the second rule. The second rule indicates that any data |
| packets must be validated along a hierarchy. And a certificate stored in |
| a file "testbed-trust-anchor.cert" is valid. |
| |
| Rules in general |
| ---------------- |
| |
| A rule has four types of properties: **id**, **for**, **filter**, and |
| **checker**. |
| |
| The property **id** uniquely identifies the rule in the configuration |
| file. As long as being unique, any name can be given to a rule, e.g., |
| "Simple Rule", "Testbed Validation Rule". A rule must have one and only |
| one **id** property. |
| |
| A rule is either used to validate an interest packet or a data packet. |
| This information is specified in the property **for**. Only two value |
| can be specified: **data** and **interest**. A rule must have one and |
| only one **for** property. |
| |
| The property **filter** further constrains the packets that can be |
| checked by the rule. Filter property is not required in a rule, in this |
| case, the rule will capture all the packets passed to it. A rule may |
| contain more than one filters, in this case, a packet can be checked by |
| a rule only if the packet satisfies all the filters. |
| |
| - \ **ATTENTION: A packet that satisfies all the filters may not be |
| valid**\ . |
| |
| The property **checker** defines the conditions that a matched packet |
| must fulfill to be treated as a valid packet. A rule must have at least |
| one **checker** property, a packet is treated as invalid if it cannot |
| pass none of the checkers. |
| |
| **filter** and **checker** have their own properties. Next, we will |
| introduce them separately. |
| |
| Filter Property |
| --------------- |
| |
| Filter has its own **type** property. Although a rule may contain more |
| than one filters, there is at most one filter of each type. So far, only |
| one type of filter is defined: **name**. In other word, only one filter |
| can be specified in a rule for now. |
| |
| Name Filter |
| ~~~~~~~~~~~ |
| |
| There are two ways to express the conditions on name. The first way is |
| to specify a relationship between the packet name and a particular name. |
| In this case, two more properties are required: **name** and |
| **relation**. A packet can fulfill the condition if the **name** has a |
| **relation\* to the packet name. Three types of **\ relation\*\* has |
| been defined: **equal**, **is-prefix-of**, **is-strict-prefix-of**. For |
| example, a filter |
| |
| :: |
| |
| filter |
| { |
| type name |
| name /localhost/example |
| relation equal |
| } |
| |
| shall only capture a packet with the exact name "/localhost/example". |
| And a filter |
| |
| :: |
| |
| filter |
| { |
| type name |
| name /localhost/example |
| relation is-prefix-of |
| } |
| |
| shall capture a packet with name "/localhost/example" or |
| "/localhost/example/data", but cannot catch a packet with name |
| "/localhost/another\_example". And a filter |
| |
| :: |
| |
| filter |
| { |
| type name |
| name /localhost/example |
| relation is-strict-prefix-of |
| } |
| |
| shall capture a packet with name "/localhost/example/data", but cannot |
| catch a packet with name "/localhost/example". |
| |
| The second way is to specify an [[Regex\|NDN Regular Expression]] that |
| can match the packet. In this case, only one property **regex** is |
| required. For example, a filter |
| |
| :: |
| |
| filter |
| { |
| type name |
| regex ^[^<KEY>]*<KEY><>*<ksk-.*><ID-CERT>$ |
| } |
| |
| shall capture all the identity certificates. |
| |
| Checker Property |
| ---------------- |
| |
| Passing all the filters in a rule only indicates that a packet can be |
| checked using the rule, and it does not necessarily implies that the |
| packet is valid. The validity of a packet is determined by the property |
| **checker**, which defines the conditions that a valid packet must |
| fulfill. |
| |
| Same as **filter**, **checker** has a property **type**. We have defined |
| three types of checkers: **customized**, and **hierarchical**, and |
| **fixed-signer**. As suggested by its name, **customized** checker |
| allows you to customize the conditions according to specific |
| requirements. **hierarchical** checker and **fixed-signer** checker are |
| pre-defined shortcuts, which specify specific trust models separately. |
| |
| Customized Checker |
| ~~~~~~~~~~~~~~~~~~ |
| |
| So far, we only allow three customized properties in a customized |
| checker: **sig-type**, **key-locator**. All of them are related to the |
| ``SignatureInfo`` of a packet. |
| |
| :: |
| |
| checker |
| { |
| type customized |
| sig-type ... |
| key-locator |
| { |
| ... |
| } |
| } |
| |
| The property **sig-type** specifies the acceptable signature type. Right |
| now two signature types have been defined: **rsa-sha256** (which is a |
| strong signature type) and **sha256** (which is a weak signature type). |
| If sig-type is sha256, then **key-locator** will be ignored. Validator |
| will simply calculate the digest of a packet and compare it with the one |
| in ``SignatureValue``. If sig-type is rsa-sha256, you have to further |
| customize the checker with **key-locator**. |
| |
| The property **key-locator** which specifies the conditions on |
| ``KeyLocator``. If the **key-locator** property is specified, it |
| requires the existence of the ``KeyLocator`` field in ``SignatureInfo``. |
| Although there are more than one types of ``KeyLocator`` defined in the |
| `Packet Format <http://named-data.net/doc/ndn-tlv/signature.html>`__, |
| **key-locator** property only supports one type: **name**: |
| |
| :: |
| |
| key-locator |
| { |
| type name |
| ... |
| } |
| |
| Such a key-locator property specifies the conditions on the certificate |
| name of the signing key. Since the conditions are about name, they can |
| be specified in the same way as the name filter. For example, a checker |
| could be: |
| |
| :: |
| |
| checker |
| { |
| type customized |
| sig-type rsa-sha256 |
| key-locator |
| { |
| type name |
| name /ndn/edu/ucla/KEY/yingdi/ksk-1234/ID-CERT |
| relation equal |
| } |
| } |
| |
| This checker property requires that the packet must have a rsa-sha256 |
| signature generated by a key whose certificate name is |
| "/ndn/edu/ucla/KEY/yingdi/ksk-1234/ID-CERT". |
| |
| Besides the two ways to express conditions on the ``KeyLocator`` name |
| (name and regex), you can further constrain the ``KeyLocator`` name |
| using the information extracted from the packet name. This third type of |
| condition is expressed via a property **hyper-relation**. The |
| **hyper-relation** property consists of three parts: |
| |
| - an NDN regular expression that can extract information from packet |
| name |
| - an NDN regular expression that can extract information from |
| ``KeyLocator`` name |
| - relation from the part extracted from ``KeyLocator`` name to the one |
| extracted from the packet name |
| |
| For example, a checker: |
| |
| :: |
| |
| checker |
| { |
| type customized |
| sig-type rsa-sha256 |
| key-locator |
| { |
| type name |
| hyper-relation |
| { |
| k-regex ^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>$ |
| k-expand \\1\\2 |
| h-relation is-prefix-of |
| p-regex ^(<>*)$ |
| p-expand \\1 |
| |
| } |
| } |
| } |
| |
| requires the packet name must be under the corresponding namespace of |
| the ``KeyLocator`` name. |
| |
| In some cases, you can even customize checker with another property For |
| example: |
| |
| :: |
| |
| checker |
| { |
| type customized |
| sig-type rsa-sha256 |
| key-locator |
| { |
| type name |
| hyper-relation |
| { |
| k-regex ^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>$ |
| k-expand \\1\\2 |
| h-relation is-prefix-of |
| p-regex ^(<>*)$ |
| p-expand \\1 |
| } |
| } |
| } |
| |
| Hierarchical Checker |
| ~~~~~~~~~~~~~~~~~~~~ |
| |
| As implied by its name, hierarchical checker requires that the packet |
| name must be under the namespace of the packet signer. A hierarchical |
| checker: |
| |
| :: |
| |
| checker |
| { |
| type hierarchical |
| sig-type rsa-sha256 |
| } |
| |
| is equivalent to a customized checker: |
| |
| :: |
| |
| checker |
| { |
| type customized |
| sig-type rsa-sha256 |
| key-locator |
| { |
| type name |
| hyper-relation |
| { |
| k-regex ^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>$ |
| k-expand \\1\\2 |
| h-relation is-prefix-of |
| p-regex ^(<>*)$ |
| p-expand \\1 |
| } |
| } |
| } |
| |
| Fixed-Signer Checker |
| ~~~~~~~~~~~~~~~~~~~~ |
| |
| In some cases, you only accept packets signed with pre-trusted |
| certificates, i.e. "one-step validation". Such a trust model can be |
| expressed with **fixed-signer** checker. And you only need to specify |
| the trusted certificate via property **signer**. The definition of |
| **signer** is the same as **trust-anchor**. For example: |
| |
| :: |
| |
| checker |
| { |
| type fixed-signer |
| sig-type rsa-sha256 |
| signer |
| { |
| type file |
| file-name "trusted-signer.cert" |
| } |
| signer |
| { |
| type base64 |
| base64-string "Bv0DGwdG...amHFvHIMDw==" |
| } |
| } |
| |
| Trust Anchors |
| ------------- |
| |
| Although **trust-anchor** is always not required in the configuration |
| file (for example, if fixed-signer checker is used), it is very common |
| to have a few trust-anchors in the configuration file, otherwise most |
| packets cannot be validated. A configuration file may contain more than |
| one trust anchors, but the order of trust anchors does not matter. The |
| structure of trust-anchor is same as the **signer** in fixed-signer |
| checker, for example: |
| |
| :: |
| |
| trust-anchor |
| { |
| type file |
| file-name "trusted-signer.cert" |
| } |
| trust-anchor |
| { |
| type base64 |
| base64-string "Bv0DGwdG...amHFvHIMDw==" |
| } |
| |
| You may also specify a trust-anchor directory. All certificates under this |
| directory are taken as trust anchors. For example, if all trust anchors are |
| put into ``/usr/local/etc/ndn/keys``. |
| |
| :: |
| |
| trust-anchor |
| { |
| type dir |
| file-name /usr/local/etc/ndn/keys |
| } |
| |
| If certificates under the directory might be changed during runtime, you can |
| set a refresh period, such as |
| |
| :: |
| |
| trust-anchor |
| { |
| type dir |
| file-name /usr/local/etc/ndn/keys |
| refresh 1h ; refresh certificates every hour, other units include m (for minutes) and s (for seconds) |
| } |
| |
| There is another special trust anchor **any**. |
| As long as such a trust-anchor is defined in config file, |
| packet validation will be turned off. |
| |
| - **ATTENTION: This type of trust anchor is dangerous. |
| You should used it only when you want to disable packet validation temporarily |
| (e.g, debugging code, building a demo).** |
| |
| :: |
| |
| trust-anchor |
| { |
| type any |
| } |
| |
| |
| Example Configuration For NLSR |
| ------------------------------ |
| |
| The trust model of NLSR is semi-hierarchical. An example certificate |
| signing hierarchy is: |
| |
| :: |
| |
| root |
| | |
| +--------------+---------------+ |
| site1 site2 |
| | | |
| +---------+---------+ + |
| operator1 operator2 operator3 |
| | | | |
| +-----+-----+ +----+-----+ +-----+-----+--------+ |
| router1 router2 router3 router4 router5 router6 router7 |
| | | | | | | | |
| + + + + + + + |
| NLSR NSLR NSLR NSLR NSLR NSLR NSLR |
| |
| However, entities name may not follow the signing hierarchy, for |
| example: |
| |
| +------------+-------------------------------------------------------------------------------------+ |
| | Entity | Identity name and examples | |
| +============+=====================================================================================+ |
| | root | ``/<network>`` | |
| | | | |
| | | Identity example: ``/ndn`` | |
| | | | |
| | | Certificate name example: ``/ndn/KEY/ksk-1/ID-CERT/%01`` | |
| +------------+-------------------------------------------------------------------------------------+ |
| | site | ``/<network>/<site>`` | |
| | | | |
| | | Identity example: ``/ndn/edu/ucla`` | |
| | | | |
| | | Certificate name example: ``/ndn/edu/ucla/KEY/ksk-2/ID-CERT/%01`` | |
| +------------+-------------------------------------------------------------------------------------+ |
| | operator | ``/<network>/<site>/%C1.O.N./<operator-id>`` | |
| | | | |
| | | Identity example: ``/ndn/edu/ucla/%C1.O.N./op1`` | |
| | | | |
| | | Certificate name example: ``/ndn/edu/ucla/%C1.O.N./op1/KEY/ksk-3/ID-CERT/%01`` | |
| +------------+-------------------------------------------------------------------------------------+ |
| | router | ``/<network>/<site>/%C1.O.R./<router-id>`` | |
| | | | |
| | | Identity example: ``/ndn/edu/ucla/%C1.O.R./rt1`` | |
| | | | |
| | | Certificate name example: ``/ndn/edu/ucla/%C1.O.R./rt1/KEY/ksk-4/ID-CERT/%01`` | |
| +------------+-------------------------------------------------------------------------------------+ |
| | NLSR | ``/<network>/<site>/%C1.O.R./<router-id>/NLSR`` | |
| | | | |
| | | Identity example: ``/ndn/edu/ucla/%C1.O.R./rt1/NLSR`` | |
| | | | |
| | | Certificate name example: ``/ndn/edu/ucla/%C1.O.R./rt1/NLSR/KEY/ksk-5/ID-CERT/%01`` | |
| +------------+-------------------------------------------------------------------------------------+ |
| |
| Assume that a typical NLSR data name is |
| ``/ndn/edu/ucla/%C1.O.R./rt1/NLSR/LSA/LSType.1/%01``. Then, the exception |
| of naming hierarchy is "operator-router". So we can write a |
| configuration file with three rules. The first one is a customized rule |
| that capture the normal NLSR data. The second one is a customized rule |
| that handles the exception case of the hierarchy (operator->router). And |
| the last one is a hierarchical rule that handles the normal cases of the |
| hierarchy. |
| |
| We put the NLSR data rule to the first place, because NLSR data packets |
| are the most frequently checked. The hierarchical exception rule is put |
| to the second, because it is more specific than the last one. |
| |
| And here is the configuration file: |
| |
| :: |
| |
| rule |
| { |
| id "NSLR LSA Rule" |
| for data |
| filter |
| { |
| type name |
| regex ^[^<NLSR><LSA>]*<NLSR><LSA> |
| } |
| checker |
| { |
| type customized |
| sig-type rsa-sha256 |
| key-locator |
| { |
| type name |
| hyper-relation |
| { |
| k-regex ^([^<KEY>]*)<KEY><ksk-.*><ID-CERT>$ |
| k-expand \\1 |
| h-relation equal |
| p-regex ^([^<NLSR><LSA>]*)<NLSR><LSA><LSType\.\d><>$ |
| p-expand \\1 |
| } |
| } |
| } |
| } |
| rule |
| { |
| id "NSLR Hierarchy Exception Rule" |
| for data |
| filter |
| { |
| type name |
| regex ^[^<KEY><%C1.O.R.>]*<%C1.O.R.><><KEY><ksk-.*><ID-CERT><>$ |
| } |
| checker |
| { |
| type customized |
| sig-type rsa-sha256 |
| key-locator |
| { |
| type name |
| hyper-relation |
| { |
| k-regex ^([^<KEY><%C1.O.N.>]*)<%C1.O.N.><><KEY><ksk-.*><ID-CERT>$ |
| k-expand \\1 |
| h-relation equal |
| p-regex ^([^<KEY><%C1.O.R.>]*)<%C1.O.R.><><KEY><ksk-.*><ID-CERT><>$ |
| p-expand \\1 |
| } |
| } |
| } |
| } |
| rule |
| { |
| id "NSLR Hierarchical Rule" |
| for data |
| filter |
| { |
| type name |
| regex ^[^<KEY>]*<KEY><ksk-.*><ID-CERT><>$ |
| } |
| checker |
| { |
| type hierarchical |
| sig-type rsa-sha256 |
| } |
| } |
| trust-anchor |
| { |
| type file |
| file-name "testbed-trust-anchor.cert" |
| } |
| |
| Example Configuration For NRD |
| ----------------------------- |
| |
| Assume NRD allows any valid testbed certificate to register prefix, the |
| configuration file could be written as: |
| |
| :: |
| |
| rule |
| { |
| id "NRD Prefix Registration Command Rule" |
| for interest |
| filter |
| { |
| type name |
| regex ^<localhost><nrd>[<register><unregister><advertise><withdraw>] |
| } |
| checker |
| { |
| type customized |
| sig-type rsa-sha256 |
| key-locator |
| { |
| type name |
| regex ^[^<KEY>]*<KEY><>*<ksk-.*><ID-CERT>$ |
| } |
| } |
| } |
| rule |
| { |
| id "Testbed Hierarchy Rule" |
| for data |
| filter |
| { |
| type name |
| regex ^[^<KEY>]*<KEY><>*<ksk-.*><ID-CERT><>$ |
| } |
| checker |
| { |
| type hierarchical |
| sig-type rsa-sha256 |
| } |
| } |
| trust-anchor |
| { |
| type file |
| file-name "testbed-trust-anchor.cert" |
| } |