Browse Source

Add an example usage

Baptiste Jonglez 7 years ago
parent
commit
4785ad64b8
4 changed files with 180 additions and 11 deletions
  1. 28 11
      README.md
  2. 31 0
      examples/slash32_leases/README.md
  3. 95 0
      examples/slash32_leases/kea-dhcp4.conf
  4. 26 0
      examples/slash32_leases/script.sh

+ 28 - 11
README.md

@@ -38,13 +38,38 @@ this hook is well-suited:
 
 - add/remove routing entries when DHCP clients arrive or leave.  This can be useful
   when handing out IPv4 addressing in /32 subnets, or IPv6 Prefix Delegation
-  with DHCPv6-PD;
+  with DHCPv6-PD.  An example is included in `examples/slash32_leases/`;
 - update firewall rules to allow/refuse access to new DHCP clients;
 - log information about successful leases.
 
 For more complex use-cases, including non-trivial changes to Kea's behaviour,
 it may be easier to just write a Kea hook yourself.
 
+## Examples
+
+If you have more examples of usage, feel free to contribute your Kea
+config and your scripts!
+
+### Handing out IPv4 addresses in /32 subnets
+
+This example allows to lease IPv4 addresses individually (/32 subnets), by
+inserting routes in the kernel each time a DHCP client connects, and
+sending custom routes to clients using DHCP option 121.  This is mostly
+useful to hand out public IPv4 addresses to customers.
+
+See [README](examples/slash32_leases/README.md) for more details.
+
+### Debug script
+
+To experiment, a simple debug script is provided: `examples/debug.sh`.  It
+simply prints the name of the hook point and all environment variables
+passed to it.
+
+The output of the script is at `/tmp/kea-hook-runscript-debug.log`.  A nice way to debug
+is to continously display the content of this file:
+
+    tail -F /tmp/kea-hook-runscript-debug.log
+
 ## How to build
 
 You first need to compile the hook.  For this, you need Kea and Boost
@@ -102,21 +127,13 @@ The script will receive the name of the hook point as first argument, and all
 relevant information available at the current hook point will be passed as
 environment variables, documented below.
 
+To debug, see the `examples/debug.sh` script described above.
+
 Refer to the Kea documentation for more information about each hook point:
 
 - DHCPv4 hooks reference: <https://jenkins.isc.org/job/Kea_doc/doxygen/de/df3/dhcpv4Hooks.html>
 - DHCPv6 hooks reference: <https://jenkins.isc.org/job/Kea_doc/doxygen/d1/d02/dhcpv6Hooks.html>
 
-## Debug script
-
-To experiment, an example script is provided: `examples/debug.sh`.  It simply prints
-the name of the hook point and all environment variables passed to it.
-
-The output of the script is at `/tmp/kea-hook-runscript-debug.log`.  A nice way to debug
-is to continously display the content of this file:
-
-    tail -F /tmp/kea-hook-runscript-debug.log
-
 # Reference of variables passed to the external script
 
 ## DHCPv4 variables

+ 31 - 0
examples/slash32_leases/README.md

@@ -0,0 +1,31 @@
+The goal of this example is to lease IPv4 addresses individually (/32 design).
+This is essentially a "out-of-subnet" reservation mode, because clients do not
+need to be in the same IP subnet as the DHCP server.  This is mostly
+useful to hand out public IPv4 addresses to customers.
+
+This method is very flexible:
+
+- each DHCP server can handle clients with very different IP addresses
+  (there is no need to partition the network with static subnets)
+- clients can "move" from one DHCP server to another while keeping
+  their IP address (even when moving to a different layer 2 network),
+  provided that a dynamic routing protocol is used.
+
+The script adds a route in the Linux kernel whenever a DHCP client gets a lease,
+so that the new client's IP address becomes reachable.  Similarly, when an IP address
+is released or a lease expires, the route is removed from the kernel.  This assumes
+that clients are directly connected to Kea (same layer 2 network), so it will not
+work with DHCP relays.  In such cases, the DHCP relay itself should manage routes
+towards clients, not Kea.
+
+The routes added by the script can then be picked up by a routing daemon
+(e.g. [Bird](http://bird.network.cz/)) and propagated in a IGP like OSPF.
+
+On the client side, DHCP option 121 is used so that the client can use the
+DHCP server as gateway without being in the same subnet.  Assuming the DHCP
+server's IP is `10.250.250.1/32` and the client's leased IP is `192.0.2.201/32`,
+the routing table of the client will look like this:
+
+    10.250.250.1 dev eth0 proto kernel  scope link  src 192.0.2.201  metric 224 
+    default via 10.250.250.1 dev eth0 src 192.0.2.201  metric 224 
+

+ 95 - 0
examples/slash32_leases/kea-dhcp4.conf

@@ -0,0 +1,95 @@
+{
+"Dhcp4":
+{
+  "interfaces-config": {
+    "interfaces": [ "eth0" ]
+  },
+
+  "hooks-libraries": [
+    {
+      "library": "/path/to/kea-hook-runscript/kea-hook-runscript.so",
+      "parameters": {
+        "script": "/path/to/script.sh"
+      }
+    }
+  ],
+
+  "lease-database": {
+    "type": "memfile"
+  },
+
+  /* Option 121 definition */
+  "option-def": [
+         {
+              "name": "rfc3442-classless-static-routes",
+              "code": 121,
+              "space": "dhcp4",
+              "type": "record",
+              "array": false,
+              /* This is not a general option 121, it is specific to this usage with two routes: */
+              /* Subnet length of destination1 (32), destination1 (X/32), router1,    destination2 (0/0), router2 */
+              "record-types": "uint8, ipv4-address, ipv4-address,                    uint8, ipv4-address"
+    }
+  ],
+
+
+  /* Only use client MAC address, not Client ID */
+  "match-client-id": false,
+
+  /* Set short lifetime, so that routes are removed from the kernel shortly after
+     a client leaves the network without sending a DHCPRELEASE. */
+  "valid-lifetime": 300,
+  "renew-timer": 220,
+  "rebind-timer": 220,
+
+  "host-reservation-identifiers": ["hw-address"],
+  "subnet4": [
+  {
+    /* Hack so that Kea hands out addresses in /32 subnets */
+    "subnet": "0.0.0.0/32",
+
+    /* Send appropriate routes to the client (you should adapt this, see README) */
+    "option-data": [
+        {
+          "name": "rfc3442-classless-static-routes",
+           /*       10.250.250.1/32 via 0.0.0.0,   0/0 via 10.250.250.1 */
+           "data": "32, 10.250.250.1, 0.0.0.0,     0, 10.250.250.1"
+        }
+    ],
+
+    "interface": "eth0",
+    "reservation-mode": "out-of-pool",
+    /* IP addresses reserved for clients, can be any /32 address. */
+    "reservations": [
+         {
+             "hw-address": "96:ec:f8:ac:d8:bf",
+             "ip-address": "192.0.2.201"
+         },
+         {
+             "hw-address": "aa:bb:cc:dd:ee:ff",
+             "ip-address": "203.0.113.12"
+         }
+    ]
+  }
+  ]
+},
+
+"Logging":
+{
+  "loggers": [
+    {
+      "name": "kea-dhcp4",
+      "output_options": [
+          {
+            "output": "stdout"
+            #"output": "/var/log/kea-dhcp4.log"
+          }
+      ],
+      "severity": "DEBUG",
+      "debuglevel": 0
+    }
+  ]
+}
+
+}
+

+ 26 - 0
examples/slash32_leases/script.sh

@@ -0,0 +1,26 @@
+#!/bin/sh
+# This script adds and removes routes in the Linux kernel whenever a DHCP client
+# gets a lease or a lease expires.
+
+# Protocol to use in "ip route"
+PROTO=static
+
+case "$1" in
+  "lease4_select")
+    # Only add route if FAKE_ALLOCATION is set to 0
+    [ "${KEA_FAKE_ALLOCATION}" = "0" ] || break
+    ip route replace "${KEA_LEASE4_ADDRESS}"/32 dev "${KEA_QUERY4_INTERFACE}" proto "${PROTO}"
+    ;;
+  "lease4_renew")
+    ip route replace "${KEA_LEASE4_ADDRESS}"/32 dev "${KEA_QUERY4_INTERFACE}" proto "${PROTO}"
+    ;;
+  "lease4_release"|"lease4_expire")
+    ip route del "${KEA_LEASE4_ADDRESS}"/32 proto "${PROTO}"
+    ;;
+  "lease4_decline")
+    echo "$(date -R): received DHCPDECLINE on ${KEA_QUERY4_INTERFACE} from ${KEA_QUERY4_HWADDR} about ${KEA_LEASE4_ADDRESS}." >&2
+    echo "Probably a duplicate IP assignment, not removing any route." >&2
+    echo "Existing route for this IP: $(ip route show ${KEA_LEASE4_ADDRESS})" >&2
+    echo "Existing ARP entry for this IP: $(ip neigh show ${KEA_LEASE4_ADDRESS})" >&2
+    ;;
+esac