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.
_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
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.
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@%dfallback_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.
Hey Michel
Nice Article. but i am still getting the insufficient permsission error after adding rdns = false too.
Do you actually have correct permissions in AD to join the machine to the domain? Look into AD logs for a clue.
Hi Michel,
i am able to login with individual users, but when i try to setup group restricting account Login Access, i am facing issue”s.
config file : /etc/sssd/sssd.conf
============================
domains = example.com
config_file_version = 2
services = nss, pam
ad_domain = example.com
krb5_realm = EXAMPLE.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/%u@%d
access_provider = ad
ad_access_filter = (memberOf=cn=dev,ou=Users,ou=exmaple,dc=example,dc=com)
============================================
dev=groupname
ou=group is located in Users Organizational Unit.
============================================
errors: remote side unexpectedly closed the network
sshd pam_sss(sshd:auth): authentication success; logname= uid=0 euid=0 tty=ssh ruser= rhost=182.72.147.2 user=user1@example.com
sshd pam_sss(sshd:account): Access denied for user user1@example.com: 6 (Permission denied)
sshd Failed password for user1@example.com from 167.09.198.8 port 52519 ssh2
sshd fatal: Access denied for user user1@example.com by PAM account configuration
I usually use
pam_listfile
orAllowGroups
in/etc/ssh/sshd_config
to control access by group membership. I’ve never tried to do it through sss, sorry.hi . i am also facing the permission issue , but i can able to join windows client to the domain with same credential , pls help
I am also having same issue, Windows machines (both from AWS and Azure) and Linux Machines (from AWS) are able to join AD domain with same credentials and same configs.
But Linux Servers on Azure VM are failing to join AD with “Insufficient permissions to join the domain” error, and we already have rdns=false.
My Firewall was blocking few ports access from Linux server to AD domain controllers.
Once that access is allowed, domain join was success.
How can I identify if a ec2 instance is domain joined using aws cloudwatch.
CloudWatch has nothing to do with your OS authentication. You may be able to feed some logs to CW and analyse them but that seems quite complicated when you can simply check the logs on the instance.