Skip to content

Fix/Allow internal underscores in static DHCP hostnames - #3853

Open
RMA1313 wants to merge 1 commit into
pi-hole:developmentfrom
RMA1313:fix/dhcp-hostname-underscore
Open

Fix/Allow internal underscores in static DHCP hostnames#3853
RMA1313 wants to merge 1 commit into
pi-hole:developmentfrom
RMA1313:fix/dhcp-hostname-underscore

Conversation

@RMA1313

@RMA1313 RMA1313 commented Aug 15, 2026

Copy link
Copy Markdown

Thank you for your contribution to the Pi-hole Community!

Please read the comments below to help us consider your Pull Request.

We are all volunteers and completing the process outlined will help us review your commits quicker.

Please make sure you

  1. Base your code and PRs against the repositories developmental branch.
  2. [Sign Off](https://docs.pi-hole.net/guides/github/how-to-signoff/) all commits as we enforce the [DCO](https://docs.pi-hole.net/guides/github/dco/) for all contributions
  3. [Sign](https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits) all your commits as they must have verified signatures
  4. File a pull request for any change that requires changes to [our documentation](https://docs.pi-hole.net/) at our [documentation repo](https://github.com/pi-hole/docs)

What does this PR aim to accomplish?:

Fixes #3814.

Static DHCP hostnames containing internal underscores, such as TPLinkCam_6FAC, are currently highlighted as invalid and rejected on save by the Web interface.

This PR allows internal underscores in static DHCP hostnames while keeping the existing validation behavior for other hostname formats.

How does this PR accomplish the above?:

  • Adds validation specific to static DHCP hostnames instead of relaxing the shared strict hostname validator.
  • Allows underscores within hostname labels while continuing to reject leading or trailing underscores.
  • Applies the validation consistently when saving, highlighting invalid table entries, and editing hostnames.
  • Leaves DNS-related and other strict hostname validation unchanged.
  • Updates the Static DHCP help text to reflect the accepted format.
  • Tested with npm test, which completes successfully with the repository's existing warnings.

Link documentation PRs if any are needed to support this PR:

No documentation changes are required. The relevant inline help text in the Web interface has been updated as part of this PR.


By submitting this pull request, I confirm the following:

  1. I have read and understood the [contributors guide](https://docs.pi-hole.net/guides/github/contributing/), as well as this entire template. I understand which branch to base my commits and Pull Requests against.
  2. I have commented my proposed changes within the code and I have tested my changes.
  3. I am willing to help maintain this change if there are issues with it later.
  4. It is compatible with the [EUPL 1.2 license](https://opensource.org/licenses/EUPL-1.2)
  5. I have squashed any insignificant commits. ([git rebase](http://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html))
  6. I have checked that another pull request for this purpose does not exist.
  7. I have considered, and confirmed that this submission will be valuable to others.
  8. I accept that this submission may not be used, and the pull request closed at the will of the maintainer.
  9. I give this submission freely, and claim no ownership to its content.

  • I have read the above and my PR is ready for review.

@RMA1313
RMA1313 requested a review from a team as a code owner August 15, 2026 13:52
@RMA1313
RMA1313 changed the base branch from master to new/simple-dhcp-static-leases August 15, 2026 13:59
@RMA1313
RMA1313 changed the base branch from new/simple-dhcp-static-leases to development August 15, 2026 14:01
@rdwebdesign

Copy link
Copy Markdown
Member

Internet standards (RFC 952 and RFC 1123) state that hostnames can only use letters (A-Z), numbers (0-9), and hyphens (-).

@RMA1313

RMA1313 commented Aug 16, 2026

Copy link
Copy Markdown
Author

Internet standards (RFC 952 and RFC 1123) state that hostnames can only use letters (A-Z), numbers (0-9), and hyphens (-).

Thanks for pointing that out.

My intention here was specifically to address the behavior described in #3814: these names appear to work for static DHCP assignments, while the Web UI rejects them. That's also why I kept the existing strict hostname validation unchanged for DNS-related uses and scoped this change only to static DHCP entries.

If Pi-hole intentionally wants to enforce RFC-compliant hostnames for static DHCP entries as well, then I agree this change shouldn't relax the validation. Could you confirm whether that's the intended policy here?

@yubiuser

Copy link
Copy Markdown
Member

We had some internal discussion around this and lean towards the allowing underscores as well. In contrast to RFC 952 and RFC 1123 there is also RFC2181 which states in section 11

The DNS itself places only one restriction on the particular labels
that can be used to identify resource records. That one restriction
relates to the length of the label and the full name. The length of
any one label is limited to between 1 and 63 octets. A full domain
name is limited to 255 octets (including the separators). The zero
length full name is defined as representing the root of the DNS tree,
and is typically written and displayed as ".". Those restrictions
aside, any binary string whatever can be used as the label of any
resource record
. Similarly, any binary string can serve as the value
of any record that includes a domain name as some or all of its value
(SOA, NS, MX, PTR, CNAME, and any others that may be added).
Implementations of the DNS protocols must not place any restrictions
on the labels that can be used. In particular, DNS servers must not
refuse to serve a zone because it contains labels that might not be
acceptable to some DNS client programs. A DNS server may be
configurable to issue warnings when loading, or even to refuse to
load, a primary zone containing labels that might be considered
questionable, however this should not happen by default.

I suggest to allow underscores, but do not create a new function for validating DHCP hostnames, but to loose requirements in validateHostnameStrict() - which is currently only used for revserver-domain besides DHCP hostname validation. We could even go even further and use validateHostname() which places almost no restrictions on the hostname we use for defining client identifiers in the group section.

I'd like to get some input from @rdwebdesign and @DL6ER because the have been part of the internal discussion

@DL6ER

DL6ER commented Aug 22, 2026

Copy link
Copy Markdown
Member

Agreed on relaxing validateHostnameStrict() rather than adding a third validator.

Not validateHostname() though. That one is not really a validator: /[^<>;"]/ is unanchored, so it returns true as soon as one character is not <, >, ; or " - evil<script> passes it. It is a catch-all because the group client field also takes an interface like :eth0, which a hostname regex would reject, and the table escapes on render, so that character list guards nothing. I am fixing and renaming it separately.

On the underscore itself, FTL has already answered twice: valid_domain() and valid_hostname() both accept [A-Za-z0-9._-]. The resolver will happily record TPLinkCam_6FAC as a client name, so today the web interface is the only thing rejecting it.

I would therefore relax validateHostnameStrict() to that same set. That fixes #3814 and leaves us with one rule instead of three that disagree.

@DL6ER

DL6ER commented Aug 22, 2026

Copy link
Copy Markdown
Member

@RMA1313 could you fold this into validateHostnameStrict() instead? The whole regex can be:

/^[a-zA-Z0-9][\w.-]*$/u

That is dnsmasq's own rule for a DHCP host name (legal_hostname()), which is what parses the generated dhcp-host= line: underscores anywhere except as the first character. validateStaticDHCPHostname() can then go, and revserver-domain, the function's other caller, keeps working - FTL validates that domain itself.

Signed-off-by: RMA1313 <75065599+RMA1313@users.noreply.github.com>
@RMA1313
RMA1313 force-pushed the fix/dhcp-hostname-underscore branch from 330b042 to 2aa0831 Compare August 23, 2026 09:32
@RMA1313

RMA1313 commented Aug 23, 2026

Copy link
Copy Markdown
Author

@RMA1313 could you fold this into validateHostnameStrict() instead? The whole regex can be:

/^[a-zA-Z0-9][\w.-]*$/u

That is dnsmasq's own rule for a DHCP host name (legal_hostname()), which is what parses the generated dhcp-host= line: underscores anywhere except as the first character. validateStaticDHCPHostname() can then go, and revserver-domain, the function's other caller, keeps working - FTL validates that domain itself.

Updated as suggested.

I removed the DHCP-specific validator and relaxed the shared validateHostnameStrict() implementation to:

/^[a-zA-Z0-9][\w.-]*$/u

Static DHCP now uses the shared validator again, and I left validateHostname() unchanged.

I also updated the inline DHCP help text to match the new accepted format.

npm test and git diff --check both pass.

@rdwebdesign
rdwebdesign requested review from DL6ER and yubiuser August 23, 2026 17:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Static DHCP assignment instructions suggest underscores are not supported in hostname, but they work

4 participants