Integrating Linux with Active Directory: Ubuntu


This details how to integrate Ubuntu into an Active Directory (AD) domain. It provides the the steps needed, and it gives an intermediate view of the process, technologies, and settings.

Many organizations have an Active Directory domain to manage Windows installs, and many organizations have Linux boxes to run various services on. Quite often, the same team manages Windows and Linux, so it makes sense to leverage an existing AD installation to provide centralized authentication services.


As with all things, assumptions are made, and the following need to exist for the steps in this article to work:

  • Working Active Directory (AD) installation
  • AD account with ability to join machines to the domain
  • Working NTP servers
  • Domain name
  • Ubuntu 14.04+ installed
  • Local account which does not cause a naming collisions with domain accounts
  • SSH or console access to server via local account
  • dig installed on the server

The local account should, ideally, be something other then root with the ability to use sudo or su.


  • Names of domain controller (DC) servers

The names of the DCs isn't really needed since they'll be discovered via dig, but it's nice to be able to make sure the names are correct.

Quick Reference


Why AD integration?

AD is in wide spread use, so this allows Linux systems to be used with existing infrastructure. It eases the management of systems by centralizing authentication to 1 technology rather then having 2 different technologies to manage.

Kerberos comes with AD for free. Modern versions of AD use Kerberos for authentication, and Linux systems can make use of Kerberos. It's design to survive in hostile environments, and it can be used for single sign-on (SSO) when kerberized services are used.

Notes on the technologies

Active Directory is Microsoft's identity management suite. It's core services are LDAP, Kerberos, NTP (Windows Time service), and DNS. There are other services, like a certificate authority and DHCP service, which can be added, but those are the 4 crucial services. For the most part, they act like standard servers of their service type.

Time keeping is very important when using Kerberos. Authentication will fail if the time delta between the client and server is greater then +/-5 minutes in order to prevent replay attacks, so it is very important everything is kept in sync.

Staying on the subject of time. Virtual machines (VMs) keep very poor time, and a best practice is to sync with 3-4 NTP servers running on real hardware. DCs can be virtualized, and they are excellent candidates for virtualization, but the host machine needs to be kept in sync somehow. Most hypervisors make some sort of provision for this, so make sure the hypervisior is configured to sync its time.

Active Directory relies heavily on DNS records to work, and it works best with Microsoft's DNS servers. BIND can be setup as the primary DNS service for AD rather then the MS DNS service, but not everything works. Partial DNS implementations can lead to odd errors and failures, so it's best to just use MS's DNS service rather then recreating the entire DNS tree.

On the Linux side, sssd and MIT Kerberos are the technologies that will be used to interact with AD. sssd is the System Security Services Daemon which provides a common framework for identifying and authenticating remote resources, and MIT Kerberos is a network authentication protocol, client tools and libraries, and server which provides network authentication. In this instance, the client portion will be used to access the Microsoft Kerberos server included with AD.

Setup AD Authentication

Prep the server

  1. SSH into the server or login via the console.
  2. Check to make sure the LDAP service records can be found.

    dig +short SRV _ldap._tcp.domain.tld

    The answer section should return the names of the DCs, and DNS needs to be fixed if it doesn't.

  3. Next, install the needed packages.

    • Ubuntu 14.04

      apt install realmd sssd sssd-tools adcli samba-common krb5-user chrony packagekit libpam-krb5

    • Ubuntu 16.04+

      apt install realmd oddjob oddjob-mkhomedir sssd sssd-tools adcli samba-common krb5-user chrony packagekit libpam-krb5

    krb5-user isn't technically needed, but it provides tools like klist, kinit, and kdestroy which are nice for working with Kerberos tickets.

    chrony might already be installed, and adding it to the list is to make sure it gets installed. It could also be substituted for another NTP client, but I happen to like chrony.

  4. Add the DCs and/or the appropriate NTP pool to chrony.conf.

    vim /etc/chrony.conf
    server dc0.domain.tld iburst
    server dc1.domain.tld iburst
    pool iburst
    pool iburst
    pool iburst
    pool iburst

    Check out the NTP Pool Project for NTP pools in regions other then the US.

  5. Edit the hosts file to include the server hostname.

    vim /etc/hosts   servername.domain.tld   servername  localhost

    By default, Ubuntu sets the host name on rather then on, but that doesn't work for some pieces of software since the convention is to return the hostname when querying

  6. Next, create or edit the PAM mkhomedir file to enable the creation of home directories on first login for network users.

    • Ubuntu 14.04:

      1. Create the mkhomedir file.

           vim /usr/share/pam-configs/mkhomedir
           Name: Create home directory on login
           Default: no
           Priority: 0
           Session-Type: Additional
           Session-Interactive-Only: yes
               optional umask=0077
      2. Enable home directory creation on login with the pam-auth-update tool.

        [*] Create home directory on login

        The PAM file can be edited manually to enable home directory creation on login, but updates will try to overwrite the changes. By using the pam-auth-update tool, the changes will automatically be applied to new files, and everything work across updates is what we want.

    • Ubuntu 16.04:

      1. Edit the mkhomedir file.

        vim /usr/share/pam-configs/mkhomedir
             optional umask=0077
      2. Enable home directory creation on login with the pam-auth-update tool.

        [*] Create home directory on login

      Uncharacteristically, or staying consistent with the theme of general inconsistency, Ubuntu doesn't enable mkhomedir when the oddjob-mkhomedir package is installed. Red Hat products enable the script when the package is installed, but Ubuntu does not.

  7. Enable GSSAPI authentication in OpenSSH.

    vim /etc/ssh/sshd_config
    GSSAPIAuthentication yes
    GSSAPICleanupCredentials yes
    GSSAPIKeyExchange yes
    UseDNS yes

    GSSAPIAuthentication enables OpenSSH to use Kerberos for authentication.

    GSSAPICleanupCredentials specifies if the credential cache is destroyed on logout. By default the credential cache is removed when the user logs out, but setting it to no will allow the tickets to exist until they expire.

    GSSAPIKeyExchange allows Kerberos to authenticate the system in place of SSH host keys. Normally, OpenSSH will ask for the host key to be accepted when users log into new hosts, unless the host key has been added to the known_hosts files prior to logging in. Accepting host keys can be a tedious process for more then a few servers, so the trust relationship between the client, the server, and the domain is substituted for the host keys. The client trusts the domain, and the server trusts the domain. The domain trusts the client and server if they have valid keytabs. If the server can authenticate the client via Kerberos, then the client trusts the server to be the server it's supposed to be since each keytab is unique. Host keys are still apart of OpenSSH, but they only apply to accounts not using Kerberos.

  8. Restart OpenSSH for the changes to take effect.

    systemctl restart openssh
  9. Create any needed sudo files.

    • Specifying domain groups when fully qualified names are not used.

      visudo -f /etc/sudoers.d/domainadmins
      %domain\ admins ALL=(ALL) ALL
    • Specifying domain groups when fully qualified names are used.

      visudo -f /etc/sudoers.d/domainadmins
      %domain\ admins@domain.tld ALL=(ALL) ALL
  10. Edit nsswitch.conf to keep sudo from checking AD for configuration information.

    vim /etc/nsswitch.conf
    sudoers:    files

    If nsswitch.conf isn't edited, emails containing something like host1.domain.tld : Jun 6 14:40:44 : root : problem with defaults entries ; TTY=pts/2 ; PWD=/root ; would be generated when sudo is invoked. The sss portion of sudoers: files sss causes checks to be issued for sudo rules in AD via SSSD, but AD doesn't contain anything related to sudo. The command succeeds if rules are found in the sudoers files, but an error is produced when nothing is found in AD. The email is just noise, and it can be a distraction. It's nice to know when sudo has been run, but this is a bug.

  11. Setup krb5.conf for the domain. The Ubuntu version of krb5.conf contains a lot of entries that are unnecessary, and it needs to be cut down to make it readable.

    vim /etc/krb5.conf
        default = FILE:/var/log/krb5libs.log
        kdc = FILE:/var/log/krb5kdc.log
        admin_server = FILE:/var/log/kadmind.log
        dns_lookup_realm = false
        ticket_lifetime = 24h
        renew_lifetime = 7d
        forwardable = false
        proxiable = false
        rdns = false
        default_ccache_name = KEYRING:persistent:%{uid}
        default_realm = DOMAIN.TLD
        DOMAIN.TLD = {
        .domain.tld = DOMAIN.TLD
        domain.tld = DOMAIN.TLD

    forwardable and proxiable need to be set as needed. A system which will access kerberized services will need one or the other set. Which setting to set, depends on the service. Most of the time, enabling tickets to be forwarded is enough.

    Also, forwardable is generally synonymous with delegation. The terminology used depends on the person writing the documentation and which term they are familiar with.

  12. Create the realmd.conf file to set various options for realm.

    vim /etc/realmd.conf
    default-home = /home/%D/%U
    automatic-install = yes
    fully-qualified-names = no
    manage-system = no
    automatic-id-mapping = yes

    default-home controls how home directories are created. Recent versions default to /home/%U@%D which translates to /home/accountname@domain.tld which is rather clunky.

    automatic-install allows the realm command to install any missing packages via PackageKit. Everything should already be installed, but this will allow for any dependency changes.

    fully-qualified-names turns off the need to provide a domain after the username at the login prompt, and it is mainly a convenience feature. "person@domain.tld" becomes just "person" at the login prompt. This only works when local usernames and domain usernames have different account naming conventions. For instance, the domain naming convention could specify first initial, last name as the convention to produce domain names like "jsmith", and the local naming convention could be first name, last initial to produce local names like "johns". This would be perfectly acceptable, and it wouldn't create a conflict between the two scopes. If the account naming convention is the same everywhere, fully-qualified-names needs to be set to yes to prevent conflicts between local accounts and groups with domain accounts and groups.

    manage-system controls whether or not AD can control aspects of the machine. Authentication and identity are the only two features we want to use, so this needs to be no.

    automatic-id-mapping controls whether the UID and GID from the directory will be used or if the machine will auto generate them. My tendency is to use the UID and GID from the directory since it makes things more consistent across multiple machines. This might not seem like a big deal, but having consistent IDs for accounts makes moving, or sharing, files between machines much easier. One of the problems with using Samba's Winbind for authentication is inconsistent ID mapping. Each machine has a pool of numbers for UIDs and GIDs, and each machine maps UIDs and GIDs as it sees fit which can result in directories and files owned by random numbers instead of accounts. automatic-id-mapping makes sure different machines use the same IDs, and consistent IDs is one of the reasons to use a centralized directory in the first place.

    realmd.conf is only used when realm joins the domain. Once everything is working, it can be deleted.

Join the domain

  1. First, check to make sure realm can find the domain.

    realm discover -v domain.tld
  2. Next, join the machine to the domain.

    realm join -vU domainuser domain.tld
  3. Check out the results and list the domain the machine is participating in.

    realm list
  4. Finally, allow who can access the machine aside from local accounts.

    • Allow everyone with a valid domain account access the machine
    realm permit -a
    • Allow a specific group access to the machine
    realm permit -R domain.tld -g "linuxusers"
    • Allow a specific account to access the machine
    realm pemit person@domain.tld

Test Authentication

It's time to test domain authentiction. At this point, everything should work. The machine has been joined to the domain, and the machine should have a valid Kerberos keytab.

Testing locally

  1. First thing to check is to make sure Kerberos tickets can be acquired. Run kinit and pass it an active domain account. It will ask for the password of the provided domain account, and then exit quietly.

    kinit person@DOMAIN.TLD

    By convention, Kerberos realms are uppercase, and the realm needs to be specified in uppercase. The MIT Kerberos server is case sensitive, but the de facto standard is to create realms that are all uppercase to distinguish them from domain names.

    It's also a de facto standard to sync the name of the realm and the domain. The Kerberos realm for could be named BANANAS, but no one does this.

  2. Next, check to see if a ticket has been issued.

  3. Once Kerberos authentication has been confirmed to work, go ahead and retire the ticket.

  4. Now, check to make sure the system can find accounts in AD.

    • Using fully qualified domain names
    id person@domain.tld
    • Using account names only
    id person
  5. Once accounts can be found, check to make sure account details can be retrieved.

    • Using fully qualified domain names
    id person@domain.tld
    • Using account names only
    id person

    It is important that account details are able to be retrieved. AD groups will be the main control mechanism used to allow or deny access to resources.

Testing remotely

  1. SSH into the server using a domain account.

    ssh person@server.domain.tld
  2. Check and make sure the home directory was created in the correct place.

  3. Check and make sure account details are being retrieved.

  4. Check sudo privileges, if applicable.

    sudo -l
  5. Make sure a Kerberos ticket was created on login.


Once everything passes, the machine is a fully functional domain member.

Misc. Notes

  • Enable Kerberos delegation in Active Directory

    Enabling Kerberos delegation for Linux machines is only necessary if the Linux machine will need to use tickets to log into other services. The tickets the machine creates will be forwardable, and they can be used to access other machines or services. This is handy if the machine is a bastion host, and users will log into other servers from it. Accessing CIFS/SMB shares is another example.

    Delegation and forwarding are synonymous. Enabling forwarding in the Kerberos config is the same as enabling delegation in AD, PuTTY, and OpenSSH.

    1. Open Active Directory Users and Computers either on a DC or on a client which has Windows remote server administration tools (RSAT) installed.
    2. Go to the OU which holds the computers. It's Computers in the default AD configuration.
    3. Locate the system to be modified.
    4. Right click and select Properties from the menu.
    5. Click on the Delegation tab.
    6. Select Trust this computer for delegation to any service (Kerberos only).
    7. Click the OK or Apply button to save the changes.


Previous Post