This post is not too AWS-specific, in fact the steps below should work not only on Amazon Linux but also on RedHat Linux, CentOS and Oracle Linux and posibly on Debian and Ubuntu based distros as well.
There is a number of prerequisities for a successful completion of this task.
EC2 instance must be able to look up Active Directory related DNS records.
At least the following records should be resolvable:
_gc._tcp.example.com. 3600 IN SRV 1 100 3268 adc1.example.com.
_gc._tcp.example.com. 3600 IN SRV 1 100 3268 adc2.example.com.
_kerberos-master._tcp.example.com. 3600 IN SRV 1 100 88 adc1.example.com.
_kerberos-master._tcp.example.com. 3600 IN SRV 1 100 88 adc2.example.com.
_kerberos-master._udp.example.com. 3600 IN SRV 1 100 88 adc1.example.com.
_kerberos-master._udp.example.com. 3600 IN SRV 1 100 88 adc2.example.com.
_kerberos._tcp.dc._msdcs.example.com. 3600 IN SRV 1 100 88 adc1.example.com.
_kerberos._tcp.dc._msdcs.example.com. 3600 IN SRV 1 100 88 adc2.example.com.
_kerberos._tcp.example.com. 3600 IN SRV 1 100 88 adc1.example.com.
_kerberos._tcp.example.com. 3600 IN SRV 1 100 88 adc2.example.com.
_kerberos._udp.example.com. 3600 IN SRV 1 100 88 adc1.example.com.
_kerberos._udp.example.com. 3600 IN SRV 1 100 88 adc2.example.com.
_ldap._tcp.dc._msdcs.example.com. 3600 IN SRV 1 100 389 adc1.example.com.
_ldap._tcp.dc._msdcs.example.com. 3600 IN SRV 1 100 389 adc2.example.com.
_ldap._tcp.example.com. 3600 IN SRV 1 100 389 adc1.example.com.
_ldap._tcp.example.com. 3600 IN SRV 1 100 389 adc2.example.com.
Verify that it works with dig command from bind-utils package:
~ # dig srv _kerberos-master._tcp.example.com.
;; QUESTION SECTION:
;_kerberos-master._tcp.example.com. IN SRV
;; ANSWER SECTION:
_kerberos-master._tcp.example.com. 3600 IN SRV 1 100 88 adc1.example.com.
_kerberos-master._tcp.example.com. 3600 IN SRV 1 100 88 adc2.example.com.
;; ADDITIONAL SECTION:
adc1.example.com. 3600 IN A 192.168.148.5
adc2.example.com. 3600 IN A 192.168.148.4
The instance must have network connectivity to the AD servers.
telnet adc1.example.com. 88
Trying 192.168.148.4...
Connected to adc1.example.com.
Escape character is '^]'.
^]
telnet> Connection closed.
If instead you get a connection timeout then there is something wrong with the connectivity, routing, VPN, firewall, security groups, etc.
Your AD account must have privileges to join computers to the domain.
Typically if you are member of Domain Administrators group you should be fine. If not ask the AD admins to give you the privilege to join machines to the domain.
You must have root or sudo access to the EC2 instance.
I’m pretty sure you have this part sorted if you are reading this blog post 🙂
Now that you ticked all the boxes we are ready for the real work!
Joining a Linux server to AD domain
First of all install the necessary packages.
[root@ec2-instance ~]# yum install sssd realmd krb5-workstation pam_krb5 \
oddjob samba-winbind samba-winbind-clients
Discover the AD domain – obviously replace EXAMPLE.COM with your real domain written in UPPERCASE. This is really important with all the commands below that show uppercase domain names!!!
[root@ec2-instance ~]# realm discover EXAMPLE.COM
example.com
type: kerberos
realm-name: EXAMPLE.COM
domain-name: example.com
configured: kerberos-member
server-software: active-directory
client-software: winbind
required-package: oddjob-mkhomedir
required-package: oddjob
required-package: samba-winbind-clients
required-package: samba-winbind
required-package: samba-common-tools
login-formats: EXAMPLE\%U
login-policy: allow-any-login
Test login to the domain.
[root@ec2-instance ~]# kinit michael.ludvig@EXAMPLE.COM
Password for michael.ludvig@EXAMPLE.COM:
[root@ec2-instance ~]#
This step will fail if the DNS is not correctly configured or resolvable or if the network connectivity to the ADC is broken. The error will be something along these lines:
kinit: Cannot find KDC for realm "ENTERPRISEIT.CO.NZ" while getting initial credentials
In that case double check the DNS configuration – expand the list above for an example and minimum requirements.
If kinit worked it’s finally time to join the system to the AD realm. This step will fail if your AD account doesn’t have enough privileges to join new computers to the realm.
[root@ec2-instance ~]# realm join -U michael.ludvig@EXAMPLE.COM EXAMPLE.COM
Password for michael.ludvig@EXAMPLE.COM:
[root@ec2-instance ~]#
Succeeded? Great! Got an error? Not so great, see below for common errors and solutions…
One last step
One last step, entirely optional, is to change /etc/sssd/sssd.conf to make the newly joined domain a default for Linux logins. Without it the users will have to login as EXAMPLE.COM\\michael.ludvig. With the settings below the username michael.ludvig will be looked up in EXAMPLE.COM by default.
Also the home directories will be created with just the user name without the domain.
# /etc/sssd/sssd.conf
[sssd]
default_domain_suffix = EXAMPLE.COM
full_name_format = %1$s
[domain/example.com]
fallback_homedir = /home/%u@%d
fallback_homedir = /home/%u
DNS issues
Recently I started getting this error:
[...]
* Authenticated as user: michael.ludvig@EXAMPLE.COM
! 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)
adcli: couldn't connect to example.com domain: 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)
! Insufficient permissions to join the domain
Although it looks like it’s a permission problem it’s in fact a DNS issue. Make sure the reverse resolution of the AD servers IPs works. If for any reason you can’t work around it:
# /etc/krb5.conf
[libdefaults]
rdns = false
Testing and maintenance
Make sure you test the AD username resolution by running id command:
[root@ec2-instance ~]# id some.user
uid=946201234(some.user) gid=946200513(domain users) groups=946200513(domain users),...
In case the recently logged in user’s AD domain membership changes it may take some time for the Linux box to catch up with the changes. Speed it up by flushing the SSSD users and groups cache.
sss_cache -U -G
That’s it. Leave me a comment if I should add or clarify something in the steps above.