Managing sudo using Active Directory

In my previous post I explained how you could, in just a few steps, join an Ubuntu machine into an Active Directory domain. After a lot of online and offline feedback (Thanks everyone!) I thought it would be time for a follow-up post. This time I’m addressing centralized management of sudo users. Meaning who can execute commands as sudo on defined linux desktops (in my case Ubuntu) , although it’s exactly the same on a server class installation.

My setup is very straightforward and is basically a copy of my previous post. I’ve installed one Windows Server 2016 domain controller in the domain “” and joined a Ubuntu 18.04 LTS to that domain. Users from that domain can happily login to the Ubuntu workstation using their domain credentials. In this post we’ll have to deal with two users:

  • Domain Administrator: Administrator
  • Local Root user: Superuser

So our mission will be to configure the domain and Ubuntu desktop in such a way that members of a domain security group will be able to use sudo once logged in on the Ubuntu desktop.

The first task at hand is to make Active Directory capable for supporting centralized sudo management. Out of the box AD can’t be used for this because of the simple fact that it’s missing the attributes in the AD schema. The cool part is that the people that created and maintain sudo made it very easy for us to extend active directory with the appropriate attributes. First we need to download the latest sudo package from Click on “download” and get the latest package. In my case I’ve created this blog based on the 1.8.23 release. Once the package is extracted (7Zip is an excellent client on Windows for that) you end up with a folder that contains the file that we need. Browse to the doc folder.


There should be a file named  “schema.ActiveDirectory“. This file is used to extent the Active Directory Schema to include the sudo attributes that we will be using. In your Active Directory environment, login to the domain controller that has the schema master role with an account that has the privileges to extent the schema. In my case I’ll just use the all-powerful Administrator account. At a minimum copy the “schema.ActiveDirectory” file to that server and open up an elevated command prompt. In the command-prompt browse to the location where you stored the schema extension file. Execute the following “ldifde.exe” command, leave the command-line exactly as is, only replace the latter part of the line to reflect your domain structure.

ldifde -i -f schema.ActiveDirectory -c dc=X dc=corp,dc=bitsofwater,dc=com


Open “adsiedit.msc” and connect to the “Default naming context“. In the root create a new organization unit and give it a name “sudoers“. This is the default location sudo will look for user defined rules in AD, don’t worry, I’ll show you later on in this post how you can change that.

What we need to do next is create a new object that will contain our attributes. On the organizational unit that you just created, right click and select “new-object“. In the next window select “sudoRule”.


If you don’t see the object class immediately that probably means that the class hasn’t been replicated to your DC yet, just give it some time. In the next screen use the name “default”. In my experience it really doesn’t matter what name you give the object. I tend to use a more descriptive name like, desktops or servers. That makes it a bit more clear on what purpose the object serves. At the last screen click finish to create the “sudoRole” object.

Now we need to edit the attributes of the default object we just created. This way we can configure the behavior of the sudo commands into what can (or cannot) be executed on the Linux host. Select properties on the “cn=default,ou=sudoers” object. Just for testing purposes, we’re going to enable all sudo privileges on all machines. Edit these attributes:

  • sudoCommand: ALL
  • sudoHost: ALL
  • sudoUser: ALL


Next, login at the ubuntu machine as a root user, in my case “SuperUser”, start a terminal, open the bash shell as sudo and restart the sssd service with “systemctl restart sssd

to test the configuration, use “su administrator”, enter the password. Now do “sudo bash“, “sudo -l“, or whatever sudo command you would like to use. After entering your password you should be having the ability to execute as sudo.


Easy right! Now we have the basics covered, here are some hints on tuning it a bit here and there.

Domain Security Groups

In any infrastructure of some size it’s highly unlikely that you will have many individual users that will be listed on the “sudoUser” attribute. Instead having a group listed there makes more sense. Instead of a user that can be set by just using the “sAMAccountName” a group will need to contain a % sign at the beginning. So suppose we want to copy the behavior of Windows and add the “Domain Admins” to every machine (Which is a terrible idea btw!) the sudoUser attribute would look like this:


  • sudoUser: %Domain Admins

Note! Although you would expect there to be an escape character (\) after “%Domain” to cope with the space, this seems to be completely handled by the sssd service. Very cool if you ask me!

Note! As you can see there’s also a possibility to use wildcard characters for the attributes, (See sudoHost). There are more options available listed here:

Organizational Units

By default sudo will look for an organizational container with the name “sudoers” in the root of the directory. There is however a way to tell sudo to look elsewhere. For example if you have two OU’s assigned to different groups, you could use that setup to apply different sudo configurations. So let’s assume we have the “OUa” and “OUb”. The Ubuntu machine in our example belongs to OUb and we want to point it to a OU named Linux that resides within “OUb”.


Actually it’s not hard to do. Create the organizational structure I described and create a new “sudoRole” object in there. On the Ubuntu host, open the file “etc/sssd/sssd.conf” as sudo. Add the following line under the [domain/YourDomain]:

ldap_sudo_search_base = ou=linux,ou=OUb,dc=corp,dc=bitsofwater,dc=com


restart the sssd service and you are ready to go.

Troubleshooting Tips

Sometimes the caching mechanism from the sssd service is so persistent that the entries for sudo users remain, even after several reboot. One command in particular has helped me to clear the cache is:

sss_cache -E

If that doesn’t work, stop the sssd service and delete the database files in “/var/lib/sss/db“.

rm /var/lib/sss/db/*

Just remember that the cache receives a full update every six hours and an incremental one every 15 minutes. But that really doesn’t help when the cache is broken. Those values can be altered by setting:

  • ldap_sudo_full_refresh_interval=86400
  • ldap_sudo_smart_refresh_interval=3600

Configuration files

Sometimes, specially between sssd versions or linux distributions, not all the files are appropriately configured. For example I noticed significant differences between Ubuntu and Redhat. Make sure that these two files are configured as shown here:

sudoers: files sss

services = nss, pam, sudo

I hope that this was useful to you! As always, you can leave comments, remarks or questions below or send me a direct message.

Join Ubuntu 18.04 to Active Directory

At work, we are building a data ingress environment for analytical purposes. The setup will include both Windows and Linux based machines for managing the infrastructure and data processing. One of my tasks (next to the usual security hardening) was to investigate how we could add the Linux based nodes to the Windows Active Directory domain for simplified management. Turns out that there are a couple of way of accomplishing that task. It’s not really that straight forward as it is with Windows but once you get the right tools and know what files to edit it’s really not that hard. With this post I want to share my experiences and show you step-by-step on how to add a Linux based host to a Windows Active Directory.

System Security Services Daemon

I’ve tried a couple of options/packages for joining a Linux machine into a Windows based Active Directory domain, but in the end, for me, using the System Security Services Daemon (SSSD) was the most effective way to accomplish my task at hand.  The SSSD is like the intermediary that helps you to configure the system without you needing to know what files you need to edit (Although it can be very useful). The other benefit that I discovered is that it’s available on all major distributions, like RedHat or Ubuntu. So What I will be describing here will be useful in many situations. Let’s dive in.


My setup is straightforward. A single Domain Controller, named DC01 in the “” domain. Next to the DC role it also hosts the DNS role. The client computer is an Ubuntu 18.04 machine, named “Ubuntu18”, and is configured to use the DNS server on DC01. I’ve checked connectivity to DC01 with a simple ICMP ping and name resolution with NSLookup. Both work as expected.


First thing we need to do is install all the appropriate packages. This post will focus on Ubuntu 18.04, but it’s almost the same on other distributions that use apt (or yum) as their package manager. Open up a terminal, gain root privileges, install these packages:

  • Realmd
  • sssd
  • sssd-tools
  • libnss-sss
  • libpam-sss
  • krb5-user
  • adcli
  • samba-common-bin


apt install -y realmd sssd sssd-tools libnss-sss libpam-sss krb5-user adcli samba-common-bin

During the installation of the “krb5-user” you’ll be prompted for the domain name. Fill in your domain name in capital letters. See my example below.


If for some reason this pop-up does not appear (That happened to me once) or you want to change it afterwards, edit the file “krb5.conf” file in the “/etc/” directory. I always add these two entries to the file:

  • dns_lookup_realm = true
  • dns_lookup_kdc = true

That will explicitly tell the client to use DNS for all lookups instead of expecting it to be present in the “krb5.conf” file.

More info about configuration options can be found here:

Timing is everything

Using Kerberos authentication relies heavily on the correct time being set at both ends. It should always be within a maximum of 5 minutes difference between the two entities trying to authenticate. On Ubuntu, “timesyncd” is responsible for all thing related with time. First we need to point the client to the closest time source. Usually this is the DC that will provide the correct time, but any time source will do. Edit the following file to add the NTP source as displayed in the example:



Use these steps to set the correct time:

  • timedatectl set-ntp true (Set the NTP sync to true)
  • systemctl restart systemd-timesyncd.service (restart the service)
  • timedatectl –adjust-system-clock (Force sync)

After a while the time will start to sync. Use “timedatectl status” to get the actual status.

Configure realmd

Realmd is the configuration to add the linux host to a Kerberos realm like Active Directory. It consists out of tools and configuration options. The configuration is stored in the “realmd.conf” file that’s located in the “/etc/” directory.

The configuration that I found useful is the following:

 default-home = /home/%D/%U
 default-shell = /bin/bash

 default-client = sssd
 os-name = Ubuntu Workstation
 os-version = 18.04

 automatic-install = no

 fully-qualified-names = yes
 automatic-id-mapping = no
 user-principal = yes
 manage-system = yes

Information about the various options of the realmd.conf file can be found here:

Auto create home folders

Before we join the domain the system needs to be told that is needs to auto create users home folders. By default this is turned off for domain accounts and needs to be enabled first. This is easily done with the “pam-auth-update” tool. Type in that command while having root privileges and tick the box “Create home directory on login”.


The changes are saved to the file “/etc/pam.d/common-session“.

Testing Directory Access

Now that I have installed all the packages and configured the appropriate settings, I’m ready to test the setup. Ubuntu has a few very useful tools to see if Kerberos authentication will succeed. Use the following command to test it out:

Discover the domain

realm discover

Get a Kerberos ticket for the user Admin

kinit Admin

Display the Kerberos ticket


Destroy the ticket



The reason I destroy the ticket first is that it will otherwise be used during the domain join that I’ll show you next.

Joining the domain

Now that Kerberos is successfully tested, I am ready to join the domain. The tools that I’ll be using was installed with the realmd package, “realm“. Use the following command:

realm join --verbose --user=admin --computer-ou=OU=Linux,DC=corp,DC=bitsofwater,DC=com

In the example above I’ve turned on verbose output, told the command that I will be using the user named “Admin” to join the domain, put the created object into the “Linux” organizational unit in the “” domain. Hit enter and you’ll be prompted for the password, enter it and the domain join is executed. If all goes well it ends with “Successfully enrolled machine in realm”. Easy right!?


Checking the domain, a new object is created in the organizational unit.


If you want to change any configuration setting at a later stage, edit the SSSD file located at “/etc/sssd/sssd.conf“. Only thing I changed is the entry “ldap_id_mapping”, changed it to “True” as I don’t have the POSIX attributes set in Active Directory. Without this set, I could not login because it can’t translate user id’s.

Login Screen

For domain users to be able to login On Ubuntu 16.04 the login screen need to reconfigured. Normally it would only list the local users without the possibility to login other, domain based users. This capability was enabled by editing the unity login screen located at “/usr/share/lightdm/lightdm.conf.d/50-unity-greeter.conf” and adding the line:


On Ubuntu 18.04 there’s no need to change the login screen anymore. Simply selecting “Not Listed?” on the screen will provide you with a username / password screen. Enter the username with or without the domain suffix.


And that’s it! login with a domain account, the user will be authenticate to Active Directory and a local home folder will automatically be created for the user.

I hope that you will find this information useful.

10-07-2018: Update after user feedback

Make sure that your active directory is prepared for IPv6 as Ubuntu 1804 combined with Windows 2016 seems to default to IPv6 under certain circumstances. A user and myself got this error message “Couldn’t join realm: Insufficient permissions to join the domain“. Kind of a bogus message, but it turned out to be missing IPv6 information in AD DNS. Solution was to fix DNS or disable IPv6.

In my example above I used the domain suffix during login. At that time I didn’t know that there was an option to select a default domain if you only enter the user name. Edit the [sssd] section in “/etc/sssd/sssd.conf” to include the following “default_domain_suffix“.