📜 ⬆️ ⬇️

The laureates of the international SSH and sudo competitions are on stage again. Under the leadership of the distinguished conductor of Active Directory

Historically, sudo rights were governed by the contents of files from /etc/sudoers.d and visudo , and authorization by keys was done using ~ / .ssh / authorized_keys . However, with the growth of infrastructure, there is a desire to manage these rights centrally. To date, there may be several solutions:


In my subjective opinion, the best option of centralized management is still a bunch of Active Directory + sssd . The advantages of this approach are:


Today’s suite will be dedicated specifically to Active Directory + sssd for managing sudo rights and storing ssh keys in a single repository.
So, the hall froze in tense silence, the conductor raised his wand, the orchestra prepared.
Go.

Given:
')

Both solutions make changes to the Active Directory schema , so we check everything on the test environment and only then make changes to the working infrastructure. I want to note - all changes are point and, in fact, add only the necessary attributes and classes.

Step 1: Manage sudo roles through Active Directory .


To extend the Active Directory schema, you need to download the latest release of sudo - 1.8.27 today. Unpack, copy the file schema.ActiveDirectory from the ./doc directory to the domain controller. From the command line with administrator rights from the directory where you copied the file, run:

ldifde -i -f schema.ActiveDirectory -c dc=X dc=testopf,dc=local
(Do not forget to substitute your values)

Open adsiedit.msc and connect to the default context:

At the root of the domain we create the sudoers division. (The bourgeois stubbornly asserts that it is in this subdivision that the sssd daemon searches for sudoRole objects. However, after turning on detailed debugging and studying logs, it was revealed that the search is performed across the entire directory tree.)

Create in the division the first object belonging to the class sudoRole . The name can be chosen absolutely arbitrarily, since it serves exclusively for easy identification.

Among the possible attributes available from the schema extension are the following:



Figure 1. The sudoRole objects in the sudoers subdivision in the root of the directory


Figure 2. Membership in security groups specified in sudoRole objects.

The following setup is done on the Linux side.

In the /etc/nsswitch.conf file, add the line to the end of the file:

 sudoers: files sss 

In the /etc/sssd/sssd.conf file in the [sssd] section, add sudo to the services

 cat /etc/sssd/sssd.conf | grep services services = nss, pam, sudo 

After all operations, you need to clear the sssd daemon cache. Automatic updates are performed every 6 hours, but why should we wait so much when we want to now.

 sss_cache -E 

It often happens that clearing the cache does not help. Then we stop the service, clean the base, start the service.

 service sssd stop rm -rf /var/lib/sss/db/* service sssd start 

Connect under the first user and check what is available to him from under sudo:

 su user1 [user1@testsshad log]$ id uid=1109801141(user1) gid=1109800513(domain users) groups=1109800513(domain users),1109801132(admins_) [user1@testsshad log]$ sudo -l [sudo] password for user1: Matching Defaults entries for user1 on testsshad: !visiblepw, always_set_home, match_group_by_gid, always_query_group_plugin, env_reset, env_keep="COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS", env_keep+="MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE", env_keep+="LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES", env_keep+="LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE", env_keep+="LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY", secure_path=/sbin\:/bin\:/usr/sbin\:/usr/bin User user1 may run the following commands on testsshad: (root) /usr/bin/ls, /usr/bin/cat 

Do the same with our second user:

 su user2 [user2@testsshad log]$ id uid=1109801142(user2) gid=1109800513(domain users) groups=1109800513(domain users),1109801138(sudo_root) [user2@testsshad log]$ sudo -l Matching Defaults entries for user2 on testsshad: !visiblepw, always_set_home, match_group_by_gid, always_query_group_plugin, env_reset, env_keep="COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS", env_keep+="MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE", env_keep+="LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES", env_keep+="LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE", env_keep+="LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY", secure_path=/sbin\:/bin\:/usr/sbin\:/usr/bin User user2 may run the following commands on testsshad: (root) ALL 

This approach allows you to centrally define sudo roles for different groups of users.

Storing and using ssh keys in Active Directory


With a small extension of the scheme, it is possible to store ssh keys in the attributes of an Active Directory user and use them when authorizing on Linux hosts.

Authentication via sssd must be configured.

Add the desired attribute using the PowerShell script.

AddsshPublicKeyAttribute.ps1
Function New-AttributeID {
$ Prefix = "1.2.840.113556.1.8000.2554"
$ GUID = [System.Guid] :: NewGuid (). ToString ()
$ Parts = @ ()
$ Parts + = [UInt64] :: Parse ($ guid.SubString (0,4), "AllowHexSpecifier")
$ Parts + = [UInt64] :: Parse ($ guid.SubString (4,4), "AllowHexSpecifier")
$ Parts + = [UInt64] :: Parse ($ guid.SubString (9,4), "AllowHexSpecifier")
$ Parts + = [UInt64] :: Parse ($ guid.SubString (14,4), "AllowHexSpecifier")
$ Parts + = [UInt64] :: Parse ($ guid.SubString (19,4), "AllowHexSpecifier")
$ Parts + = [UInt64] :: Parse ($ guid.SubString (24,6), "AllowHexSpecifier")
$ Parts + = [UInt64] :: Parse ($ guid.SubString (30,6), "AllowHexSpecifier")
$ oid = [String] :: Format ("{0}. {1}. {2}. {3}. {4}. {5}. {6}. {7}", $ prefix, $ Parts [ 0]
$ Parts [1], $ Parts [2], $ Parts [3], $ Parts [4], $ Parts [5], $ Parts [6])
$ oid
}
$ schemaPath = (Get-ADRootDSE) .schemaNamingContext
$ oid = New-AttributeID
$ attributes = @ {
lDAPDisplayName = 'sshPublicKey';
attributeId = $ oid;
oMSyntax = 22;
attributeSyntax = "2.5.5.5";
isSingleValued = $ true;
adminDescription = 'User Public key for SSH login';
}

New-ADObject -Name sshPublicKey -Type attributeSchema -Path $ schemapath -OtherAttributes $ attributes
$ userSchema = get-adobject -SearchBase $ schemapath -Filter 'name -eq "user"'
$ userSchema | Set-ADObject -Add @ {mayContain = 'sshPublicKey'}

After adding the attribute, you need to restart Active Directory Domain Services.
Go to the users of Active Directory. In any way convenient for you, we generate a pair of keys for ssh connection.

Start PuttyGen, click the “Generate” button and frantically move the mouse within the empty area.

Upon completion of the process, we can save the public and private keys, pour the public key into the Active Directory user attribute and enjoy the process. However, the public key must be used from the " Public key for pasting into OpenSSH authorized_keys file: " window.



Add the key to the user attribute.

Option 1 - GUI:



Option 2 - PowerShell:

get-aduser user1 | set-aduser -add @{sshPublicKey = 'AAAAB...XAVnX9ZRJJ0p/Q=='}

So, we have at the moment: a user with the sshPublicKey attribute filled in, a Putty client configured for key authorization. One small moment remains, how can we force the sshd daemon to pull out the public key we need from the user's attributes. A small script successfully found on the open spaces of the bourgeois Internet successfully copes with this.

 cat /usr/local/bin/fetchSSHKeysFromLDAP #!/bin/sh ldapsearch -h testmdt.testopf.local -xb "dc=testopf,dc=local" '(sAMAccountName='"${1%@*}"')' -D Administrator@testopf.local -w superSecretPassword 'sshPublicKey' | sed -n '/^ /{H;d};/sshPublicKey:/x;$g;s/\n *//g;s/sshPublicKey: //gp' 

We put on it the rights 0500 for root.

 chmod 0500 /usr/local/bin/fetchSSHKeysFromLDAP 

In this example, for the bind to the directory, the administrator account is used. In combat, there should be a separate account with a minimum set of rights.

I personally was very embarrassed by the moment of the password in its pure form in the script, despite the rights granted.

Solution option:


Final chord in today's suite edit sshd_config

 cat /etc/ssh/sshd_config | egrep -v -E "#|^$" | grep -E "AuthorizedKeysCommand|PubkeyAuthe" PubkeyAuthentication yes AuthorizedKeysCommand /usr/local/bin/fetchSSHKeysFromLDAP AuthorizedKeysCommandUser root 

As a result, we get the following sequence when configured key authorization in the ssh client:

  1. The user connects to the server, indicating your username.
  2. The sshd daemon through the script pulls the value of the public key from the user attribute in Active Directory and authorizes the keys.
  3. The sssd daemon performs further user authentication based on group membership. Attention! If it is not configured, then any user of the domain will have access to the host.
  4. When attempting to sudo, the sssd daemon searches the Active Directory directory for roles. If roles are present, the attributes and membership of the user in the group are checked (if sudoRoles is configured to use user groups)

Total


Thus, keys are stored in Active Directory user attributes, sudo permissions are similarly, access to Linux hosts by domain accounts is done by checking membership in an Active Directory group.

The final wave of the conductor's wand - and the hall freezes in reverent silence.

Resources used when writing:

Source: https://habr.com/ru/post/449702/


All Articles