summaryrefslogtreecommitdiff
path: root/programs/pluto/routing.txt
diff options
context:
space:
mode:
authorRene Mayrhofer <rene@mayrhofer.eu.org>2006-05-22 05:12:18 +0000
committerRene Mayrhofer <rene@mayrhofer.eu.org>2006-05-22 05:12:18 +0000
commitaa0f5b38aec14428b4b80e06f90ff781f8bca5f1 (patch)
tree95f3d0c8cb0d59d88900dbbd72110d7ab6e15b2a /programs/pluto/routing.txt
parent7c383bc22113b23718be89fe18eeb251942d7356 (diff)
downloadvyos-strongswan-aa0f5b38aec14428b4b80e06f90ff781f8bca5f1.tar.gz
vyos-strongswan-aa0f5b38aec14428b4b80e06f90ff781f8bca5f1.zip
Import initial strongswan 2.7.0 version into SVN.
Diffstat (limited to 'programs/pluto/routing.txt')
-rw-r--r--programs/pluto/routing.txt331
1 files changed, 331 insertions, 0 deletions
diff --git a/programs/pluto/routing.txt b/programs/pluto/routing.txt
new file mode 100644
index 000000000..a69b8a542
--- /dev/null
+++ b/programs/pluto/routing.txt
@@ -0,0 +1,331 @@
+Routing and Erouting in Pluto
+=============================
+
+RCSID $Id: routing.txt,v 1.1 2004/03/15 20:35:29 as Exp $
+
+This is meant as internal documentation for Pluto. As such, it
+presumes some understanding of Pluto's code.
+
+It also describes KLIPS 1 erouting, including details not otherwise
+documented. KLIPS 1 documentation would be better included in KLIPS.
+
+Routing and erouting are complicated enough that the Pluto code needs
+a guide. This document is meant to be that guide.
+
+
+Mechanisms available to Pluto
+-----------------------------
+
+All outbound packets that are to be processed by KLIPS 1 must be
+routed to an ipsecN network interface. Pluto only uses normal routing
+(as opposed to "Advanced Routing"), so the selection of packets is
+made solely on the basis of the destination address. (Since the
+actual routing commands are in the updown script, they could be
+changed by the administrator, but Pluto needs to understand what is
+going on, and it currently assumes normal routing is used.)
+
+When an outbound packet hits an ipsecN interface, KLIPS figures out
+how to process it by finding an eroute that applies to the source and
+destination addresses. Eroutes are global: they are not specific to a
+particular ipsecN interface (routing needs to get the packets to any
+ipsecN interface; erouting takes it from there, ignoring issues of
+source IP address and nexthop (because nobody knows!)). If multiple
+eroutes apply to the packet, among the ones with the most specific
+source subnet, the one with the most specific destination subset is
+chosen (RGB thinks). If no eroute is discovered, KLIPS acts as if it
+was covered by a DROP eroute (this is the default behaviour; it can be
+changed). At most one eroute can exist for a particular pair of
+client subnets.
+
+There are fundamentally two kinds of eroutes: "shunt" eroutes and ones
+that specify that a packet is to be processed by a group of IPSEC SAs.
+Shunt eroutes specify what is to be done with the packet. Remember
+that these only apply to outbound packets.
+
+- TRAP: notify Pluto of the packet (presumably to attempt to negotiate
+ an appropriate group of IPSEC SAs). At the same time, KLIPS
+ installs a HOLD shunt (see below) for the specific source and
+ destination addresses from the packet and retains the packet
+ for later reprocessing (KLIPS does not yet implement retention).
+ Beware: if the TRAP's subnets both contained a single IP address
+ then installing the HOLD would actually delete the TRAP.
+
+- PASS: let the packet through in the clear
+
+- DROP: discard the packet
+
+- REJECT: discard the packet and notify the sender
+
+- HOLD: (automatically created by KLIPS when a TRAP fires) block
+ the packet, but retain it. If there is already a retained
+ packet, drop the old one and retain the new. When the HOLD
+ shunt is deleted or replaced, the retained packet is reinjected --
+ there might now be a tunnel. Note that KLIPS doesn't yet
+ implement the retention part, so HOLD is really like a DROP.
+
+One consequence of there being only one eroute for a pair of clients
+is that KLIPS will only use one SA group for output for this pair,
+even though there could be several SA groups that are authorised and
+live. Pluto chooses to make this the youngest such group.
+
+
+
+KLIPS lets through in the clear outbound UDP/500 packets that would
+otherwise be processed if they originate on this host and meet certain
+other conditions. The actual test is
+ source == me
+ && (no_eroute || dest == eroute.dest || isanyaddr(eroute.dest))
+ && port == UDP/500
+The idea is that IKE packets between us and a peer should not be
+sent through an IPSEC tunnel negotiated between us. Furthermore,
+our shunt eroutes should not apply to our IKE packets (shunt eroutes
+will generally have an eroute.dest of 0.0.0.0 or its IPv6 equivalent).
+
+Inbound behaviour is controlled in a quite different way. KLIPS
+processes only those inbound packets of ESP or AH protocol, with a
+destination address for this machine's ipsecN interfaces. The
+processing is as dictated by the SAs involved. Unfortunately, the
+decapsulated packet's source and destination address are not checked
+(part of "inbound policy checking").
+
+To prevent clear packets being accepted, firewall rules must be put in
+place. This has nothing to do with KLIPS, but is nonetheless in
+important part of security. It isn't clear what firewalling makes
+sense when Opportunism is allowed.
+
+
+For routing and firewalling, Pluto invokes the updown script. Pluto
+installs eroutes via extended PF_KEY messages.
+
+
+Current Pluto Behaviour
+-----------------------
+
+Data Structures:
+
+Routes and most eroutes are associated with connections (struct
+connection, a potential connection description). The enum routing_t
+field "routing" in struct connection records the state of routing and
+erouting for that connection. The values are:
+ RT_UNROUTED, /* unrouted */
+ RT_UNROUTED_HOLD, /* unrouted, but HOLD shunt installed */
+ RT_ROUTED_PROSPECTIVE, /* routed, and TRAP shunt installed */
+ RT_ROUTED_HOLD, /* routed, and HOLD shunt installed */
+ RT_ROUTED_FAILURE, /* routed, and failure-context shunt installed */
+ RT_ROUTED_TUNNEL /* routed, and erouted to an IPSEC SA group */
+Notice that the routing and erouting are not independent: erouting
+(except for HOLD) implies that the connection is routed.
+
+Several struct connections may have the same destination subnet. If
+they agree on what the route should be, they can share it -- any of
+them may have routing >= RT_ROUTED_PROSPECTIVE. If they disagree,
+they cannot simultaneously be routed.
+
+invariant: for all struct connections c, d:
+ (c.that.client == d.that.client
+ && c.routing >= RT_ROUTED_PROSPECTIVE
+ && d.routing >= RT_ROUTED_PROSPECTIVE)
+ => c.interface == d.interface && c.this.nexthop == d.this.nexthop
+
+There are two kinds of eroutes: shunt eroutes and ones for an IPSEC SA
+Group. Most eroutes are associated with and are represeented in a
+connection. The exception is that some HOLD and PASS shunts do not
+correspond to connections; those are represented in the bare_shunt
+table.
+
+An eroute for an IPSEC SA Group is associated with the state object
+for that Group. The existence of such an eroute is also represented
+by the "so_serial_t eroute_owner" field in the struct connection. The
+value is the serial number of the state object for the Group. The
+special value SOS_NOBODY means that there is no owner associated with
+this connection for the eroute and hence no normal eroute. At most
+one eroute owner may exist for a particular (source subnet,
+destination subnet) pair. A Pluto-managed eroute cannot be associated
+with an RT_UNROUTED connection.
+
+invariant: for all struct connection c:
+ c.routing == RT_EROUTED_TUNNEL || c.eroute_owner == SOS_NOBODY
+
+invariant: for all struct connections c, d:
+ c.this.client == d.this.client && c.that.client == d.that.client
+ && &c != &d
+ => c.routing == RT_UNROUTED || d.routing == RT_UNROUTED
+
+If no normal eroute is set for a particular (source subnet,
+destination subnet) pair for which a connection is routed, then a
+shunt eroute would have been installed. This specifies what should
+happen to packets snared by the route.
+
+When Pluto is notified by KLIPS of a packet that has been TRAPped,
+there is no connection with which to associate the HOLD. It is
+temporarily held in the "bare_shunt table". If Opportunism is
+attempted but DNS doesn't provide Security Gateway information, Pluto
+will replace the HOLD with a PASS shunt. Since this PASS isn't
+associated with a connection, it too will reside in the bare_shunt
+table. If the HOLD can be associated with a connection, it will be
+removed from the bare_shunt table and represented in the connection.
+
+There are two contexts for which shunt eroutes are installed by Pluto
+for a particular connection. The first context is with the prospect
+of dealing with packets before any negotiation has been attempted. I
+call this context "prospective". Currently is a TRAP shunt, used to
+catch packets for initiate opportunistic negotiation. In the future,
+it might also be used to implement preordained PASS, DROP, or REJECT
+rules.
+
+The second context is after a failed negotiation. I call this context
+"failure". At this point a different kind of shunt eroute is
+appropriate. Depending on policy, it could be PASS, DROP, or REJECT,
+but it is unlikely to be TRAP. The shunt eroute should have a
+lifetime (this isn't yet implemented). When the lifetime expires, the
+failure shunt eroute should be replaced by the prospective shunt
+eroute.
+
+The kind and duration of a failure shunt eroute should perhaps depend
+on the nature of the failure, at least as imperfectly detected by
+Pluto. We haven't looked at this. In particular, the mapping from
+observations to robust respose isn't obvious.
+
+The shunt eroute policies should be a function of the potential
+connection. The failure shunt eroute can be specified for a
+particular connection with the flags --pass and --drop in a connection
+definition. There are four combinations, and each has a distinct
+meaning. The failure shunt eroute is incompletely implemented and
+cannot be represented in /etc/ipsec.conf.
+
+There is as yet no control over the prospective shunt eroute: it is
+always TRAP as far as Pluto is concerned. This is probably
+reasonable: any other fate suggests that no negotiation will be done,
+and so a connection definition is inappropriate. These should be
+implemented as manual conns. There remains the issue of whether Pluto
+should be aware of them -- currently it is not.
+
+
+Routines:
+
+[in kernel.c]
+
+bool do_command(struct connection *c, const char *verb)
+ Run the updown script to perform such tasks as installing a route
+ and adjust the firewall.
+
+bool could_route(struct connection *c)
+ Check to see whether we could route and eroute the connection.
+ <- shunt_eroute_connection (to check if --route can be performed)
+ <- install_inbound_ipsec_sa (to see if it will be possible
+ to (later) install route and eroute the corresponding outbound SA)
+ <- install_ipsec_sa (to see if the outbound SA can be routed and erouted)
+
+bool trap_connection(struct connection *c)
+ Install a TRAP shunt eroute for this connection. This implements
+ "whack --route", the way an admin can specify that packets for a
+ connection should be caught without first bringing it up.
+
+void unroute_connection(struct connection *c)
+ Delete any eroute for a connection and unroute it if route isn't shared.
+ <- release_connection
+ <- whack_handle (for "whack --unroute)
+
+bool eroute_connection(struct connection *c
+, ipsec_spi_t spi, unsigned int proto, unsigned int satype
+, unsigned int op, const char *opname UNUSED)
+ Issue PF_KEY commands to KLIPS to add, replace, or delete an eroute.
+ The verb is specified by op and described (for logging) by opname.
+ <- assign_hold
+ <- sag_eroute
+ <- shunt_eroute
+
+bool assign_hold(struct connection *c
+, const ip_address *src, const ip_address *dst)
+ Take a HOLD from the bare_shunt table and assign it to a connection.
+ If the HOLD is broadened (i.e. the connection's source or destination
+ subnets contain more than one IP address), this will involve replacing
+ the HOLD with a different one.
+
+bool sag_eroute(struct state *st, unsigned op, const char *opname)
+ SA Group eroute manipulation. The SA Group concerned is
+ identified with a state object.
+ <- route_and_eroute several times
+
+bool shunt_eroute(struct connection *c, unsigned int op, const char *opname)
+ shunt eroute manipulation. Shunt eroutes are associated with
+ connections.
+ <- unroute_connection
+ <- route_and_eroute
+ <- delete_ipsec_sa
+
+bool route_and_eroute(struct connection *c, struct state *st)
+ Install a route and then a prospective shunt eroute or an SA group
+ eroute. The code assumes that could_route had previously
+ given the go-ahead. Any SA group to be erouted must already
+ exist.
+ <- shunt_eroute_connection
+ <- install_ipsec_sa
+
+void scan_proc_shunts(void)
+ Every SHUNT_SCAN_INTERVAL scan /proc/net/ipsec_eroute.
+ Delete any PASS eroute in the bare_shunt table that hasn't been used
+ within the last SHUNT_PATIENCE seconds.
+ For any HOLD for which Pluto hasn't received an ACQUIRE (possibly
+ lost due to congestion), act as if an ACQUIRE were received.
+
+[in connection.c]
+
+struct connection *route_owner(struct connection *c, struct connection **erop)
+ Find the connection to connection c's peer's client with the
+ largest value of .routing. All other things being equal,
+ preference is given to c. Return NULL if no connection is routed
+ at all. If erop is non-null, sets it to a connection sharing both
+ our client subnet and peer's client subnet with the largest value
+ of .routing.
+ The return value is used to find other connections sharing
+ a route. The value of *erop is used to find other connections
+ sharing an eroute.
+ <- could_route (to find any conflicting routes or eroutes)
+ <- unroute_connection (to find out if our route is still in use
+ after this connection is finished with it)
+ <- install_inbound_ipsec_sa (to find other IPSEC SAs for the
+ same peer clients; when we find them WE KILL THEM; a
+ kludge to deal with road warriors reconnecting)
+ <- route_and_eroute (to find all the connections from which the
+ route or eroute is being stolen)
+
+Uses:
+
+- setting up route & shunt eroute to TRAP packets for opportunism
+ (whack --route). Perhaps also manually designating DROP, REJECT, or
+ PASS for certain packets.
+
+ whack_handle() responds to --route; calls route_connection()
+
+
+- removing same (whack --unroute)
+
+ whack_handle() responds to --unroute; calls unroute_connection()
+
+- installing route & normal eroute for a newly negotiated group of
+ outbound IPSEC SAs
+
+ + perhaps an (additional) route is not needed: if the negotiation
+ was initiated by a TRAPped outgoing packet, then there must
+ already have been a route that got the packet to ipsecN. Mind
+ you, it could have been the wrong N!
+
+ install_ipsec_sa()
+
+- updating a normal eroute when a new group of IPSEC SAs replaces
+ an old one due to rekeying.
+
+ install_ipsec_sa()
+
+- replacing an old eroute when a negotiation fails. But this is
+ tricky. If this was a rekeying, we should just leave the old
+ normal eroute be -- it might still work. Otherwise, this was
+ an initial negotiation: we should replace the shunt eroute
+ with one appropriate for the failure context.
+
+- when a group of IPSEC SAs dies or is killed, and it had the eroute,
+ its normal eroute should be replaced by a shunt eroute. If there
+ was an attempt to replace the group, the replacement is in the
+ failure context; otherwise the replacement is in the prospective
+ context.