1

Im using isc-dhcpd and bind9 to do ddns.

It is mostly working, but updates from clients with invalid names, like "leif_opo5" or "Danfoss Connect CC" are rejected.

I changed the hostname for my phone to leif-opo5, and it got registered, but I can't change the hardcoded hostname of the Danfoss unit.

I could hardcode the name and give it a fixed IP, but there might come other devices, so i wonder:

Is it possible for isc-dhcpd to rewrite hostnames with "bad characters", replacing with '-' for instance?

Lenne
  • 987
  • 1
  • 13
  • 32
  • Hi @lenne! Did you ever figure out a solution? I have the same problem with my "iHome SmartPlug-967B65" device flooding my syslog with "dhcpd Unable to add forward map from iHome SmartPlug-967B65.myprivatedomain.com. to 10.100.111.47: REFUSED" (Note the space in the hostname.) – Jonathan Wheeler Sep 20 '22 at 03:51
  • Nope, but I could change the name the ESP8266 presented. – Lenne Sep 21 '22 at 10:59

3 Answers3

0

@Lenne, I solved this immediately after replying to your OP, but I forgot to circle back and provide the solution. Thus it's no longer fresh on my mind, so please let me know if there or any errors, or if I forgot any detail.

Using Sidvind's "Dhcpd on Commit" tutorial as a reference, I added the following to /etc/dhcp/dhcpd.conf, which causes clients without a hostname (or with an invalid hostname) to be assigned something similar to ip-10-12-34-56:

on commit {
    set clientIpHyphenated = binary-to-ascii(10, 8, "-", leased-address);

    # Check whether the client supplied a hostname with illegal characters,
    # e.g., "iHome SmartPlug-27C139" with a space or underscore in it.
    # This resolves failures when trying to update DNS forward maps:
    #   dhcpd: Unable to add forward map from
    #       iHome SmartPlug-27C139.JonathansSecretDomain.com. to 10.12.34.56: REFUSED
    if (option host-name ~~ "^[a-z0-9][a-z0-9\-]+[a-z0-9]$") {
        set valid-hostname-else-null = option host-name;
    } else {
        set valid-hostname-else-null = null;
    }

    # Get the client name from the first of the following:
    #   1. Client DHCP Option FQDN
    #   2. Client DHCP Option Hostname (and it is a valid hostname without spaces, underscores, etc)
    #   3. Name of static lease (host-decl-name)
    #   4. A generated name that looks like: "ip-10-12-34-56"
    #   5. "none", if all else fails. Shouldn't ever occur.
    set clientName = pick-first-value(
        option fqdn.hostname,
        valid-hostname-else-null,
        # Optional:
        # This can cause an annoying repetitive error in syslog and dhcpd.log that I suppressed:
        #   dhcpd[965395]: data: host_decl_name: not available
        # If you uncomment it, then also add my rsyslog code below.
        #host-decl-name,
        concat("ip-", clientIpHyphenated),
        "none"
    );

    # Set the dynamic hostname, which otherwise wouldn't have been set if the client didn't
    # request one. We also ensure above that it doesn't contain invalid characters, and that a
    # fallback hostname will be generated if needed.
    ddns-hostname = clientName;

    # Optional:
    # If the client supplied a hostname with illegal characters, log what we changed it to for ddns.
    # (e.g., "iHome SmartPlug-27C139" with a space or underscore in it.)
    #if (not (option host-name = valid-hostname-else-null)) {
    #    log(info, concat("Invalid hostname: \"", option host-name, "\" --> \"", clientName, "\""));
    #} elsif (not (option host-name = clientName)) {
    #    log(info, concat("Hostname overridden: \"", option host-name, "\" --> \"", clientName, "\""));
    #}
}

If you uncomment some of the optional stuff in the above config, then create /etc/rsyslog.d/10-dhcpd.conf and add the following:

# Log most dhcpd messages to /var/log/dhcpd.log.
if $programname == 'dhcpd' then {

    # Spam: If it's a notice message containing "...host_decl_name...", then don't log it.
    # I think this "stop" rule is specific enough to not be exploitable, but I'm open to feedback.
    if $msg contains "data: host_decl_name: not available" and $syslogseverity-text == 'error'
        then stop

    # Otherwise, log the message.
    /var/log/dhcpd.log

    # Prevent info and debug-level events from also appearing in the syslog.
    # (Stop will prevent any additional rules from being applied to the message, including
    # preventing it from being duplicated to the syslog later on.)
    # Higher severity messages will otherwise intentionally be allowed
    # to continue to be processed, and thus will be duped to syslog.
    # If you don't like this behavior, then just add an unconditional "stop".
    if $syslogseverity-text == 'info' or $syslogseverity-text == 'debug'
        then stop
}

Finally, run:

sudo systemctl restart rsyslog.service isc-dhcp-server.service

Although this solution doesn't replace specific invalid characters (which doesn't seem to be possible?), it does replace invalid hostnames containing invalid characters with a generic hostname, which is sufficient for my needs, and hopefully for yours as well. (I like that it also assigns clients without a hostname a generic hostname based on their IP.)

-1

For each host with invalid hostname you can create "hostname" specification at it's own "host" declaration: .. # Color ink printer-scanner host EPSON1EE63C { hardware ethernet a4:ee:57:1e:e6:3c; hostname EpsonPrt; } .. Note EPSON1EE63C means nothing for dhcp daemon and for DDNS (if used). It means only original identifier for one of "host" declarations, but "hostname" instide block does.

-3

Can you try the below in DDNS section of the DHCP config?

ddns-updates on;
# DNS host name rewrite policy:
#   Name: Default
#   Valid characters: a-z0-9
#   Replace invalid characters by: -
Vignesh SP
  • 129
  • 1
  • 10