The order of files in /etc/ssh/sshd_config.d/ matters

Config directories vs single configs

  • Some admins prefer to delete distro-provided sshd_config (and templates under sshd_config.d/) and replace them with a minimal hand-written file to avoid surprises and cloud/vps “cruft.”
  • Others argue .d-style config directories are valuable, especially with tools like Ansible:
    • Easier to add/remove a feature by dropping/removing a file vs patching a monolithic config.
    • Avoids complex in-place edits and merge logic; each managed file is an independent unit.
    • Helps achieve idempotency and clean lifecycle management across server fleets.
  • Detractors find multi-file setups harder to reason about, especially when distro packaging, cloud-init, and other tools inject snippets. For small services like SSH, they see .d as overkill.
  • Several suggest minimal, secure defaults by distros, with advanced config-management systems as optional packages.

Ordering and “first wins” semantics

  • Many expected “last one wins” when multiple config snippets define the same option; OpenSSH’s “first one wins” surprised them.
  • Numeric prefixes in .d directories exist precisely to control lexicographic order, but the first-wins rule inverts many people’s intuition (they expect 99-*.conf to override, not be ignored).
  • Some defend first-wins as simpler or historically common and useful for matching host patterns: you put the most specific/important rules first.
  • Others note a security rationale: global/system configs can precede user configs so users cannot override certain policies.

How parsing works (and old vs modern design)

  • There is an extended debate about how config parsers historically worked:
    • One side argues early “first match” parsers were simplest: scan line by line, stop on first setting, don’t build big in-memory structures.
    • Another points out modern OpenSSH parses configs at startup into an internal structure with sentinel values; performance and RAM concerns are largely moot.
  • Participants disagree on whether first-wins really results in less code or simpler logic compared to overwriting on later entries.

Intuition vs documentation (“RTFM”)

  • Some insist unusual semantics (like first-wins) are fine as long as they are documented; users should read the manual.
  • Others push back that “intuitive” behavior matters, especially today when engineers juggle many tools; relying on RTFM for every quirk is seen as poor UX.
  • There’s back-and-forth about whether “last one wins” is more intuitive and whether documentation should be treated as primary or as backup to sensible defaults.

Tooling, validation, and cloud-init

  • sshd -T (and sshd -T -f %s in automation) is recommended to see the effective configuration and validate changes, though it reflects what will run, not necessarily what the current daemon is using.
  • Some prefer socket-activated, per-connection sshd so new configs apply immediately.
  • cloud-init is mentioned mainly as a delivery mechanism for problematic snippets; views on cloud-init are mixed, with some only encountering it when it causes trouble.

Distro specifics and generalization

  • sshd_config.d/ appears as a Debian/Ubuntu and some Linux distro convention, not in OpenBSD’s default OpenSSH; OpenBSD uses Include but doesn’t ship .d by default.
  • The discussion generalizes to other .d schemes (nginx sites-enabled, apt snippets, modules-load.d), with the same ordering, maintainability, and complexity trade-offs.