secnet(8) | System Manager's Manual | secnet(8) |
secnet - VPN router daemon
secnet [OPTIONS]
secnet allows virtual private networks to be constructed spanning multiple separate sites.
Sites negotiate with each other during key exchange in order to determine which cryptographic algorithms and other features – termed capabilities – they each support. Capabilities are assigned small integer numbers. In many cases, capability numbers can be assigned in the configuration file, as described below; but secnet's default assignments will often be satisfactory.
Capability numbers between 0 and 7 inclusive are reserved for local use: secnet will never make use of them without explicit configuration. This may be useful to migrate from one set of parameters for a particular cryptographic algorithm to different, incompatible, parameters for the same algorithm. Other capability numbers are assigned by default by various kinds of closures. See the descriptions below for details.
It is essential that a capability number mean the same thing to each of a pair of peers. It's possible to configure a site so that it uses different capability numbers for the same feature when it communicates with different peer sites, but this is likely to be more confusing than useful.
The default configuration file is /etc/secnet/secnet.conf. This can be overridden with the --config option.
The configuration file defines a dictionary (a mapping from keys to values) of configuration information for secnet. It is recursive in nature, i.e. values may themselves include dictionaries. Any node in the nested structure thus defined can be identified by a path, which is the sequence of keys necessary to reach it from the root, separated by "/" characters. See Paths below for how this is used.
Furthermore, when a key is looked up in a dictionary, if it cannot be found, it is sought in the parent dictionary, and so on back to the root. For instance, each site must contain the resolver key, but in a typical configuration there is no value in having different resolvers for each site. Therefore resolver is defined at the root and thus automatically incorporated into all sites.
Whitespace, including newlines, is ignored except to the extent that it bounds other symbols.
Comment begin with "#" and continues to the end of the line. Comments are ignored.
A file may be recursively included into the configuration file using a line of the form:
This is handled at a higher level than the main parser and so precludes the possibility of using the string include for any other purpose.
The configuration file contains one or more assigments. Each assignment is written:
i.e. the equals sign is optional. The semicolon is mandatory in all contexts.
Keys start with a letter or "_" and continue with any numbers of letters, digits, "_" and "-".
Each key is a list of one or more values, separated by commas. Possible values types are boolean, string, number, dictionary, path and closure evaluation.
Strings are contained within "double quotes". There is (currently) no escape syntax and no way to include quotes inside strings.
Example:
filename "/var/log/secnet";
Numbers are encoded in decimal and do not include a sign. Numbers must lie in the range 0 to 4294967295.
Example:
mtu 1400;
Dictionaries consist of one or more assignments, in the same syntax as given above, enclosed in "{" and "}".
Example:
system { userid "secnet"; pidfile "/var/run/secnet.pid"; };
Paths allow a key already defined in the configuration to be aliased.
Paths consist of a sequence of keys separated by "/". If the path starts with a "/" then it is an absolute path and the search starts at the root of the configuration. Otherwise it is a relative path and starts in the containing dictionary or in any of its parents, down to and including the root. If there is more than one match, the one furthest from the root "wins".
The value of a path is the list assigned to the key it refers to. Lists are flattened; for example if a key is defined as a list of two paths, and each of those refers to a list of two integers, the original key is therefore defined to be a list of four integers, not a list consisting of two lists.
It is not possible to refer to a later key using a path.
Example:
vpn { test { kakajou vpn-data/test/kakajou/kakajou; araminta vpn-data/test/araminta/araminta; deodand vpn-data/test/deodand/deodand; all-sites kakajou,araminta,deodand; }; }; all-sites vpn/test/all-sites;
Here, each of vpn/test/kakajou, vpn/test/araminta and vpn/test/deodand are defined as aliases to values defined elsewhere. vpn/tests/all-sites is defined as the list of all three of those values, and all-sites is then defined to be an alias for that.
The (single-element) paths false, no and nowise are predefined and refer to a boolean false value. Similarly true, yes and verily point at a boolean true value.
In all six cases, variants with just the first letter capitalized, and with all letters capitalized, are also provided.
Example:
random randomfile("/dev/urandom",no);
Closure evaluation uses the following syntax:
CLOSURE may be a path referring to a closure, or may itself be a closure evaluation.
ARGUMENTS is a list of zero or more values, separated by commas. As a shortcut, if the arguments consist of a single dictionary, the parentheses may be ommitted:
Example:
sites map(site, vpn/test/all-sites);
When a closure is evaluated it returns a value (a list, much as above) and may also have side effects (which may be immediate or may be deferred to some later phase of execution). A list of built-in closures is given below.
Two keys are mandatory. system must be a dictionary in which the following keys can be looked up:
sites should be a list of site closures; see the site documentation below. This defines the collection of tunnel endpoints that secnet will communicate with.
Recall the recursive lookup logic described in Overview above: if (for instance) log is defined in the top level dictionary but not in system, it will nevertheless be found when looked up in the latter.
secnet contains a collection of built-in closures with names (i.e. single-element paths) given below.
Most of them return anonymous closures of various types, which are described contextually.
adns(DICT) => resolver closure
A resolver closure is a means of converting hostnames into network addresses.
diffie-hellman(MODULUS, GENERATOR[, CHECK]) => dh closure
A dh closure defines a group to be used for key exchange.
logfile(DICT) => log closure
Valid keys in the DICT argument are:
A log closure is a means of saving log messages. See also syslog below.
makelist(DICT) => LIST
Returns the (flattened) list of values from the dictionary, discarding the keys.
map(CLOSURE, INPUT...) => LIST
Applies CLOSURE to all its additional input arguments and returns the resulting list.
md5 is a hash closure implementing the MD5 algorithm.
null-netlink(DICT) => netlink
closure
null-netlink(DICT) => pure closure
Valid keys in the DICT argument are:
If ptp-address is used then the result is a netlink closure. This can be used directly with the link key in the sites closure (see below).
If secnet-address is used then the result is a pure closure. This must be evaluated to yield a netlink closure, using a dictionary argument with the following keys:
A netlink closure is a virtual IP link, and is supplied to the link key of a site closure.
The netlink created by null-netlink has no connection to the host. See tun and userv-ipif below for more useful alternatives.
randomfile(FILENAME[, BLOCKING]) => randomsource closure
A randomsource closure is a source of random numbers.
readfile(PATH) => STRING
Read the contents of the file PATH (a string) and return it as a string.
eax-serpent(DICT) => transform closure
Valid keys in the DICT argument are:
A transform closure is a reversible means of transforming messages for transmission over a (presumably) insecure network. It is responsible for both confidentiality and integrity.
serpent256-cbc(DICT) => transform closure
This transform is deprecated as its security properties are poor; it should be specified only alongside a better transform such as eax-serpent.
Valid keys in the DICT argument are:
Note that this uses a big-endian variant of the Serpent block cipher (which is not compatible with most other Serpent implementations).
rsa-private(PATH[, CHECK]) => sigprivkey closure
rsa-public(KEY, MODULUS) => sigpubkey closure
sha1 is a hash closure implementing the SHA-1 algorithm.
site(DICT) => site closure
Valid keys in the DICT argument are:
A site closure defines one site to communicate with. secnet expects the (root) key site to be a list of site closures.
sysbuffer([SIZE[, OPTIONS]]) => buffer closure
A buffer closure is a means of buffering packets to send or that have been received.
syslog(DICT) => log closure
Valid keys in the DICT argument are:
See also logfile above.
tun(DICT) => netlink closure
tun(DICT) => pure closure
Valid keys in the DICT argument are those documented for null-netlink above, plus:
The ifconfig-type and route-type values determine how those commands are executed. If they are set to ioctl then low-level system calls are used directly instead of invoking the commands.
The netlink created by tun uses the tun device to communicate with the host kernel.
udp(DICT) => comm closure
Valid keys in the DICT argument are:
A comm closure is a means of sending and receiving messages via a network. It does not provide confidentiality, reliablity or availability.
userv-ipif(DICT) => netlink closure
userv-ipif(DICT) => pure closure
Valid keys in the DICT argument are those documented for null-netlink above, plus:
The netlink created by userv-ipif invokes the specified userv service with pipes connected to its standard input and output. It uses SLIP to communicate with the host kernel via these pipes.
userv(1)