sssdを使ってLDAPクライアントを作る機会があったので、その時の手順です。
はじめに
LDAPクライアントを作るとなると普通はnslcd(nss-pam-ldapd)+nscdを使うものの、nscdが障害を起こすたびに何度も悩まされてきました。そこで障害に強い他の方法がないか探したところ、SSSD(System Security Services Daemon)による方法を見つけました。
さらに調べてみると、いまのRedHat系OSではsssdの利用が推奨されていました。そこで今回sssdによるLDAPクライアントの構築に挑戦したのですが、意外にも情報がまとまってなかったので手順をまとめました。
sssdの利点
今までLDAPクライアントを作る場合はnslcd+nscdの組み合わせが普通でしたが、sssdを使うことで以下のようなメリットがあります。
- nslcd+nscdよりLDAPサーバ障害に強い
- sssdの方が設定が分散しないためシンプル
詳細は以下を参照してください
要件とやったこと
sssdを使うこと以外にも要件がありました。そこで要件に合わせてやったこともまとめると、以下のようになりました。
要件 | やったこと |
---|---|
sssdを使う | sssdをインストール&設定 |
ホームディレクトリがない場合は自動作成 | PAMを利用 |
LDAP+SSH公開鍵による認証 | sss_ssh_authorizedkeysを利用 |
環境
- CentOS 7.2
- sssd 1.14.0
- openssh 6.6.1p1
構築
以下のように構築を行いました。なお前提条件として、LDAPサーバは構築済とします。
sssd
インストール
sssdをインストールします。またnscdはsssdとバッティングするため、このタイミングでnscdをアンインストールします(nscdをインストールしてなければアンインストール作業不要)
# yum install sssd sssd-client sssd-ldap openldap-clients
# yum erase nscd
自動起動の設定
# systemctl enable sssd
sssd設定
/etc/sssd/sssd.confを作成します。なお元となるファイルはないため、以下をベースに1から作成します。(ldap_uri
やldap_search_base
は自分の環境に合わせます)
[sssd]
debug_level = 0
config_file_version = 2
services = nss, pam, ssh, sudo
domains = default
[domain/default]
id_provider = ldap
auth_provider = ldap
chpass_provider = ldap
sudo_provider = ldap
ldap_uri = ldap://{LDAPサーバのIPアドレス}
ldap_search_base = dc=my-domain,dc=com
ldap_id_use_start_tls = False
ldap_search_timeout = 3
ldap_network_timeout = 3
ldap_opt_timeout = 3
ldap_enumeration_search_timeout = 60
ldap_enumeration_refresh_timeout = 300
ldap_connection_expire_timeout = 600
ldap_sudo_smart_refresh_interval = 600
ldap_sudo_full_refresh_interval = 10800
entry_cache_timeout = 1200
cache_credentials = True
[nss]
homedir_substring = /home
entry_negative_timeout = 20
entry_cache_nowait_percentage = 50
[pam]
[sudo]
[autofs]
[ssh]
[pac]
[ifp]
sssd.confファイルのパーミションとOwner/Group設定をします
# chmod 600 /etc/sssd/sssd.conf
# chown root:root /etc/sssd/sssd.conf
sssdを起動させます
# systemctl start sssd
sssdの有効化(authconfig利用)
/etc/nsswitch.conf
や/etc/pam.d/password-auth
や /etc/pam.d/system-auth
を直接編集してもよいのですが、CentOSの場合はauthconfigを使って設定することが推奨されているようなので、それに合わせて行いました。
(直接編集した場合、どのような設定にすればよいかは後述の記事を参照)
# authconfig \
--enablesssd --enablesssdauth --enablelocauthorize \
--disableldap --disableldapauth --disableldaptls \
--update
#
-
--disableldap
や--disableldapauth
してますが、authconfigではnss_ldap
(--disableldapが対応)とpam_ldap
(--disableldapauthが対応)を想定してます。今回はsssdでLDAP認証をしているため、これで問題ありません。
設定確認
# authconfig --test | grep sss
nss_sss is enabled by default
pam_sss is enabled by default
#
ホームディレクトリ自動作成
sssdにもデフォルトでホームディレクトリ自動作成機能がありますが、これはローカルユーザのみでLDAPユーザには適用されません。しかし今回ユーザ情報はLDAPに持たせているので、pam_oddjob_mkhomedir.so
というPAMモジュールを利用してホームディレクトリを自動作成させることにしました。
oddjob_mkhomedirインストール
oddjob_mkhomedir
を利用してホームディレクトリを作成させるため、インストールします。
# yum install oddjob-mkhomedir
(略)
# systemctl enable oddjobd
Created symlink from /etc/systemd/system/multi-user.target.wants/oddjobd.service to /usr/lib/systemd/system/oddjobd.service.
# systemctl start oddjobd
#
ホームディレクトリ自動作成機能の有効化
# authconfig \
--enablemkhomedir \
--update
#
設定確認
# authconfig --test | grep home
pam_mkhomedir or pam_oddjob_mkhomedir is enabled (umask=0077)
#
LDAP+SSH公開鍵による認証
OpenSSH 6.2からAuthorizedKeysCommand
という設定で外部コマンドを指定することで、LDAPの公開鍵情報が取り出せるようになりました。そこでsss用の公開鍵情報取り出しコマンドである/usr/bin/sss_ssh_authorizedkeys
を利用します。
以下のようにして、公開鍵認証を行うこととsss_ssh_authorizedkeys
を利用するための設定をします。
RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysCommand /usr/bin/sss_ssh_authorizedkeys
AuthorizedKeysCommandUser root
sssdとsshdを再起動します
# systemctl restart sssd
# systemctl restart sshd
障害時の動作確認
LDAPサーバ障害時
軽く動作確認してみたところ、以下の動きをすることが確認できました。
- 一度ログインすればキャッシュに情報を持つので、LDAPサーバが落ちていてもログイン可能
- キャッシュの有効期限は特になし(nscdの場合はpositive-time-to-liveの値がキャッシュの有効期限。password情報の場合はデフォルト値で600秒。)
- ただしキャッシュなので、1度もログインしていない場合はログインできない
sssd障害時
sssdプロセスを落とすとログインできなくなりました。sssdでLDAP認証させているから、そりゃそうですね。そこでログインできなくなる問題を防ぐには、monitを使うなどしてプロセスが落ちても自動起動させるようにします。
戯言1
今回はsshでログインした時にホームディレクトリがなければ、ホームディレクトリが自動作成される機能が必要でした。しかし、自動作成が不要なら以下のようにしてPAMを利用しない方が設定がシンプルになります。そのため、自動作成が不要ならこちらがおすすめです。
-
/etc/ssh/sshd_config
のUsePAM yes
をコメントアウト。その後でsssd
とsshd
再起動。
戯言2
今回はCentOS7.2での構築だったのでauthconfigを使いましたが、使わない場合は以下のように設定します。
#%PAM-1.0
auth required pam_sepermit.so
auth substack password-auth
auth include postlogin
# Used with polkit to reauthorize users in remote sessions
-auth optional pam_reauthorize.so prepare
account required pam_nologin.so
account include password-auth
password include password-auth
# pam_selinux.so close should be the first session rule
session required pam_selinux.so close
session required pam_loginuid.so
# pam_selinux.so open should only be followed by sessions to be executed in the user context
session required pam_selinux.so open env_params
session required pam_namespace.so
session optional pam_keyinit.so force revoke
session include password-auth
session include postlogin
# Used with polkit to reauthorize users in remote sessions
-session optional pam_reauthorize.so prepare
#
→以下のような記述になっているため、password-auth``(password-auth-ac)
の編集を行えばよくなっています。
auth substack password-auth
account include password-auth
password include password-auth
session include password-auth
password-auth-ac
を以下のようにする
#%PAM-1.0
# This file is auto-generated.
# User changes will be destroyed the next time authconfig is run.
auth required pam_env.so
auth [default=1 success=ok] pam_localuser.so
auth [success=done ignore=ignore default=die] pam_unix.so nullok try_first_pass
auth requisite pam_succeed_if.so uid >= 1000 quiet_success
auth sufficient pam_sss.so forward_pass
auth required pam_deny.so
account required pam_unix.so
account sufficient pam_localuser.so
account sufficient pam_succeed_if.so uid < 1000 quiet
account [default=bad success=ok user_unknown=ignore] pam_sss.so
account required pam_permit.so
password requisite pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type=
password sufficient pam_unix.so sha512 shadow nullok try_first_pass use_authtok
password sufficient pam_sss.so use_authtok
password required pam_deny.so
session optional pam_keyinit.so revoke
session required pam_limits.so
-session optional pam_systemd.so
session optional pam_oddjob_mkhomedir.so umask=0077
session [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session required pam_unix.so
session optional pam_sss.so
system-auth(system-auth-ac)は以下のようにします。
#%PAM-1.0
# This file is auto-generated.
# User changes will be destroyed the next time authconfig is run.
auth required pam_env.so
auth [default=1 success=ok] pam_localuser.so
auth [success=done ignore=ignore default=die] pam_unix.so nullok try_first_pass
auth requisite pam_succeed_if.so uid >= 1000 quiet_success
auth sufficient pam_sss.so forward_pass
auth required pam_deny.so
account required pam_unix.so
account sufficient pam_localuser.so
account sufficient pam_succeed_if.so uid < 1000 quiet
account [default=bad success=ok user_unknown=ignore] pam_sss.so
account required pam_permit.so
password requisite pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type=
password sufficient pam_unix.so sha512 shadow nullok try_first_pass use_authtok
password sufficient pam_sss.so use_authtok
password required pam_deny.so
session optional pam_keyinit.so revoke
session required pam_limits.so
-session optional pam_systemd.so
session optional pam_oddjob_mkhomedir.so umask=0077
session [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session required pam_unix.so
session optional pam_sss.so
(略)
passwd: files sss
shadow: files sss
group: files sss
#initgroups: files
#hosts: db files nisplus nis dns
hosts: files dns myhostname
→sssdでLDAP認証をするため、nsswitch.confでldap
は不要。
戯言3
※2017/02/04追記
sshで何らかの値を利用してアクセス制限を行う時、ldap.confの場合は以下のような設定をしてフィルタリングするかと思います
pam_filter &(objectclass=posixaccount)(|(description=server))
→descriptionが"server"となっているユーザだけSSH接続可能
これをsssdで行う場合には、[domain/?????]の部分で以下の設定追加します。
access_provider = ldap
ldap_access_filter = description=server
description
以外でも可能で、仮にtitle
の値で制限を行う場合は以下のようにします。
access_provider = ldap
ldap_access_filter = title=manager
参考資料