| 1 | secnet - flexible VPN software |
| 2 | |
| 3 | * Copying |
| 4 | |
| 5 | secnet is Copyright (C) 1995--2003 Stephen Early <steve@greenend.org.uk> |
| 6 | It is distributed under the terms of the GNU General Public License, |
| 7 | version 2 or later. See the file COPYING for more information. |
| 8 | |
| 9 | The IP address handling library in ipaddr.py is Copyright (C) |
| 10 | 1996--2000 Cendio Systems AB, and is distributed under the terms of |
| 11 | the GPL. |
| 12 | |
| 13 | * Introduction |
| 14 | |
| 15 | secnet allows large virtual private networks to be constructed |
| 16 | spanning multiple separate sites. It is designed for the case where a |
| 17 | private network connecting many hosts is 'hidden' behind a single |
| 18 | globally-routable IP address, but can also be applied in other |
| 19 | circumstances. It communicates entirely using UDP, and works well |
| 20 | with gateways that implement network address translation. |
| 21 | |
| 22 | If you are installing secnet to join an existing VPN, you should read |
| 23 | the 'INSTALL' file and your particular VPN's documentation now. You |
| 24 | may need to refer back to this file for information on the netlink and |
| 25 | comm sections of the configuration file. |
| 26 | |
| 27 | If you are thinking about setting up a new VPN of any size (from one |
| 28 | providing complete links between multiple sites to a simple |
| 29 | laptop-to-host link), read the section in this file on 'Creating a |
| 30 | VPN'. |
| 31 | |
| 32 | * Mailing lists and bug reporting |
| 33 | |
| 34 | There are two mailing lists associated with secnet: an 'announce' list |
| 35 | and a 'discuss' list. Their addresses are: |
| 36 | http://www.chiark.greenend.org.uk/mailman/listinfo/secnet-announce |
| 37 | http://www.chiark.greenend.org.uk/mailman/listinfo/secnet-discuss |
| 38 | |
| 39 | The -announce list receives one message per secnet release. The |
| 40 | -discuss list is for general discussion, including help with |
| 41 | configuration, bug reports, feature requests, etc. |
| 42 | |
| 43 | Bug reports should be sent to <steve@greenend.org.uk>; they will be |
| 44 | forwarded to the -discuss list by me. |
| 45 | |
| 46 | * Creating a VPN |
| 47 | |
| 48 | XXX TODO |
| 49 | |
| 50 | * secnet configuration file format |
| 51 | |
| 52 | By default secnet on linux reads /etc/secnet/secnet.conf. The default |
| 53 | may be different on other platforms. |
| 54 | |
| 55 | This file defines a dictionary (a mapping from keys to values) full of |
| 56 | configuration information for secnet. Two keys must be defined in |
| 57 | this file for secnet to start. One is "system", a dictionary |
| 58 | containing systemwide control parameters. The other is "sites", a |
| 59 | list of all the sites that you intend to communicate with. |
| 60 | |
| 61 | The configuration file has a very simple syntax; keys are defined as |
| 62 | follows: |
| 63 | |
| 64 | key definition; |
| 65 | or |
| 66 | key = definition; |
| 67 | |
| 68 | (the "=" is optional) |
| 69 | |
| 70 | Keys must match the following regular expression: |
| 71 | [[:alpha:]_][[:alnum:]\-_]* |
| 72 | |
| 73 | i.e. the first character must be an alpha or an underscore, and the |
| 74 | remaining characters may be alphanumeric, '-' or '_'. |
| 75 | |
| 76 | Keys can be defined to be a comma-separated list of any of the |
| 77 | following types: |
| 78 | |
| 79 | a boolean |
| 80 | a string, in quotes |
| 81 | a number, in decimal |
| 82 | a dictionary of definitions, enclosed in { } |
| 83 | a "closure", followed by arguments |
| 84 | a path to a key that already exists, to reference that definition |
| 85 | |
| 86 | Note that dictionaries can be nested: a key in one dictionary can |
| 87 | refer to another dictionary. When secnet looks for a key in a |
| 88 | particular directory and can't find it, it looks in the dictionary's |
| 89 | lexical 'parents' in turn until it finds it (or fails to find it at |
| 90 | all and stops with an error). |
| 91 | |
| 92 | Definitions can refer to previous definitions by naming them with a |
| 93 | path. Paths are key1/key2/key3... (starting from wherever we find |
| 94 | key1, i.e. in the current dictionary or any of its parents), or |
| 95 | alternatively /key1/key2/key3... (to start from the root). |
| 96 | Definitions cannot refer to future definitions. |
| 97 | |
| 98 | Example: |
| 99 | |
| 100 | a=1; |
| 101 | b=2; |
| 102 | c={ d=3; e=a; }; |
| 103 | f={ a=4; g=c; }; |
| 104 | |
| 105 | The following paths are valid: |
| 106 | a is 1 |
| 107 | b is 2 |
| 108 | c is a dictionary: |
| 109 | c/d is 3 |
| 110 | c/e is 1 |
| 111 | f is a dictionary: |
| 112 | f/a is 4 |
| 113 | f/g is a dictionary: |
| 114 | f/g/d is 3 |
| 115 | f/g/e is 1 |
| 116 | |
| 117 | Note that f/g/e is NOT 4. |
| 118 | |
| 119 | Elements that are lists are inserted into lists in definitions, not |
| 120 | referenced by them (i.e. you can't have lists of lists). |
| 121 | |
| 122 | Some closures may be followed by an argument list in ( ), and may |
| 123 | return any number of whatever type they like (including other |
| 124 | closures). Some types of closure (typically those returned from |
| 125 | invokations of other closures) cannot be invoked. |
| 126 | |
| 127 | closure { definitions } is short for closure({definitions}). |
| 128 | |
| 129 | The main body of secnet, and all the additional modules, predefine |
| 130 | some keys in the root dictionary. The main ones are: |
| 131 | |
| 132 | yes, true, True, TRUE, on: the boolean value True |
| 133 | no, false, False, FALSE, off: the boolean value False |
| 134 | makelist: turns a dictionary (arg1) into a list of definitions |
| 135 | (ignoring the keys) |
| 136 | readfile: reads a file (arg1) and returns it as a string |
| 137 | map: applies the closure specified as arg1 to each of the |
| 138 | remaining elements in the list in turn. Returns a list |
| 139 | made up of the outputs of the closure. |
| 140 | |
| 141 | Keys defined by modules are described below, in the module |
| 142 | documentation. |
| 143 | |
| 144 | Other configuration files can be included inline by writing "include |
| 145 | filename" at the start of a line. |
| 146 | |
| 147 | After the configuration file is read, secnet looks for particular keys |
| 148 | in configuration space to tell it what to do: |
| 149 | |
| 150 | system: a dictionary which can contain the following keys: |
| 151 | log (log closure): a destination for system messages |
| 152 | userid (string): the userid for secnet to run as once it drops privileges |
| 153 | pidfile (string): where to store its PID |
| 154 | |
| 155 | sites: a list of closures of type 'site', which define other tunnel |
| 156 | endpoints that secnet will attempt to communicate with |
| 157 | |
| 158 | * secnet command line options |
| 159 | |
| 160 | Usage: secnet [OPTION]... |
| 161 | |
| 162 | -f, --silent, --quiet suppress error messages |
| 163 | -w, --nowarnings suppress warnings |
| 164 | -v, --verbose output extra diagnostics |
| 165 | -c, --config=filename specify a configuration file |
| 166 | -j, --just-check-config stop after reading configfile |
| 167 | -n, --nodetach do not run in background |
| 168 | -d, --debug=item,... set debug options |
| 169 | --help display this help and exit |
| 170 | --version output version information and exit |
| 171 | |
| 172 | * secnet builtin modules |
| 173 | |
| 174 | ** resolver |
| 175 | |
| 176 | Defines: |
| 177 | adns (closure => resolver closure) |
| 178 | |
| 179 | adns: dict argument |
| 180 | config (string): optional, a resolv.conf for ADNS to use |
| 181 | |
| 182 | ** random |
| 183 | |
| 184 | Defines: |
| 185 | randomsrc (closure => randomsrc closure) |
| 186 | |
| 187 | randomsrc: string[,bool] |
| 188 | arg1: filename of random source |
| 189 | arg2: if True then source is blocking |
| 190 | |
| 191 | ** udp |
| 192 | |
| 193 | Defines: |
| 194 | udp (closure => comm closure) |
| 195 | |
| 196 | udp: dict argument |
| 197 | address (string list): IPv6 or IPv4 addresses to listen and send on |
| 198 | port (integer): UDP port to listen and send on |
| 199 | buffer (buffer closure): buffer for incoming packets |
| 200 | authbind (string): optional, path to authbind-helper program |
| 201 | |
| 202 | ** log |
| 203 | |
| 204 | Defines: |
| 205 | logfile (closure => log closure) |
| 206 | syslog (closure => log closure) |
| 207 | |
| 208 | logfile: dict argument |
| 209 | filename (string): where to log to |
| 210 | class (string list): what type of messages to log |
| 211 | { "debug-config", M_DEBUG_CONFIG }, |
| 212 | { "debug-phase", M_DEBUG_PHASE }, |
| 213 | { "debug", M_DEBUG }, |
| 214 | { "all-debug", M_DEBUG|M_DEBUG_PHASE|M_DEBUG_CONFIG }, |
| 215 | { "info", M_INFO }, |
| 216 | { "notice", M_NOTICE }, |
| 217 | { "warning", M_WARNING }, |
| 218 | { "error", M_ERROR }, |
| 219 | { "security", M_SECURITY }, |
| 220 | { "fatal", M_FATAL }, |
| 221 | { "default", M_WARNING|M_ERROR|M_SECURITY|M_FATAL }, |
| 222 | { "verbose", M_INFO|M_NOTICE|M_WARNING|M_ERROR|M_SECURITY|M_FATAL }, |
| 223 | { "quiet", M_FATAL } |
| 224 | |
| 225 | logfile will close and reopen its file upon receipt of SIGHUP. |
| 226 | |
| 227 | syslog: dict argument |
| 228 | ident (string): include this string in every log message |
| 229 | facility (string): facility to log as |
| 230 | { "authpriv", LOG_AUTHPRIV }, |
| 231 | { "cron", LOG_CRON }, |
| 232 | { "daemon", LOG_DAEMON }, |
| 233 | { "kern", LOG_KERN }, |
| 234 | { "local0", LOG_LOCAL0 }, |
| 235 | { "local1", LOG_LOCAL1 }, |
| 236 | { "local2", LOG_LOCAL2 }, |
| 237 | { "local3", LOG_LOCAL3 }, |
| 238 | { "local4", LOG_LOCAL4 }, |
| 239 | { "local5", LOG_LOCAL5 }, |
| 240 | { "local6", LOG_LOCAL6 }, |
| 241 | { "local7", LOG_LOCAL7 }, |
| 242 | { "lpr", LOG_LPR }, |
| 243 | { "mail", LOG_MAIL }, |
| 244 | { "news", LOG_NEWS }, |
| 245 | { "syslog", LOG_SYSLOG }, |
| 246 | { "user", LOG_USER }, |
| 247 | { "uucp", LOG_UUCP } |
| 248 | |
| 249 | ** util |
| 250 | |
| 251 | Defines: |
| 252 | sysbuffer (closure => buffer closure) |
| 253 | |
| 254 | sysbuffer: integer[,dict] |
| 255 | arg1: buffer length |
| 256 | arg2: options: |
| 257 | lockdown (boolean): if True, mlock() the buffer |
| 258 | |
| 259 | ** site |
| 260 | |
| 261 | Defines: |
| 262 | site (closure => site closure) |
| 263 | |
| 264 | site: dict argument |
| 265 | local-name (string): this site's name for itself |
| 266 | name (string): the name of the site's peer |
| 267 | link (netlink closure) |
| 268 | comm (one or more comm closures): if there is more than one, the |
| 269 | first one will be used for any key setups initiated by us using the |
| 270 | configured address. Others are only used if our peer talks to |
| 271 | them. |
| 272 | resolver (resolver closure) |
| 273 | random (randomsrc closure) |
| 274 | local-key (rsaprivkey closure) |
| 275 | address (string list): optional, DNS name(s) used to find our peer; |
| 276 | address literals are supported too if enclosed in `[' `]'. |
| 277 | port (integer): mandatory if 'address' is specified: the port used |
| 278 | to contact our peer |
| 279 | key (rsapubkey closure): our peer's public key |
| 280 | transform (transform closure): how to mangle packets sent between sites |
| 281 | dh (dh closure) |
| 282 | hash (hash closure) |
| 283 | key-lifetime (integer): max lifetime of a session key, in ms |
| 284 | [one hour; mobile: 2 days] |
| 285 | setup-retries (integer): max number of times to transmit a key negotiation |
| 286 | packet [5; mobile: 30] |
| 287 | setup-timeout (integer): time between retransmissions of key negotiation |
| 288 | packets, in ms [2000; mobile: 1000] |
| 289 | wait-time (integer): after failed key setup, wait this long (in ms) before |
| 290 | allowing another attempt [20000; mobile: 10000] |
| 291 | renegotiate-time (integer): if we see traffic on the link after this time |
| 292 | then renegotiate another session key immediately (in ms) |
| 293 | [half key-lifetime, or key-lifetime minus 5 mins (mobile: 12 hours), |
| 294 | whichever is longer]. |
| 295 | keepalive (bool): if True then attempt always to keep a valid session key. |
| 296 | Not actually currently implemented. [false] |
| 297 | log-events (string list): types of events to log for this site |
| 298 | unexpected: unexpected key setup packets (may be late retransmissions) |
| 299 | setup-init: start of attempt to setup a session key |
| 300 | setup-timeout: failure of attempt to setup a session key, through timeout |
| 301 | activate-key: activation of a new session key |
| 302 | timeout-key: deletion of current session key through age |
| 303 | security: anything potentially suspicious |
| 304 | state-change: steps in the key setup protocol |
| 305 | packet-drop: whenever we throw away an outgoing packet |
| 306 | dump-packets: every key setup packet we see |
| 307 | errors: failure of name resolution, internal errors |
| 308 | peer-addrs: changes to sets of peer addresses (interesting for mobile peers) |
| 309 | all: everything (too much!) |
| 310 | mobile (bool): if True then peer is "mobile" ie we assume it may |
| 311 | change its apparent IP address and port number without either it |
| 312 | or us being aware of the change; so, we remember the last several |
| 313 | port/addr pairs we've seen and send packets to all of them |
| 314 | (subject to a timeout). We maintain one set of addresses for key |
| 315 | setup exchanges, and another for data traffic. Two communicating |
| 316 | peers must not each regard the other as mobile, or all the traffic |
| 317 | in each direction will be triplicated (strictly, transmitted |
| 318 | mobile-peers-max times) and anyway two peers whose public contact |
| 319 | address may suddenly change couldn't communicate reliably because |
| 320 | their contact addresses might both change at once. [false] |
| 321 | mobile-peers-max (integer): Maximum number of peer port/addr pairs we |
| 322 | remember and send to. Must be at least 1 and no more than 5. |
| 323 | [4 if any address is configured, otherwise 3] |
| 324 | static-peers-max (integer): Maximum number of peer port/addr pairs |
| 325 | we can try for a static site. Must be at least 1 and no more |
| 326 | than 5. [4 or 3, as above] |
| 327 | mobile-peer-expiry (integer): For "mobile" peers only, the length |
| 328 | of time (in seconds) for which we will keep sending to multiple |
| 329 | address/ports from which we have not seen incoming traffic. [120] |
| 330 | local-mobile (bool): if True then other peers have been told we are |
| 331 | "mobile". This should be True iff the peers' site configurations |
| 332 | for us have "mobile True" (and if we find a site configuration for |
| 333 | ourselves in the config, we insist on this). The effect is to |
| 334 | check that there are no links both ends of which are allegedly |
| 335 | mobile (which is not supported, so those links are ignored) and |
| 336 | to change some of the tuning parameter defaults. [false] |
| 337 | mtu-target (integer): Desired value of the inter-site MTU for this |
| 338 | peering. This value will be advertised to the peer (which ought |
| 339 | to affect incoming packets), and if the peer advertises an MTU its |
| 340 | value will be combined with this setting to compute the inter-site |
| 341 | MTU. (secnet will still accept packets which exceed the |
| 342 | (negotiated or assumed) inter-site MTU.) Setting a lower |
| 343 | inter-site MTU can be used to try to restrict the sizes of the |
| 344 | packets sent over the underlying public network (e.g. to work |
| 345 | around network braindamage). It is not normally useful to set a |
| 346 | larger value for mtu-target than the VPN's general MTU (which |
| 347 | should be reflected in the local private interface MTU, ie the mtu |
| 348 | parameter to netlink). If this parameter is not set, or is set |
| 349 | to 0, the default is to use the local private link mtu. |
| 350 | |
| 351 | Links involving mobile peers have some different tuning parameter |
| 352 | default values, which are generally more aggressive about retrying key |
| 353 | setup but more relaxed about using old keys. These are noted with |
| 354 | "mobile:", above, and apply whether the mobile peer is local or |
| 355 | remote. |
| 356 | |
| 357 | ** transform-eax |
| 358 | |
| 359 | Defines: |
| 360 | eax-serpent (closure => transform closure) |
| 361 | |
| 362 | ** transform-cbcmac |
| 363 | |
| 364 | Defines: |
| 365 | serpent256-cbc (closure => transform closure) |
| 366 | |
| 367 | ** netlink |
| 368 | |
| 369 | Defines: |
| 370 | null-netlink (closure => closure or netlink closure) |
| 371 | |
| 372 | null-netlink: dict argument |
| 373 | name (string): name for netlink device, used in log messages |
| 374 | networks (string list): networks on the host side of the netlink device |
| 375 | remote-networks (string list): networks that may be claimed |
| 376 | by the remote site using this netlink device |
| 377 | local-address (string): IP address of host's tunnel interface |
| 378 | secnet-address (string): IP address of this netlink device |
| 379 | ptp-address (string): IP address of the other end of a point-to-point link |
| 380 | mtu (integer): MTU of host's tunnel interface |
| 381 | |
| 382 | Only one of secnet-address or ptp-address may be specified. If |
| 383 | point-to-point mode is in use then the "routes" option must also be |
| 384 | specified, and netlink returns a netlink closure that should be used |
| 385 | directly with the "link" option to the site closure. If |
| 386 | point-to-point mode is not in use then netlink returns a closure that |
| 387 | may be invoked using a dict argument with the following keys to yield |
| 388 | a netlink closure: |
| 389 | routes (string list): networks reachable down the tunnel attached to |
| 390 | this instance of netlink |
| 391 | options (string list): |
| 392 | allow-route: allow packets coming from this tunnel to be routed to |
| 393 | other tunnels as well as the host (used for mobile devices like laptops) |
| 394 | soft: remove these routes from the host's routing table when |
| 395 | the tunnel link quality is zero |
| 396 | mtu (integer): MTU of host's tunnel interface |
| 397 | |
| 398 | Netlink will dump its current routing table to the system/log on |
| 399 | receipt of SIGUSR1. |
| 400 | |
| 401 | ** slip |
| 402 | |
| 403 | Defines: |
| 404 | userv-ipif (closure => netlink closure) |
| 405 | |
| 406 | userv-ipif: dict argument |
| 407 | userv-path (string): optional, where to find userv ["userv"] |
| 408 | service-user (string): optional, username for userv-ipif service ["root"] |
| 409 | service-name (string): optional, name of userv-ipif service ["ipif"] |
| 410 | buffer (buffer closure): buffer for assembly of host->secnet packets |
| 411 | plus generic netlink options, as for 'null-netlink' |
| 412 | |
| 413 | ** tun |
| 414 | |
| 415 | Defines: |
| 416 | tun (closure => netlink closure) [only on linux-2.4] |
| 417 | tun-old (closure => netlink closure) |
| 418 | |
| 419 | tun: dict argument |
| 420 | flavour (string): optional, type of TUN interface to use |
| 421 | ("guess","linux","bsd","streams") |
| 422 | device (string): optional, path of TUN/TAP device file ["/dev/net/tun"] |
| 423 | interface (string): optional, name of tunnel network interface |
| 424 | ifconfig-path (string): optional, path to ifconfig command |
| 425 | route-path (string): optional, path to route command |
| 426 | ifconfig-type (string): optional, how to perform ifconfig |
| 427 | route-type (string): optional, how to add and remove routes |
| 428 | types are: "guess", "ioctl", "bsd", "linux", "solaris-2.5" |
| 429 | buffer (buffer closure): buffer for host->secnet packets |
| 430 | plus generic netlink options, as for 'null-netlink' |
| 431 | |
| 432 | I recommend you don't specify the 'interface' option unless you're |
| 433 | doing something that requires the interface name to be constant. |
| 434 | |
| 435 | ** rsa |
| 436 | |
| 437 | Defines: |
| 438 | rsa-private (closure => rsaprivkey closure) |
| 439 | rsa-public (closure => rsapubkey closure) |
| 440 | |
| 441 | rsa-private: string[,bool] |
| 442 | arg1: filename of SSH private key file (version 1, no password) |
| 443 | arg2: whether to check that the key is usable [default True] |
| 444 | |
| 445 | rsa-public: string,string |
| 446 | arg1: encryption key (decimal) |
| 447 | arg2: modulus (decimal) |
| 448 | |
| 449 | ** dh |
| 450 | |
| 451 | Defines: |
| 452 | diffie-hellman (closure => dh closure) |
| 453 | |
| 454 | diffie-hellman: string,string[,bool] |
| 455 | arg1: modulus (hex) |
| 456 | arg2: generator (hex) |
| 457 | arg3: whether to check that the modulus is prime [default True] |
| 458 | |
| 459 | ** md5 |
| 460 | |
| 461 | Defines: |
| 462 | md5 (hash closure) |
| 463 | |
| 464 | ** sha1 |
| 465 | |
| 466 | Defines: |
| 467 | sha1 (hash closure) |
| 468 | |
| 469 | ** conffile |
| 470 | |
| 471 | Defines: |
| 472 | makelist (dictionary => list of definitions) |
| 473 | readfile (string => string) |
| 474 | map (closure,list => list) |
| 475 | |
| 476 | makelist: dictionary |
| 477 | returns a list consisting of the definitions in the dictionary. The keys |
| 478 | are discarded. |
| 479 | |
| 480 | readfile: string |
| 481 | reads the named file and returns its contents as a string |
| 482 | |
| 483 | map: |
| 484 | applies the closure specified as arg1 to each of the elements in the list. |
| 485 | Returns a list made up of the outputs of the closure. |