kanidm/stable/developers/faq.html
2023-05-06 13:04:04 +00:00

292 lines
23 KiB
HTML

<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>FAQ - 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"><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" class="active"><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/developers/faq.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>
<h2 id="frequently-asked-questions"><a class="header" href="#frequently-asked-questions">Frequently Asked Questions</a></h2>
<p>This is a list of common questions that are generally raised by developers or technical users.</p>
<h2 id="why-dont-you-use-libraryproject-x"><a class="header" href="#why-dont-you-use-libraryproject-x">Why don't you use library/project X?</a></h2>
<p>A critical aspect of kanidm is the ability to test it. Generally requests to add libraries or
projects can come in different forms so I'll answer to a few of them:</p>
<h2 id="is-the-library-in-rust"><a class="header" href="#is-the-library-in-rust">Is the library in Rust?</a></h2>
<p>If it's not in Rust, it's not ellegible for inclusion. There is a single exception today (rlm
python) but it's very likely this will also be removed in the future. Keeping a single language
helps with testing, but also makes the project more accessible and consistent to developers.
Additionally, features exist in Rust that help to improve quality of the project from development to
production.</p>
<h2 id="is-the-project-going-to-create-a-microservice-like-architecture"><a class="header" href="#is-the-project-going-to-create-a-microservice-like-architecture">Is the project going to create a microservice like architecture?</a></h2>
<p>If the project (such as an external OAuth/OIDC gateway, or a different DB layer) would be used in a
tight-knit manner to Kanidm then it is no longer a microservice, but a monolith with multiple moving
parts. This creates production fragility and issues such as:</p>
<ul>
<li>Differences and difficulties in correlating log events</li>
<li>Design choices of the project not being compatible with Kanidm's model</li>
<li>Extra requirements for testing/production configuration</li>
</ul>
<p>This last point is key. It is a critical part of kanidm that the following must work on all
machines, and run every single test in the suite.</p>
<pre><code>git clone https://github.com/kanidm/kanidm.git
cd kanidm
cargo test
</code></pre>
<p>Not only this, but it's very important for quality that running <code>cargo test</code> truly tests the entire
stack of the application - from the database, all the way to the client utilities and other daemons
communicating to a real server. Many developer choices have already been made to ensure that testing
is the most important aspect of the project to ensure that every feature is high quality and
reliable.</p>
<p>Addition of extra projects or dependencies, would violate this principle and lead to a situation
where it would not be possible to effectively test for all developers.</p>
<h2 id="why-dont-you-use-raftetcdmongodbother-to-solve-replication"><a class="header" href="#why-dont-you-use-raftetcdmongodbother-to-solve-replication">Why don't you use Raft/Etcd/MongoDB/Other to solve replication?</a></h2>
<p>There are a number of reasons why these are generally not compatible. Generally these databases or
technolgies do solve problems, but they are not the problems in Kanidm.</p>
<h2 id="cap-theorem"><a class="header" href="#cap-theorem">CAP theorem</a></h2>
<p>CAP theorem states that in a database you must choose only two of the three possible elements:</p>
<ul>
<li>Consistency - All servers in a topology see the same data at all times</li>
<li>Availability - All servers in a a topology can accept write operations at all times</li>
<li>Partitioning - In the case of a network separation in the topology, all systems can continue to
process read operations</li>
</ul>
<p>Many protocols like Raft or Etcd are databases that provide PC guarantees. They guarantee that they
are always consistent, and can always be read in the face of partitioning, but to accept a write,
they must not be experiencing a partitioning event. Generally this is achieved by the fact that
these systems elect a single node to process all operations, and then re-elect a new node in the
case of partitioning events. The elections will fail if a quorum is not met disallowing writes
throughout the topology.</p>
<p>This doesn't work for Authentication systems, and global scale databases. As you introduce
non-negligible network latency, the processing of write operations will decrease in these systems.
This is why Google's Spanner is a PA system.</p>
<p>PA systems are also considered to be &quot;eventually consistent&quot;. All nodes can provide reads and writes
at all times, but during a network partitioning or after a write there is a delay for all nodes to
arrive at a consistent database state. A key element is that the nodes perform an consistency
operation that uses application aware rules to allow all servers to arrive at the same state
<em>without</em> communication between the nodes.</p>
<h2 id="update-resolutionn"><a class="header" href="#update-resolutionn">Update Resolutionn</a></h2>
<p>Many databases do exist that are PA, such as CouchDB or MongoDB. However, they often do not have the
properties required in update resolution that is required for Kanidm.</p>
<p>An example of this is that CouchDB uses object-level resolution. This means that if two servers
update the same entry the &quot;latest write wins&quot;. An example of where this won't work for Kanidm is if
one server locks the account as an admin is revoking the access of an account, but another account
updates the username. If the username update happened second, the lock event would be lost creating
a security risk. There are certainly cases where this resolution method is valid, but Kanidm is not
one.</p>
<p>Another example is MongoDB. While it does attribute level resolution, it does this without the
application awareness of Kanidm. For example, in Kanidm if we have an account lock based on time, we
can select the latest time value to over-write the following, or we could have a counter that can
correctly increment/advance between the servers. However, Mongo is not aware of these rules, and it
would not be able to give the experience we desire. Mongo is a very good database, it's just not the
right choice for Kanidm.</p>
<p>Additionally, it's worth noting that most of these other database would violate the previous desires
to keep the language as Rust and may require external configuration or daemons which may not be
possible to test.</p>
<h2 id="how-pamnsswitch-work"><a class="header" href="#how-pamnsswitch-work">How PAM/nsswitch Work</a></h2>
<p>Linux and BSD clients can resolve identities from Kanidm into accounts via PAM and nsswitch.</p>
<p>Name Service Switch (NSS) is used for connecting the computers with different data sources to
resolve name-service information. By adding the nsswitch libraries to /etc/nsswitch.conf, we are
telling NSS to lookup password info and group identities in Kanidm:</p>
<pre><code>passwd: compat kanidm
group: compat kanidm
</code></pre>
<p>When a service like sudo, sshd, su etc. wants to authenticate someone, it opens the pam.d config of
that service, then performs authentication according to the modules defined in the pam.d config. For
example, if you run <code>ls -al /etc/pam.d /usr/etc/pam.d</code> in SUSE, you can see the services and their
respective pam.d config.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../DEVELOPER_README.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="../developers/designs/access_profiles_rework_2022.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="../DEVELOPER_README.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="../developers/designs/access_profiles_rework_2022.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>