做Strongswan测试的时候,我发现strongswan不能为同一个目的网络建立起多条隧道,百思不得其解,最后在pluto的man手册里找到了答案,里面郑重声明pluto不支持相同目标网络而不同隧道,即使是拥有不同的IP或设备接口。但同样使用pluto做IKE daemon的openswan对待这种情况的政策却比较宽松,在其比较靠后的版本里,默认支持不同设备+IP到同一目标网络(通常配置为rightsubnet)的多条隧道。Pluto 的路由策略都在两者的codebase中指定,路径为:/openswan-x.x.x/programs/pluto/kernel.c , 或者/strongswan-x.x.x/src/pluto/kernel.c , 有兴趣的朋友可以研究下。相关内容如下:
>> /* If there is already a route for peer’s client subnet
>> * and it disagrees about interface or nexthop, we cannot steal it.
>> * Note: if this connection is already routed (perhaps for another
>> * state object), the route will agree.
>> * This is as it should be — it will arise during rekeying.
>> */
>> if (ro != NULL && !routes_agree(ro, c))
>> {
>> loglog(RC_LOG_SERIOUS, “cannot route — route already in use for \”%s\””
>> , ro->name);
>> return route_impossible; /* another connection already
>> using the eroute */
>> }
貌似国内网站上对*swan的讨论比较少,有也只是一些基本安装配置,其实那些硬件防火墙和路由器的实现好多都是以swan的代码为基础的,swan们的功能是相当强大的,我们国内的东东基本就是把那些现成的代码复制过来再稍加修改的。呵呵。这次来学习下pluto的路由机制吧。
1 Routing and Erouting in Pluto
2 =============================
3
4 This is meant as internal documentation for Pluto. As such, it
5 presumes some understanding of Pluto’s code.
6
7 It also describes KLIPS 1 erouting, including details not otherwise
8 documented. KLIPS 1 documentation would be better included in KLIPS.
9
10 Routing and erouting are complicated enough that the Pluto code needs
11 a guide. This document is meant to be that guide.
12
13
14 Mechanisms available to Pluto
15 —————————–
16
17 All outbound packets that are to be processed by KLIPS 1 must be
18 routed to an ipsecN network interface. Pluto only uses normal routing
19 (as opposed to “Advanced Routing”), so the selection of packets is
20 made solely on the basis of the destination address. (Since the
21 actual routing commands are in the updown script, they could be
22 changed by the administrator, but Pluto needs to understand what is
23 going on, and it currently assumes normal routing is used.)
24
25 When an outbound packet hits an ipsecN interface, KLIPS figures out
26 how to process it by finding an eroute that applies to the source and
27 destination addresses. Eroutes are global: they are not specific to a
28 particular ipsecN interface (routing needs to get the packets to any
29 ipsecN interface; erouting takes it from there, ignoring issues of
30 source IP address and nexthop (because nobody knows!)). If multiple
31 eroutes apply to the packet, among the ones with the most specific
32 source subnet, the one with the most specific destination subset is
33 chosen (RGB thinks). If no eroute is discovered, KLIPS acts as if it
34 was covered by a DROP eroute (this is the default behaviour; it can be
35 changed). At most one eroute can exist for a particular pair of
36 client subnets.
37
38 There are fundamentally two kinds of eroutes: “shunt” eroutes and ones
39 that specify that a packet is to be processed by a group of IPSEC SAs.
40 Shunt eroutes specify what is to be done with the packet. Remember
41 that these only apply to outbound packets.
42
43 – TRAP: notify Pluto of the packet (presumably to attempt to negotiate
44 an appropriate group of IPSEC SAs). At the same time, KLIPS
45 installs a HOLD shunt (see below) for the specific source and
46 destination addresses from the packet and retains the packet
47 for later reprocessing (KLIPS does not yet implement retention).
48 Beware: if the TRAP’s subnets both contained a single IP address
49 then installing the HOLD would actually delete the TRAP.
50
51 – PASS: let the packet through in the clear
52
53 – DROP: discard the packet
54
55 – REJECT: discard the packet and notify the sender
56
57 – HOLD: (automatically created by KLIPS when a TRAP fires) block
58 the packet, but retain it. If there is already a retained
59 packet, drop the old one and retain the new. When the HOLD
60 shunt is deleted or replaced, the retained packet is reinjected —
61 there might now be a tunnel. Note that KLIPS doesn’t yet
62 implement the retention part, so HOLD is really like a DROP.
63
64 One consequence of there being only one eroute for a pair of clients
65 is that KLIPS will only use one SA group for output for this pair,
66 even though there could be several SA groups that are authorised and
67 live. Pluto chooses to make this the youngest such group.
68
69
70
71 KLIPS lets through in the clear outbound UDP/500 packets that would
72 otherwise be processed if they originate on this host and meet certain
73 other conditions. The actual test is
74 source == me
75 && (no_eroute || dest == eroute.dest || isanyaddr(eroute.dest))
76 && port == UDP/500
77 The idea is that IKE packets between us and a peer should not be
78 sent through an IPSEC tunnel negotiated between us. Furthermore,
79 our shunt eroutes should not apply to our IKE packets (shunt eroutes
80 will generally have an eroute.dest of 0.0.0.0 or its IPv6 equivalent).
81
82 Inbound behaviour is controlled in a quite different way. KLIPS
83 processes only those inbound packets of ESP or AH protocol, with a
84 destination address for this machine’s ipsecN interfaces. The
85 processing is as dictated by the SAs involved. Unfortunately, the
86 decapsulated packet’s source and destination address are not checked
87 (part of “inbound policy checking”).
88
89 To prevent clear packets being accepted, firewall rules must be put in
90 place. This has nothing to do with KLIPS, but is nonetheless in
91 important part of security. It isn’t clear what firewalling makes
92 sense when Opportunism is allowed.
93
94
95 For routing and firewalling, Pluto invokes the updown script. Pluto
96 installs eroutes via extended PF_KEY messages.
97
98
99 Current Pluto Behaviour
100 ———————–
101
102 Data Structures:
103
104 Routes and most eroutes are associated with connections (struct
105 connection, a potential connection description). The enum routing_t
106 field “routing” in struct connection records the state of routing and
107 erouting for that connection. The values are:
108 RT_UNROUTED, /* unrouted */
109 RT_UNROUTED_HOLD, /* unrouted, but HOLD shunt installed */
110 RT_ROUTED_PROSPECTIVE, /* routed, and TRAP shunt installed */
111 RT_ROUTED_HOLD, /* routed, and HOLD shunt installed */
112 RT_ROUTED_FAILURE, /* routed, and failure-context shunt installed */
113 RT_ROUTED_TUNNEL /* routed, and erouted to an IPSEC SA group */
114 Notice that the routing and erouting are not independent: erouting
115 (except for HOLD) implies that the connection is routed.
116
117 Several struct connections may have the same destination subnet. If
118 they agree on what the route should be, they can share it — any of
119 them may have routing >= RT_ROUTED_PROSPECTIVE. If they disagree,
120 they cannot simultaneously be routed.
121
122 invariant: for all struct connections c, d:
123 (c.that.client == d.that.client
124 && c.routing >= RT_ROUTED_PROSPECTIVE
125 && d.routing >= RT_ROUTED_PROSPECTIVE)
126 => c.interface == d.interface && c.this.nexthop == d.this.nexthop
127
128 There are two kinds of eroutes: shunt eroutes and ones for an IPSEC SA
129 Group. Most eroutes are associated with and are represeented in a
130 connection. The exception is that some HOLD and PASS shunts do not
131 correspond to connections; those are represented in the bare_shunt
132 table.
133
134 An eroute for an IPSEC SA Group is associated with the state object
135 for that Group. The existence of such an eroute is also represented
136 by the “so_serial_t eroute_owner” field in the struct connection. The
137 value is the serial number of the state object for the Group. The
138 special value SOS_NOBODY means that there is no owner associated with
139 this connection for the eroute and hence no normal eroute. At most
140 one eroute owner may exist for a particular (source subnet,
141 destination subnet) pair. A Pluto-managed eroute cannot be associated
142 with an RT_UNROUTED connection.
143
144 invariant: for all struct connection c:
145 c.routing == RT_EROUTED_TUNNEL || c.eroute_owner == SOS_NOBODY
146
147 invariant: for all struct connections c, d:
148 c.this.client == d.this.client && c.that.client == d.that.client
149 && &c != &d
150 => c.routing == RT_UNROUTED || d.routing == RT_UNROUTED
151
152 If no normal eroute is set for a particular (source subnet,
153 destination subnet) pair for which a connection is routed, then a
154 shunt eroute would have been installed. This specifies what should
155 happen to packets snared by the route.
156
157 When Pluto is notified by KLIPS of a packet that has been TRAPped,
158 there is no connection with which to associate the HOLD. It is
159 temporarily held in the “bare_shunt table”. If Opportunism is
160 attempted but DNS doesn’t provide Security Gateway information, Pluto
161 will replace the HOLD with a PASS shunt. Since this PASS isn’t
162 associated with a connection, it too will reside in the bare_shunt
163 table. If the HOLD can be associated with a connection, it will be
164 removed from the bare_shunt table and represented in the connection.
165
166 There are two contexts for which shunt eroutes are installed by Pluto
167 for a particular connection. The first context is with the prospect
168 of dealing with packets before any negotiation has been attempted. I
169 call this context “prospective”. Currently is a TRAP shunt, used to
170 catch packets for initiate opportunistic negotiation. In the future,
171 it might also be used to implement preordained PASS, DROP, or REJECT
172 rules.
173
174 The second context is after a failed negotiation. I call this context
175 “failure”. At this point a different kind of shunt eroute is
176 appropriate. Depending on policy, it could be PASS, DROP, or REJECT,
177 but it is unlikely to be TRAP. The shunt eroute should have a
178 lifetime (this isn’t yet implemented). When the lifetime expires, the
179 failure shunt eroute should be replaced by the prospective shunt
180 eroute.
181
182 The kind and duration of a failure shunt eroute should perhaps depend
183 on the nature of the failure, at least as imperfectly detected by
184 Pluto. We haven’t looked at this. In particular, the mapping from
185 observations to robust respose isn’t obvious.
186
187 The shunt eroute policies should be a function of the potential
188 connection. The failure shunt eroute can be specified for a
189 particular connection with the flags –pass and –drop in a connection
190 definition. There are four combinations, and each has a distinct
191 meaning. The failure shunt eroute is incompletely implemented and
192 cannot be represented in /etc/ipsec.conf.
193
194 There is as yet no control over the prospective shunt eroute: it is
195 always TRAP as far as Pluto is concerned. This is probably
196 reasonable: any other fate suggests that no negotiation will be done,
197 and so a connection definition is inappropriate. These should be
198 implemented as manual conns. There remains the issue of whether Pluto
199 should be aware of them — currently it is not.
200
201
202 Routines:
203
204 [in kernel.c]
205
206 bool do_command(struct connection *c, const char *verb)
207 Run the updown script to perform such tasks as installing a route
208 and adjust the firewall.
209
210 bool could_route(struct connection *c)
211 Check to see whether we could route and eroute the connection.
212 <- shunt_eroute_connection (to check if –route can be performed)
213 <- install_inbound_ipsec_sa (to see if it will be possible
214 to (later) install route and eroute the corresponding outbound SA)
215 <- install_ipsec_sa (to see if the outbound SA can be routed and erouted)
216
217 bool trap_connection(struct connection *c)
218 Install a TRAP shunt eroute for this connection. This implements
219 “whack –route”, the way an admin can specify that packets for a
220 connection should be caught without first bringing it up.
221
222 void unroute_connection(struct connection *c)
223 Delete any eroute for a connection and unroute it if route isn’t shared.
224 <- release_connection
225 <- whack_handle (for “whack –unroute)
226
227 bool eroute_connection(struct connection *c
228 , ipsec_spi_t spi, unsigned int proto, unsigned int satype
229 , unsigned int op, const char *opname UNUSED)
230 Issue PF_KEY commands to KLIPS to add, replace, or delete an eroute.
231 The verb is specified by op and described (for logging) by opname.
232 <- assign_hold
233 <- sag_eroute
234 <- shunt_eroute
235
236 bool assign_hold(struct connection *c
237 , const ip_address *src, const ip_address *dst)
238 Take a HOLD from the bare_shunt table and assign it to a connection.
239 If the HOLD is broadened (i.e. the connection’s source or destination
240 subnets contain more than one IP address), this will involve replacing
241 the HOLD with a different one.
242
243 bool sag_eroute(struct state *st, unsigned op, const char *opname)
244 SA Group eroute manipulation. The SA Group concerned is
245 identified with a state object.
246 <- route_and_eroute several times
247
248 bool shunt_eroute(struct connection *c, unsigned int op, const char *opname)
249 shunt eroute manipulation. Shunt eroutes are associated with
250 connections.
251 <- unroute_connection
252 <- route_and_eroute
253 <- delete_ipsec_sa
254
255 bool route_and_eroute(struct connection *c, struct state *st)
256 Install a route and then a prospective shunt eroute or an SA group
257 eroute. The code assumes that could_route had previously
258 given the go-ahead. Any SA group to be erouted must already
259 exist.
260 <- shunt_eroute_connection
261 <- install_ipsec_sa
262
263 void scan_proc_shunts(void)
264 Every SHUNT_SCAN_INTERVAL scan /proc/net/ipsec_eroute.
265 Delete any PASS eroute in the bare_shunt table that hasn’t been used
266 within the last SHUNT_PATIENCE seconds.
267 For any HOLD for which Pluto hasn’t received an ACQUIRE (possibly
268 lost due to congestion), act as if an ACQUIRE were received.
269
270 [in connection.c]
271
272 struct connection *route_owner(struct connection *c, struct connection **erop)
273 Find the connection to connection c’s peer’s client with the
274 largest value of .routing. All other things being equal,
275 preference is given to c. Return NULL if no connection is routed
276 at all. If erop is non-null, sets it to a connection sharing both
277 our client subnet and peer’s client subnet with the largest value
278 of .routing.
279 The return value is used to find other connections sharing
280 a route. The value of *erop is used to find other connections
281 sharing an eroute.
282 <- could_route (to find any conflicting routes or eroutes)
283 <- unroute_connection (to find out if our route is still in use
284 after this connection is finished with it)
285 <- install_inbound_ipsec_sa (to find other IPSEC SAs for the
286 same peer clients; when we find them WE KILL THEM; a
287 kludge to deal with road warriors reconnecting)
288 <- route_and_eroute (to find all the connections from which the
289 route or eroute is being stolen)
290
291 Uses:
292
293 – setting up route & shunt eroute to TRAP packets for opportunism
294 (whack –route). Perhaps also manually designating DROP, REJECT, or
295 PASS for certain packets.
296
297 whack_handle() responds to –route; calls route_connection()
298
299
300 – removing same (whack –unroute)
301
302 whack_handle() responds to –unroute; calls unroute_connection()
303
304 – installing route & normal eroute for a newly negotiated group of
305 outbound IPSEC SAs
306
307 + perhaps an (additional) route is not needed: if the negotiation
308 was initiated by a TRAPped outgoing packet, then there must
309 already have been a route that got the packet to ipsecN. Mind
310 you, it could have been the wrong N!
311
312 install_ipsec_sa()
313
314 – updating a normal eroute when a new group of IPSEC SAs replaces
315 an old one due to rekeying.
316
317 install_ipsec_sa()
318
319 – replacing an old eroute when a negotiation fails. But this is
320 tricky. If this was a rekeying, we should just leave the old
321 normal eroute be — it might still work. Otherwise, this was
322 an initial negotiation: we should replace the shunt eroute
323 with one appropriate for the failure context.
324
325 – when a group of IPSEC SAs dies or is killed, and it had the eroute,
326 its normal eroute should be replaced by a shunt eroute. If there
327 was an attempt to replace the group, the replacement is in the
328 failure context; otherwise the replacement is in the prospective
329 context.
本文转自 拾瓦兴阁 51CTO博客,原文链接:http://blog.51cto.com/ponyjia/933624