[RFC ] include with wildcard filenames

Bob Harold rharolde at umich.edu
Wed Feb 28 14:55:23 UTC 2018


On Wed, Feb 28, 2018 at 4:48 AM, Ulf Samuelsson <dhcp at emagii.com> wrote:

> The device consist of a master and several slaves.
> Normally, the unit is installed and the slave configuration rarely changes.
> Restarting the dhcp server during installation is not a problem
> In many cases, the slaves never change after installation.
> If the slave configuration changes, then the unit does not need to operate
> normally during the installation  so a few restarts are not a problem.
>
> In this scenario, only an intruder will cause the adding to the
> ”untrusted” class.
>
> I was thinking that omshell might help avoid a restart here, but I have
> not studied
> it in detail, so this is still an unknown.
>
> The DHCP server has a single ethernet MAC, connected directly to the
> switch.
>
> There were VLANs before protecting the slaves, but they were removed for
> some reason, but I do not know the details.
>
> Having wildcards still seems useful, anyway.
>
> Best Regards,
> Ulf Samuelsson
>
> > 28 feb. 2018 kl. 09:52 skrev Bill Shirley <bill at c3po.polymerindustries.
> biz>:
> >
> > This sounds like the wrong approach to addressing your problem because
> > for dhcpd to honor the new configuration, it would need to be restarted
> every
> > time a file is added/deleted/changed in the wildcard directory.
> >
> > This sounds more like a task for iptables and ipsets.
> >
> > Are all four of these private networks on the same NIC?  Are these
> subnets
> > VLANs?
> >
> > As far as I know, there is no mechanism to consult an source external to
> the
> > dhcpd program for information.
> >
> > Bill
> >
> >> On 2/27/2018 5:33 PM, Ulf Samuelsson wrote:
> >> I was trying out a dhcpd configuration, and found to my dismay
> >> that the DHCP server did not support wildcards for include statements.
> >> include "/etc/dhcp/pools/*.conf";
> >> did not work.
> >>
> >> BACKGROUND:
> >>
> >> I have an application, where I want to use the DHCP server
> >> as part of the authentication process for connected machines.
> >>
> >> I want to use three ranges.
> >> pool 0 => 169.254.128.x            trusted units
> >> pool 1 => 169.254.254.x            units demanding to be trusted
> >> pool 2 => 169.254.1.x              normal units
> >> pool 3 => 169.254.253.x            untrusted units/intruders
> >>
> >> The DHCP CPU Ethernet Controller communicates through a five port
> switch.
> >> port 0: trusted units    pool 0
> >> port 2: internet port
> >> port 3: service port
> >> port 4: CPU port    169.254.1.1
> >>
> >> Units connected on port 0, provides a dhcp-client-identifier indicating
> that they want an address in pool 0, but initially they will get a short
> term lease in pool 1, until it is verified that they are on port 0.
> >>
> >> Units without this dhcp-client-identifier, should get an address in
> pool 2.
> >>
> >> An intruder, trying to get a pool 0 address, will supply the same
> dhcp-client-identifier as port 0 units. They will also initially get a
> short term pool 1 address, but when the intrusion attempt is detected, they
> should be declared "untrusted". Future leases should be in pool 3.
> >>
> >> =====
> >> When a pool 1 address is allocated, the commit event is used to run a
> script which will read out information from the switch and determine if the
> request comes from port 0.
> >>
> >> Request comes from (port == 0) => the mac address should be "trusted"
> >> Request comes from (port != 0) => the mac address should be "untrusted".
> >>
> >> I define:
> >> class "trusted" {
> >>     match hardware;
> >> }
> >>
> >> class "untrusted" {
> >>     match hardware;
> >> }
> >>
> >> An incoming request from "00:11:22:33:44:55" adds a file:
> >> /etc/dhcp/trusted/00:11:22:33:44:55:
> >>       sub-class "trusted" 1:00:11:22:33:44:55;
> >> or
> >> /etc/dhcp/untrusted/00:11:22:33:44:55:
> >>       sub-class "trusted" 1:00:11:22:33:44:55;
> >>
> >>
> >> When the short term pool 1 lease expires (after 1-2 minutes)
> >> the new lease will be classified either as "trusted" (getting a pool 0
> lease) or "untrusted" (getting a pool 3 lease).
> >>
> >> It would be practical to have the dhcpd.conf file contain:
> >>
> >> include "/etc/dhcp/trusted/*";
> >> include "/etc/dhcp/untrusted/*";
> >>
> >> but unfortunately wildcards in include statements are not supported.
> >>
> >> ====================================
> >>
> >> I did a patch for dhcp-4.3.6 which is slightly limited.
> >> It supports only wildcards on files within a single directory.
> >> I.E: include "/etc/dhcp/pools/*.conf"; is supported
> >> I.E: include "/etc/dhcp/*/dhcp.conf"; is not supported
> >> The wildcard may not be in a directory.
> >>
> >> Did a small test program which tested the functionality of wildcards,
> >> and then patched the dhcp server, but it has not been tested yet, as
> part of dhcp
> >> Still would like to have peoples opinion, whether this type of
> functionality is desirable.
> >> It is certainly possible to do this without wildcards,
> >> but wildcards seems a much cleaner solution.
> >> ====================================
> >>
> >> From dcc981f1371f390befffc950b9dc3a8107059643 Mon Sep 17 00:00:00 2001
> >> From: Ulf Samuelsson <ulf at emagii.com>
> >> Date: Tue, 27 Feb 2018 21:03:52 +0100
> >> Subject: [PATCH 14/14] Support wildcard in include files
> >>
> >> Signed-off-by: Ulf Samuelsson <ulf at emagii.com>
> >> ---
> >>  includes/dhcpd.h  |  3 +++
> >>  server/confpars.c | 71 ++++++++++++++++++++++++++++++
> +++++++++++++++++++++++--
> >>  2 files changed, 72 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/includes/dhcpd.h b/includes/dhcpd.h
> >> index eab09a6..8208fbe 100644
> >> --- a/includes/dhcpd.h
> >> +++ b/includes/dhcpd.h
> >> @@ -53,6 +53,9 @@
> >>  #include <sys/mman.h>
> >>  #include <ctype.h>
> >>  #include <time.h>
> >> +#include <dirent.h>
> >> +#include <libgen.h>
> >> +#include <fnmatch.h>
> >>
> >>  #include <net/if.h>
> >>  #undef FDDI
> >> diff --git a/server/confpars.c b/server/confpars.c
> >> index c0735fe..c12f5c7 100644
> >> --- a/server/confpars.c
> >> +++ b/server/confpars.c
> >> @@ -327,7 +327,7 @@ isc_result_t lease_file_subparse (struct parse
> *cfile)
> >>     parameter :== DEFAULT_LEASE_TIME lease_time
> >>             | MAX_LEASE_TIME lease_time
> >>             | DYNAMIC_BOOTP_LEASE_CUTOFF date
> >> -           | DYNAMIC_BOOTP_LEASE_LENGTH lease_time
> >> +           | DYNAMIC_BOOTP_LEASE_LENGTH l#include <string.h>ease_time
> >>             | BOOT_UNKNOWN_CLIENTS boolean
> >>             | ONE_LEASE_PER_CLIENT boolean
> >>             | GET_LEASE_HOSTNAMES boolean
> >> @@ -352,6 +352,73 @@ isc_result_t lease_file_subparse (struct parse
> *cfile)
> >>           | VENDOR_CLASS class-declaration
> >>           | USER_CLASS class-declaration
> >>           | RANGE address-range-declaration */
> >> +#include <string.h>
> >> +isc_result_t read_multiple_conf_files(path, group, type)
> >> +    const char *path;
> >> +    struct group *group;
> >> +    int type;
> >> +{
> >> +    char    *buf_dir;
> >> +    char    *dir;
> >> +    char    *buf_base;
> >> +    char    *base;
> >> +    DIR    *d;
> >> +    struct    dirent *entry;
> >> +    int reti;
> >> +    isc_result_t status;
> >> +
> >> +    dir    = dirname (buf_dir    = strdup(path));
> >> +    base    = basename(buf_base    = strdup(path));
> >> +
> >> +    if (!(d = opendir(dir))) {
> >> +        status = DHCP_R_INVALIDARG;
> >> +        goto    exit;
> >> +    }
> >> +
> >> +    while ((entry = readdir(d)) != NULL) {
> >> +        if (entry->d_type == DT_DIR) {
> >> +            continue;
> >> +        } else {
> >> +            reti = fnmatch(base, entry->d_name, 0);
> >> +            if (reti == 0) {
> >> +                status = read_conf_file (path, group, type, 0);
> >> +                if (status != ISC_R_SUCCESS) {
> >> +                    goto exit;
> >> +                }
> >> +            } else {
> >> +                continue;
> >> +            }
> >> +        }
> >> +    }
> >> +    closedir(d);
> >> +exit:
> >> +    free(buf_dir);
> >> +    free(buf_base);
> >> +    return status;
> >> +}
> >> +
> >> +isc_result_t include_files(path, group, type)
> >> +    const char *path;
> >> +    struct group *group;
> >> +    int type;
> >> +{
> >> +    const char    *eos;
> >> +    const char    *wildcard = strchr(path, '*');
> >> +    char    *p;
> >> +
> >> +    if (wildcard == NULL) {
> >> +        return read_conf_file (path, group, type, 0);
> >> +    }
> >> +
> >> +    eos = &path[strlen(path)];
> >> +    for (wildcard++; wildcard < eos; wildcard++) {
> >> +        if (*wildcard == '/') {
> >> +            /* wildcard in directory, not allowed */
> >> +            return DHCP_R_INVALIDARG;
> >> +        }
> >> +    }
> >> +    return read_multiple_conf_files(path, group, type);
> >> +}
> >>
> >>  int parse_statement (cfile, group, type, host_decl, declaration)
> >>      struct parse *cfile;
> >> @@ -383,7 +450,7 @@ int parse_statement (cfile, group, type, host_decl,
> declaration)
> >>              parse_warn (cfile, "filename string expected.");
> >>              skip_to_semi (cfile);
> >>          } else {
> >> -            status = read_conf_file (val, group, type, 0);
> >> +            status = include_files(val, group, type);
> >>              if (status != ISC_R_SUCCESS)
> >>                  parse_warn (cfile, "%s: bad parse.", val);
> >>              parse_semi (cfile);
>
>
omshell would be much better - it avoids restarts.  I use an appliance
(BlueCat) that does it for me, so I have not scripted it myself.

If you don't use omshell, then you could simply in your scripting:
cat /etc/dhcp/pools/*.conf > /etc/dhcp/pools.conf
and then in the dhcpd.conf:
include "/etc/dhcp/pools.conf";

-- 
Bob Harold
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.isc.org/pipermail/dhcp-users/attachments/20180228/77cce855/attachment.html>


More information about the dhcp-users mailing list