国际大赛SSH和sudo的获奖者再次登上舞台。 由杰出的 Active Directory 指挥领导

从历史上看,sudo 权限是由以下文件的内容控制的 /etc/sudoers.d и 维苏多,并使用密钥授权进行 〜/.ssh/authorized_keys。 然而,随着基础设施的发展,人们希望集中管理这些权利。 今天可能有几种解决方案可供选择:

  • 配置管理系统 - 厨师, 木偶, Ansible,
  • 活动目录 + 固态硬盘
  • 脚本和手动文件编辑形式的各种变态

个人认为,集中管理的最佳选择仍然是组合 活动目录 + 固态硬盘。 这种方法的优点是:

  • 真正的单一集中式用户目录。
  • 权利分配 须藤 归根结底是将用户添加到特定的安全组。
  • 对于各种Linux系统,在使用配置系统时有必要引入额外的检查来确定操作系统。

今天的套件将专门致力于连接 活动目录 + 固态硬盘 用于权限管理 须藤 和存储 SSH 单个存储库中的密钥。
于是,大厅陷入了紧张的沉默,指挥举起指挥棒,乐团准备就绪。
我们走吧

给定:
— 活动目录域 testopf.local 在 Windows Server 2012 R2 上。
— 运行 Centos 7 的 Linux 主机
— 配置授权使用 固态硬盘
两种解决方案都对架构进行了更改 活动目录,因此我们在测试环境中检查所有内容,然后才对工作基础架构进行更改。 我想指出的是,所有更改都是有针对性的,事实上,仅添加必要的属性和类。

动作一:控制 须藤 角色通过 活动目录.

扩大电路 活动目录 你需要下载最新版本 须藤 — 1.8.27 年 XNUMX 月 XNUMX 日起。 解压并复制文件 架构.ActiveDirectory 从 ./doc 目录到域控制器。 从复制文件的目录中具有管理员权限的命令行中,运行:
ldifde -i -f schema.ActiveDirectory -c dc=X dc=testopf,dc=local
(不要忘记替换你的价值观)
打开 adsiedit.msc 并连接到默认上下文:
在域的根部创建一个分区 毛衣。 (资产阶级顽固地声称,正是在这个单位里,恶魔 固态硬盘 搜索一个项目 sudo角色 对象。 然而,在打开详细调试并研究日志后,发现搜索是在整个目录树中执行的。)
我们创建属于该类的第一个对象 sudo角色。 该名称可以完全任意选择,因为它仅用于方便识别。
在架构扩展的可能可用属性中,主要的属性如下:

  • sudo命令 — 确定允许在主机上执行哪些命令。
  • sudo主机 — 确定该角色适用于哪些主机。 可以指定为 全部产品,并针对单个主机的名称。 也可以使用面罩。
  • sudo用户 — 指示允许哪些用户执行 须藤.
    如果指定安全组,请在名称开头添加“%”符号。 如果组名中有空格,则无需担心。 从日志来看,转义空格的任务被机制接管了 固态硬盘.

国际大赛SSH和sudo的获奖者再次登上舞台。 由杰出的 Active Directory 指挥领导
图 1. 根目录中 sudoers 细分中的 sudoRole 对象

国际大赛SSH和sudo的获奖者再次登上舞台。 由杰出的 Active Directory 指挥领导
图 2. sudoRole 对象中指定的安全组中的成员资格。

以下设置是在 Linux 端完成的。
在文件中 /etc/nsswitch.conf 将行添加到文件末尾:

sudoers: files sss

在文件中 /etc/sssd/sssd.conf 在部分 [固态硬盘] 添加到服务 须藤

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

所有操作完成后,需要清除sssd守护进程缓存。 自动更新每 6 小时进行一次,但我们现在想要更新为什么要等这么久呢?

sss_cache -E

经常会发生清除缓存没有帮助的情况。 然后我们停止服务,清理数据库,然后启动服务。

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

我们以第一个用户身份连接,并检查 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

我们对第二个用户执行相同的操作:

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

这种方法允许您为不同的用户组集中定义 sudo 角色。

在 Active Directory 中存储和使用 ssh 密钥

通过稍微扩展该方案,可以将 ssh 密钥存储在 Active Directory 用户属性中,并在 Linux 主机上授权时使用它们。

必须配置通过 sssd 的授权。
使用 PowerShell 脚本添加所需的属性。
添加sshPublicKeyAttribute.ps1函数新属性ID {
$前缀=“1.2.840.113556.1.8000.2554”
$GUID=[System.Guid]::NewGuid().ToString()
$零件=@()
$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 = 新属性ID
$属性=@{
lDAPDisplayName = 'sshPublicKey';
属性ID = $oid;
oMSyntax = 22;
属性语法 = "2.5.5.5";
isSingleValued = $true;
adminDescription = '用于 SSH 登录的用户公钥';
}

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

添加属性后,必须重新启动 Active Directory 域服务。
让我们继续讨论 Active Directory 用户。 我们将使用您方便的任何方法生成用于 ssh 连接的密钥对。
我们启动 PuttyGen,按下“生成”按钮,然后在空白区域内疯狂移动鼠标。
该过程完成后,我们可以保存公钥和私钥,将公钥上传到Active Directory用户属性并享受该过程。 但是,公钥必须从“用于粘贴到 OpenSSHauthorized_keys 文件中的公钥:«。
国际大赛SSH和sudo的获奖者再次登上舞台。 由杰出的 Active Directory 指挥领导
将密钥添加到用户属性。
选项 1 - 图形用户界面:
国际大赛SSH和sudo的获奖者再次登上舞台。 由杰出的 Active Directory 指挥领导
选项 2 - PowerShell:
get-aduser user1 | set-aduser -add @{sshPublicKey = 'AAAAB...XAVnX9ZRJJ0p/Q=='}
因此,我们当前拥有:一个填写了 sshPublicKey 属性的用户,一个配置好的 Putty 客户端,用于使用密钥进行授权。 还有一个小问题:如何强制 sshd 守护进程从用户的属性中提取我们需要的公钥。 在资产阶级互联网上找到的一个小脚本可以成功地解决这个问题。

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'

我们将其权限设置为 root 0500。

chmod 0500  /usr/local/bin/fetchSSHKeysFromLDAP

在本例中,使用管理员帐户绑定到目录。 在战斗条件下,必须有一个具有最低权限的单独帐户。
尽管设置了权限,但我个人对脚本中纯形式的密码感到非常困惑。
解决方案选项:

  • 我将密码保存在单独的文件中:
    echo -n Supersecretpassword > /usr/local/etc/secretpass

  • 我将 root 的文件权限设置为 0500
    chmod 0500 /usr/local/etc/secretpass

  • 更改 ldapsearch 启动参数:参数 -w 超级秘密密码 我把它改为 -y /usr/local/etc/secretpass

今天套件中的最后一个和弦是编辑 sshd_config

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

结果,我们得到以下序列,并在 ssh 客户端中配置了密钥授权:

  1. 用户通过指示其登录名来连接到服务器。
  2. sshd 守护程序通过脚本从 Active Directory 中的用户属性中提取公钥值,并使用这些密钥执行授权。
  3. sssd 守护进程根据组成员身份进一步验证用户身份。 注意力! 如果未配置,则任何域用户都可以访问该主机。
  4. 当您尝试使用 sudo 时,sssd 守护程序会在 Active Directory 中搜索角色。 如果存在角色,则检查用户的属性和组成员身份(如果 sudoRoles 配置为使用用户组)

总结。

因此,密钥存储在 Active Directory 用户属性、sudo 权限中 - 类似地,域帐户对 Linux 主机的访问是通过检查 Active Directory 组中的成员身份来执行的。
指挥棒最后一挥,大厅陷入肃静。

书面使用的资源:

通过 Active Directory 执行 Sudo
通过 Active Directory 的 SSH 密钥
Powershell 脚本,向 Active Directory 架构添加属性
sudo 稳定版本

来源: habr.com

添加评论