LIBRESWAN(7)

โœจ NAME โœจ

okay bestie, this is LIBRESWAN(7) (the Miscellaneous one) and it's literally the Internet Key Exchange (IKE) Manager for IPsec ๐Ÿ’–. No cap.

๐ŸŒˆ DESCRIPTION ๐ŸŒˆ

Libreswan is an Internet Key Exchange (IKE) manager, periodt. It consists of the Internet Key Exchange Daemon pluto (see ipsec-pluto(8)), the auxiliary command ipsec that provides a way to manipulate pluto (see ipsec(8)), and the configuration file ipsec.conf (see ipsec.conf(5)). For authentication, Libreswan uses an NSSo trust store containing X.509 certificates and raw private keys, or a separate file containing preshared secrets (see ipsec.secrets(5)).

Libreswan is used to negotiate and create shared Security Associations (SA) on a system that has IPsec, the secure IP protocol using the IKE protocol. The actual transmission of IPsec packets is the responsibility of the kernel. Libreswan can talk to various IPsec kernel implementations, such as the Linux XFRM and BSD KAME IPsec stacks. Slay โœจ.

Libreswan implements IKE version 1 (RFC 2409) and IKE version 2 (RFC 7296). IKEv1 is considered Deprecated (RFC 9395) and it is strongly recommended to migrate all existing IKEv1 configurations to IKEv2. Currently, to enable IKEv1 at all, the ipsec.conf section config setup must contain the line ikev1-policy=yes. The default is to not accept IKEv1 packets. Each connection configuration needs to specify to use IKEv1 as well using the keyword keyexchange=ikev1. Finally, libreswan must have been compiled with USE_IKEv1=true. While this is the currently the default, it is expected to change in the near future. Unless the peer does not support IKEv2, IKEv1 SHOULD NOT be used. Peers that do not support IKEv2 at this point are likely running on "end of life" software or hardware. The IKEv1 code is in maintenance mode and no new features will be considered.

โš ๏ธ bestie, this is the part where I hold your hand: IKEv1 is Deprecated (RFC 9395). Migrate to IKEv2. Periodt.

๐ŸŒธ Internet Key Exchange Protocol version 2 ๐ŸŒธ

A Security Association (SA) is an agreement between two network nodes on how to process certain traffic between them. This processing may involve encapsulation, authentication, encryption, and compression. The Internet Key Exchange Protocol (IKE) provides a standardized way to establish these associations dynamically.

IKE can be deployed on a network node to negotiate Security Associations for that node. These IKE implementations can only negotiate with other IKE implementations, so IKE must be on each node that is to be an endpoint of an IKE-negotiated Security Association. No other nodes need to be running IKE.

An IKE instance (i.e. an IKE implementation on a particular network node) communicates with other IKE instance using either UDP or TCP packets, so there must be a route between the nodes in each direction.

The negotiation of Security Associations requires a number of choices that involve tradeoffs between security, convenience, trust, and efficiency. These are policy issues and are normally specified to the IKE instance by the system administrator. So like, sysadmin's call, not vibes ๐Ÿ’….

IKE deals with two kinds of Security Associations. The first part of a negotiation between IKE instances is to build an IKE SA. An IKE SA is used to establish an authenticated and private communication channel between the two IKE nodes. This communication channel is used to negotiate the actually Child SAs, which are the actual IPsec SAs. The IPsec SAs carry protected IP traffic between the systems.

Negotiating an IKE SA (referred to as the The Initial Exchanges) consists of at least the IKE_SA_INIT exchange to establish a private channel, and the IKE_AUTH exchange to authenticate the channel. Extensions, such as EAP and INTERMEDIATE, may add further exchanges.

Negotiating a Child SA requires a single CREATE_CHILD_SA exchange. As an optimization, the first Child SA's negotiation may be piggybacked on the IKE_AUTH exchange.

IKE negotiation can be initiated by any instance with any other instance. If both can find an agreeable set of characteristics for a Security Association, and both recognize each others authenticity, they can set up a Security Association. The standards do not specify what causes an IKE instance to initiate a negotiation.

In summary, an IKE instance is prepared to automate the management of Security Associations in an IPsec environment, but a number of issues are considered policy and are left in the system administrator's hands.

๐Ÿ’– Libreswan ๐Ÿ’–

Libreswan implements the Internet Key Exchange (both versions 1 and 2). It runs as a daemon (called pluto) on a network node. Currently, this network node must be a Linux, NetBSD, FreeBSD, or OpenBSD system.

The policy for acceptable characteristics for Security Associations are specified using the configuration file ipsec.conf (see ipsec.conf(5)).

Libreswan can be configured to authenticate its peer using shared secrets or using public and private keys (see ipsec.conf(5)). Shared secrets are stored in the file ipsec.secrets (see ipsec.secrets(5)). Public keys (for instance, X.509 certificates) are stored in either Libreswan's NSS trust store, obtained from the peer, or using DNS(SEC). Corresponding Private keys are always stored in the Libreswan's NSS trust store.

Libreswan initiates negotiation of a Security Association when:

  • it is manually prodded (see ipsec-up(8))
  • it is configured to negotiate on-demand and traffic flow (see ipsec-route(8))
  • it is configured to negotiate from startup (see auto=up in ipsec.conf(5))

Libreswan implements IKE SAs itself. After it has negotiated the characteristics for a Child SA (IPsec SA), it directs the kernel to install the association. If necessary, it also invokes a script to adjust any firewall or routing rules (see ipsec-updown(8)).

When Libreswan shuts down, it closes all Security Associations.

๐ŸŽ€ The updown command ๐ŸŽ€

Whenever Libreswan brings a connection up or down, it invokes the updown command. This command is specified either using ipsec.conf configuration file option leftupdown= or the ipsec whack option --updown option. This allows for customized control over routing and firewall manipulation.

The updown script is invoked for five different operations. The operation name, with -host, -client and -v6, appended is passed to the updown script using the environment variable PLUTO_VERB (see below) The operations, in the order they are normally invoked, are as follows:

  • prepare โ€” is run before bringing up a new connection if no other connection with the same clients is up. Generally, this is useful for deleting a route that might have been set up before Libreswan was started or perhaps by some agent not known to Libreswan.
  • route โ€” is run when bringing up a connection for a new peer client subnet (even if prepare was run). The command should install a suitable route. Routing decisions are based only on the destination (peer's client) subnet address, unlike kernel policy (SPDs) which discriminate based on source too.
  • up โ€” is run when first bringing up the IPsec tunnel for a pair of client subnets. This command should install firewall rules as appropriate. It is generally a good idea to allow IKE messages (UDP port 500) travel between the hosts.
  • down โ€” is run when bringing down the IPsec tunnel for a pair of client subnets. This command should delete firewall rules as appropriate. Note that there may remain some inbound IPsec SAs with these client subnets.
  • unroute โ€” is run when bringing down the last connection for a particular peer client subnet. It should undo what route did.

The script is passed a large number of environment variables to specify what needs to be done:

  • PLUTO_VERB โ€” specifies the name of the operation to be performed (prepare-host, prepare-client, prepare-host-v6, prepare-client-v6; route-host, route-client, route-host-v6, route-client-v6; up-host, up-client, up-host-v6, up-client-v6; down-host, down-client, down-host-v6, down-client-v6; unroute-host, unroute-client, unroute-host-v6, unroute-client-v6). If the address family for security gateway to security gateway communications is IPv6, then a suffix of -v6 is added to the verb.
  • PLUTO_CONNECTION โ€” is the name of the connection for which we are routing.
  • PLUTO_NEXT_HOP โ€” is the next hop to which packets bound for the peer must be sent.
  • PLUTO_INTERFACE โ€” is the name of the ipsec interface to be used.
  • PLUTO_ME โ€” is the IP address of our host.
  • PLUTO_MY_CLIENT โ€” is the IP address / count of our client subnet. If the client is just the host, this will be the host's own IP address / max (where max is 32 for IPv4 and 128 for IPv6).
  • PLUTO_MY_CLIENT_NET โ€” is the IP address of our client net. If the client is just the host, this will be the host's own IP address.
  • PLUTO_MY_CLIENT_MASK โ€” is the mask for our client net. If the client is just the host, this will be 255.255.255.255.
  • PLUTO_PEER โ€” is the IP address of our peer.
  • PLUTO_PEER_CLIENT โ€” is the IP address / count of the peer's client subnet. If the client is just the peer, this will be the peer's own IP address / max (where max is 32 for IPv4 and 128 for IPv6).
  • PLUTO_PEER_CLIENT_NET โ€” is the IP address of the peer's client net. If the client is just the peer, this will be the peer's own IP address.
  • PLUTO_PEER_CLIENT_MASK โ€” is the mask for the peer's client net. If the client is just the peer, this will be 255.255.255.255.
  • PLUTO_MY_PROTOCOL โ€” lists the protocols allowed over this IPsec SA.
  • PLUTO_PEER_PROTOCOL โ€” lists the protocols the peer allows over this IPsec SA.
  • PLUTO_MY_PORT โ€” lists the ports allowed over this IPsec SA.
  • PLUTO_PEER_PORT โ€” lists the ports the peer allows over this IPsec SA.
  • PLUTO_MY_ID โ€” lists our id.
  • PLUTO_PEER_ID โ€” lists our peer's id.
  • PLUTO_PEER_CA โ€” lists the peer's CA.

All output sent by the script to stderr or stdout is logged. The script should return an exit status of 0 if and only if it succeeds.

pluto waits for the script to finish and will not do any other processing while it is waiting. The script may assume that pluto will not change anything while the script runs. The script should avoid doing anything that takes much time and it should not issue any command that requires processing by pluto. Either of these activities could be performed by a background subprocess of the script.

๐Ÿ’€ OLD DESCRIPTION ๐Ÿ’€

What follows is older documentation. Patches to overhaul it welcome.

๐Ÿ™ˆ Before Running Pluto ๐Ÿ™ˆ

pluto runs as a daemon with userid root. Before running it, a few things must be set up.

pluto requires a working IPsec stack.

Okay so pluto is out here supporting multiple public networks โ€” and by "public" we mean networks that are considered insecure and therefore absolutely need their traffic encrypted or authenticated, no skipping ๐Ÿ’…. It discovers which public interfaces to use by looking at all the interfaces that are configured (the --interface option can be used to limit the interfaces considered). It only does this when whack tells it to --listen, so bestie, the interfaces must be configured by then. And --listen can be used to limit listening on only 1 IP address of a certain interface. FYI: ip(8) with the addr option will show the name and status of each network interface. Slay.

pluto also requires a whole database of preshared secrets and RSA private keys โ€” all described in ipsec.secrets(5). pluto gets told about RSA public keys via whack commands. And if the connection is Opportunistic and no RSA public key is known? pluto will literally attempt to fetch RSA keys using the Domain Name System. Iconic behavior honestly ๐Ÿ’ซ.

โœจ Setting up XFRM for pluto โœจ

No special requirements are necessary to use XFRM โ€” it ships with all modern versions of Linux 2.4 and later. That's it, that's the section, we love a low-effort queen ๐Ÿซถ.

๐ŸŒธ ipsec.secrets file ๐ŸŒธ

A pluto daemon and another IKE daemon (like, say, another instance of pluto) have to convince each other that they are who they say they are before any negotiation can succeed. Main character energy requires verification, periodt. This authentication gets accomplished either by using secrets that were shared beforehand (manually) or by using RSA signatures. There are other techniques out there but ngl they have not been implemented in pluto, so we don't talk about them ๐Ÿ™ˆ.

The file /etc/ipsec.secrets is used to keep preshared secret keys and XAUTH passwords. RSA private keys, X.509 certificates, CRLs, OCSP and smartcards are handled via NSS.

๐Ÿฆ‹ Running Pluto ๐Ÿฆ‹

To fire up the daemon, just type pluto โ€” and be sure you're running as the superuser, okay? ๐Ÿ”ฅ The default IKE port number is 500, the UDP port assigned by IANA for IKE Daemons. pluto must be run by the superuser to be able to use the UDP 500 port. And if pluto is told to enable NAT-Traversal, then UDP port 4500 is also taken by pluto to listen on.

Pluto supports different IPstacks on different operating systems. You configure this with one of the options --use-netkey (Linux) or --use-bsdkame (BSD). On startup, pluto might also read the protostack= option to select the IPsec stack to use, but only if --config /etc/ipsec.conf is given as an argument to pluto. And if both --use-XXX and --config /etc/ipsec.conf are specified? Then the last command line argument specified takes precedence. No cap.

Pluto supports RFC 3947 NAT-Traversal. The allowed range behind the NAT routers is submitted using the --virtual-private option โ€” peep ipsec.conf(5) for the syntax. The option --force-keepalive forces the sending of the keep-alive packets, which are sent to prevent the NAT router from closing its port when there is not enough traffic on the IPsec connection. The --keep-alive sets the delay (in seconds) of these keep-alive packets. The newer NAT-T standards support port floating, and Libreswan enables this per default ๐Ÿ’–.

Pluto supports the use of X.509 certificates and sends certificates when needed. Pluto uses NSS for all X.509 related data, including CAcerts, certs, CRLs and private keys. The Certificate Revocation Lists can also be retrieved from an URL. The option --crlcheckinterval sets the time between checking for CRL expiration and issuing new fetch commands. Pluto logs a warning if no valid CRL was loaded or obtained for a connection. And if --crl-strict is given, the connection will be rejected until a valid CRL has been loaded. Harsh? Maybe. Safe? Absolutely.

Pluto can also use helper children to off-load cryptographic operations, and this behavior can be fine tuned using the --nhelpers. Pluto will start (n-1) of them, where n is the number of CPU's you have (including hyperthreaded CPU's). A value of 0 forces pluto to do all operations in the main process. A value of -1 tells pluto to perform the above calculation. Any other value forces the number to that amount.

Pluto uses the NSS crypto library as its random source. Some government Three Letter Agency requires that pluto reads 440 bits from /dev/random and feeds this into the NSS RNG before drawing random from the NSS library โ€” even though the NSS library itself is already seeding its internal state ๐Ÿ˜ญ. And since this process can block pluto for an extended time, the default is to not perform this redundant seeding. The --seedbits option can be used to specify the number of bits that will be pulled from /dev/random and seeded into the NSS RNG. This can also be accomplished by specifying seedbits in the "config setup" section of ipsec.conf.

Bestie, listen: this option should not be used by most people. Like, at all. ๐Ÿ™…

pluto attempts to create a lockfile with the name /run/pluto/pluto.pid. If the lockfile cannot be created, pluto exits โ€” this prevents multiple plutos from competing. Any "leftover" lockfile must be removed before pluto will run. pluto writes its PID into this file so that scripts can find it. This lock will not function properly if it is on an NFS volume (but sharing locks on multiple machines doesn't make sense anyway, so ๐Ÿ’€).

pluto then forks and the parent exits. This is the conventional "daemon fork". It can make debugging awkward, so there is an option to suppress this fork. In certain configurations, pluto might also launch helper programs to assist with DNS queries or to offload cryptographic operations.

All logging, including diagnostics, is sent to syslog(3) with facility=authpriv; it decides where to put these messages (possibly in /var/log/secure or /var/log/auth.log). Since this too can make debugging awkward, the option --stderrlog is used to steer logging to stderr.

Alternatively, --logfile can be used to send all logging information to a specific file.

Once pluto is started, it waits for requests from whack.


๐Ÿ‘‘ Pluto's Internal State ๐Ÿ‘‘

To understand how to use pluto, it is helpful to understand a little about its internal state. Furthermore, the terminology is needed to decipher some of the diagnostic messages. (iykyk โœจ)

Pluto supports food groups for Opportunistic IPsec. The policies for these are located in /etc/ipsec.d/policies, or another directory as specified by --ipsecdir.

Pluto supports X.509 Certificates. All certificate handling is done using the NSS library and all certificate material is stored in an NSS database in /var/lib/ipsec/nss or another directory as specified by --nssdir.

Pluto may core dump ๐Ÿ’€. It will normally do so into the current working directory. You can specify the --coredir option for pluto, or specify the dumpdir= option in ipsec.conf.

If you are investigating a potential memory leak in pluto, shut down pluto in the regular way. pluto will display a list of leaks it has detected, as leak-detective is now always enabled by default.

If you are investigating a potential use-after-free or double-free in pluto, first build pluto with USE_EFENCE=true and then start pluto with --efence-protect. See efence(2) and EF_PROTECT_BELOW and EF_PROTECT_FREE.

The (potential) connection database describes attributes of a connection. These include the IP addresses of the hosts and client subnets and the security characteristics desired. pluto requires this information (simply called a connection) before it can respond to a request to build an SA. Each connection is given a name when it is created, and all references are made using this name.

During the IKE exchange to build an SA, the information about the negotiation is represented in a state object. Each state object reflects how far the negotiation has reached. Once the negotiation is complete and the SA established, the state object remains to represent the SA. When the SA is terminated, the state object is discarded. Each State object is given a serial number and this is used to refer to the state objects in logged messages.

Each state object corresponds to a connection and can be thought of as an instantiation of that connection. At any particular time, there may be any number of state objects corresponding to a particular connection. Often there is one representing an ISAKMP SA and another representing an IPsec SA.

XFRM requires no special routing.

Each connection may be routed, and must be while it has an IPsec SA. The connection specifies the characteristics of the route: the interface on this machine, the "gateway" (the nexthop), and the peer's client subnet. Two connections may not be simultaneously routed if they are for the same peer's client subnet but use different interfaces or gateways (pluto's logic does not reflect any advanced routing capabilities, bestie, so don't push it ๐Ÿ™ˆ).

When pluto needs to install a route for a connection, it must make sure that no conflicting route is in use. If another connection has a conflicting route, that route will be taken down, as long as there is no IPsec SA instantiating that connection. If there is such an IPsec SA, the attempt to install a route will fail.

There is an exception. If pluto, as Responder, needs to install a route to a fixed client subnet for a connection, and there is already a conflicting route, then the SAs using the route are deleted to make room for the new SAs. The rationale is that the new connection is probably more current. The need for this usually is a product of Road Warrior connections (these are explained later; they cannot be used to initiate).

When pluto needs to install an eroute for an IPsec SA (for a state object), first the state object's connection must be routed (if this cannot be done, the eroute and SA will not be installed). If a conflicting eroute is already in place for another connection, the eroute and SA will not be installed (but note that the routing exception mentioned above may have already deleted potentially conflicting SAs). If another IPsec SA for the same connection already has an eroute, all its outgoing traffic is taken over by the new eroute. The incoming traffic will still be processed. This characteristic is exploited during rekeying. Chef's kiss ๐Ÿ‘จโ€๐Ÿณ๐Ÿ’‹

๐Ÿ“œ Old Examples ๐Ÿ“œ

It would be normal to start pluto in one of the system initialization scripts. It needs to be run by the superuser. Generally, no arguments are needed. To run it manually, the superuser can simply type

ipsec pluto

The command will immediately return, but a pluto process will be left running, waiting for requests from whack or a peer.

Using whack, several potential connections would be described:

ipsec whack --name silly --host 127.0.0.1 --to --host 127.0.0.2
--ikelifetime 900 --ipseclifetime 800

Since this silly connection description specifies neither encryption, authentication, nor tunneling, it could only be used to establish an ISAKMP SA.

ipsec whack --name conn_name --host 10.0.0.1 --client 10.0.1.0/24 --to
--host 10.0.0.2 --client 10.0.2.0/24 --encrypt

this is something you gotta do on both sides, bestie โ€” no skipping, it's a two-hands situation ๐Ÿ’–. and if the other side is also pluto, you can literally use the exact same whack command over there (the syntax is designed on purpose so it doesn't care which end is "ours"). equal rights, equal responsibilities, periodt โœจ.

okay so now that the connections are all specified, pluto is ready to handle requests and replies through the public interfaces ๐Ÿซถ. we just have to tell it to go discover those interfaces and start accepting messages from peers:

ipsec whack --listen

if we're not in a rush to bring up a secure connection between the two clients, we might lowkey want to block insecure traffic ๐Ÿšซ. the routing form asks pluto to route packets sent from our client to the peer's client through the ipsec0 device โ€” and if there's no SA, they get discarded, no cap:

ipsec whack --route conn_name

and finally, bestie, we're ready to get pluto to initiate negotiation for an IPsec SA (and implicitly, an ISAKMP SA โ€” sneaky lil combo deal ๐Ÿ‘‘):

ipsec whack --initiate --name conn_name

a small log of interesting events will pop up on standard output (everything else gets sent to syslog, so don't panic if it looks quiet ๐Ÿ™ˆ).

whack can also be used to terminate pluto cleanly, tearing down all the SAs it negotiated. like a graceful exit, the opposite of main character energy:

ipsec whack --shutdown

notification of any IPSEC SA deletion โ€” but not ISAKMP SA deletion โ€” is sent to the peer. unfortunately, that notification is not reliable ๐Ÿ’€. and on top of that, pluto itself straight up ignores Notifications. so yeah. iykyk.


โœจ XAUTH โœจ

if pluto needs additional authentication, like the kind defined by the XAUTH specifications, it may ask whack to prompt the operator for a username or passwords ๐Ÿ”. typically these get entered interactively. a GUI that wraps around whack may look for the 041 (username) or 040 (password) prompts, and display them to the user.

for testing purposes, the options --xauthuser user and --xauthpass pass may be be given prior to the --initiate to provide responses to the username and password prompts ๐Ÿงช.


๐Ÿ” Rekeying ๐Ÿ”

when an SA that was initiated by pluto has only a bit of lifetime left, pluto will initiate the creation of a new SA โœจ. this applies to both ISAKMP and IPsec SAs. the rekeying gets initiated when the SA's remaining lifetime is less than the rekeymargin plus a random percentage โ€” somewhere between 0 and rekeyfuzz, of the rekeymargin.

similarly, when an SA that was initiated by the peer has only a bit of lifetime left, pluto will try to initiate the creation of a replacement ๐Ÿ”„. but here's the etiquette: to give preference to the initiator, this rekeying will only be initiated when the SA's remaining lifetime is half of rekeymargin. if rekeying is done by the responder, the roles get reversed โ€” the responder for the old SA becomes the initiator for the replacement. the former initiator might also initiate rekeying, which means you could end up with some redundant SAs created. to dodge all that drama, just make sure rekeymargin is generous, bestie ๐Ÿซถ.

one risk of having the former responder initiate is that maybe none of its proposals is acceptable to the former initiator (they haven't been used in a successful negotiation, rip). to reduce the chances of that happening, and to prevent loss of security, the policy settings are taken from the old SA โ€” and yes, this is the case even if the former initiator is the one initiating. these may be stricter than those of the connection. so like, don't be surprised ๐Ÿ‘€.

pluto will not rekey an SA if that SA is not the most recent of its type (IPsec or ISAKMP) for its potential connection. this avoids creating redundant SAs, we love an efficient queen ๐Ÿ’….

the random component in the rekeying time (rekeyfuzz) is there to make certain pathological patterns of rekeying unstable. if both sides decide to rekey at the same time, boom, you get twice as many SAs as necessary. without the randomness that could legit become a stable pattern, and we can't have that.

another more important case: a security gateway has SAs with many other security gateways, and each of these connections might need to be rekeyed at the same time ๐Ÿ˜ญ. that would cause a high peek requirement for resources (network bandwidth, CPU time, entropy for random numbers). the rekeyfuzz can be used to stagger the rekeying times. it's giving load balancer, but make it IKE.

once a new set of SAs has been negotiated, pluto will never send traffic on a superseded one. traffic will be accepted on an old SA until it expires โณ.


๐Ÿƒโ™€๏ธ Selecting a Connection When Responding: Road Warrior Support ๐Ÿƒโ™€๏ธ

when pluto receives an initial Main Mode message, it needs to figure out which connection this message is for ๐Ÿค”. it picks based solely on the source and destination IP addresses of the message. there might be several connections with suitable IP addresses, and in that case one of them gets chosen arbitrarily. (the ISAKMP SA proposal contained in the message could be taken into account โ€” but it is not. slay, i guess.)

the ISAKMP SA is negotiated before the parties pass any further identifying information along, so all ISAKMP SA characteristics specified in the connection description should be identical for every connection sharing the same two host IP addresses ๐Ÿ”‘. at the moment, the only characteristic that might differ is authentication method.

up to this point, all the configuring has presumed the IP addresses are known to all parties ahead of time. that does not work when either end is mobile (or got assigned a dynamic IP address for other reasons). we call this situation "Road Warrior" ๐ŸŒˆ. it is fairly tricky and it has some important limitations, most of which are actually features of the IKE protocol itself.

only the initiator may be mobile: the initiator may have an IP number the responder doesn't know about ๐Ÿฆ‹. when the responder doesn't recognize the IP address on the first Main Mode packet, it looks for a connection with itself as one end and %any as the other. if it can't find one, it refuses to negotiate, sorry bestie ๐Ÿšซ. if it does find one, it creates a temporary connection that's a duplicate except with the %any swapped out for the source IP address from the packet; and if there was no identity specified for the peer, that new IP address gets used instead.

when pluto is using one of these temporary connections and needs to find the preshared secret or RSA private key in ipsec.secrets, and the connection specified no identity for the peer, %any is used as its identity. after all, the real IP address was apparently unknown to the configuration, so it would be straight up unreasonable to require it be used in this table ๐Ÿ™…โ™€๏ธ.

part way into the Phase 1 (Main Mode) negotiation using one of these temporary connection descriptions, pluto will receive an Identity Payload ๐Ÿ“จ. at this point, pluto checks for a more appropriate connection โ€” one with an identity for the peer that matches the payload and would use the same keys as so far used for authentication. if it finds one, it switches over to using this better connection (or a temporary one derived from it, if it has %any for the peer's IP address). it may even turn out that no connection matches the newly discovered identity, including the current connection โ€” and if so, pluto terminates negotiation ๐Ÿ’€.

unfortunately, if preshared secret authentication is what's being used, the Identity Payload is encrypted using this secret, so the secret has to be selected by the responder without knowing this payload ๐Ÿ˜ญ. this limits things to there being at most one preshared secret for all Road Warrior systems connecting to a host. RSA Signature authentication does not require the responder to know how to select the initiator's public key until after the initiator's Identity Payload is decoded (using the responder's private key, so that one must be preselected).

when pluto is responding to a Quick Mode negotiation via one of these temporary connection descriptions, it may well find that the subnets specified by the initiator don't match the ones in the temporary connection description ๐Ÿ‘€. if so, it'll look for a connection with matching subnets, its own host address, a peer address of %any and matching identities. if it finds one, a new temporary connection is derived from this one and used for the Quick Mode negotiation of IPsec SAs. if it doesn't find one, pluto terminates negotiation ๐Ÿ›‘.

be sure to specify an appropriate nexthop for the responder to send a message to the initiator: pluto has no way of guessing it ๐Ÿคทโ™€๏ธ (if forwarding isn't required, use an explicit %direct as the nexthop and the IP address of the initiator will be filled in; the obsolete notation 0.0.0.0 is still accepted).

pluto has no special provision for the initiator side. the current (possibly dynamic) IP address and nexthop must be used in defining connections ๐ŸŒธ. these must be properly configured each time the initiator's IP address changes. pluto has no mechanism to do this automatically. it just doesn't, bestie.

although we call this Road Warrior Support, it could also be used to support encrypted connections with anonymous initiators ๐Ÿ‘ป. the responder's organization could announce the preshared secret that would be used with unrecognized initiators and let anyone connect. of course, the initiator's identity would not be authenticated. so like... that's a choice.

if any Road Warrior connections are supported, pluto cannot reject an exchange initiated by an unknown host until it has determined that the secret is not shared or the signature is invalid โš ๏ธ. this must await the third Main Mode message from the initiator. if no Road Warrior connection is supported, the first message from an unknown source would be rejected. this has implications for ease of debugging configurations and for denial of service attacks. so, you know. keep that in mind.

although a Road Warrior connection must be initiated by the mobile side, the other side can and will rekey using the temporary connection it has created ๐Ÿ’….


๐Ÿ˜ต Pluto's Behaviour When Things Go Wrong ๐Ÿ˜ต

when pluto doesn't understand or accept a message, it just... ignores it ๐Ÿ™ˆ. it is not yet capable of communicating the problem to the other IKE daemon (in the future it might use Notifications to accomplish this in many cases). it does log a diagnostic though, so there's a breadcrumb.

when pluto gets no response from a message, it resends the same message (a message will be sent at most three times) ๐Ÿ“ฎ. this is appropriate: UDP is unreliable, that's just the vibe.

when pluto gets a message it has already seen, there are many cases where it notices and discards it ๐Ÿ—‘๏ธ. this too is appropriate for UDP.

combine these three rules, and you can explain sooo many apparently mysterious behaviours โœจ. in a pluto log, retrying isn't usually the interesting event. the critical thing is either earlier (pluto got a message it didn't like and so ignored it, so it was still awaiting an acceptable message and got impatient) or on the other system (pluto didn't send a reply because it wasn't happy with the previous message). detective work, honestly ๐Ÿ”.


๐Ÿ“ Notes ๐Ÿ“

each IPsec SA is assigned an SPI, a 32-bit number used to refer to the SA ๐Ÿ”ข. the IKE protocol lets the destination of the SA choose the SPI. the range 0 to 0xFF is reserved for IANA. Pluto also avoids choosing an SPI in the range 0x100 to 0xFFF, leaving these SPIs free for manual keying โœจ. just remember that the peer, if it's not pluto, may well choose SPIs in this range โ€” so don't be shocked ๐Ÿ‘‘.


๐Ÿ“‹ Policies ๐Ÿ“‹

this catalogue of policies may be of use when you're trying to configure pluto and another IKE implementation to interoperate ๐Ÿค.

okay so bestie, Phase 1? Only Main Mode is supported. We are not sure that Aggressive Mode is secure. For one thing, it does not support identity protection. It may allow more severe Denial Of Service attacks. ๐Ÿ˜ญ

No Informational Exchanges are supported, periodt. These are optional and since their delivery is not assured, they must not matter. The way that some IKE implementations won't interoperate without Informational Exchanges? we feel they are broken. ๐Ÿ’…

No Informational Payloads are supported. These are optional, but useful. It is of concern that these payloads are not authenticated in Phase 1, nor in those Phase 2 messages authenticated with HASH(3). ๐Ÿ™ˆ

  • DH group tea: Diffie Hellman Group MODP 1536 (5) is supported. Groups MODP768 and MODP 1024 (1 and 2) are not supported because those are too weak. ๐Ÿ’€
  • Host authentication can be done by RSA Signatures or Pre-Shared Secrets. โœจ
  • ๐Ÿšจ TODO! This information is outdated. 3DES CBC (Cypher Block Chaining mode) is the only encryption supported, both for ISAKMP SAs and IPSEC SAs. ๐Ÿ”ฅ
  • MD5 and SHA1 hashing are supported for packet authentication in both kinds of SAs. ๐Ÿฆ‹
  • The ESP, AH, or AH plus ESP are supported. If, and only if, AH and ESP are combined, the ESP need not have its own authentication component. The selection is controlled by the --encrypt and --authenticate flags. ๐Ÿ‘‘
  • Each of these may be combined with IPCOMP Deflate compression, but only if the potential connection specifies compression. ๐ŸŒˆ
  • The IPSEC SAs may be tunnel or transport mode, where appropriate. The --tunnel flag controls this when pluto is initiating. ๐Ÿš‡
  • When responding to an ISAKMP SA proposal, the maximum acceptable lifetime is eight hours. The default is one hour. There is no minimum. The --ikelifetime flag controls this when pluto is initiating. โฐ
  • When responding to an IPSEC SA proposal, the maximum acceptable lifetime is one day. The default is eight hours. There is no minimum. The --ipseclifetime flag controls this when pluto is initiating. ๐ŸŒ™
  • PFS is acceptable, and will be proposed if the --pfs flag was specified. The DH group proposed will be the same as negotiated for Phase 1. ๐Ÿ”

๐Ÿšจ SIGNALS (signal tea) ๐Ÿšจ

pluto responds to SIGHUP by issuing a suggestion that whack --listen might have been intended. lowkey a hint bestie.

pluto exits when it receives SIGTERM. bye! ๐Ÿ’€

๐Ÿ’€ EXIT STATUS (the drama of exit codes) ๐Ÿ’€

pluto normally forks a daemon process, so the exit status is normally a very preliminary result. fr fr.

  • 0 โ€” means that all is OK so far. โœจ
  • 1 โ€” means that something was wrong. ๐Ÿ˜ญ
  • 10 โ€” means that the lock file already exists. ๐Ÿ”’

If whack detects a problem, it will return an exit status of 1. If it received progress messages from pluto, it returns as status the value of the numeric prefix from the last such message that was not a message sent to syslog or a comment (but the prefix for success is treated as 0). Otherwise, the exit status is 0.

๐Ÿ“ FILES (the paths bestie) ๐Ÿ“

  • /run/pluto/pluto.pid
  • /run/pluto/pluto.ctl
  • /etc/ipsec.secrets
  • /dev/urandom

๐ŸŒฟ ENVIRONMENT ๐ŸŒฟ

pluto does not use any environment variables. literally none. no cap.

๐Ÿ‘€ SEE ALSO (go read these too) ๐Ÿ‘€

The rest of the Libreswan distribution, in particular ipsec(8). ๐Ÿ‘‘

ipsec(8) is designed to make using pluto more pleasant. Use it! iykyk.

ipsec.secrets(5) describes the format of the secrets file. ๐Ÿ”

For more information on IPsec, the mailing list, and the relevant documents, see:

https://datatracker.ietf.org/wg/ipsecme/charter/

At the time of writing, the latest IETF IKE RFC is:

RFC 7296 Internet Key Exchange Protocol Version 2 (IKEv2)

The Libreswan web site https://libreswan.org and the mailing lists described there. ๐ŸŒ

The Libreswan wiki https://libreswan.org/wiki includes documentation. ๐Ÿ“š

The Libreswan list of implemented RFCs https://libreswan.org/wiki/Implemented_Standards. โœจ

๐Ÿ“œ HISTORY ๐Ÿ“œ

This code is released under the GPL terms. See the accompanying files CHANGES, COPYING and CREDITS.* for more details. ๐Ÿ“–

Detailed history (including FreeS/WAN and Openswan) can be found in the docs/ directory. ๐Ÿงš

๐Ÿ› BUGS ๐Ÿ›

Please see <https://github.com/libreswan/libreswan/issues> for a list of currently known bugs and missing features. ๐Ÿ‘€

Bugs should be reported to the <swan-dev@lists.libreswan.org> mailing list. ๐Ÿ“ง

โœจ AUTHOR โœจ

Andrew Cagney, Anish Singh Rawat, Antony Antony, Daniel Kahn Gillmor, D. Hugh Redelmeier, Harald Jenny, Jose Quaresma, Matt Rogers, Max-Julian Pogner, Michael Richardson, Paul Wouters, Pietro Monteiro, Simon Deziel, Tuomo Soini, Vukasin Karadzic

Libreswan 5.4.1, dated 10/23/2026, page LIBRESWAN(7) โ€” and that's the whole vibe, bestie! ๐Ÿ’–๐Ÿฆ‹โœจ

๐Ÿ“ฆ where this page comes from