web/ponderings/joining-debian-to-ad-domain/index.html

324 lines
23 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<title>Joining Debian Linux (Desktop) to an Active Directory Domain | Paul&#x27;s Site of Stuff</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1">
<meta name="robots" content="noodp"/>
<link rel="stylesheet" href="https://paulwilde.uk/style.css">
<link rel="stylesheet" href="https://paulwilde.uk/color/orange.css">
<link rel="stylesheet" href="https://paulwilde.uk/color/background_blue.css">
<link rel="stylesheet" href="https://paulwilde.uk/font-hack-subset.css">
<meta name="description" content="">
<meta property="og:description" content="">
<meta property="og:title" content="Joining Debian Linux (Desktop) to an Active Directory Domain | Paul's Site of Stuff">
<meta property="og:type" content="article">
<meta property="og:url" content="https://paulwilde.uk/ponderings/joining-debian-to-ad-domain/">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:description" content="">
<meta name="twitter:title" content="Joining Debian Linux (Desktop) to an Active Directory Domain | Paul's Site of Stuff">
<meta property="twitter:domain" content="paulwilde.uk">
<meta property="twitter:url" content="https://paulwilde.uk/ponderings/joining-debian-to-ad-domain/">
<link rel="alternate" type="application/atom+xml" title="RSS" href="https://paulwilde.uk/atom.xml">
<link rel="shortcut icon" type="image/png" href="/favicon.png">
<script defer data-domain="paulwilde.uk" src="https://plausible.io/js/script.js"></script>
</head>
<body class="">
<div class="container">
<header class="header">
<div class="header__inner">
<div class="header__logo">
<a href="https://paulwilde.uk" style="text-decoration: none;">
<div class="logo">
Hello, I&#x27;m Paul
</div>
</a>
</div>
</div>
<nav class="menu">
<ul class="menu__inner">
<li><a href="/">home</a></li>
<li><a href="/aboutme">about me</a></li>
<li><a href="/ponderings">ponderings</a></li>
<li><a href="/iuse">i use …</a></li>
<li><a href="/tags">tags</a></li>
<li><a href="/atom.xml">rss</a></li>
</ul>
</nav>
</header>
<div class="post">
<h1 class="post-title"><a href="https://paulwilde.uk/ponderings/joining-debian-to-ad-domain/">Joining Debian Linux (Desktop) to an Active Directory Domain</a></h1>
<div class="post-meta-inline">
<span class="post-date">
2025-01-09
</span>
</div>
<span class="post-tags-inline">
:: tags:&nbsp;
<a class="post-tag" href="https://paulwilde.uk/tags/linux/">#linux</a>&nbsp;
<a class="post-tag" href="https://paulwilde.uk/tags/sysadmin/">#sysadmin</a>&nbsp;
<a class="post-tag" href="https://paulwilde.uk/tags/tech/">#tech</a>&nbsp;
<a class="post-tag" href="https://paulwilde.uk/tags/using-linux-in-a-windows-domain/">#using linux in a windows domain</a></span>
<div class="post-content">
<p>I've come across many articles about how to join a linux system to a Microsoft
Active Directory domain and they all work more or less with some tweaking. This is
my article, here describing my own processes for doing it, trying to explain each
bit as it comes.</p>
<p>Part of a <a href="/tags/using-linux-in-a-windows-domain">"Using Linux in a Windows Domain"</a> group of posts.<br />
This article is for desktop Debian Linux - for setting up a PC so it can be used by a standard user of the PC.</p>
<span id="continue-reading"></span><h2 id="basics">Basics</h2>
<p>I'll be running through the process I use for joining Debian Linux as a desktop to Active Directory. The steps should be fairly generic as they use packages available in most distributions, so adapt to your distro as required.<br />
This follows <a href="https://www.pierreblazquez.com/2024/02/04/how-to-join-debian-12-to-an-active-directory-domain/">this article</a> quite closely, with some changes.</p>
<p>I use <code>neovim</code> as an editor, aliases to <code>vim</code>. If you use another editor then replace <code>vim</code> with your editor i.e. <code>nano</code> in all cases.</p>
<h2 id="required-packages">Required Packages</h2>
<p>First things first we need the right packages installed. This can be done by the following command:</p>
<pre data-lang="sh" style="background-color:#212121;color:#eeffff;" class="language-sh "><code class="language-sh" data-lang="sh"><span style="font-style:italic;color:#4a4a4a;"># apt install realmd sssd samba-common krb5-user adcli libsss-sudo sssd-tools libsasl2-modules-ldap packagekit libpam-mount
</span></code></pre>
<ul>
<li><code>sssd</code> is a set of services and tools to manage the connection to the domain.</li>
<li><code>pam</code> handles general user authentication, and creation of mounts for network shares etc.</li>
<li><code>realmd</code> is a tool providing a simple way to discover and join domains.</li>
<li><code>krb5</code> is a kerberos (authentication token) handler amongst other things.</li>
<li>The other packages like <code>*-ldap</code>, <code>adcli</code> are further tools use for domain administration.</li>
</ul>
<p>For the most part, when we say <code>realm</code> we mean your windows "domain name". We'll be using <strong>YOURDOMAIN.LOCAL</strong> as an example.</p>
<h2 id="joining-the-domain">Joining the Domain</h2>
<p>This is at its simplest a case of configuring basic <code>krb5</code> and using <code>realm join</code> to actually join the domain.</p>
<h3 id="configuring-krb5">Configuring krb5</h3>
<p>Edit the <code>krb5.conf</code> file to set the default realm:</p>
<pre data-lang="sh" style="background-color:#212121;color:#eeffff;" class="language-sh "><code class="language-sh" data-lang="sh"><span style="color:#82aaff;">vim /etc/krb5.conf
</span></code></pre>
<pre data-lang="conf" style="background-color:#212121;color:#eeffff;" class="language-conf "><code class="language-conf" data-lang="conf"><span style="font-style:italic;color:#c792ea;">[libdefaults]
</span><span style="color:#f78c6c;">default_realm </span><span style="color:#89ddff;">= </span><span style="color:#f78c6c;">YOURDOMAIN</span><span style="color:#89ddff;">.</span><span style="color:#f78c6c;">LOCAL </span><span style="font-style:italic;color:#4a4a4a;"># Should be in CAPS
</span></code></pre>
<p>This will allow the krb5 client to identified the default realm. If you don't set this, then a realm will need to be specified with every kerberos request i.e. with <code>kinit</code>.</p>
<h3 id="realm-join">Realm Join</h3>
<p>Realmd handles a massive amount of the work here. It used to be we had to manage a lot of this configuration ourselves, but realm now does a lot of it for us.</p>
<p>You can discover information about the local domain by issuing the below command</p>
<pre data-lang="sh" style="background-color:#212121;color:#eeffff;" class="language-sh "><code class="language-sh" data-lang="sh"><span style="color:#82aaff;">realm discover
</span><span style="font-style:italic;color:#4a4a4a;"># or
</span><span style="color:#82aaff;">realm discover YOURDOMAIN.LOCAL
</span></code></pre>
<p>If all looks good you can join it</p>
<pre data-lang="sh" style="background-color:#212121;color:#eeffff;" class="language-sh "><code class="language-sh" data-lang="sh"><span style="color:#82aaff;">realm join</span><span style="color:#89ddff;"> --</span><span style="color:#f78c6c;">user</span><span style="color:#89ddff;">={</span><span style="color:#82aaff;">your administrator account</span><span style="color:#89ddff;">}</span><span style="color:#82aaff;"> YOURDOMAIN.LOCAL
</span></code></pre>
<p>And to check everything is OK</p>
<pre data-lang="sh" style="background-color:#212121;color:#eeffff;" class="language-sh "><code class="language-sh" data-lang="sh"><span style="color:#82aaff;">realm list
</span></code></pre>
<p>which should output something like</p>
<pre data-lang="sh" style="background-color:#212121;color:#eeffff;" class="language-sh "><code class="language-sh" data-lang="sh"><span style="color:#82aaff;">yourdomain.local
</span><span> </span><span style="color:#82aaff;">type: kerberos
</span><span> </span><span style="color:#82aaff;">realm-name: YOURDOMAIN.LOCAL
</span><span> </span><span style="color:#82aaff;">domain-name: yourdomain.local
</span><span> </span><span style="color:#82aaff;">configured: kerberos-member
</span><span> </span><span style="color:#82aaff;">server-software: active-directory
</span><span> </span><span style="color:#82aaff;">client-software: sssd
</span><span> </span><span style="color:#82aaff;">required-package: sssd-tools
</span><span> </span><span style="color:#82aaff;">required-package: sssd
</span><span> </span><span style="color:#82aaff;">required-package: libnss-sss
</span><span> </span><span style="color:#82aaff;">required-package: libpam-sss
</span><span> </span><span style="color:#82aaff;">required-package: adcli
</span><span> </span><span style="color:#82aaff;">required-package: samba-common-bin
</span><span> </span><span style="color:#82aaff;">login-formats: </span><span style="color:#89ddff;">%</span><span>U</span><span style="color:#82aaff;">@yourdomain.local
</span><span> </span><span style="color:#82aaff;">login-policy: allow-realm-logins
</span></code></pre>
<h3 id="testing-connection">Testing Connection</h3>
<p>Technically now the computer is joined to the domain and can authenticate. You can test with:</p>
<pre data-lang="sh" style="background-color:#212121;color:#eeffff;" class="language-sh "><code class="language-sh" data-lang="sh"><span style="color:#82aaff;">kinit </span><span style="color:#89ddff;">{</span><span style="color:#82aaff;">domain user</span><span style="color:#89ddff;">} </span><span style="font-style:italic;color:#4a4a4a;"># will authenticate as that user
</span><span style="color:#82aaff;">klist </span><span style="font-style:italic;color:#4a4a4a;"># to show the kerberos token validity
</span><span style="color:#82aaff;">kdestroy </span><span style="font-style:italic;color:#4a4a4a;"># deauthenticate as that user
</span></code></pre>
<p>Or, of course, log out and back in as a domain user account.</p>
<h3 id="tuning-sssd">Tuning SSSD</h3>
<p>Open up your <code>/etc/sssd/sssd.conf</code> file and make a few tweaks</p>
<pre data-lang="sh" style="background-color:#212121;color:#eeffff;" class="language-sh "><code class="language-sh" data-lang="sh"><span style="color:#82aaff;">vim /etc/sssd/sssd.conf
</span></code></pre>
<p>Most of this will already be completed in your file as realmd handled it. But check over
it anyway.</p>
<pre data-lang="conf" style="background-color:#212121;color:#eeffff;" class="language-conf "><code class="language-conf" data-lang="conf"><span style="font-style:italic;color:#c792ea;">[sssd]
</span><span style="color:#f78c6c;">domains </span><span style="color:#89ddff;">=</span><span> yourdomain</span><span style="color:#89ddff;">.</span><span>local
</span><span style="color:#f78c6c;">config_file_version </span><span style="color:#89ddff;">= </span><span style="color:#f78c6c;">2
</span><span style="font-style:italic;color:#4a4a4a;">#services = nss, pam # commented out as these are socket units which are dynamically handled by systemd
</span><span style="color:#f78c6c;">implicit_pac_responder </span><span style="color:#89ddff;">= </span><span style="color:#f78c6c;">false </span><span style="font-style:italic;color:#4a4a4a;"># having set to true allegedly crashed some SSSD services. It&#39;s not essential.
</span><span>
</span><span style="font-style:italic;color:#c792ea;">[domain/yourdomain.local]
</span><span style="color:#f78c6c;">access_provider </span><span style="color:#89ddff;">=</span><span> ad
</span><span style="color:#f78c6c;">id_provider </span><span style="color:#89ddff;">=</span><span> ad
</span><span style="color:#f78c6c;">default_shell </span><span style="color:#89ddff;">= /</span><span>bin</span><span style="color:#89ddff;">/</span><span>bash
</span><span style="color:#f78c6c;">krb5_store_password_if_offline </span><span style="color:#89ddff;">= </span><span style="color:#f78c6c;">True
</span><span style="color:#f78c6c;">cache_credentials </span><span style="color:#89ddff;">= </span><span style="color:#f78c6c;">True
</span><span style="color:#f78c6c;">krb5_realm </span><span style="color:#89ddff;">= </span><span style="color:#f78c6c;">YOURDOMAIN</span><span style="color:#89ddff;">.</span><span style="color:#f78c6c;">LOCAL
</span><span style="color:#f78c6c;">krb5_ccachedir </span><span style="color:#89ddff;">= /</span><span>tmp
</span><span style="color:#f78c6c;">krb5_ccname_template </span><span style="color:#89ddff;">= </span><span style="color:#f78c6c;">FILE</span><span style="color:#89ddff;">:</span><span>%d</span><span style="color:#89ddff;">/.</span><span>krb5cc_%U
</span><span style="color:#f78c6c;">full_name_format </span><span style="color:#89ddff;">= </span><span>%1$s
</span><span style="color:#f78c6c;">realmd_tags </span><span style="color:#89ddff;">=</span><span> manages</span><span style="color:#89ddff;">-</span><span>system joined</span><span style="color:#89ddff;">-</span><span>with</span><span style="color:#89ddff;">-</span><span>adcli
</span><span style="color:#f78c6c;">fallback_homedir </span><span style="color:#89ddff;">= /</span><span>home</span><span style="color:#89ddff;">/</span><span>%u@%d
</span><span style="color:#f78c6c;">override_homedir </span><span style="color:#89ddff;">= /</span><span>home</span><span style="color:#89ddff;">/</span><span>%u@%d
</span><span style="color:#f78c6c;">ad_domain </span><span style="color:#89ddff;">=</span><span> yourdomain</span><span style="color:#89ddff;">.</span><span>local
</span><span style="color:#f78c6c;">use_fully_qualified_names </span><span style="color:#89ddff;">= </span><span style="color:#f78c6c;">False
</span><span style="color:#f78c6c;">ldap_id_mapping </span><span style="color:#89ddff;">= </span><span style="color:#f78c6c;">True
</span><span style="color:#f78c6c;">dydns_update </span><span style="color:#89ddff;">= </span><span style="color:#f78c6c;">False
</span><span>
</span><span style="font-style:italic;color:#4a4a4a;"># This next one was a real fix for me. I had some issues where a Group Policy was unreadable which crashed SSSD and prevented the user from logging in. Windows would silently ignore it, so never an issue. I like the fact it was highlighted to me, but is not ideal for a production machine where people need to log in. So we ignore unreadable GPOs.
</span><span style="color:#f78c6c;">ad_gpo_ignore_unreadable </span><span style="color:#89ddff;">= </span><span style="color:#f78c6c;">True
</span></code></pre>
<p>Now update the PAM modules</p>
<pre data-lang="sh" style="background-color:#212121;color:#eeffff;" class="language-sh "><code class="language-sh" data-lang="sh"><span style="color:#82aaff;">pam-auth-update
</span></code></pre>
<p>and make sure to check <code>[*] Create home directory on login</code> is enabled.<br />
This will allow the system to validate the user again the domain, create the user's home directory and mount the user's network shares if set.</p>
<h3 id="sudo">Sudo</h3>
<p>There's a chance you may want domain administrators to have sudo privileges. This can be done by adding the following line to <code>/etc/sudoers</code></p>
<pre data-lang="conf" style="background-color:#212121;color:#eeffff;" class="language-conf "><code class="language-conf" data-lang="conf"><span>%domainadmins </span><span style="color:#f78c6c;">ALL</span><span style="color:#89ddff;">=</span><span>(</span><span style="color:#f78c6c;">ALL</span><span style="color:#89ddff;">:</span><span style="color:#f78c6c;">ALL</span><span>) </span><span style="color:#f78c6c;">ALL
</span></code></pre>
<h3 id="samba">Samba</h3>
<p>Having Samba configured also helps streamline connectivity to network shares.</p>
<pre data-lang="sh" style="background-color:#212121;color:#eeffff;" class="language-sh "><code class="language-sh" data-lang="sh"><span style="color:#82aaff;">vim /etc/samba/smb.conf
</span></code></pre>
<pre data-lang="conf" style="background-color:#212121;color:#eeffff;" class="language-conf "><code class="language-conf" data-lang="conf"><span style="font-style:italic;color:#c792ea;">[global]
</span><span> </span><span style="color:#f78c6c;">workgroup </span><span style="color:#89ddff;">=</span><span> yourdomain</span><span style="color:#89ddff;">.</span><span>local
</span><span> </span><span style="color:#f78c6c;">realm </span><span style="color:#89ddff;">= </span><span style="color:#f78c6c;">YOURDOMAIN</span><span style="color:#89ddff;">.</span><span style="color:#f78c6c;">LOCAL
</span><span> </span><span style="color:#f78c6c;">encrypt </span><span>passwords </span><span style="color:#89ddff;">= </span><span style="color:#f78c6c;">yes
</span><span> </span><span style="color:#f78c6c;">client </span><span>protection </span><span style="color:#89ddff;">=</span><span> encrypt
</span></code></pre>
<p>There are a couple of further notes regarding GVFS and automatically mounting network shares in <a href="https://www.pierreblazquez.com/2024/02/04/how-to-join-debian-12-to-an-active-directory-domain/">the article mentioned at the start</a>, if you need those things in place I recommend checking through that article as well.</p>
<h2 id="testing">Testing.</h2>
<p>We should be good to go. Let's run some tests.</p>
<h3 id="are-services-running">Are services running?</h3>
<pre data-lang="sh" style="background-color:#212121;color:#eeffff;" class="language-sh "><code class="language-sh" data-lang="sh"><span style="color:#82aaff;">systemctl status
</span><span style="font-style:italic;color:#4a4a4a;"># If the state is `degraded` you can see failed services by running this command
</span><span style="color:#82aaff;">systemctl list-units</span><span style="color:#89ddff;"> --</span><span style="color:#f78c6c;">failed
</span></code></pre>
<p>I experienced some issues with SSSD failing due to unreadable GPOs mentioned above. I discovered SSSD crashed when trying to log in, and adding the SSSD option to ignore unreadable GPOs fixed it.</p>
<h2 id="login">Login</h2>
<p>Great! We're here. Now we can log in.
Either log in using the desktop login screen, or from a terminal enter:</p>
<pre data-lang="sh" style="background-color:#212121;color:#eeffff;" class="language-sh "><code class="language-sh" data-lang="sh"><span style="color:#82aaff;">login </span><span style="color:#89ddff;">{</span><span style="color:#82aaff;">user name</span><span style="color:#89ddff;">}
</span></code></pre>
<p>to log in as that user. The home directory should be created during login and everything is ready to go.</p>
<h2 id="automatically-mounting-shared-folders">Automatically Mounting Shared Folders</h2>
<p>You can edit <code>/etc/security/pam_mount.conf.xml</code> to enable automatic mounting of shared folders at login. I have had mixed success with this, but I'll put it here anyway:</p>
<pre data-lang="xml" style="background-color:#212121;color:#eeffff;" class="language-xml "><code class="language-xml" data-lang="xml"><span>...prefilled content...
</span><span style="font-style:italic;color:#4a4a4a;">&lt;!-- this should go somewhere before the `&lt;mkmountpoint ... &gt;` block.
</span><span style="font-style:italic;color:#4a4a4a;"> &lt;volume
</span><span style="font-style:italic;color:#4a4a4a;"> fstype=&quot;cifs&quot;
</span><span style="font-style:italic;color:#4a4a4a;"> sgrp=&quot;domain users&quot;
</span><span style="font-style:italic;color:#4a4a4a;"> server=&quot;yourserver.yourdomain.local&quot;
</span><span style="font-style:italic;color:#4a4a4a;"> path=&quot;share&quot;
</span><span style="font-style:italic;color:#4a4a4a;"> mountpoint=&quot;~/Network Drives/Share&quot;
</span><span style="font-style:italic;color:#4a4a4a;"> options=&quot;vers=3.0,sec=krb5i,cruid=%(USERUID),nodev,nosuid,noexec,rw&quot;
</span><span style="font-style:italic;color:#4a4a4a;"> /&gt;
</span><span style="font-style:italic;color:#4a4a4a;">...prefilled content...
</span></code></pre>
</div>
<div class="pagination">
<div class="pagination__title">
<span class="pagination__title-h">Thanks for reading! Read other posts?</span>
<hr />
</div>
<div class="pagination__buttons">
<span class="button previous">
<a href="https://paulwilde.uk/ponderings/robots-aint-hacking/">
<span class="button__icon"></span>&nbsp;
<span class="button__text">Accused of Hacking</span>
</a>
</span>
<span class="button next">
<a href="https://paulwilde.uk/ponderings/ms-exchange-room-calendar-title-replaced-by-organiser/">
<span class="button__text">Microsoft Exchange 365 Room Calendar - Subject Replaced by Organizer</span>&nbsp;
<span class="button__icon"></span>
</a>
</span>
</div>
</div>
</div>
<footer class="footer">
<div class="footer__inner">
<a href="https:&#x2F;&#x2F;notnull.space&#x2F;@paul" rel="me">fediverse (gts)</a>
<a href="https:&#x2F;&#x2F;snac.notnull.space&#x2F;paul" rel="me">fediverse (snac)</a>
<a href="https:&#x2F;&#x2F;codeberg.org&#x2F;pswilde" rel="me">codeberg</a>
<a href="https:&#x2F;&#x2F;keyoxide.org&#x2F;85633E30514CC1932E4268460ED12CF710BC42CA" rel="me">keyoxide</a>
</div>
<div class="footer__inner">
<div class="copyright">
<span>©
2025
Paul Wilde</span>
<span class="copyright-theme">
<span class="copyright-theme-sep">:: </span>
Theme: <a href="https://github.com/pawroman/zola-theme-terminimal/">Terminimal</a>
</span>
</div>
</div>
</footer>
</div>
</body>
</html>