Linux Domain join howto

There are quite a few tutorials on how to join a Linux machine into a Windows Domain. Some of them are outdated and talk about old-style domains instead of Active Directory. Others require the Active Directory schema be extended. Most of them neglect configuring the system so that Kerberos can be used correctly. And almost none of 'em show how to configure stable user IDs that are reproducible across multiple systems, so using NFS and DRBD will actually work instead of completely breaking permissions.

So, here's my own howto which fixes all of this. It lays out the config I use in my home samba4 domain, LOCAL.LAN. (Yes, I do have an Active Directory domain at home. I like it, even. This is how crazy I am.)

  1. You'll want to make sure that your hostname (the one that the hostname command spits out) is not longer than 15 characters and does not consist of numbers only. (I once named a host 1319. This seemed to work at first but caused some very strange behaviour later on. Renaming the host 13-19 fixed that.)

  2. Make sure that hostname --fqdn actually spits out an FQDN and not just the hostname. Vice versa, make sure that hostname without --fqdn does not spit out an FQDN.

    You can do this by adjusting /etc/hostname and /etc/hosts. Make sure /etc/hosts contains a line such as this one for the hostname you set in /etc/hostname:

    # IP            FQDN               Hostname
    127.0.1.1       hive.local.lan     hive

    Put the FQDN first, and the short hostname second. Do not omit either one. Do not put the FQDN in /etc/hostname.

  3. Install the samba daemons, winbind and the Kerberos utilities:

    apt-get install samba winbind libnss-winbind krb5-user

    It doesn't matter if you're using Samba 3 or Samba 4.

  4. Put the following into /etc/krb5.conf, replacing LOCAL.LAN with your domain name:

    [libdefaults]
       default_realm = LOCAL.LAN
       default_keytab_name = /etc/krb5.keytab
       default_tkt_enctypes = rc4-hmac des-cbc-crc des-cbc-md5
       default_tgs_enctypes = rc4-hmac des-cbc-crc des-cbc-md5
    
    [domain_realm]
       .local.lan = LOCAL.LAN
       local.lan = LOCAL.LAN

    Note that capitalization matters.

  5. Put this into /etc/samba/smb.conf, again adapting the netbios name, workgroup and realm to your environment:

    [global]
       netbios name = HIVE
       workgroup    = LOCALLAN
       realm        = LOCAL.LAN
       security     = ADS
    
       encrypt passwords = yes
    
       # Load the acl_xattr module for Windows ACL support
       vfs objects = shadow_copy2 acl_xattr
    
       # Use an external keytab that can be used for other services (e.g. apache)
       kerberos method = dedicated keytab
       dedicated keytab file = /etc/krb5.keytab
    
       idmap config *:backend = tdb
       idmap config *:range   = 1000000-1999999
    
       # Make sure we have reproducible user IDs
       idmap config LOCALLAN:backend = rid
       idmap config LOCALLAN:range   = 10000-999999
    
       winbind nss info = rfc2307
       winbind trusted domains only = no
       winbind use default domain = yes
    
       # should "getent passwd" and "getent group" list *all* AD users/groups?
       winbind enum users  = yes
       winbind enum groups = yes
    
       # Default shell that users get (/bin/true = no login)
       template shell = /bin/true
  6. Just in case, rm -f /etc/krb5.keytab. It shouldn't be there, but now it definitely won't be.

  7. Authenticate as an administrator:

    kinit Administrator

    You will be prompted for your password. (See how to get rid of passwords)

  8. Once that worked, proceed to actually joining the domain:

    net ads -k join
    net ads -k keytab create
  9. If you want to provide authentication for other services via Kerberos, add the service principal names for those services to your newly-created machine account:

    net ads -k keytab add HTTP
    net ads -k keytab add HTTPS
    net ads -k keytab add NFS

    I'm not sure if you need one for SSH too, or if SSH just uses the default HOST principal, but you might as well add it just-in-case. By the way, this command also updates the machine account on the AD side, so no adsiedit and copying around keytab files necessary.

  10. Now you won't need the Kerberos ticket anymore:

    kdestroy
  11. Let's see if the domain account is set up correctly and Kerberos authentication works. We do this by acquiring a Kerberos ticket for the machine account:

    kinit -k HOSTNAME$

    That $ sign at the end of the HOSTNAME is part of the command, so for hive, I'd have to run kinit -k HIVE$. HIVE$ is the name of the computer account created for the machine named HIVE, for which we want to get a ticket.

    Note that you may need to retry this command a few times until ADS set up everything. It should work after a couple of seconds though.

  12. Restart the samba services:

    service smbd restart
    service nmbd restart
    service winbind restart
  13. For users and groups to be resolvable in the system (e.g. for ls and friends), modify /etc/nsswitch.conf:

    passwd: compat winbind
    group:  compat winbind

    Verify using:

    # getent passwd Administrator
    administrator:*:10500:10513:Administrator:/home/LOCALLAN/administrator:/bin/true
    # getent group "Domain Admins"
    domain admins:x:10512:svedrin,administrator

    Both commands should spit out something.

Congrats, you've joined an Active Directory domain!

Update: This guy appears to have been as frustrated with this stuff as I have, and he has some nice tips about what to do when the getent something parts fail.