歴史的に、sudo 権限は次のファイルの内容によって管理されていました。 /etc/sudoers.d и visudo、キー認証は次を使用して実行されました。 ~/.ssh/authorized_keys。 ただし、インフラストラクチャが成長するにつれて、これらの権利を一元的に管理することが望まれます。 現在、いくつかの解決策の選択肢がある可能性があります。
- 構成管理システム - シェフ, 人形, Ansible, 塩
- Active Directory + sssd
- スクリプトや手動ファイル編集の形でのさまざまな不正行為
私の主観的な意見では、一元管理に最適なオプションは依然として次の組み合わせです。 Active Directory + sssd。 このアプローチの利点は次のとおりです。
- 真に単一の集中型ユーザー ディレクトリ。
- 権利の分配 sudo つまり、ユーザーを特定のセキュリティ グループに追加することになります。
- さまざまな Linux システムの場合、構成システムを使用するときに OS を判断するために追加のチェックを導入する必要があります。
今日のスイートは接続に特化したものになります Active Directory + sssd 権利管理のため sudo とストレージ ssh 単一のリポジトリ内のキー。
そのため、ホールは緊張した静寂に凍りつき、指揮者が指揮棒を上げ、オーケストラが準備を始めました。
行きましょう。
月:
— Active Directory ドメイン testopf.local Windows Server 2012 R2 上。
— Centos 7 を実行している Linux ホスト
— を使用して認証を構成しました sssd
どちらのソリューションもスキーマに変更を加えます Active Directoryしたがって、テスト環境ですべてをチェックしてから、動作するインフラストラクチャに変更を加えます。 すべての変更は対象を絞ったものであり、実際には必要な属性とクラスのみを追加していることに注意してください。
アクション 1: 制御 sudo 役割を通じて Active Directory.
回路を拡張するには Active Directory 最新リリースをダウンロードする必要があります
ldifde -i -f schema.ActiveDirectory -c dc=X dc=testopf,dc=local
(値を置き換えることを忘れないでください)
開く adsiedit.msc そしてデフォルトのコンテキストに接続します。
ドメインのルートにディビジョンを作成する スーダーズ。 (ブルジョワジーは、この部隊に悪魔がいると頑なに主張する。 sssd アイテムを検索する sudoRole オブジェクト。 ただし、詳細なデバッグを有効にしてログを調査したところ、ディレクトリ ツリー全体にわたって検索が実行されたことが判明しました。)
Division 内のクラスに属する最初のオブジェクトを作成します sudoRole。 名前は識別を容易にするためにのみ使用されるため、完全に任意に選択できます。
スキーマ拡張から使用できる属性のうち、主なものは次のとおりです。
- sudoコマンド — ホスト上でどのコマンドの実行を許可するかを決定します。
- sudoホスト — この役割がどのホストに適用されるかを決定します。 として指定できます 全て、および名前による個々のホストの場合。 マスクの使用も可能です。
- sudoユーザー — どのユーザーが実行を許可されているかを示します sudo.
セキュリティグループを指定する場合は、名前の先頭に「%」記号を追加してください。 グループ名にスペースが含まれていても心配する必要はありません。 ログから判断すると、スペースをエスケープするタスクはメカニズムによって引き継がれます。 sssd.
図 1. ディレクトリのルートにある sudoers サブディビジョン内の sudoRole オブジェクト
図 2. sudoRole オブジェクトで指定されたセキュリティ グループのメンバーシップ。
Linux側では以下の設定を行います。
ファイル内 /etc/nsswitch.conf ファイルの末尾に次の行を追加します。
sudoers: files sss
ファイル内 /etc/sssd/sssd.conf セクションで [SSD] サービスに追加する sudo
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
XNUMX 番目のユーザーに対しても同じことを行います。
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 キーの保存と使用
スキームをわずかに拡張することで、Active Directory ユーザー属性に ssh キーを保存し、Linux ホストでの認証時にそれらを使用することができます。
sssd による認証を設定する必要があります。
PowerShell スクリプトを使用して必要な属性を追加します。
AddsshPublicKeyAttribute.ps1関数 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 = 新しい属性ID
$attributes = @{
lDAPDisplayName = 'sshPublicKey';
属性ID = $oid;
oMSyntax = 22;
属性構文 = "2.5.5.5";
isSingleValued = $true;
adminDescription = 'SSH ログイン用のユーザー公開キー';
}
New-ADObject -Name sshPublicKey -TypeattributeSchema -Path $schemapath -OtherAttributes $attributes
$userSchema = get-adobject -SearchBase $schemapath -Filter 'name -eq "user"'
$userSchema | Set-ADObject -Add @{mayContain = 'sshPublicKey'}
属性を追加した後、Active Directory ドメイン サービスを再起動する必要があります。
Active Directory ユーザーに移りましょう。 ご都合のよい方法を使用して、ssh 接続用のキーペアを生成します。
PuttyGen を起動し、「生成」ボタンを押して、空の領域内でマウスを必死に動かします。
プロセスが完了したら、公開キーと秘密キーを保存し、公開キーを Active Directory ユーザー属性にアップロードして、プロセスを楽しむことができます。 ただし、公開鍵は「」から使用する必要があります。OpenSSH allowed_keys ファイルに貼り付けるための公開キー:"
ユーザー属性にキーを追加します。
オプション 1 - GUI:
オプション 2 - PowerShell:
get-aduser user1 | set-aduser -add @{sshPublicKey = 'AAAAB...XAVnX9ZRJJ0p/Q=='}
したがって、現在、sshPublicKey 属性が入力されたユーザー、キーを使用した認証用に設定された Putty クライアントが存在します。 小さな点が XNUMX つ残っています。それは、ユーザーの属性から必要な公開キーを 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 superSecretPassword に変更します -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 クライアントでキー認証が設定された次のシーケンスが得られます。
- ユーザーはログインを示してサーバーに接続します。
- sshd デーモンは、スクリプトを通じて Active Directory のユーザー属性から公開キーの値を抽出し、そのキーを使用して認証を実行します。
- sssd デーモンは、グループ メンバーシップに基づいてユーザーをさらに認証します。 注意! これが構成されていない場合、すべてのドメイン ユーザーがホストにアクセスできます。
- sudo を実行しようとすると、sssd デーモンは Active Directory でロールを検索します。 ロールが存在する場合、ユーザーの属性とグループのメンバーシップがチェックされます (sudoRoles がユーザー グループを使用するように構成されている場合)
まとめ。
したがって、キーは Active Directory ユーザー属性、sudo 権限に保存されます。同様に、ドメイン アカウントによる Linux ホストへのアクセスは、Active Directory グループのメンバーシップを確認することによって実行されます。
指揮棒の最後の波 - そしてホールは敬虔な静寂に凍りつきました。
執筆に使用したリソース:
出所: habr.com