FreeS/WAN Opportunism HowTo =========================== RCSID $Id: opportunism.howto,v 1.8 2001/06/15 02:38:09 dhr Exp $ D. Hugh Redelmeier FreeS/WAN, the LINUX IPSEC implementation, is intended to allow systems to connect through secure tunnels without prearrangement. This HowTo is intended to be a guide to setting up a system to enable this feature, which we call opportunism. Much more information about FreeS/WAN is provided at http://www.freeswan.org. You are expected to already have built and used FreeS/WAN. This document is only intended to describe the support for opportunism after release 1.9. For a more complete description of the design of Opportunism, see our paper "Opportunistic Encryption" (available as opportunism.spec in the same directory as this document). Steps ===== - Understand what you are attempting. Security requires care. Problems are hard to untangle. Be sure to read the last section "Important Limitations". - Install FreeS/WAN (version 1.91 or later). - Add appropriate DNS records to your reverse-map domains. - Add suitable conns to /etc/ipsec.conf. - Try it out: start it, monitor it, fix it. - Now you understand the system better, reread "Important Limitations" These steps are also an outline of this document. Theory ====== If opportunism is enabled, a Security Gateway running FreeS/WAN will intercept the first outbound packet to a particular destination (IP address), and try to negotiate a security tunnel suitable for traffic to that destination. Note that throughout this document, the term "Security Gateway" is meant to include a machine that is protecting its own traffic. To make this work going the other way, the Security Gateway must be willing to negotiate with peers trying to protect traffic initiated from their side. The first novel problem is that our Security Gateway needs to discover the IP address of the other Security Gateway for the packet that prompted the negotiation. Oh, and quickly discover if there is none -- that negotiation will be impossible. The second novel problem is that our Security Gateway needs to authenticate the other Security Gateway. This authentication needs to ensure that the other Security Gateway is who it claims to be AND that it is authorized to represent the client for which it claims to be the gateway. The roles in a particular negotiation are: Source----Initiator----...----Responder----Destination The Source and Destination are endpoints of the traffic that is to be protected. The Source is the one that happened to send the first packet of traffic. Neither needs to be aware of IPSEC or FreeS/WAN. That is the job of their respective Security Gateways, Initiator and Responder. The names "Initiator" and "Responder" match those used in the IPSEC standards. It is quite possible for Source and Initiator to be the same machine; similarly, Destination and Responder could be the same. All traffic from Source or Destination must flow through their Security Gateways if it is to be considered for protection. These roles are fluid -- they can be different for each negotiation. We use the DNS (the Domain Name System) as a distributed database to hold the required information. DNS Records Required ==================== See section 2.3 of "Opportunistic Encryption" for a fuller explanation. Generally, we need to add records to the reverse-map DNS entries for the client machine and the Security Gateway machine. There are special cases that are exceptions. A Security Gateway that is going to initiate an Opportunistic negotiation needs to provide a way for the Responding SG to find a public key for the Initiator to allow authentication. This is accomplished by putting the public key in a KEY record in the reverse-map of the Initiator. Conveniently, the KEY record can be generated by the ipsec_showhostkey(8) command. All you need to do is copy the output of the command ipsec showhostkey into the zone information for the reverse-map. Here is an example, with many characters of the key itself left out: ; RSA 2048 bits xy.example.com Sat Apr 15 13:53:22 2000 xy.example.com. IN KEY 0x4200 4 1 AQOF8tZ2...+buFuFn/ Each client that is to be protected by Opportunistic Encryption must include a special TXT record in its reverse-map. The ipsec_showhostkey(8) command is willing to do this too. Remember: this command must be run on the Security Gateway where the ipsec.secrets file resides. In this case, you must tell the command what IP address to in the TXT record: ipsec showhostkey --txt 10.11.12.13 might produce the output: ; RSA 2048 bits xy.example.com Sat Apr 15 13:53:22 2000 IN TXT "X-IPsec-Server(10)=10.11.12.13 AQOF8tZ2...+buFuFn/" - the quotes matter: this is a single string, as far as DNS is concerned - the X-IPsec-Server is a prefix that signifies that the TXT record contains Opportunism configuration information - the (10) specifies a precedence for this record. This is similar to MX record preferences. Lower numbers have stronger preference. - 10.11.12.13 specifies the IP address of the Security Gateway for this machine. - AQOF8tZ2...+buFuFn/ is the (shortened) encoding of the RSA Public key of the Security Gateway. This output must be added to the zone information for the reverse-map for each client machine. This gets a bit dull and repetitive. Unfortunately, not every administrator has control over the contents of the reverse-map. The only case where we can work around this is where the Initiator has no suitable reverse map (but the Source must!). In this case, the Source's TXT record gives @FQDN ("Fully Qualified Domain Name") in place of its Security Gateway's IP address. This FQDN must match the ID-payload used by the Initiator. Furthermore, a forward lookup for a KEY record on the FQDN must yield the Initiator's public key. Obscure fact: the forward lookup is only done by a Responder, and then only when the Initiator's ID payload specifies the FQDN. There is no provision for a Responder with no control over its reverse-map. DNS changes sometimes take a long time to propagate. Configuring FreeS/WAN ===================== To enable opportunism, you must include a suitable conn in /etc/ipsec.conf and you must enable it. A suitable conn looks like an ordinary conn. It more closely resembles a Road Warrior conn (one that has a wildcard %any specified as the other Security Gateway). But in this case, both the other Security Gateway AND its client are unknown. conn ours-to-anyone # for our client subnet leftsubnet=10.3.2.1.0/24 # any single client in our subnet also=us-to-anyone # rest is same as for SG conn us-to-anyone # for our Security Gatway left=%defaultroute # our SG (defaults leftnexthop too) right=%opportunistic (%defaultroute only works if you have specified interfaces=%defaultroute. Since this isn't the topic of the howto, you will have to look at the other documentation to find out how to handle other cases.) You can have any number of opportunistic conns, but generally it only makes sense to have one for each client subnet and one for the Security Gateway itself. Currently only one interface may be used for opportunism: Pluto knows nothing about routing, so would be unable to choose amongst several. Almost certainly our side's nexthop must be predetermined (%defaultroute will do that). Note: the routing done for outbound Opportunism will catch any packets not covered by a more specific route. This is what you want for packets that are also covered by an eroute. But packets caught by the route and not an eroute will be subject to the no-eroute policy of KLIPS, which defaults to %drop. To enable these conns for inbound opportunistic negotiation, it must be --added: ipsec auto --add us-to-anyone ipsec auto --add ours-to-anyone If you want this automatically done on startup, put auto=add in the us-to-anyone conn. To enable these conns for outbound opportunistic negotiation, it must be both --added and --routed. Outbound packets will then be trapped and will trigger negotiation: ipsec auto --add us-to-anyone ipsec auto --add ours-to-anyone ipsec auto --route us-to-anyone ipsec auto --route ours-to-anyone If you want this automatically done on startup, put auto=route in the us-to-anyone conn (this feature may be renamed in the future). Getting DNS Through =================== There is a serious chicken-and-egg problem. Outbound Opportunism blocks communication with an IP address until it discovers whether that IP address can have an IPSEC connection negotiated. This discovery takes DNS queries. These DNS queries might involve communicating with arbitrary IP addresses. Thus we require DNS queries to succeed before any communication succeeds, including those same DNS queries! The way out of this conundrum is to exempt at least some DNS query IP traffic from Opportunism. There are several possible solutions, all of which have advantages and disadvantages. 1. If you use a single machine, outside your Security Gateway, as DNS server, you can build a clear path (or even an IPSEC tunnel, but not opportunistically) directly to that machine. - you could use a type=passthrough conn to provide a clear path between your machine and the DNS machine. - you could explicitly create an IPSEC connection to your DNS server. Just be sure that it need not access DNS to find the IP addresses or RSA public keys. - you could install an explicit route to the DNS machine through your public interface (not ipsecN). This will bypass KLIPS processing. You might have to adjust your firewall. For example: route add host -net ns.example.com gw gw.example.com dev eth1 2. Generally, it is better to run DNS on your Security Gateway. This leads to a need for non-opportunistic paths to an arbitrary number of DNS servers in the internet. One way to accomplish this is to NOT have outbound opportunism cover the SG itself, but only the subnet behind it. In other words, leave out the ipsec auto --route us-to-anyone You must also add a type=passthrough eroute specifically for us-to-anyone (without this, the traffic will be handled by the KLIPS no-eroute policy). 3. It is actually possible to use a single machine inside your client subnet as a DNS server. The techniques listed in 1 could be used to let it communicate with other DNS servers without interference. This might have advantages over 1 if the DNS machine *only* did DNS. Another technique (not often possible or reasonable) is to give this machine another route to the internet, one that avoids the SG. We would like to have better solutions. Perhaps we will in the future. Suggestions are welcome. Figuring out what is going on ============================= Since Opportunism lets your SG operate with less supervision, you may be puzzled by what it is up to. The usual tools exist, but their use is more important. I like to use ipsec auto --status and also to examine the kernel's eroute table. The "file" /proc/net/ipsec_eroute contains a description of all the eroutes in the kernel (see also ipsec_look(8)). Here is an example: 10 10.3.2.1.0/24 -> 0.0.0.0/0 => %trap 259 10.3.2.1.115/32 -> 10.19.75.161/32 => tun0x1002@10.19.75.145 71 10.44.73.97/32 -> 0.0.0.0/0 => %trap 4119 10.44.73.97/32 -> 10.114.121.41/32 => %pass You read each line as: a packet from within the first subnet, destined for the second subnet, will be processed by the Security Association Identity (SAID) specified last. The first column is the number of (outbound) packets processed by this eroute. For shunt eroutes, the SAID is printed as just the type of shunt: %pass pass the packet through with no processing %drop discard the packet %reject discard the packet and notify sender %hold keep the last packet; discard others %trap cause any trapped packet to generate a PF_KEY ACQUIRE to request negotiation; install a corresponding %hold shunt and attach this packet to the %hold For other eroutes, the SAID is printed as a triple: protocol (three letters), SPI (32-bit number in hex), and destination IP address. Protocols include: tun IP in IP encapsulation (used for most tunnels) esp ESP encapsulation -- part of an IPSEC SA group ah AH packet authentication -- part of an IPSEC SA group So, looking at our sample eroutes: 10 10.3.2.1.0/24 -> 0.0.0.0/0 => %trap This is a TRAP (int0x104) shunt eroute. It was installed by Pluto so that it can catch all traffic from its client subnet to the world at large. Ten outbound packets have been trapped. 259 10.3.2.1.115/32 -> 10.19.75.161/32 => tun0x1002@10.19.75.145 This is a tunnel eroute: packets from 10.3.2.1.115 (within our client subnet) going to 10.19.75.161 will be encrypted and sent to the peer SG 10.19.75.145. This was the product of an Opportunistic negotiation (a hint is that each client subnet has only one member). 259 packets have been sent through this tunnel. 71 10.44.73.97/32 -> 0.0.0.0/0 => %trap This is another TRAP shunt eroute. It is to catch traffic from the Security Gateway to the world. It has caught 71 outbound packets. 4119 10.44.73.97/32 -> 10.114.121.41/32 => %pass This is a %pass (0x100) shunt eroute. It was installed when an attempted Opportunistic negotiation failed because the reverse domain of 10.114.121.41 had no suitable TXT record. 4119 outbound packets have been passed. Important Limitations ===================== Pluto's DNS lookup is synchronous (single-threaded). Not only does this slow things down, but it turns out that in extreme cases where there are a lot of ACQUIRE messages from KLIPS at once, some of those messages can be lost and communications will be blocked by the %hold eroute that Pluto doesn't know about. Pluto now looks every 2 minutes for any %holds that it missed. DNS lookup is not verified -- we don't use Secure DNS. A spoofed DNS could compromise Opportunism. There are several new opportunities for Denial of Service attacks. For example, a Bad Guy could spray our system with pings with forged source addresses. For each unique source address, our system would do a (synchronous!) DNS lookup. Once a %pass eroute is added for a failed negotiation, it will stay until it has been inactive for about 15 minutes. The only activity that counts is outbound -- not surprising since a %pass only affects outbound traffic. If a destination's DNS entry specifies the information we need for negotiation, Pluto will not let communications proceed without negotiating a Security Tunnel. There is currently no way to tear down a tunnel that is no longer in use. To add insult to injury, when the lifetime is about to be exceeded, the initiating Pluto will rekey! Restarting will clear these out. If one side of a Security Tunnel restarts, but doesn't initiate negotiation with the other side, the other side will not be able to communicate with it until it thinks the tunnel needs rekeying due to lifetime. KLIPS does not check that packets coming in through a tunnel have source and destination addresses suitable for that tunnel. This part of "inbound policy checking" is not implemented. A message from one peer could have been forged by another peer. It is even possible to forge the addresses so that it looks as if the packet came from inside your net and is to go out, possibly through another tunnel! So you ought not to trust information more just because it appears to have come from a source covered by a Security Tunnel. This makes it difficult to safely combine a VPN with Opportunism. It isn't clear what firewall policies make sense with Opportunism.