kanidm/master/choosing_a_domain_name.html

280 lines
21 KiB
HTML
Raw Normal View History

<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Choosing a Domain Name - Kanidm Administration</title>
<!-- Custom HTML head -->
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff" />
<link rel="shortcut icon" href="favicon.png">
<link rel="stylesheet" href="css/variables.css">
<link rel="stylesheet" href="css/general.css">
<link rel="stylesheet" href="css/chrome.css">
<link rel="stylesheet" href="css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="highlight.css">
<link rel="stylesheet" href="tomorrow-night.css">
<link rel="stylesheet" href="ayu-highlight.css">
<!-- Custom theme stylesheets -->
</head>
<body>
<div id="body-container">
<!-- Provide site root to javascript -->
<script>
var path_to_root = "";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script>
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script>
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
var html = document.querySelector('html');
html.classList.remove('no-js')
html.classList.remove('light')
html.classList.add(theme);
html.classList.add('js');
</script>
<!-- Hide / unhide sidebar before it is displayed -->
<script>
var html = document.querySelector('html');
var sidebar = null;
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
} else {
sidebar = 'hidden';
}
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item expanded "><a href="intro.html"><strong aria-hidden="true">1.</strong> Introduction to Kanidm</a></li><li class="chapter-item expanded "><a href="installing_the_server.html"><strong aria-hidden="true">2.</strong> Installing the Server</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="choosing_a_domain_name.html" class="active"><strong aria-hidden="true">2.1.</strong> Choosing a Domain Name</a></li><li class="chapter-item expanded "><a href="prepare_the_server.html"><strong aria-hidden="true">2.2.</strong> Preparing for your Deployment</a></li><li class="chapter-item expanded "><a href="server_configuration.html"><strong aria-hidden="true">2.3.</strong> Server Configuration and Install</a></li><li class="chapter-item expanded "><a href="security_hardening.html"><strong aria-hidden="true">2.4.</strong> Platform Security Hardening</a></li><li class="chapter-item expanded "><a href="server_update.html"><strong aria-hidden="true">2.5.</strong> Server Updates</a></li></ol></li><li class="chapter-item expanded "><a href="client_tools.html"><strong aria-hidden="true">3.</strong> Client Tools</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="installing_client_tools.html"><strong aria-hidden="true">3.1.</strong> Installing client tools</a></li></ol></li><li class="chapter-item expanded "><li class="part-title">Administration</li><li class="chapter-item expanded "><a href="administrivia.html"><strong aria-hidden="true">4.</strong> Administration</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="accounts_and_groups.html"><strong aria-hidden="true">4.1.</strong> Accounts and Groups</a></li><li class="chapter-item expanded "><a href="authentication.html"><strong aria-hidden="true">4.2.</strong> Authentication and Credentials</a></li><li class="chapter-item expanded "><a href="posix_accounts.html"><strong aria-hidden="true">4.3.</strong> POSIX Accounts and Groups</a></li><li class="chapter-item expanded "><a href="backup_restore.html"><strong aria-hidden="true">4.4.</strong> Backup and Restore</a></li><li class="chapter-item expanded "><a href="database_maint.html"><strong aria-hidden="true">4.5.</strong> Database Maintenance</a></li><li class="chapter-item expanded "><a href="domain_rename.html"><strong aria-hidden="true">4.6.</strong> Domain Rename</a></li><li class="chapter-item expanded "><a href="monitoring.html"><strong aria-hidden="true">4.7.</strong> Monitoring the platform</a></li><li class="chapter-item expanded "><a href="password_quality.html"><strong aria-hidden="true">4.8.</strong> Password Quality and Badlisting</a></li><li class="chapter-item expanded "><a href="recycle_bin.html"><strong aria-hidden="true">4.9.</strong> The Recycle Bin</a></li></ol></li><li class="chapter-item expanded "><li class="part-title">Services</li><li class="chapter-item expanded "><a href="integrations/pam_and_nsswitch.html"><strong aria-hidden="true">5.</strong> PAM and nsswitch</a></li><li class="chapter-item expanded "><a href="ssh_key_dist.html"><strong aria-hidden="true">6.</strong> SSH Key Distribution</a></li><li class="chapter-item expanded "><a href="integrations/oauth2.html"><strong aria-hidden="true">7.</strong> Oauth2</a></li><li class="chapter-item expanded "><a href="integrations/ldap.html"><strong aria-hidden="true">8.</strong> LDAP</a></li><li class="chapter-item expanded "><a href="integrations/radius.html"><strong aria-hidden="true">9.</strong> RADIUS</a></li><li class="chapter-item expanded affix "><li class="part-title">Synchronisation</li><li class="chapter-item expanded "><a href="sync/concepts.html"><strong aria-hidden="true">10.</strong> Concepts</a></li><li class="chapter-item expanded "><a href="sync/freeipa.html"><strong aria-hidden="true">11.</strong> FreeIPA</a></li><li class="chapter-item expanded affix "><li class="part-title">Integration Examples</li><li class="chapter-item expanded "><a href="examples/k8s_ingress_example.html"><strong aria-hidden="true">12.</strong> Kubernet
</div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky bordered">
<div class="left-buttons">
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</button>
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">Kanidm Administration</h1>
<div class="right-buttons">
<a href="print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
<a href="https://github.com/kanidm/kanidm" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
<a href="https://github.com/kanidm/kanidm/edit/master/book/src/choosing_a_domain_name.md" title="Suggest an edit" aria-label="Suggest an edit">
<i id="git-edit-button" class="fa fa-edit"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h1 id="choosing-a-domain-name"><a class="header" href="#choosing-a-domain-name">Choosing a Domain Name</a></h1>
<p>Through out this book, Kanidm will make reference to a &quot;domain name&quot;. 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.</p>
<!-- deno-fmt-ignore-start -->
<p>{{#template templates/kani-warning.md
imagepath=images/
title=Take note!
text=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.
}}</p>
<!-- deno-fmt-ignore-end -->
<h2 id="considerations"><a class="header" href="#considerations">Considerations</a></h2>
<h3 id="domain-ownership"><a class="header" href="#domain-ownership">Domain Ownership</a></h3>
<p>It is recommended you use a domain name within a domain that you own. While many examples list
<code>example.com</code> throughout this book, it is not recommended to use this outside of testing. Another
example of risky domain to use is <code>local</code>. 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.</p>
<p>Failure to use a unique domain you own, may allow DNS hijacking or other credential leaks in some
circumstances.</p>
<h3 id="subdomains"><a class="header" href="#subdomains">Subdomains</a></h3>
<p>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 <code>host.a.example.com</code>
has access to cookies from <code>a.example.com</code> and <code>example.com</code>.</p>
<p>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 <code>idm.example.com</code> as a subdomain for
exclusive use of kanidm. This is <em>inverse</em> to Active Directory which often has it's domain name
selected to be the parent (toplevel) domain (<code>example.com</code>).</p>
<p>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 scenarioes.</p>
<h2 id="examples"><a class="header" href="#examples">Examples</a></h2>
<h3 id="good-domain-names"><a class="header" href="#good-domain-names">Good Domain Names</a></h3>
<p>Consider we own <code>kanidm.com</code>. If we were to run geographical instances, and have testing
environments the following domain and hostnames could be used.</p>
<h4 id="production-domain-name"><a class="header" href="#production-domain-name">Production Domain Name</a></h4>
<ul>
<li>origin: <code>https://idm.kanidm.com</code></li>
<li>domain name: <code>idm.kanidm.com</code></li>
<li>host names: <code>australia.idm.kanidm.com</code>, <code>newzealand.idm.kanidm.com</code></li>
</ul>
<p>This allows us to have named geographical instances such as <code>https://australia.idm.kanidm.com</code> which
still works with webauthn and cookies which are transferable between instances.</p>
<p>It is critical no other hosts are registered under this domain name.</p>
<h4 id="testing-domain-name"><a class="header" href="#testing-domain-name">Testing Domain Name</a></h4>
<ul>
<li>origin: <code>https://idm.dev.kanidm.com</code></li>
<li>domain name: <code>idm.dev.kanidm.com</code></li>
<li>host names: <code>australia.idm.dev.kanidm.com</code>, <code>newzealand.idm.dev.kanidm.com</code></li>
</ul>
<p>Note that due to the name being <code>idm.dev.kanidm.com</code> vs <code>idm.kanidm.com</code>, 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.</p>
<h3 id="bad-domain-names"><a class="header" href="#bad-domain-names">Bad Domain Names</a></h3>
<p><code>idm.local</code> - This is a bad example as <code>.local</code> is an mDNS domain name suffix which means that
client machines if they visit another network <em>may</em> try to contact <code>idm.local</code> believing they are on
their usual network. If TLS verification were disabled, this would allow leaking of credentials.</p>
<p><code>kanidm.com</code> - This is bad because the use of the top level domain means that any subdomain can
access the cookies issued by <code>kanidm.com</code>, effectively leaking them to all other hosts.</p>
<p>Second instance overlap:</p>
<h4 id="production"><a class="header" href="#production">Production</a></h4>
<ul>
<li>origin: <code>https://idm.kanidm.com</code></li>
<li>domain name: <code>idm.kanidm.com</code></li>
</ul>
<h4 id="testing"><a class="header" href="#testing">Testing</a></h4>
<ul>
<li>origin: <code>https://dev.idm.kanidm.com</code></li>
<li>domain name: <code>dev.idm.kanidm.com</code></li>
</ul>
<p>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.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="installing_the_server.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next" href="prepare_the_server.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="installing_the_server.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next" href="prepare_the_server.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script>
window.playground_copyable = true;
</script>
<script src="elasticlunr.min.js"></script>
<script src="mark.min.js"></script>
<script src="searcher.js"></script>
<script src="clipboard.min.js"></script>
<script src="highlight.js"></script>
<script src="book.js"></script>
<!-- Custom JS scripts -->
</div>
</body>
</html>