The winners of the international competitions SSH and sudo are again on stage. Led by Distinguished Conductor Active Directory

Historically, sudo rights were governed by the contents of files from /etc/sudoers.d ΠΈ visudo, and authorization by keys was carried out using ~ / .Ssh / authorized_keys. However, with the growth of infrastructure, there is a desire to manage these rights centrally. At present, there are several possible solutions:

  • Configuration Management System - Executive, Puppet, Ansible, Salt
  • Active Directory + ssd
  • Various perversions in the form of scripts and manual editing of files

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

  • Really the Uniform centralized directory of users.
  • Distribution of rights sudo comes down to adding a user to a specific security group.
  • In the case of various Linux systems, it becomes necessary to introduce additional checks to determine the OS when using configuration systems.

Today's suite will be dedicated to the bundle Active Directory + ssd for rights management sudo and storage ssh keys in a single repository.
So, the hall froze in tense silence, the conductor raised his baton, the orchestra prepared.
Come on.

Given:
- Active Directory Domain testopf.local on Windows Server 2012 R2.
- Linux host running Centos 7
- Customized authorization using ssd
Both solutions make schema changes Active Directory, so we check everything on a test environment and only then make changes to the working infrastructure. I want to note that all changes are point-wise and, in fact, add only the necessary attributes and classes.

Action 1: management sudo roles through Active Directory.

To extend the schema Active Directory you need to download the latest release sudo β€” 1.8.27 today. Unpack, copy the file schema.ActiveDirectory from the ./doc directory to a domain controller. From the command line with administrator rights from the directory where the file was copied, run:
ldifde -i -f schema.ActiveDirectory -c dc=X dc=testopf,dc=local
(Don't forget to substitute your values)
Open adsiedit.msc and connect to the default context:
Create a subdivision at the root of the domain sweats. (The bourgeois stubbornly claim that it is in this unit that the demon ssd searches for an item sudoRole objects. However, after turning on detailed debugging and examining the logs, it was found that the search is performed throughout the entire directory tree.)
Create the first object in the division that belongs to the class sudoRole. The name can be chosen absolutely arbitrarily, as it serves solely for convenient identification.
Among the possible attributes available from a schema extension, the main ones are:

  • sudoCommand - determines which commands are allowed to be executed on the host.
  • sudoHost - determines for which hosts this role is applied. Can be given as ALL, and for a separate host by name. It is also possible to use a mask.
  • sudoUser - specify which users are allowed to execute sudo.
    If a security group is specified, add a β€œ%” sign at the beginning of the name. If there are spaces in the group name, there is nothing to worry about. Judging by the logs, the task of escaping spaces is taken over by the mechanism ssd.

The winners of the international competitions SSH and sudo are again on stage. Led by Distinguished Conductor Active Directory
Figure 1 sudoRole objects in the sudoers subdivision at the root of the directory

The winners of the international competitions SSH and sudo are again on stage. Led by Distinguished Conductor Active Directory
Fig 2. Membership in security groups specified in sudoRole objects.

The following setup is done on the Linux side.
In file /etc/nsswitch.conf add the following line to the end of the file:

sudoers: files sss

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

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

After all operations, you need to clear the cache of the sssd daemon. Automatic updates are made every 6 hours, but why should we wait so long 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 database, start the service.

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

We connect as 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

We 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 user groups.

Storing and using ssh keys in Active Directory

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

Authorization via sssd must be configured.
We add the required attribute using the PowerShell script.
AddsshPublicKeyAttribute.ps1Function 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 = $id;
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 must restart Active Directory Domain Services.
Let's move on to Active Directory users. In any way convenient for you, we generate a pair of keys for ssh connection.
We launch PuttyGen, press the "Generate" button and frantically crawl the mouse within the empty area.
Upon completion of the process, we can save the public and private keys, upload the public key to 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:Β«.
The winners of the international competitions SSH and sudo are again on stage. Led by Distinguished Conductor Active Directory
Add the key to the user attribute.
Option 1 - GUI:
The winners of the international competitions SSH and sudo are again on stage. Led by Distinguished Conductor Active Directory
Option 2 - PowerShell:
get-aduser user1 | set-aduser -add @{sshPublicKey = 'AAAAB...XAVnX9ZRJJ0p/Q=='}
So, at the moment we have: a user with the sshPublicKey attribute filled in, a configured Putty client for authorization by keys. There remains one small point, how to force the sshd daemon to pull the public key we need from the user's attributes. A small script 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 [email protected] -w superSecretPassword 'sshPublicKey' | sed -n '/^ /{H;d};/sshPublicKey:/x;$g;s/n *//g;s/sshPublicKey: //gp'

We set the rights to it 0500 for root.

chmod 0500  /usr/local/bin/fetchSSHKeysFromLDAP

In this example, the administrator account is used to bind to the directory. In combat conditions, there should be a separate account with a minimum set of rights.
Personally, I was very embarrassed by the moment of the password in its pure form in the script, despite the set rights.
Solution option:

  • I save the password in a separate file:
    echo -n Supersecretpassword > /usr/local/etc/secretpass

  • I set the rights to the file 0500 for root
    chmod 0500 /usr/local/etc/secretpass

  • Change ldapsearch startup options: parameter -w superSecretPassword change to -y /usr/local/etc/secretpass

The final chord in today's suite is editing 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 with configured authorization by keys in the ssh client:

  1. The user connects to the server by specifying his login.
  2. The sshd daemon pulls the value of the public key from the user attribute in Active Directory through a script and performs authorization by keys.
  3. The sssd daemon further authenticates the user based on group membership. Attention! If this is not configured, then any user in the domain will have access to the host.
  4. When you try to sudo, the sssd daemon searches the Active Directory for roles. If there are roles, the attributes and group membership of the user are checked (if sudoRoles is configured to use user groups)

Summary.

Thus, keys are stored in Active Directory user attributes, sudo permissions - similarly, access to Linux hosts using domain accounts is carried out by checking membership in an Active Directory group.
The final wave of the conductor's baton - and the hall freezes in reverent silence.

Resources used in writing:

Sudo via Active Directory
Ssh keys via Active Directory
Powershell script, adding an attribute to Active Directory Schema
sudo stable release

Source: habr.com

Add a comment