Joining Debian 8 to Active Directory

Joining a GNU/Linux machine to a Microsoft Active Directory has been possible for years, but it’s always been a bit of a science project that involved touching half-a-dozen obscure config files and usually resulted in me getting completely locked out of the machine. Various commercial packages such as Likewise and Centrify aimed to smooth out the process, but they weren’t universally accessible across distros, and often produced inconsistent results.

After upgrading a system to Debian 8, I noticed a new option for joining the domain, courtesy of the folks at RedHat: realmd. Realmd puports to make joining an Active Directory domain dead simple. How does it do?

What means this “join”?

When I think of “joining a domain”, my expectation is that I should be able to login to my system as a domain user, have a computer account created in the directory, have a home directory created for me, and potentially have some appropriate permissions granted to me (e.g., sudo privileges for domain admins). Apparently that’s not what everyone means, including the developers of realmd.

realmd will get us part of the way there, but unfortunately we’ll still have to do some config file twiddling to get the last nine yards.

Pre-Setup

Sanity checks

  • Make sure you have Debian 8 installed.
  • Make sure your machine is on the network, of course, and that you have a domain admin account ready (or one that can join machines to the domain).
  • Make sure your DNS server is pointing to a DNS server that knows about AD. We have some pre-AD ones that don’t, and I ran into trouble with this. Most people probably don’t need to worry about this.
  • I use sudo in these examples because I prefer it. If you don’t, make sure you’re root and omit the “sudo” whenever you see it.

Installing packages

Realmd is easy enough to install using aptitude:

sudo aptitude install realmd

Ideally, realmd is meant to install other packages required to join your domain (be it Active Directory, openldap, or some other supported directory) automatically when you attempt to join.

In practice, I found this unreliable. So for my AD, I also installed adcli and sssd manually. And since time synchronization is critical for Active Directory, I also installed ntp.

sudo aptitude install ntp adcli sssd

Some fixes

For some reason, the first attempts I made to join a domain failed because a certain samba-related directory didn’t exist. I don’t know if this is a bug in realmd, or something to do with the way it installs dependencies, but simply creating the directory fixes this:

sudo mkdir -p /var/lib/samba/private

Also, sssd was not configured to start at boot for some reason, so this also needed to be done.

sudo systemctl enable sssd

sssd won’t actually start until it has a config file, which realmd will generate for us.

Join up

At this point, you should be able to get some information about your domain with this command:

sudo realm discover my-domain.local

Obviously, replace “my-domain.local” with your AD domain. You should see some output that looks like this:

my-domain.local
  type: kerberos
  realm-name: MY-DOMAIN.LOCAL
  domain-name: my-domain.local
  configured: no
  server-software: active-directory
  client-software: sssd

If this looks good, we can join the domain:

sudo realm join --user=joe.smith my-domain.local

This assumes joe.smith is a domain admin. Use whatever domain admin account you have. You’ll be prompted for a password, of course, and then the magic happens.

If all goes well, your machine should be configured to authenticate users to your domain at this point. You may need to start up sssd:

sudo systemctl start sssd

We can verify this by trying to get a password entry for a domain user:

sudo getent passwd joe.smith@my-domain.local

If that returns something that looks like a line from /etc/passwd for your joe.smith user, you’re in! Otherwise, something went wrong.

Vital finishing touches

You can authenticate users at this point, but we’re not quite done. Two more tweaks are necessary here:

You want a home directory?

By default, Debian isn’t going to make a home directory whenever the user logs in. We need to fix this, because without this you can’t actually log in to the computer. Fortunately, it takes only one line in one config file to acheive this:

echo "session required pam_mkhomedir.so skel=/etc/skel/ umask=0022" | sudo tee -a /etc/pam.d/common-session

This tells PAM to create a home directory for any authenticating user if they don’t have one, and to copy the default contents from /etc/skel. You can change that to something else if you want a different default home directory for domain users.

Local admin privileges

Typically on a domain, domain admins would get local admin rights so they can do admin things on computers. Makes sense.

To get this in our Debian setup, we need to make sure our sudo supports this, and then configure it.

sudo aptitude install libsss-sudo
echo "%domain\ admins@my-domain.local ALL=(ALL) ALL" | sudo tee -a /etc/sudoers.d/domain_admins

The first line installs a library to allow sssd and sudo to talk. The second adds a directive to sudo to allow domain admins at my-domain.local sudo privileges. (Copy-pasters take note: you need to edit that command with your domain name.)

Prepare for lift-off

Might as well give it a good reboot at this point just for the heck of it, but it may not actually be required (just a habit from Windows, I guess).

At this point you should be able to log in as any domain user, and domain admins should be able to sudo. Congrats!

For the completely lazy, I’ve thrown this script together that should do the job:

#!/bin/bash

# This script should join Debian Jessie (8) to an Active Directory domain.
echo "Please authenticate with your sudo password"
sudo -v

if ! $(sudo which realmd 2>/dev/null); then
    sudo aptitude install realmd adcli sssd
fi

if ! $(sudo which ntpd 2>/dev/null); then
    sudo aptitude install ntp
fi

sudo mkdir -p /var/lib/samba/private

echo "Please enter the domain you wish to join: "
read DOMAIN

echo "Please enter a domain admin login to use: "
read ADMIN

sudo realm join --user=$ADMIN $DOMAIN

if [ $? -ne 0 ]; then
    echo "AD join failed.  Please run 'journalctl -xn' to determine why."
    exit 1
fi

sudo systemctl enable sssd
sudo systemctl start sssd

echo "session required pam_mkhomedir.so skel=/etc/skel/ umask=0022" | sudo tee -a /etc/pam.d/common-session

# configure sudo
sudo aptitude install libsss-sudo

echo "%domain\ admins@$DOMAIN ALL=(ALL) ALL" | sudo tee -a /etc/sudoers.d/domain_admins

echo "The computer is joined to the domain.  Please reboot, ensure that you are connected to the network, and you should be able to login with domain credentials."

59 Thoughts on “Joining Debian 8 to Active Directory

  1. Rutger says:

    Works like a charm. Thank you!

  2. Giuseppe Mainardi says:

    “Unable to find adcli package”
    “Package sssd is not available, but is referred to by another package….”

    I’m using Debian 8 stable version, Is this a good version to be joined to AD?

    1. Alan says:

      You’re either not running Debian 8, or something is really wrong with your setup. Or maybe you just need to run “aptitude update”?

    2. Mickey says:

      You’re probably still pointing the package manager at the Debian install DVDs. The adcli and sssd are probably missing or cannot be found on the media.

      Be sure you add a main repository to /etc/apt/sources.list. The repository URL may vary based on your location.

      deb http://ftp.us.debian.org/debian/ jessie main

      OR

      deb http://http.us.debian.org/debian/ jessie main

  3. Nathan says:

    works perfect – thnx!

    To login as “user” instead of “user@my-domain.local” set in /etc/sssd/sssd.conf:
    use_fully_qualified_names = False

    1. Rich says:

      Thanks for that Nathan, that’s what I was looking for. =)

  4. schwartz says:

    hey,

    all works perfect except the sudo part, it says “user $RandomAdminUser is not allowed to run sudo on this machine.”
    i have an 2008R2 active directory ( in french i don’t know if this change anything ) i already try with “%doamain\ admins\ du\ domaine@mydomain ALL=(ALL) ALL
    have you a tips ? 🙂

  5. Juan says:

    Hi, i do every steps, when i do a sudo getent passwd, i get the info of the user from the server, but in login screen, it always says wrong password, i try 2 or 3 users anda same happens.

    1. Llyd says:

      Same problem here, anyone get an answer for this?

  6. Jim says:

    WOW! This was without a doubt the best tutorial I have seen on this subject!
    I have tried MANY other tutorials, with no success.
    These instructions are clear and concise.
    Thank you so much for this wonderful page!

  7. Marcio Souza says:

    Very thanks!!! Excellent post!!!

  8. Ravi says:

    For some reason this is not working for me. I was able to join the machine to the domain. But “getent” with the domain_adm@domain_name returns nothing. Running “sudo systemctl status sssd” shows me this warning “ldapdb_canonuser_plug_init() failed in sasl_canonuser_add_plugin(): invalid parameter supplied”; any idea what I am doing wrong?

  9. Alan says:

    Hey all — as much as I’d like to be able to solve everyone’s issues with this, it pretty much “works for me”, and I don’t know why it isn’t working for anyone else. Given the complexity and variety of AD setups, there are easily N+1 things that can go wrong with this.

    If you really need help, you’re probably better off heading to your nearest Debian help forum, subreddit, irc, or mailing list.

  10. Grzyboll says:

    Everything works fine except groups sudo supports. For example I have user grzyboll with uid=1790201640(grzyboll@musch.local) gid=1790200513(domain users@musch.local) groups=1790200513(domain users@musch.local),1790201326(linux_admin@musch.local), and when I add to sudoers
    “%musch.local\\linux_admin ALL=(ALL) ALL” (where domain is musch.local, and group is linux_admin) or “%domain\ linux_admin@musch.local ALL=(ALL) ALL” it doesn’t work. But when I add only user grzyboll@musch.local ALL=(ALL:ALL) ALL it’s work.

  11. Rich says:

    One note, on my system anyway, for sudo I had to uncomment the following line

    sudoedit /etc/sudoers:

    Changed:
    #includedir /etc/sudoers.d
    To:
    includedir /etc/sudoers.d

    After that I did /etc/init.d/sudo restart

    Sudo then worked for my domain admins. Thanks for the great write-up.

    1. Rich says:

      Oops that’s wrong! (delete that comment so no one makes that mistake!)

    2. Rich says:

      Changing the domain_admins file to be:

      domain\ admins ALL= ALL

      Is what worked for me for domain admins sudo’ing.

      1. Thanks Rick and Nate and Alan! These directions worked perfectly. I can now login with my domain account and I can sudo. Life is good. I am now using a Debian machine for my work computer.

  12. Guy Lovell says:

    I received the following error message when attempting to login

    See: journalctl REALMD_OPERATION=454.3065
    realm: Cannot join this realm

    1. luis says:

      I have exactly the same error, can someone help us?

      1. Stephen Smalley says:

        On a fresh install you need to edit the /etc/nsswitch.conf file. From:

        hosts: files myhostname mdns4_minimal [NOTFOUND=return]
        dns

        To:
        hosts: files dns

        Worked perfectly for me.

  13. bussillis says:

    If i only have regular user account on AD, and for some reason, my sys Admin is so so so so afraid of Linux, is there a way to join my machine to AD?

    1. Alan says:

      Pretty sure the answer there is going to be ‘no’, joining a machine typically requires Domain Admin privileges in the default configuration, but unless you need to authenticate logins against the AD, there may not really be a reason to. If you just want access to your profile/home directory from a Linux system, it’s quite possible to mount samba shares using AD credentials without actually joining the machine to the domain.

    2. Martin says:

      Hi bussillis,

      as I know, every domain-USER can join up to 10 (ten) computers to a domain without being an administrator.

      An administrator can join unlimited computers.

      The counter (of up to ten computers) can not be resetted. So if your user-account has joined al 10 computers, you can not join the 11th one …

      BUT. Do not fight against your admin!

  14. Sid says:

    This is the best tutorial for the topic I’ve found. Thanks a ton! Worked like a charm!

  15. Dion says:

    In my system I have a HUGE AD with students staff alumni contractors etc in it. I dont want any of these users to be able to login. I only want specific AD groups to be able to login.

    How can I limit the login via ssh and console to local groups and/or specific AD groups?

  16. dicter says:

    Hello,

    I did everything, and i can join the ad. But when I log out from the local user, and try to login with AD user, it accepts the user/password, try to log in, and then log me out immediately. Can anyone help me with this? Or at least, where should I search for login logs?

    Thanks in advance!

  17. Dion says:

    I have noticed that login works fine but sudo takes forever to run before reaching the password prompt for the first time.

    From what I have read it is the sss_cache being cached. I assume because our AD is so large this is why.

    As I am not storing my rules is AD, it just needs to look at the group membership. Is there any way to speed this up?

    Dion

  18. sloniupl says:

    You can also create your own security group in AD for example “Linux sudo”
    and grant sudo rights to that goroup:
    echo “%linux\ sudo@mydomain.local ALL=(ALL) ALL” | tee -a /etc/sudoers.d/linux_sudo
    works for me and user don’t have to be Domain admin 🙂

  19. initd says:

    I got to the same problem as some of the others here, as I wasn’t able to see the domain users with getenv, then I found that avahi ‘loop’ my attempts because my domain suffix is .local
    I followed this guide and everything worked:
    http://www.lowlevelmanager.com/2011/09/fix-linux-dns-issues-with-local.html

  20. Mat Simon says:

    Hi

    Thanks for your article which was helpful, however I’d like to hear from you if you also get spammed for every sudo command issued once libsss-sudo is installed on jessie?

    The user who gets root mails (/etc/aliases will tell you who, typicall the first user at install) receives an error message for each and every sudo command executed once it is installed.

    Would be interesting to know since it is really annoying here on even fresh jessie setups here.

    1. Alan says:

      I haven’t noticed this so far. I just tried it on a system and did not get a mail, but I don’t have a lot of systems configured like this so maybe something is different with my configurations.

  21. marc says:

    thank you for this very useful write-up.

    i haven’t been able to get the sudo via group membership to work but that’s surely not your fault 😉

    1. Marc says:

      update:

      had to enter this string into a file in /etc/sudoers.d

      %ADgroupname ALL=(ALL) ALL

      without passing a domain at all

      again thank you for this excellent tutorial!

  22. gpb says:

    Thanks a lot for this tutorial. For me it needed a reboot between join and getent working. Everything else worked like a charm.

  23. Kris the Man says:

    you should also touch a /etc/sssd/sssd.conf

    my sssd didnt work and the AD-Join failed, because it didnt create the file itself

  24. andrea says:

    Hi Thanks a lot for this tutorial
    i have a problem, after insert this command echo “session required pam_mkhomedir.so skel=/etc/skel/ umask=0022” | sudo tee -a /etc/pam.d/common-session and reboot my screen still in black..

    1. Thrond Fjelde says:

      The same happened to me, any one that have solution to this issue ?

  25. Shmerl says:

    It didn’t work for me without creating at least the first kerberos ticket using kinit. Authentication simply didn’t work without it. Other than that, it’s pretty spot on.

  26. Zerocool says:

    Can I copy and update this a bit? It’s very useful, but missing a few easy to ignore steps that will make people think it doesn’t work

    1. theplague says:

      dade, im about to be doing this myself, can you explain what is missing here so that i don’t think it’s not working.

      thanks!

  27. jessie says:

    In order to add sudo capabilities to the user, do as follow:

    sudo adduser username@my-domain.local sudo
    sudo visudo
    and then add these line:
    name.surname@my-domain.local ALL=(ALL:ALL) ALL

  28. Amudhan says:

    Hi,

    Tutorial was good.

    i am facing different kind of issue after joining domain i was not able to list domain users using command “getent passwd domain username” but when using “realm list” shows that successfully joined domain. after few hours when system left idle it starts working and listing users.

    Error msg found in log files.
    an 19 21:38:23 debsys [sssd[ldap_child[990]]]: Client ‘debsys$@domain.com’ not found in Kerberos database
    Jan 19 21:38:24 debsys [sssd[ldap_child[991]]]: Failed to initialize credentials using keytab [default]: Client ‘debsys$@domain.com’ not found in
    Kerberos database. Unable to create GSSAPI-encrypted LDAP connection.

    (Thu Jan 19 21:45:37 2017) [[sssd[ldap_child[1010]]]] [ldap_child_get_tgt_sync] (0x0010): Failed to init credentials: Client ‘debsys$@domain.com’ not found in Kerberos database

    (Thu Jan 19 21:04:41 2017) [sssd[be[domain.com]]] [ad_account_info_complete] (0x0010): Bug: dp_error is OK on failed request
    (Thu Jan 19 21:07:06 2017) [sssd[be[domain.com]]] [ad_account_info_complete] (0x0010): Bug: dp_error is OK on failed request

    (sssd.conf file)

    [sssd]
    domains = domain.com
    config_file_version = 2
    services = nss, pam

    [domain/domain.com]
    ad_domain = domain.com
    krb5_realm = domain.com
    realmd_tags = manages-system joined-with-samba
    cache_credentials = True
    id_provider = ad
    krb5_store_password_if_offline = True
    default_shell = /bin/bash
    ldap_id_mapping = True
    use_fully_qualified_names = True
    fallback_homedir = /home/%d/%u
    access_provider = ad

  29. alain says:

    how can we with this share a folder with ad authentication

  30. Ernesto says:

    Hi everyone!!

    I have done everything in the tutorial, and I can see my debian from the AD administrator. But when I want to start a session with any of my domain users, Debian doesn’t allow it. It shows me this message:

    The system administrator has temporarily disabled the login to the system

  31. Arbi A. says:

    Hi,

    In case anyone else comes across this on Ubuntu 16.04 LTS server.

    After following this great tutorial, we were able to successfully authenticate against Acitve Directory in our test environment without installing krb5-user.

    However, when we tried the exact same steps on a clean system using client’s server, we just couldn’t join their AD realm. We kept on getting the following error:

    [,,,]
    Couldn’t authenticate to active directory: SASL(-1): generic failure: GSSAPI Error: Unspecified GSS failure. Minor code may provide more information (Server not found in Kerberos database)
    […]

    Pro Tip: For debugging purposes, turn on “–verbose” in your join realm command:

    sudo realm join –user=joe.smith my-domain.local –verbose

    To fix our problem, we ended up installing krb5-user and adding the following line to /etc/krb4.conf to disable reverse DNS lookup .

    [libdefaults]
    rdns=false

    That allowed us to successfully authenticate against AD.

    Also, if you don’t want to provide the full domain name in your login credentials, modify /etc/sssd/sssd.conf AFTER you join the realm and BEFORE you start the sssd service by changing:

    use_fully_qualified_names = False

    Hope that helps…
    A

  32. Jhon says:

    Hello everyone,
    This method is not working in Debian 9 Stretch :(, I enter the computer into the domain, but when I try to login it does not accept the user password. Any idea what it might be?

    PS: This method is working perfectly for me in Debian 8 Jessie.

    1. zCool says:

      I upgraded from Debian 8 to to Debian 9 as well and it broke. I also committed a bajillion other changes and locked myself out of SSH access so there are probably a number of other issues that resulted in this breaking. I.E I can not say for sure if upgrading to Stretch was what caused it to break; however, that being said I was able to fix my problem.

      I completely removed and reinstalled SSSD-AD on my system; however, ran into the same issue. Debian login would take my password, but it would not grant access, /var/log/auth.log revealed that my user account was not authorized.

      Ultimately the issue resided in /etc/sssd.d/sssd.conf all along

      access_provider = ad

      I set mine too

      access_provider = simple

      and added

      simple_allow_users = NameofdomainUserYouWantToAllow

      Restarted SSSD and was able to login with my FQDN.

      It’s pretty obvious now that issue lies in how access_provider = ad is set-up. I don’t know what the correct settings are to make access_provider = ad work, but I’m on the right track. I’ll see if I can make it work here soon.

      https://outsideit.net/realmd-sssd-ad-authentication/

  33. Kent says:

    Thank you, Alan! I’ve been trying off-and-on for 15 years or so to do this (it hasn’t been very high-priority), and your tutorial here made it simple, and better yet, it worked. (I realize a lot of credit goes to the realmd app and developers, but you’re the one that made me aware of it.)

    This. Is. Awesome.

    Thank you very much for your write-up!

  34. Bryan Chapman says:

    realm join –user=administrator uk.xxxx.co.uk
    Password for administrator:
    See: journalctl REALMD_OPERATION=r2645.14672
    realm: Couldn’t join realm: Necessary packages are not installed: samba-common-bin, sssd-tools, sssd, libnss-sss, libpam-sss

    But the packages are installed 🙁
    Debian 8.7

    1. loripe says:

      please could you give us result of following command
      ystemctl status sssd.service
      Did you check service is running?
      could you provide logs?

  35. Alexander Starostin says:

    Works like a charm, thank you!

  36. loripe says:

    thank you very much 🙂

  37. Fil ouzito says:

    Hi,
    Which other packet and configuration I need to share from this machine?

  38. Randy says:

    Hello,
    Thank you ! Marvellous presentation.
    It’s the first time that it’s working for me 🙂 The password, UID and GID are obtain from the AD.

    I know that is not your aim, but I have a NIS service and I would keep the UID, GID and homedirs from my NIS map ‘password’.
    Have you an idea ?

    Thanks again !

  39. Zoltan says:

    Should be any kind of kerberos to be installed on the client?
    Its crying for the KDC server of the domain.

    When i check the status of sssd servicec its saying:

    [sssd[ldap_child[1012]: Failed to initialize credentials using keytab [default]: Cannot find KDC for realm “XY.LOCAL”. Unable to create GSSAPI-encrypted LDAP connection.
    [sssd[ldap_child[1012]: Cannot find KDC for realm “XY.LOCAL”

    1. Randy says:

      Hello, from a new Jessie, in my /var/log/apt/history I find : sssd-krb5 sssd-krb5-common krb5-locales libgssapi-krb5-2 libkrb5-3 libkrb5support0

  40. Alfredo says:

    This tutorial is worked great, i tested it out on parrotOS so should work on debian 9 aswell. May need to adjust samba and krb5 config files. Just to point to domain but other than that worked just fine

Leave a Reply

Your email address will not be published. Required fields are marked *