kanidm/master/prepare_the_server.html
2023-05-06 13:04:04 +00:00

319 lines
22 KiB
HTML

<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Preparing for your Deployment - 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"><strong aria-hidden="true">2.1.</strong> Choosing a Domain Name</a></li><li class="chapter-item expanded "><a href="prepare_the_server.html" class="active"><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> Kubernetes Ingress</a></li><li class="chapter-item expanded "><a href="integrations/traefik.html"><strong aria-hidden="true">13.</strong> Traefik</a></li><li class="chapter-item expanded affix "><li class="part-title">Support</li><li class="chapter-item expanded "><a href="troubleshooting.html"><strong aria-hidden="true">14.</strong> Troubleshooting</a></li><li class="chapter-item expanded "><a href="frequently_asked_questions.html"><strong aria-hidden="true">15.</strong> Frequently Asked Questions</a></li><li class="chapter-item expanded "><a href="glossary.html"><strong aria-hidden="true">16.</strong> Glossary of Technical Terms</a></li><li class="chapter-item expanded affix "><li class="part-title">For Developers</li><li class="chapter-item expanded "><a href="DEVELOPER_README.html"><strong aria-hidden="true">17.</strong> Developer Guide</a></li><li class="chapter-item expanded "><a href="developers/faq.html"><strong aria-hidden="true">18.</strong> FAQ</a></li><li class="chapter-item expanded "><div><strong aria-hidden="true">19.</strong> Design Documents</div></li><li><ol class="section"><li class="chapter-item expanded "><a href="developers/designs/access_profiles_rework_2022.html"><strong aria-hidden="true">19.1.</strong> Access Profiles 2022</a></li><li class="chapter-item expanded "><a href="developers/designs/access_profiles_and_security.html"><strong aria-hidden="true">19.2.</strong> Access Profiles Original</a></li><li class="chapter-item expanded "><a href="developers/designs/rest_interface.html"><strong aria-hidden="true">19.3.</strong> REST Interface</a></li><li class="chapter-item expanded "><a href="developers/designs/elevated_priv_mode.html"><strong aria-hidden="true">19.4.</strong> Elevated Priv Mode</a></li><li class="chapter-item expanded "><a href="developers/designs/oauth2_refresh_tokens.html"><strong aria-hidden="true">19.5.</strong> Oauth2 Refresh Tokens</a></li></ol></li><li class="chapter-item expanded "><a href="developers/python.html"><strong aria-hidden="true">20.</strong> Python Module</a></li><li class="chapter-item expanded "><a href="developers/radius.html"><strong aria-hidden="true">21.</strong> RADIUS Integration</a></li><li class="chapter-item expanded "><a href="packaging.html"><strong aria-hidden="true">22.</strong> Packaging</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="packaging_debs.html"><strong aria-hidden="true">22.1.</strong> Debian/Ubuntu</a></li></ol></li></ol>
</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/prepare_the_server.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="preparing-for-your-deployment"><a class="header" href="#preparing-for-your-deployment">Preparing for your Deployment</a></h1>
<h2 id="software-installation-method"><a class="header" href="#software-installation-method">Software Installation Method</a></h2>
<blockquote>
<p><strong>NOTE</strong> Our preferred deployment method is in containers, and this documentation assumes you're
running in docker. Kanidm will alternately run as a daemon/service, and server builds are
available for multiple platforms if you prefer this option. You will</p>
</blockquote>
<p>We provide docker images for the server components. They can be found at:</p>
<ul>
<li><a href="https://hub.docker.com/r/kanidm/server">https://hub.docker.com/r/kanidm/server</a></li>
<li><a href="https://hub.docker.com/r/kanidm/radius">https://hub.docker.com/r/kanidm/radius</a></li>
<li><a href="https://hub.docker.com/r/kanidm/tools">https://hub.docker.com/r/kanidm/tools</a></li>
</ul>
<p>You can fetch these by running the commands:</p>
<pre><code class="language-bash">docker pull kanidm/server:latest
docker pull kanidm/radius:latest
docker pull kanidm/tools:latest
</code></pre>
<p>You may need to adjust your example commands throughout this document to suit your desired server
type if you choose not to use docker.</p>
<h2 id="development-version"><a class="header" href="#development-version">Development Version</a></h2>
<p>If you are interested in running the latest code from development, you can do this by changing the
docker tag to <code>kanidm/server:devel</code> or <code>kanidm/server:x86_64_v3_devel</code> instead. Many people run the
development version, and it is extremely reliable, but occasional rough patches may occur. If you
report issues, we will make every effort to help resolve them.</p>
<h2 id="system-requirements"><a class="header" href="#system-requirements">System Requirements</a></h2>
<h3 id="cpu"><a class="header" href="#cpu">CPU</a></h3>
<p>Kanidm relies on modern CPU optimisations for many operations. As a result your cpu must be either:</p>
<ul>
<li><code>x86_64</code> supporting <code>x86_64_v2</code> operations.</li>
<li><code>aarch64</code> supporting <code>neon_v8</code> operations.</li>
</ul>
<p>Older or unsupported CPUs may raise a SIGIL (Illegal Instruction) on hardware that is not supported
by the project.</p>
<!-- deno-fmt-ignore-start -->
<p>{{#template templates/kani-alert.md
imagepath=images
title=Tip
text=You can check your cpu flags on Linux with the command <code>lscpu</code>
}}</p>
<!-- deno-fmt-ignore-end -->
<h4 id="memory"><a class="header" href="#memory">Memory</a></h4>
<p>Kanidm extensively uses memory caching, trading memory consumption to improve parallel throughput.
You should expect to see 64KB of ram per entry in your database, depending on cache tuning and
settings.</p>
<h4 id="disk"><a class="header" href="#disk">Disk</a></h4>
<p>You should expect to use up to 8KB of disk per entry you plan to store. At an estimate 10,000 entry
databases will consume 40MB, 100,000 entry will consume 400MB.</p>
<p>For best performance, you should use non-volatile memory express (NVME), or other Flash storage
media.</p>
<h2 id="tls"><a class="header" href="#tls">TLS</a></h2>
<p>You'll need a volume where you can place configuration, certificates, and the database:</p>
<pre><code class="language-bash">docker volume create kanidmd
</code></pre>
<p>You should have a chain.pem and key.pem in your kanidmd volume. The reason for requiring Transport
Layer Security (TLS, which replaces the deprecated Secure Sockets Layer, SSL) is explained in
<a href="./frequently_asked_questions.html#why-tls">why tls</a>. In summary, TLS is our root of trust between the
server and clients, and a critical element of ensuring a secure system.</p>
<p>The key.pem should be a single PEM private key, with no encryption. The file content should be
similar to:</p>
<pre><code class="language-bash">-----BEGIN RSA PRIVATE KEY-----
MII...&lt;base64&gt;
-----END RSA PRIVATE KEY-----
</code></pre>
<p>The chain.pem is a series of PEM formatted certificates. The leaf certificate, or the certificate
that matches the private key should be the first certificate in the file. This should be followed by
the series of intermediates, and the final certificate should be the CA root. For example:</p>
<pre><code class="language-bash">-----BEGIN CERTIFICATE-----
&lt;leaf certificate&gt;
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
&lt;intermediate certificate&gt;
-----END CERTIFICATE-----
[ more intermediates if needed ]
-----BEGIN CERTIFICATE-----
&lt;ca/croot certificate&gt;
-----END CERTIFICATE-----
</code></pre>
<blockquote>
<p><strong>HINT</strong> If you are using Let's Encrypt the provided files &quot;fullchain.pem&quot; and &quot;privkey.pem&quot; are
already correctly formatted as required for Kanidm.</p>
</blockquote>
<p>You can validate that the leaf certificate matches the key with the command:</p>
<pre><code class="language-bash"># ECDSA
openssl ec -in key.pem -pubout | openssl sha1
1c7e7bf6ef8f83841daeedf16093bda585fc5bb0
openssl x509 -in chain.pem -noout -pubkey | openssl sha1
1c7e7bf6ef8f83841daeedf16093bda585fc5bb0
# RSA
# openssl rsa -noout -modulus -in key.pem | openssl sha1
d2188932f520e45f2e76153fbbaf13f81ea6c1ef
# openssl x509 -noout -modulus -in chain.pem | openssl sha1
d2188932f520e45f2e76153fbbaf13f81ea6c1ef
</code></pre>
<p>If your chain.pem contains the CA certificate, you can validate this file with the command:</p>
<pre><code class="language-bash">openssl verify -CAfile chain.pem chain.pem
</code></pre>
<p>If your chain.pem does not contain the CA certificate (Let's Encrypt chains do not contain the CA
for example) then you can validate with this command.</p>
<pre><code class="language-bash">openssl verify -untrusted fullchain.pem fullchain.pem
</code></pre>
<blockquote>
<p><strong>NOTE</strong> Here &quot;-untrusted&quot; flag means a list of further certificates in the chain to build up to
the root is provided, but that the system CA root should be consulted. Verification is NOT
bypassed or allowed to be invalid.</p>
</blockquote>
<p>If these verifications pass you can now use these certificates with Kanidm. To put the certificates
in place you can use a shell container that mounts the volume such as:</p>
<pre><code class="language-bash">docker run --rm -i -t -v kanidmd:/data -v /my/host/path/work:/work opensuse/leap:latest \
/bin/sh -c &quot;cp /work/* /data/&quot;
</code></pre>
<p>OR for a shell into the volume:</p>
<pre><code class="language-bash">docker run --rm -i -t -v kanidmd:/data opensuse/leap:latest /bin/sh
</code></pre>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="choosing_a_domain_name.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="server_configuration.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="choosing_a_domain_name.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="server_configuration.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>