(ヽ´ω`) < OpenLDAP + SSSDでLinuxログインアカウント一元管理がさっぱりわからん - 3. SSSDの設定 -
(ヽ´ω`) < SSSDが特によくわからん
そもそもSSSDってなんなのよ、という話になるが、RedHatがメインで開発しているオープンソースの統合認証基盤FreeIPAに付随して作成されたソフトウェアとのこと。
じゃあそのFreeIPAって何? となるとこれはもう下記の記事でも読んでくれとしか言えないぐらい、色々な機能を持っている。
ちなみに記事の題名が「Linuxの認証を簡単にする」と書いてあるが、機能てんこ盛りの構成要素てんこ盛りなので、最初の稼働させるまでは簡単かもしれないのだが、軽い気持ちで実際に運用し始めると軽く地獄を見ると思う。見た。見ている。
そんな重厚でイケてるFreeIPAという基盤に、認証要求元のサーバから実際に問い合わせを行う役割を担うのがSSSDとなる。
実際にはその前にPAMとNSSが入っていて、PAM・NSSから投げられた処理要求をSSSDがキャッシュやらなんやらでうまいこと処理しつつ、更に後ろのFreeIPAやらOpenLDAPやらActiveDirectoryに問い合わせを行ってくれる。
下記のサイトの一番上の図を引用する。
この図で左側の "Client" はLinux(より厳密に言うとLinux上のNSSとPAM)で、真ん中にSSSD。右側の "Identity Server" と "Authentication Server" はOpenLDAP, FreeIPA, ActiveDirectoryなどになる。
そう、実はFreeIPAだけではなくOpenLDAP(特にOpenLDAPだけでもないが)やActiveDirectoryも認証のバックエンドとして設定が可能で、今回はOpenLDAPを使った設定を行っていく。
(ヽ´ω`) < パッケージインストール
ここからの作業は、前の記事までで作成したOpenLDAPサーバではなく、実際の認証を行うStagingサーバに対して実施する。
(テストとしてOpenLDAPと同じサーバで設定しても問題なし)
必要になるパッケージをインストールする。
# yum install sssd sssd-client sssd-ldap sssd-tools sssd-common oddjob-mkhomedir
(ヽ´ω`) < SSSDの有効化
SSSDサービスの有効化とNSS, PAMの設定ファイルへの組み込みを行う。
上にも書いた通り、SSSDはNSSとPAMから呼び出されてユーザ情報をバックエンドに拾いに行くので、 /etc/nsswitch.conf
と /etc/pam.d
以下のファイルにエントリを追加する必要がある。
nsswitch.confはまだいいとして、PAM関連の設定ファイルは触りたくないという人も多いと思うがご安心を。
このための authconfig
というコマンドが用意されている。(RHEL8からは非推奨パッケージとなっていて authselect
で代替するように言われているが…)
# authconfig --enablesssd --enablesssdauth --enablemkhomedir --update
これにより /etc/nsswitch.conf
と /etc/pam.d
以下のファイルにSSSDを使用するための設定が追記される。
また --enablemkhomedir
により、ユーザログイン時にホームディレクトリが存在しない場合は、自動で作成されるようにPAMの system-auth
の session
にエントリが追加される。
(ヽ´ω`) < sssd.confの作成
/etc/sssd/sssd.conf
を作成して、SSSDの動作を定義する。
このファイルの中でOpenLDAPのサーバIPアドレスや、バインドユーザ情報、どのグループに対してログイン・sudoを許可するかを指定していく。
不親切なことにSSSDパッケージをインストールしても、サンプルファイルのようなものは作成してくれないので、0から入力していく必要がある。 流石に面倒なので下記の内容をまるっとコピーして必要な箇所だけ修正していく。
[sssd] config_file_version = 2 services = nss, pam, sudo, ssh domains = default [domain/default] id_provider = ldap chpass_provider = none ldap_uri = ldap://172.16.1.177 ldap_search_base = dc=tsugihagi,dc=local ldap_id_use_start_tls = False ldap_tls_reqcert = allow ldap_default_bind_dn = cn=Manager,dc=tsugihagi,dc=local ldap_default_authtok_type = password ldap_default_authtok = hogehoge ldap_user_ssh_public_key = sshPublicKey access_provider = simple simple_allow_groups = managers,sre ldap_sudo_search_base = cn=staging-server,ou=Sudoers,dc=tsugihagi,dc=local [nss] memcache_timeout = 300 filter_groups = root filter_users = root entry_cache_nowait_percentage = 75 [pam] [ssh] [sudo]
下記のmanを参考にしながら、上から確認していく。(下記のリンクを見ての通り、設定可能な項目が非常に多い。最低限必要と思われる箇所だけ設定していく)
sssd.conf(5): config file for SSSD - Linux man page
sssd-ldap(5): config file for SSSD - Linux man page
sssd-sudo(5): config file for SSSD - Linux man page
sssd-simple(5) - Linux man page
(ヽ´ω`) < Special Section
[sssd] config_file_version = 2 services = nss, pam, sudo, ssh domains = default
[sssd]
から始まるセクションはSpecial Sectionと呼ばれる。
実はSSSDは単一のサービスではなく、複数の、それぞれの処理を担当するサービスから成り立っている。
それら複数のサービスをまとめて管理するためのサービスはmonitorと呼ばれ、そのmonitorサービスの設定を行うのがこのセクション。
config_file_version = 2
設定ファイルの文法を指定する。SSSD 0.6.0以降は2となる。
services = nss, pam, sudo, ssh
先程複数のサービスから成り立っていると書いたが、どのサービスを使用するかを指定する。
ここで指定したサービスが sssd.service
の起動と同時に起動される。
systemdのUnitファイルも確認可能。
# ls /usr/lib/systemd/system/sssd*.service /usr/lib/systemd/system/sssd-autofs.service /usr/lib/systemd/system/sssd-pac.service /usr/lib/systemd/system/sssd.service /usr/lib/systemd/system/sssd-ifp.service /usr/lib/systemd/system/sssd-pam.service /usr/lib/systemd/system/sssd-ssh.service /usr/lib/systemd/system/sssd-nss.service /usr/lib/systemd/system/sssd-secrets.service /usr/lib/systemd/system/sssd-sudo.service
domains = default
SSSDではユーザ情報を保持するデータベースのことをdomainと呼ぶ。またdomainは複数定義することができる。
domains
ではdomainが複数存在する場合、どの順番でドメインに対して問い合わせを行うかを指定する。
今回はdomainは1つしか使用しない想定なので、どのdomainにdefaultという名前をつけて定義する。
(ヽ´ω`) < Domain Section
[domain/default] id_provider = ldap chpass_provider = none ldap_uri = ldap://172.16.1.177 ldap_search_base = dc=tsugihagi,dc=local dap_tls_reqcert = allow ldap_default_bind_dn = cn=Manager,dc=tsugihagi,dc=local ldap_default_authtok_type = password ldap_default_authtok = hogehoge ldap_user_ssh_public_key = sshPublicKey access_provider = simple simple_allow_groups = managers,sre ldap_sudo_search_base = cn=staging-server,ou=Sudoers,dc=tsugihagi,dc=local
上で記載したとおり、SSSDではユーザ情報を格納するデータベースをdomainと呼ぶが、そのdomainの情報を設定するセクションが Domain Section。
基本的にはこのセクションの設定が一番多くなる。
[domain/default]
domainの名前を記載する。
defaultという名前をつけてあるが、これは別に予約されたキーワードでもなんでもないため特にこの名前にしないといけないということはない。(hogeみたいな名前でもOK)
id_provider = ldap
ユーザ情報をどこから取得するのかを設定する。
今回はOpenLDAPなので ldap
と設定。他の値としては、FreeIPAの ipa
、ActiveDirectoryを使用する際の ad
がある。
chpass_provider = none
パスワード変更要求が来た場合、どのデータベースで処理するのかを指定する。
今回は公開鍵認証を行うので、ユーザのパスワードは取り扱わない。そのため明示的に none
を設定しておく。
ldap_uri = ldap://172.16.1.177
LDAPサーバのURI。
LDAPSを使う場合は ldaps://
を指定する。
ldap_search_base = dc=tsugihagi,dc=local
LDAPサーバに対して問い合わせ(クエリ)を発行する際のベースDN。
規模が大きくなる場合は分けたほうが管理がしやすいかもしれないが、今回はサフィックスを使用。
ldap_id_use_start_tls = False
LDAPサーバに接続した後にSTARTTLSで通信の暗号化を開始するか否か。
本番環境で扱うには暗号化は必須なのだが、その場合証明書の管理から考えないといけないので、今回は一旦暗号化は考慮せずに話をすすめる。
ldap_tls_reqcert = allow
LDAPサーバのサーバ証明書チェックの挙動。
デフォルトは hard
で証明書が確認できなかった場合は接続を切断する。
allow
は証明書が確認できない、不正な証明書であっても、そのまま接続を続行する。
ldap_default_bind_dn = cn=Manager,dc=tsugihagi,dc=local
LDAPサーバに接続する際のバインドユーザのDN。
ldap_default_authtok_type = password
バインドパスワードの形式。
password
は平文でのパスワード記載となる。
obfuscated_password
を指定することで難読化することが可能。
実際に設定するには、一旦この値を password
と指定してsssd.confを作成後に sss_obfuscate
コマンドを実行してやる。
# sss_obfuscate --domain=default
これによって /etc/sssd/sssd.conf
の中身が書き換えられて
# diff sssd.conf.bak sssd.conf -u --- sssd.conf.bak 2019-11-21 09:06:03.103978668 +0000 +++ sssd.conf 2019-11-21 09:06:27.139753597 +0000 @@ -5,7 +5,6 @@ <-- snip --> -ldap_default_authtok_type = password -ldap_default_authtok = hogehoge +ldap_default_authtok_type = obfuscated_password +ldap_default_authtok = AAAQAEHorIy2fGqSEof7f3erz5FNMvY+0xJsat5MEIFwprl9JwzghKumq3VbkJzkVHAM/8PdCM0fXSfB/EtiA8DJbn4AAQID <-- snip -->
こんな感じになるのだが… なぜか他のエントリを巻き込んで内容を消してしまったりする。(あるいはsssd.confの内容全てが消えてしまう)
実行する際には sssd.conf
のバックアップを取っておいて、コマンド実行後に該当箇所だけコピペをして復元してやる必要がある。
理想を言うならパスワード認証ではなく、クライアント証明書認証を使うべきなので、これは通信経路のTLS化も含めて後から変更する。
ldap_default_authtok = hogehoge
LDAP接続に使用するパスワード。
平文で保存したくない場合は上記の方法で難読化をする。
sssd.conf
はパーミッションが 600 でないとSSSDサービスの起動に失敗するので、OS内の他のユーザにパスワードを見られるという危険性はないのだが、構成管理ツール等で構築している場合はソースを閲覧可能なユーザには見られてしまう。
またこの設定ではサーバに接続する際に平文でパスワードを流してしまうので、LDAPSで接続するのが好ましい。この設定については一旦動作確認が取れたあとで追加設定として実施する。
ldap_user_ssh_public_key = sshPublicKey
SSH公開鍵の値が格納されている属性名。
access_provider = simple simple_allow_groups = managers,sre
SSSDによるアクセスコントロールの方法。
SSSDが認証を行う場合、どのユーザ/グループに対してアクセスを許可するかを制御することができる。
ここでは対象のサーバがstagingサーバであると仮定して simple_allow_groups
で managers,sre
グループに対してアクセスを許可している。
この値を設定することで、どのグループに対してサーバへのログインを許可するかを設定している。( ldap_search_base
は ou=Groups
に設定してあるためそのレベルでのフィルタリングは行っていない)
ldap_sudo_search_base = cn=staging-server,ou=Sudoers,dc=tsugihagi,dc=local
sudoRoleエントリを探すベースDN。
cn=dev-server
まで指定してやる。
ou=Sudoers
で終わると ou=Sudoers
以下にある全てのsudoRoleエントリが対象となってしまい、サーバ別でのsudoグループが管理できなくなってしまう。(全てのsudoRoleオブジェクトクラスを継承したエントリが検索対象となってしまう)
厳密に言うと sudoHost
の値がALLではなく、正確に対象となるホスト名を指定してあればそちらでコントロールが可能なのだが、下記の理由から sudoHost
での管理ではなく、この ldap_sudo_search_base
の設定による管理としている。
- AutoScalingGroup管理下のEC2インスタンスではデフォルトのホスト名がインスタンスIDとなる。
- 上記のような動的に作成・削除されるインスタンスに対して、全て同じホスト名を設定してしまうのは、メトリクス収集システムと相性が悪いケースが多い。例えばDatadogではデフォルトのホスト名がhostnameコマンドの戻り値。
sudoHost
の値は完全一致で、例えば "ServiceA-*" のようなワイルドカード指定ができない。
ちなみにmanの ldap_sudo_hostname
についての記載
Space separated list of hostnames or fully qualified domain names that should be used to filter the rules. If this option is empty, SSSD will try to discover the hostname and the fully qualified domain name automatically.
これを見ると sudoHost
の評価に使用されるホスト名を hostname
コマンドの出力とは別で、このオプションで指定できるように見えるのだが、
The option ldap_sudo_hostname may be used to change what rules are cached but its useless without changing the system hostname at this moment, so it is more for testing purpose. There is currently no sudo RFE to support changing the hostname AFAIK.
とのこと。
(ヽ´ω`) < sudoersの設定
authconfig
コマンドの実行で /etc/nsswitch.conf
の内容が書き換えられるのだが、sudoersの検索については手動でエントリを追加してやる必要がある。
echo "sudoers: files sss" >> /etc/nsswitch.conf
(ヽ´ω`) < サービスの有効化・起動
sssd.conf
の作成が完了したら、オーナーをrootでパーミッションを600に設定してやる。
chown root:root /etc/sssd/sssd.conf chmod 600 /etc/sssd/sssd.conf
で、サービスの有効化と起動。ついでに自動でホームディレクトリを作成する処理をしてくれるoddjob-mkhomedirを管理するoddjobdも。
systemctl enable sssd systemctl start sssd systemctl enable oddjobd systemctl start oddjobd
(ヽ´ω`) < 動作確認
id
コマンドでユーザ情報が引けるかを確認する。
# id dev-member uid=10004(dev-member) gid=10002(dev) groups=10002(dev) # id sre-member uid=10003(sre-member) gid=10001(sre) groups=10001(sre) # id sre-senior-member uid=10002(sre-senior-member) gid=10001(sre) groups=10001(sre) # id sre-manager uid=10001(sre-manager) gid=10000 groups=10000,10001(sre),10003(managers) # id hoge id: hoge: no such user
ここではサーバへのログイン可・不可を問わず( simple_allow_groups
の設定を問わず)対象ユーザのid情報を引くことができる。
これが気持ち悪い場合は ldap_group_search_base
オプションで、グループを検索するベースDNを設定する。ここでは最低限のsssd.confの設定とするため省略した。
また、同様に sudo -l -U
でsudo権限についても確認する。
# sudo -l -U dev-member User dev-member is not allowed to run sudo on ip-172-16-1-158. # sudo -l -U sre-member User sre-member is not allowed to run sudo on ip-172-16-1-158. # sudo -l -U sre-senior-member Matching Defaults entries for sre-senior-member on ip-172-16-1-158: !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 sre-senior-member may run the following commands on ip-172-16-1-158: (root) ALL # sudo -l -U sre-manager Matching Defaults entries for sre-manager on ip-172-16-1-158: !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 sre-manager may run the following commands on ip-172-16-1-158: (root) ALL
意図したとおり、 Stagingサーバについては sre-senior-member
, sre-manager
にのみsudo権限が付与されていることが確認できる。
(ヽ´ω`) < 次は?
グループとsudo権限の確認が出来たので、最後にsshd側の設定を行ってOSの認証をコントロールする。