NanoSec policy scripts syntax
11 minute read
TrustCore SDK NanoSec policy scripts are text files created to configure IPsec policies and commands. Using these scripts is an easier alternative to manually building the required structures within an application and making calls to add the policies to the SPD.
Comments
Policy scripts can be commented by using the # character. All characters from the “#” to the end of the line are ignored. Multiple comments can be included in a script.
Constants
Constants can be defined to make policy entries easier to maintain and read.
To define constants, place them inside square brackets blocks in a script. Each constant definition consists of a case-sensitive name and an optional numeric value. If the value is not present, the name is associated with the value 0. For example:
[ZERO] # this declares a constant 'ZERO' with the value 0
Values can be specified as single numbers or as IP addresses in dotted decimal notation. For example, the following entry declares two constants: HOST1 (value = 172.0.0.1) and https (value = 8080).
[HOST1 172.0.0.1 https 8080]
The table below lists the predefined constants, which can be overridden by defining constants with the same name.
| Name | Value |
|---|---|
| telnet | 23 |
| http | 80 |
| localhost | 127.0.0.1 |
Multiple definition declarations can be included for any constant in a script, but the value must be identical in every declaration. For example:
[ https 8080 ]
[ https 8080 ] # OK
[ https 8081 ] # ERROR
Commands
Each NanoSec command entry in a script contains a single command, specified as follows:
<command>;
Syntax
The NanoSec command syntax is closely based on the Linux setkey command. The complete syntax of a NanoSec command script entry is:
command ::= <add> | flush | spdflush
add ::= add <src> <dst> <protocol> <spi> [<extensions>] <algorithm>
src ::= <address>
dst ::= <address>
address ::= <IPv4 dot notation>
protocol ::= esp | ah
spi ::= <security parameter index number; a decimal number,
or a hexadecimal number with a 0x prefix>
extensions ::= -m <mode>
mode ::= transport | tunnel | any
algorithm :== -A <auth_algname> <key> [-E <encr_algname> <key>]
auth_algname :== hmac-md5 | hmac-sha1 | aes-xcbc-mac | hmac-sha256 |\
hmac-sha384 | hmac-sha512
encr_algname :== aes-cbc | des-cbc | 3des-cbc | blowfish-cbc | aes-ctr
key ::= <double-quoted character string> |
<"0x" followed by a series of hexadecimal digits>
Examples
Use the following examples (from the Linux setkey man page) as models for entries:
# Clear all SADB entries (IPsec keys).
flush ;
# Clear all SPD entries (IPsec policies).
spdflush ;
# Add an SADB entry (IPsec key).
add 10.0.11.41 10.0.11.33 esp 0x10001 -m transport
-E des-cbc 0x3ffe05014819ffff
-A hmac-md5 "authentication!!" ;
Policies
Each NanoSec policy entry in a script contains three parts specified as follows:
{pattern} action {properties}
The pattern and properties parts are name-value pairs, where name and value are separated by a space, tab, or newline character. Multiple name-value pairs are separated by a space, tab, or newline character. The beginning and end of the pattern and properties identifiers are marked by { and }, respectively. An unspecified name-value pair in the pattern is treated as a wildcard entries that can match any corresponding entry in the datagram.
Syntax
The NanoSec policy entry syntax is closely based on the ipsecconf command-line tool from the Solaris 8 IPsec implementation. The complete syntax of a NanoSec policy entry is:
policy ::= { <pattern> } <action> { <properties> }
pattern ::= <pattern_name_value_pair>*
action ::= apply | permit | bypass | drop
properties ::= {<prop_name_value_pair>}
pattern_name_value_pair ::=
saddr <address>[/<prefix>] |
sport <port> |
daddr <address>[/<prefix>] |
dport <port> |
ulp <protocol> |
dir <dir_val> |
raddr <address>[/<prefix>] |
rport <port> |
laddr <address>[/<prefix>] |
lport <port>
address ::= <IPv4 dot notation> | <String of recognized host names, customizable by integration>
prefix ::= <number>
port ::= <number> | <String of recognized services, such as telnet, http>
protocol ::= <number> | <String of recognized protocols, such as tcp, udp, icmp>
dir_val ::= out | in | out_mirrored | in_mirrored | mirrored
prop_name_value_pair ::=
auth_algs <auth_alg> |
encr_algs <encr_alg> |
encr_auth_algs <auth_alg> |
tsrc <address> |
tdst <address> |
keylength <number> |
traddr <address> |
tladdr <address> |
lifetime_secs <number> |
lifetime_bytes <number> |
tag <number>
auth_alg ::= <auth_algname>
auth_algname ::= any | md5 | sha1 |
sha256 | sha384 | sha512 | blake2b | blake2s
encr_alg ::= <encr_algname>
encr_algname ::= any | aes | des | 3des | blowfish |
gcm | ccm | gmac | chacha20
number ::= < 0 | 1 | 2 ... 9> <number>
Pattern Name-Value Description
Policy entries may contain the following pairs in the pattern_name_value_pair field. Each pair may appear only once in a given policy entry. For the corresponding structure fields, refer to the struct ipsecConf definition in src/ipsec/ipsecconf.h.
The table below lists the values that can be used in pattern name-value pairs and their descriptions.
| Name-Value Pair | Description |
|---|---|
saddr/plen | The value that follows is the source address of the datagram with the prefix length. Only plen leading bits of the source address of the packet are matched. The plen value is optional; if not specified, 32 is used. The value pair is assigned to the dwSrcIP and dwSrcIPEnd fields in the ipsecConf structure. |
daddr/plen | The value that follows is the destination address of the datagram with the prefix length. Only plen leading bits of the destination address of the packet are matched. The plen value is optional; if not specified, 32 is used. The value pair is assigned to the dwDestIP and dwDestIPEnd fields in the ipsecConf structure. |
raddr/plen | The value that follows is either the source or destination address of the datagram with the prefix length. This value is on the right side of a mirrored pattern name entry. Only plen leading bits of the source address of the packet are matched. The plen value is optional; if not specified, 32 is used. Depending on the policy direction, the value pair is assigned to the dwSrcIP and dwSrcIPEnd fields or the dwDestIP and dwDestIPEnd fields in the ipsecConf structure. |
laddr/plen | The value that follows is either the source or destination address of the datagram with the prefix length. This value is on the left side of a mirrored pattern name entry. Only plen leading bits of the source address of the packet are matched. The plen value is optional; if not specified, 32 is used. Depending on the policy direction, the value pair is assigned to the dwSrcIP and dwSrcIPEnd fields or the dwDestIP and dwDestIPEnd fields in the ipsecConf structure. |
sport | The value that follows is the source port of the datagram. The value is assigned to the wSrcPort field in the ipsecConf structure. |
dport | The value that follows is the destination port of the datagram. The value is assigned to the wDestPort field in the ipsecConf structure. |
rport | The value that follows is either the source or destination port of the datagram. This value is on the right side of a mirrored pattern name entry. The value is assigned to the wSrcPort or wDestPort field (depending on the policy direction) in the ipsecConf structure. |
sa init | Start phase 2 negotiation as soon as the policy is loaded, regardless of whether there is traffic to send over the connection. A typical usage scenario for “sa init” is establishing a VPN tunnel, and therefore keys are ready to be exchanged before there is any traffic. |
lport | The value that follows is either the source or destination port of the datagram. This value is on the left side of a mirrored pattern name entry. The value is assigned to the wSrcPort or wDestPort field (depending on the policy direction) in the ipsecConf structure. |
ulp | The value that follows is the Upper Layer Protocol that this entry should be matched against. The value is assigned to the oProto field in the ipsecConf structure. Refer to src/ipsec/ipsec_protos.h for possible values. |
dir | Values following this specify whether this entry is for outbound or inbound datagram. The value is assigned to the oDir field in the ipsecConf structure. This entry is not needed when the action is “apply”, or “permit”. Valid values are the following strings from src/ipsec/ipsec_defs.h: out: Designates the policy entry for outbound datagrams only. in: Designates the policy entry for inbound datagrams only. out_mirrored: Same as out, except a mirrored policy entry is also created that matches datagrams in the opposite direction with the same addresses and ports. in_mirrored: Same as in, except a mirrored policy entry is also created. mirrored: Same as out_mirrored and in_mirrored. Should be used only when the action field value is apply or permit (not bypass or drop). |
Action Description
The action field is mandatory and comes between the pattern and properties. Its value is matched to oAction in struct ipsecConf. Valid values are:
ipsec
Mirrored apply and permit policies for datagrams described by the properties. Defining a mirrored policy is equivalent to defining separate apply and permit policies.
The use of the mirrored ipsec definition is strongly recommend overusing separate apply and permit definitions.
For example, if the following policy is defined:
{laddr HOST1 raddr HOST2 ulp icmp} ipsec {encr_algs any encr_auth_algs any}
Equivalent separate policies would be:
{saddr HOST1 daddr HOST2 ulp icmp} apply {encr_algs any encr_auth_algs any}
{saddr HOST2 daddr HOST1 ulp icmp} permit {encr_algs any encr_auth_algs any}
apply
Apply IPsec to the datagram as described by the properties, if the pattern matches the datagram. If apply is given, the pattern is matched only on the outbound datagram.
permit
Permit the datagram if the pattern matches the incoming datagram and satisfies the constraints described by the properties. If it does not satisfy the properties, discard the datagram. If permit is given, the pattern is matched only for inbound datagrams.
bypass
Bypass any policy checks if the pattern matches the datagram. The pattern’s dir value determines whether the check is done on outbound or inbound datagrams.
drop
Drop any packets that match the pattern. The pattern’s dir value determines whether the check for matches is performed on outbound or inbound datagrams.
Properties Name-Value Description
Policy entries may contain the following pairs in the prop_name_value_pair field. Each pair may appear only once in any policy entry. For the corresponding structure fields, refer to the struct sainfo definition in src/ipsec/ipsecconf.h.
The following rules are applied in the order given to determine encryption details; the value is assigned to the oSecuProto field in the sainfo structure:
- If the policy entry contains encr_algs but not encr_auth_algs, the IPsec SPD uses an ESP SA, regardless of whether the SA has an authentication algorithm.
- If the policy entry contains encr_auth_algs but not encr_algs, null encryption is provided, which is equivalent to encr_algs with NULL for outbound and inbound datagrams.
- If the policy entry contains both encr_algs and encr_auth_algs, the ESP header with an integrity checksum is present on outbound datagrams and the same is verified for inbound datagrams.
- If the policy entry contains auth_algs, the system uses an AH SA. If any of the above (that is, if either or both encr_algs and encr_auth_algs is present), ESP SA is also used. Then an SA bundle is used (that is, the oSaLen field in the ipsecConf structure is set to 2 - ESP), followed by AH.
The table below lists the name-values pairs that can be used in the policy entries and their descriptions.
Here’s the table with the consolidated rows for clear readability:
| Entry value | Description |
|---|---|
auth_algs | Values following this entry imply that the IPsec AH header is present and describe the authentication algorithms that are to be used. The valid values are: md5, aes, sha1, sha256, sha384, sha512, blake2b, blake2s, any. |
encr_algs | An acceptable value following this entry implies that the IPsec ESP header is present. The value following this entry describes the encryption algorithms that are to be used. Valid values are: des, 3des, aes, blowfish, gcm, gmac, ccm, chacha20-poly1305, any. |
encr_auth_algs | An acceptable value following this entry implies that the IPsec ESP header is present. The values following this entry describe the authentication algorithms that are to be used. Valid values are identical to those for auth_algs and include: md5, aes, sha1, sha256, sha384, sha512, blake2b, blake2s, any. If both encr_algs and encr_auth_algs are specified, encr_algs must not be set to ciphers that include the AEAD tag (i.e., only aes, des, 3des, or blowfish may then be specified for encr_algs). |
tdst | Specifies the destination IP address for tunneling mode and sets the oMode field in the ipsecConf structure. |
tsrc | Specifies the source IP address for tunneling mode and sets the oMode field in the ipsecConf structure. |
keylength | An acceptable value following this entry implies that the encryption algorithm identified by the encr_algs use the specified key length (in bytes). |
tag | The value (8, 12, 16) specifies the Integrity Check Value for GCM and CCM ciphers. |
tladdr | Specifies the IP address on the left side of a mirrored policy specification for tunneling mode and sets the oMode field in the ipsecConf structure. |
traddr | Specifies the IP address on the right side of a mirrored policy specification for tunneling mode and sets the oMode field in the ipsecConf structure. |
lifetime_secs | Values following this pair specify the lifetime duration of the child SA, in seconds. |
lifetime_bytes | Values following this pair specify the lifetime duration of the child SA, in bytes transported. |