From 5c9eb87a75959648ea043a3d2efa0139306972e0 Mon Sep 17 00:00:00 2001 From: micolous Date: Sat, 26 Oct 2024 15:31:01 +1000 Subject: [PATCH] Rewrite "choosing a domain", add other considerations (#3147) Co-authored-by: Firstyear --- book/src/choosing_a_domain_name.md | 376 ++++++++++++++++++++++++----- 1 file changed, 313 insertions(+), 63 deletions(-) diff --git a/book/src/choosing_a_domain_name.md b/book/src/choosing_a_domain_name.md index 03c73cc6d..b57963be7 100644 --- a/book/src/choosing_a_domain_name.md +++ b/book/src/choosing_a_domain_name.md @@ -1,96 +1,346 @@ # Choosing a Domain Name -Through out this book, Kanidm will make reference to a "domain name". This is your chosen DNS domain -name that you intend to use for Kanidm. Choosing this domain name however is not simple as there are -a number of considerations you need to be careful of. +This book makes many references to a "domain name". This is the DNS domain name +that you intend to use for Kanidm. + +This isn't always simple, and this chapter covers the key issues to consider +when choosing a domain. > [!WARNING] > -> Incorrect choice of the domain name may have security impacts on your Kanidm instance, not limited -> to credential phishing, theft, session leaks and more. It is critical you follow the advice in -> this chapter. +> **Bad choices** of domain name may have security impacts on your Kanidm +> instance, not limited to credential phishing, theft, session leaks and more. +> +> **Changing** domain name is hard to do – it not only means reconfiguring all +> LDAP and OAuth clients, but will also break all registered WebAuthn +> credentials for all users (which are bound to an `Origin`). +> +> It's critical that you consider and follow the advice in this chapter, and +> aim to get it right the first time. +> +> You'll save yourself a lot of work later! + + + +> [!TIP] +> +> We believe these practices are applicable *regardless* of your organisation's +> size (even if your Kanidm instance is just for you!), or if you think your +> organisation is not "important enough" to be the target of attacks. +> +> While some suggestions may seem "extreme" or "paranoid", they generally come +> from Kanidm's authors' collective decades of experience managing, maintaining, +> and securing networks and systems at both very large and very small +> organisations both inside and outside the technology industry. ## Considerations -### Domain Ownership +### Use a domain under your exclusive control -It is recommended you use a domain name within a domain that you own. While many examples list -`example.com` throughout this book, it is not recommended to use this outside of testing. Another -example of risky domain to use is `local`. While it seems appealing to use these, because you do not -have unique ownership of these domains, if you move your machine to a foreign network, it is -possible you may leak credentials or other cookies to these domains. TLS in a majority of cases can -and will protect you from such leaks however, but it should not always be relied upon as a sole line -of defence. +You should always use a domain name that you've registered and directly control +its DNS. -Failure to use a unique domain you own, may allow DNS hijacking or other credential leaks in some -circumstances. +While `example.com` and top-level domains ending in `.example` appear throughout +this book, [these are examples only][rfc2606]. You should **not** use this +outside of testing. -### Subdomains +[rfc2606]: https://datatracker.ietf.org/doc/html/rfc2606 -Due to how web browsers and webauthn work, any matching domain name or subdomain of an effective -domain may have access to cookies within a browser session. An example is that `host.a.example.com` -has access to cookies from `a.example.com` and `example.com`. +You'll need a registered domain for a CA (certificate authority) to issue you a +TLS certificate which is widely accepted by browsers. This will also **prevent** +those same CAs from issuing a certificate for that domain to *someone else*. -For this reason your Kanidm host (or hosts) should be on a unique subdomain, with no other services -registered under that subdomain. For example, consider `idm.example.com` as a subdomain for -exclusive use of Kanidm. This is _inverse_ to Active Directory which often has its domain name -selected to be the parent (toplevel) domain (`example.com`). +If you use a domain controlled by someone else (eg: a Dynamic DNS provider, or +your cloud provider), they could take over that domain *whenever they like*. +They could also use control of DNS or email to convince a CA to issue a +certificate for that domain. -Failure to use a unique subdomain may allow cookies to leak to other entities within your domain, -and may allow webauthn to be used on entities you did not intend for which may or may not lead to -some phishing scenarios. +*Any party who holds a valid certificate for the domain can steal or issue +credentials.* -## Examples +### Avoid non-public and reserved domains -### Good Domain Names +Avoid using "made-up" (eg: `.lan`) or reserved domains (eg: +[`.local`][dot-local]), because your clients may leak credentials if they move +to another network, aren't connected to a VPN, or if it +[collides with new TLDs][name-collision]. -Consider we own `kanidm.com`. If we were to run geographical instances, and have testing -environments the following domain and hostnames could be used. +Properly-configured TLS can prevent *most* (but not all) leakage, but defence in +depth is best. -#### Production Domain Name +This will also ensure your infrastructure is accessible regardless of your +users' local network conditions. -- origin: `https://idm.kanidm.com` -- domain name: `idm.kanidm.com` -- host names: `australia.idm.kanidm.com`, `newzealand.idm.kanidm.com` +[dot-local]: https://www.rfc-editor.org/rfc/rfc6762.html#section-3 +[name-collision]: https://en.wikipedia.org/wiki/Top-level_domain#Reserved_domains -This allows us to have named geographical instances such as `https://australia.idm.kanidm.com` which -still works with webauthn and cookies which are transferable between instances. +### Domain authorities -It is critical no other hosts are registered under this domain name. +Domain authorities can set their own eligibility policies for registering a +top-level domain. They may also allow a third-party to challenge your claim to +a top-level domain, subject to a dispute resolution policy. These policies may +change over time for commercial or political reasons. -#### Testing Domain Name +If your domain is on a ccTLD (country TLD), it may be de-registered should that +country cease to exist (eg: [as for `.io`][dot-io]). -- origin: `https://idm.dev.kanidm.com` -- domain name: `idm.dev.kanidm.com` -- host names: `australia.idm.dev.kanidm.com`, `newzealand.idm.dev.kanidm.com` +[dot-io]: https://www.theverge.com/2024/10/8/24265441/uk-treaty-end-io-domain-chagos-islands -Note that due to the name being `idm.dev.kanidm.com` vs `idm.kanidm.com`, the testing instance is -not a subdomain of production, meaning the cookies and webauthn tokens can NOT be transferred -between them. This provides proper isolation between the instances. +### Top-level domains containing "kanidm" -### Bad Domain Names +We ask that you **do not** use the word `kanidm` as part of your instance's +*top-level* (or [public suffix][ps]) domain, eg: `contosokanidm.example`. -`idm.local` - This is a bad example as `.local` is an mDNS domain name suffix which means that -client machines if they visit another network _may_ try to contact `idm.local` believing they are on -their usual network. If TLS certificate verification were disabled, this would allow leaking of -credentials. +Use something like `auth`, `idm`, `login` or `sso` instead – they're shorter, +too! -`kanidm.com` - This is bad because the use of the top level domain means that any subdomain can -access the cookies issued by `kanidm.com`, effectively leaking them to all other hosts. +We're OK with you using `kanidm` in a *subdomain* to point to your Kanidm +instance, eg: `kanidm.example.com`. -Second instance overlap: +We've worked hard to build this project, and using its name in conjunction with +an organisation *not* associated with the project dilutes the name's branding +value. -#### Production +### Subdomains and Origin policy -- origin: `https://idm.kanidm.com` -- domain name: `idm.kanidm.com` +Browsers allow a server on a subdomain to use intra-domain resources, and access +and set credentials and cookies from all of its parents until a +[public suffix][ps]. This can allow a malicious or compromised service to attack +other services which share a parent domain. -#### Testing +[ps]: https://publicsuffix.org/ -- origin: `https://dev.idm.kanidm.com` -- domain name: `dev.idm.kanidm.com` +Public suffix rules are *mostly* predictable, but has some exceptional cases. +For example: -While the production instance has a valid and well defined subdomain that doesn't conflict, because -the dev instance is a subdomain of production, it allows production cookies to leak to dev. Dev -instances may have weaker security controls in some cases which can then allow compromise of the -production instance. +* `host.a.example.com` can access and set cookies for: + + * `host.a.example.com` (itself) + * `a.example.com` + * `example.com` + + But **not** the public suffix `.com`. + +* `host.a.example.qld.gov.au` can access and set cookies for: + + * `host.a.example.qld.gov.au` (itself) + * `a.example.qld.gov.au` + * `example.qld.gov.au` + + But **not** any public suffix: + + * `qld.gov.au` (Queensland state government) + * `gov.au` (Australian federal government) + * `.au` (Australia) + +* `host.a.example.nsw.gov.au` can access and set cookies for: + + * `host.a.example.nsw.gov.au` (itself) + * `a.example.nsw.gov.au` + * `example.nsw.gov.au` + * `nsw.gov.au` ([NSW state government has opted out][nsw-optout]) + + But **not** any public suffix: + + * `gov.au` (Australian federal government) + * `.au` (Australia) + +[nsw-optout]: https://bugzilla.mozilla.org/show_bug.cgi?id=547985 + +This can be an issue if Kanidm shares a domain with: + +* applications which serve raw, user-supplied data in APIs (eg: blob/file + storage and [Matrix homeservers][matrix-csp]) +* third-party servers *outside* of your organisation's control (eg: SaaS apps) +* anything which can be deployed to with minimal oversight (eg: a web host that + allows uploading content via unencrypted FTP) + +[matrix-csp]: https://github.com/element-hq/synapse/blob/develop/README.rst#security-note + +### Avoid wildcard and widely-scoped certificates + +CAs can issue wildcard TLS certificates, which apply to all subdomains in the +same domain (eg: `*.example.com`). + +This is used by some organisations to avoid leaking information about what +services exist on a domain in certificate transparency logs. However, this +information will exposed *anyway* whenever a client makes a DNS query. + +If a service is issued a wildcard TLS certificate which *also* covers a Kanidm +installation on the same domain, any DNS hijacking could let that service +impersonate Kanidm to those clients, and steal credentials. + +While DNS-over-HTTPS generally prevents local hijacking, it's +[possible for a network to disable it when automatically enabled][disable-doh], +or just block it entirely. + +[disable-doh]: https://support.mozilla.org/en-US/kb/canary-domain-use-application-dnsnet + +Sharing a single certificate between many services increases the risk that the +private key may be exposed, and broadens the impact scope. + +### Separate production and testing environments + +If running more than one instance of Kanidm, ensure that no two deployments +share the same subdomain. This prevents credential and cookie transfers between +the two environments. For example: + +* Production: `idm.example.com` +* Testing: `idm-test.example.com` + +If you instead had an instance of Kanidm at `idm.example.com` for production and +another at `test.idm.example.com` for testing, then the test instance could +access the credentials and cookies of the production environment. + +This also prevents credentials intended for the test environment from being used +in production (where there may be stricter controls). + +### Regional deployments + +You could have multiple instances of Kanidm configured with replication, with a +single domain name and origin (eg: `idm.example.com`). + +You could then make regional instances accessible from different host names (eg: +`au.idm.example.com` and `nz.idm.example.com`). + +This allows credentials and cookies to be freely transferred between hosts that +are part of a single environment. + +## Recommendations + +For **maximum** security, your Kanidm domain name should be a subdomain of a +top-level domain (or domain under a [public suffix][ps]) that has no other +services assigned it, eg: + +* Origin: `https://idm.exampleauth.example` +* Domain name: `idm.exampleauth.example` + +When using [OAuth 2.0/OpenID Connect](./integrations/oauth2.md), there is no +need for a client app to share a top-level domain with Kanidm, because the app +does not need to share cookies. + +Large public auth providers (eg: Google, Meta, Microsoft) work the same way with +both first and third-party apps. + +If you have strict security controls for all apps on your top-level domain, you +could run Kanidm on a subdomain of your main domain, eg: + +* Origin: `https://idm.example.com` +* Domain name: `idm.example.com` + +But running Kanidm on a *separate* top-level domain makes it much easier to +restrict changes that *could* affect your IDM infrastructure. + +> [!NOTE] +> +> This is the **inverse** of the common Active Directory practice of using the +> organisation's primary top-level domain directly, eg: `example.com`. + +### Multi-environment and regional deployments + +If we were to run regional instances, and have a separate testing environment, +the following domain and hostnames could be used: + +#### Production environment + +- Origin: `https://idm.example.com` +- Domain name: `idm.example.com` +- Host names: `australia.idm.example.com`, `newzealand.idm.example.com` + +This allows us to have named regional instances such as +`https://australia.idm.example.com` which still works with WebAuthn and cookies +which are transferable between instances. + +It is critical no other hosts are registered under `idm.example.com`. + +#### Testing environment + +- Origin: `https://idm-test.example.com` +- Domain name: `idm-test.example.com` +- Host names: `australia.idm-test.example.com`, `newzealand.idm-test.example.com` + +This puts the testing instance under a separate subdomain of the top-level +domain to production (`idm.example.com`), so cookies and WebAuthn tokens can +**not** be transferred between them. + +This provides proper isolation between the instances. + +## Bad domain names + +Domains you should avoid: + +
+ +
+ +`idm.local` + +
+ +
+ +The `.local` top-level domain is [reserved for multicast DNS][dot-local]. + +If a client visits another network, it _may_ try to contact `idm.local` +believing it is on its usual network. If TLS certificate verification were +disabled (or not configured correctly), this would leak credentials. + +
+ +
+ +`example.com` + +
+ +
+ +Using the top-level domain directly allows any subdomain of that domain to +access credentials and cookies intended for Kanidm. + +
+ +
+ +`idm.example.nsw.gov.au` + +
+ +
+ +[`nsw.gov.au` has opted out of being a public suffix][nsw-optout], so all +domains under that suffix (except `schools.nsw.gov.au`) share origin and +cookies. + +
+ +
+ +`idm.examplekanidm.example` + +
+ +
+ +Kanidm is the brand for this project. + +
+ +
+ +### Multi-instance with overlap + +* Production: + * Origin: `https://idm.example.com` + * Domain name: `idm.example.com` + +* Testing: + * Origin: `https://test.idm.example.com` + * Domain name: `test.idm.example.com` + +While the production instance has a valid and well defined subdomain that +doesn't conflict, because the testing instance is a subdomain of production, it +allows production cookies to leak to the testing environment. + +Testing environments may have weaker security controls in some cases which can +then allow compromise of services using the production instance.