diff options
Diffstat (limited to 'src/pluto/routing.txt')
-rw-r--r-- | src/pluto/routing.txt | 329 |
1 files changed, 0 insertions, 329 deletions
diff --git a/src/pluto/routing.txt b/src/pluto/routing.txt deleted file mode 100644 index 2609bf86d..000000000 --- a/src/pluto/routing.txt +++ /dev/null @@ -1,329 +0,0 @@ -Routing and Erouting in Pluto -============================= - -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. |