これはなに
OSSTech Advent Calendar 2019の5日目の記事です。
普段は自分が使っている技術の備忘録のような記事しか書いてないのですが、
一応認証に関する記事になるつもりです。
嘘ですまた備忘録です。
今回はCentOS 8
をインストールした後、ユーザー認証をOpenLDAPと連携したSSSDで行うことを目標にします。
主にSSSDのお話です。
SSSDのインストール
# dnf install sssd sssd-tools sssd-dbus
SSSDを動かすだけならsssd
だけで大丈夫です。
sssd-tools
とsssd-dbus
をインストールすると、sssctl
というコマンドが利用できるようになり、
SSSDの設定を確認する時などに使えます。
sssctl
は偶然見つけて使ってみたのですがわりと良い感じ。
連携先となるOpenLDAPの準備
OpenLDAPを準備する方法はなんでもいいんですが、気をつけることがいくつかあります。
-
LDAPS通信が必須
SSSDのプロバイダとしてLDAPを利用するとき、LDAPS通信が必須になります。
-
sudo設定用のスキーマを追加する
sudo設定は
sudoRole
というobjectClass内で定義されている属性から参照します。
LDAPでobjectClass: sudoRole
が利用出来るようにしておいてください。
特にsudoRole
のスキーマを追加するのを見落としていて、
しばらく「ログイン認証は通るけどsudoコマンドを使うとエラーになる」という状態でハマっていました。
sudoRole
用のスキーマはsudo
パッケージの中に同梱されていました。(これがなかなか見つからない...)
$ rpm -ql sudo | grep OpenLDAP
/usr/share/doc/sudo/schema.OpenLDAP
コピーするなりしてOpenLDAPにこのスキーマを適用してください。
LDAPのツリー
今回用意したLDAPのツリーは以下の通りです。
dc=example,dc=com
├── cn=sssd
├── ou=Users
│ └── uid=user1
│ ├── objectClass=person
│ ├── objectClass=posixAccount
│ ├── objectClass=top
│ ├── cn=user1
│ ├── sn=user
│ ├── givenName=test
│ ├── uidNumber=10000
│ └── gidNumber=10000
├── ou=Groups
│ └── cn=group1
│ ├── objectClass=posixGroup
│ ├── cn=group1
│ └── gidNumber=10000
└── ou=SUDOers
└── cn=%group1
├── objectClass=top
├── objectClass=sudoRole
├── cn=%group1
├── sudoCommand=ALL
├── sudoHost=ALL
└── sudoUser=%group1
LDIFファイルのサンプル
dn: dc=example,dc=com
objectClass: domain
dc: example
dn: ou=Users,dc=example,dc=com
objectClass: organizationalUnit
ou: Users
dn: ou=Groups,dc=example,dc=com
objectClass: organizationalUnit
ou: Groups
dn: ou=SUDOers,dc=example,dc=com
objectClass: organizationalUnit
ou: SUDOers
dn: cn=sssd,dc=example,dc=com
objectClass: applicationProcess
objectClass: simpleSecurityObject
cn: sssd
userPassword: password
dn: uid=user1,ou=Users,dc=example,dc=com
objectClass: top
objectClass: person
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: posixAccount
uid: user1
cn: user1
sn: user1
uidNumber: 10000
gidNumber: 10000
givenName: test
homeDirectory: /home/user1
loginShell: /bin/zsh
userPassword: password
description: Test Account
dn: cn=group1,ou=Groups,dc=example,dc=com
objectClass: top
objectClass: posixGroup
cn: group1
gidNumber: 10000
description: Test Group
memberUid: group1
dn: cn=%group1,ou=SUDOers,dc=example,dc=com
objectClass: top
objectClass: sudoRole
cn: %group1
sudoUser: %group1
sudoHost: ALL
sudoCommand: ALL
あくまで必要最小限のLDIFですので、必要に応じてエントリーや属性を追加・変更してください。
これでLDAP側の準備は完了です。
気をつけることとして思いつくのは以下の通りです。
- cn=sssdのエントリーにアクセス権が必要
- ユーザーエントリーは
posixAccount
(別のクラスでも出来るが面倒くさい) - グループエントリーは
posixGroup
(別のクラスでも出来るが略) - sudo設定用のエントリーは
sudoRole
SSSDの設定
ここまでで連携先のLDAPサーバーの準備が出来たと思うので、いよいよSSSDの設定を行います。
SSSDの設定ファイルは/etc/sssd/
配下に保存します。今回は/etc/sssd/sssd.conf
というファイルを編集して、SSSDの設定をおこなって行こうと思います。このファイルは初期インストール時には存在しないので、エディタなどで適宜作成してください。
権限が適切でないと起動に失敗するので、ファイルの作成後に以下のコマンドを実行してください。
# chown root:root /etc/sssd/sssd.conf
# chmod 600 /etc/sssd/sssd.conf
ユーザー認証が出来るようになるまで
/etc/sssd/sssd.conf
を以下の用に編集します。
[sssd]
debug_level = 4
services = nss, pam, ifp
domains = mydomain
[nss]
filter_groups = root
filter_users = root
[pam]
[domain/mydomain]
id_provider = ldap
auth_provider = ldap
chpass_provider = ldap
enumerate = True
cache_credentials = True
case_sensitive = false
ldap_uri = ldap://ldap.example.com
ldap_search_base = dc=example,dc=com
ldap_default_bind_dn = cn=sssd,dc=example,dc=com
ldap_tls_reqcert = never
ldap_id_use_start_tls = True
LDAPサーバーへの接続設定は[domain/mydomain]
のセクションに記述します。このmydomain
の部分は任意の名前に変更可能です。実際にSSSDが利用するドメインを[sssd]
セクション内のdomains
で指定します。
今回は自己証明書のLDAPS通信を利用しているので、ldap_tls_reqcert
をnever
にしていますが、
基本的にはこの項目は設定せず、証明書が正しいことを検証するべきです。
このままではcn=sssd
のバインドパスワードが無いのでSSSDは利用出来ません。
ldap_default_authtok
というパラメータを追記し、パスワードをそのままいれれば動きますがよろしくありません。
そこでsss_obfuscate
というコマンドを利用しましょう。
このコマンドはsssd-tools
パッケージに含まれています。
以下のコマンドを実行してください。
# sss_obfuscate -d mydomain
Enter password: <- cn=sssdのパスワードを入力
Re-enter password:
そうするとsssd.conf
に自動的に難読化されたパスワードが設定されます。
[sssd]
debug_level = 4
services = nss, pam, ifp
domains = mydomain
[nss]
filter_groups = root
filter_users = root
[pam]
[domain/mydomain]
id_provider = ldap
auth_provider = ldap
chpass_provider = ldap
enumerate = True
cache_credentials = True
case_sensitive = false
ldap_uri = ldap://ldap.example.com
ldap_search_base = dc=example,dc=com
ldap_default_bind_dn = cn=sssd,dc=example,dc=com
ldap_tls_reqcert = never
ldap_id_use_start_tls = True
ldap_default_authtok_type = obfuscated_password
ldap_default_authtok = xxxxxxxxxxx難読化済みのパスワードxxxxxxxxxxxxxx
ネームサービスと認証サービスにSSSDを利用するようにします。
CentOS 8
ではauthselect
というコマンドを利用します。
以下のコマンドを実行してください。
# authselect select sssd with-sudo --force
この状態でSSSDを再起動します。
# systemctl restart sssd
sssctl
コマンドなどでLDAPサーバーへの接続が出来ているか確認しましょう。
# sssctl domain-status mydomain
Online status: Online
getent
コマンドやid
コマンドでLDAPサーバー上のユーザー情報が正常に取れているか確認しましょう。
# getent passwd user1
user1:*:10000:10000:Test Account:/home/user1:/bin/zsh
# id user1
uid=10000(user1) gid=10000(group1) groups=10000(group1)
これでログイン時などパスワード認証にLDAPサーバーで設定したパスワードが利用できれば、ユーザー認証の設定は完成です。
sudoが出来るようになるまで
上記の設定のままだと、user1でログインしたあと、sudo
コマンドが利用できません。
これでは不便なのでsudo
の設定も追加しましょう。
sudo
の設定を追記したsssd.conf
が以下になります。
[sssd]
debug_level = 4
services = nss, pam, ifp, sudo
domains = mydomain
[sudo]
[nss]
filter_groups = root
filter_users = root
[pam]
[domain/mydomain]
id_provider = ldap
auth_provider = ldap
chpass_provider = ldap
sudo_provider = ldap
enumerate = True
cache_credentials = True
case_sensitive = false
ldap_uri = ldap://ldap.example.com
ldap_search_base = dc=example,dc=com
ldap_default_bind_dn = cn=sssd,dc=example,dc=com
ldap_tls_reqcert = never
ldap_id_use_start_tls = True
ldap_default_authtok_type = obfuscated_password
ldap_default_authtok = xxxxxxxxxxx難読化済みのパスワードxxxxxxxxxxxxxx
sudo
の設定エントリーはデフォルトでou=sudoers,<ldap_search_base>
を検索するので、LDAPのツリーで作成したツリーを利用している場合は特に設定する項目はありません。
別のツリーを指定したい場合はldap_sudo_search_base
というパラメータで指定してください。
SSSDを再起動します。
# systemctl restart sssd
LDAPサーバー上のユーザーでログインした後、sudo -i
などを実行して正常にsudo
コマンドが実行できれば完了です。
おわり
以前触ってみた時はsudo
が出来ずに挫折したのですが、今回なんとか目的の設定ができました。
authconfig
で全部コマンドで設定していたときと比べると設定ファイルを書く手間がありますが、
一度使った設定ファイルを使い回せば新しい環境でもすぐに使えるようになるので、結果的に楽でした。
今後はこのファイルを使いまわす予定なので来年くらいにはまた忘れているんだろうな...