ディレクトリサービスの具体例は以下の2つです。
- ActiveDirectory(Windows), OpenLDAP(Linux)
- ユーザー名(リソース)から、パスワード(情報)を検索して認証を行います。
- ユーザー名(リソース)ごとに権限(情報)も記録しており、検索することが可能です。
- DNS サーバー
関連記事:サーバー | ||||
---|---|---|---|---|
本記事は OpenLdap を利用して、ディレクトリサービスを解説します。
ディレクトリサービスの利点
情報を1箇所に集約可能となります。
例として情報を 1 箇所に集約するメリットを3つ挙げます。
- 情報の検索が楽!
- 誰が情報を持っているか意識しなくて良い
- とりあえずディレクトリサービスに聞けばいい
- 情報の修正が楽!
- ディレクトリに集約されている場合は1箇所(ディレクトリ)だけの修正でよい
- 100 台のコンピュータが情報を持っている場合、100箇所の修正が必要
- 情報の保存が効率的!
ディレクトリサービスを実現する技術
ディレクトリサービスのディレクトリは DIT(Directory Information Tree) と呼ばれる木構造で構成されています。具体的には下記の通りとなります。下記のディレクトリでは、hogetech_company の development 部署に所属する user01, user02 を表しています。
ディレクトリサービスにアクセスするには、LDAP プロトコルを使用します。
例えば ldap://directory_service.com/ のようにアクセスします。
ディレクトリサービスで使用する用語
ディレクトリサディレクトリサービスで使用される用語で特に重要なものについて説明します。
- エントリー (オブジェクト): 木構造のノードのことです。
- 属性: エントリーが持つ情報の種類と値です。
- 属性は属性タイプと属性値をセットで持ちます。ようするにキーバリュー形式で情報を持ってます。
属性タイプ 説明 dc ドメイン構成要素 (Domain Component) cn 一般名称 (Common Name) o 組織名 (Organization) ou 組織名 (Organization) o 組織単位 (Organization Unit) uid ユーザーID (User ID) gidNumber グループ ID 番号 (Group ID Number) - スキーマ (オブジェクトクラス): エントリーで使用する属性一覧を予め定義したものです。
- DN (Distinguish Name): エントリーを一意に識別する primary key です [2] 。
- バインド DN (Login DN): ディレクトリを操作するするユーザーです。
- ディレクトリの中に存在する「ユーザー」エントリーにバインドします。
- ベース DN: 検索の起点となるエントリーです。
- ルート DN: 根ノードのことです。
それぞれの用語と DIT の関係は下記の通りです。
ディレクトリサービスの実装方法
オープンソースソフトウェアである OpenLDAP を使用してディレクトリサービスの具体的な実装方法を紹介します。OpenLDAP を利用するシナリオとしては、入社・退職する人に対して、社内の Linux へログイン権限を OpenLDAP で管理する状況を想定します。
OpenLDAP の起動
今回は環境に依存する問題を回避するために Docker を使用します。Docker について詳しく知りたい方は、以下の記事をご覧ください。
Docker を使用して OpenLDAP のコンテナを起動
まずは、OpenLDAP の docker コンテナを起動するために docker-compose.yml を作成します。
docker-compose.yml に記載する内容は下記の通りです。
version: '3' services: ldap-server: image: osixia/openldap:latest restart: always container_name: ldap-host environment: LDAP_ORGANISATION: "hogetech_company" LDAP_DOMAIN: "hogetech.com" LDAP_ADMIN_PASSWORD: "hogetech" #cn=admin,dc=hogetech,dc=com のパスワード LDAP_CONFIG_PASSWORD: "hogetech" #cn=admin,cn=config のパスワード LDAP_TLS_VERIFY_CLIENT: "try" networks: - webnet ports: - "389:389" - "636:636" ldap-admin: image: osixia/phpldapadmin:latest restart: always container_name: ldap-admin environment: PHPLDAPADMIN_LDAP_HOSTS: "ldap" PHPLDAPADMIN_HTTPS: "false" ports: - "8080:80" links: - "ldap-server:ldap" networks: - webnet networks: webnet:
docker-compose.yml で記載した環境変数の詳細は下記の URL に記載されています。
作成した docker-compose.yml を使用して、下記のコマンドで OpenLDAP の docker コンテナを起動します。
起動した OpenLDAP に存在するディレクトリの種類
起動 OpenLDAP は、次の 2 つのディレクトリを持っています。
- ルート DN が cn=config であるディレクトリ
dn: cn=module{0},cn=config
dn:cn=schema,cn=config
- 独自に作成したディレクトリです。今回は社員に関連する情報を格納していきます。
- 起動した時点でのディレクトリ構造は下記の通りです。
なお、docker-compose.yml で同時に起動した LdapAdmin (GUIツール) を使っても、ディレクトリの構造を確認したり、操作できます。使用方法は下記のとおりとなります。
- LdapAdmin へのアクセス URL は 「<サーバーのIPアドレス>:8080」
- Login DNは「cn=admin,dc=hogetech,dc=com」
- パスワードは「hogetech」
ディレクトリを構築
dc=com ディレクトリにユーザーを登録し、下記のようなディレクトリを構築します。
ディレクトリにユーザーを登録
OpenLDAP では、ディレクトリにエントリーを登録する際に LDIF ファイルを使用します。LDIF ファイルは下記の 3 つの要素で構成されます。
要素 | LDIF での書き方 |
---|---|
操作するDN | dn: から記載を初めます |
オブジェクトクラス: | objectClass:から記載を初めます |
属性 | <属性タイプ>:から記載を初めます |
オブジェクトクラスや属性は複数指定することができます。今回作成する LDIF ファイルは下記の通りです。
dn: ou=development,dc=hogetech,dc=com objectClass: organizationalUnit ou: development dn: cn=Manager,ou=development,dc=hogetech,dc=com objectClass: organizationalRole cn: Manager dn: ou=People,ou=development,dc=hogetech,dc=com objectClass: organizationalUnit ou: People dn: ou=Group,ou=development,dc=hogetech,dc=com ObjectClass: organizationalUnit ou: Group dn: cn=development,ou=Group,ou=development,dc=hogetech,dc=com objectClass: posixGroup cn: development gidNumber: 3001 dn: uid=user01,ou=People,ou=development,dc=hogetech,dc=com objectClass: account objectClass: posixAccount uid: user01 cn: Test User 01 userPassword: {SSHA}ABCDEFG******* loginShell: /bin/bash uidNumber: 3001 gidNumber: 3001 homeDirectory: /home/user01 ou: developer dn: uid=user02,ou=People,ou=development,dc=hogetech,dc=com objectClass: account objectClass: posixAccount uid: user02 cn: Test User 02 userPassword: {SSHA}ABCDEFG******* loginShell: /bin/bash uidNumber: 3002 gidNumber: 3001 homeDirectory: /home/user02 ou: developer
userPassword 属性タイプは、Linux へのログインパスワードを指定します。平文だと抵抗があるので、下記のコマンドで暗号化しておきましょう。この記事の例では、パスワードに "hogetech" を使用します。
New password:<ログインで使用するパスワードを入力> Re-enter new password:<ログインで使用するパスワードを入力> {SSHA}ABCDEFG*******
LDIF ファイルが完成したので、 ldapsearch コマンドを使用して、ディレクトリにエントリーを追加します。
上記のコマンドはバインド DN ("cn=admin,dc=hogetech,dc=com")で initAll.ldif ファイルのエントリーをディレクトリに追加します。パスワードは docker-compose.yml で指定した "hogetech" です。
完成したディレクトリは下記のとおりです。
登録したユーザーをディレクトリから検索
ディレクトリにユーザーが登録できているか確認するために、ディレクトリを検索してみます。ディレクトリの検索には ldapsearch コマンドを使用します。
dn: uid=user01,ou=People,ou=development,dc=hogetech,dc=com objectClass: account objectClass: posixAccount uid: user01 cn: Test User 01 userPassword:: ****** loginShell: /bin/bash uidNumber: 3001 gidNumber: 3001 homeDirectory: /home/user01 ou: development
user01 という社員を正しく登録できてることが確認できました。
ディレクトリのアクセス制御を変更
デフォルトのアクセス制御では、バインド DN ("cn=admin,dc=hogetech,dc=com") 以外で、他のエントリーを参照出来ません。アクセス制御は DN (olcDatabase={1}mdb,cn=config) の olcAccess 属性タイプを変更することで設定可能です。
olcAccess を変更する LDIF ファイルの書式は次のとおりです。
olcAccess: to attrs=<属性タイプ> by <アクセスを許可する対象> <アクセス許可レベル>
<アクセスを許可する対象> の一覧は次のとおりです。
設定 | 対象 |
---|---|
* | すべて |
anonymous | 匿名ユーザー |
users | 認証したユーザー |
self | ユーザー自身 |
dn=<正規表現> | 正規表現に一致したユーザー |
<アクセス許可レベル> の一覧は次のとおりです。
レベル | 説明 |
---|---|
none | アクセス権無し |
auth | バインド可能(ログインで使用可能) |
compare | 比較可能 |
search | 検索フィルタリング実行可能 |
read | 検索結果参照可能 |
write | 更新可能 |
disclose | エラー情報の開示可能 |
一例として、バインド DN (dn=uid=user01,ou=People,ou=development,dc=hogetech,dc=com) 『以降 バインド DN user01 と表記』で userPassword 属性タイプ以外の、全ての属性タイプを読み取れる olcAcsess を設定する LDIF ファイルを作成します。
dn: olcDatabase={1}mdb,cn=config changetype: modify replace: olcAccess olcAccess: to attrs=userPassword by anonymous auth by dn=cn=admin,dc=hogetech,dc=com read by * none olcAccess: to * by self read by dn=uid=user01,ou=People,ou=development,dc=hogetech,dc=com read by dn=cn=admin,dc=hogetech,dc=com read by * none
■アクセス制御を変更する前
Enter LDAP Password: No such object (32)
バインド DN user01 で user02 の情報を検索することができません。
次に、先程作成した access.ldif ファイルを cn=config ディレクトリに適用し、アクセス制御を変更します。(パスワードは"hogetech"です。)
■アクセス制御を変更した後
Enter LDAP Password:
dn: uid=user02,ou=People,ou=development,dc=hogetech,dc=com
objectClass: account
objectClass: posixAccount
uid: user02
cn: Test User 02
loginShell: /bin/bash
uidNumber: 3002
gidNumber: 3001
homeDirectory: /home/user02
ou: development
バインド DN user01 で user02 の情報を検索できるようになりました。また、バインド DN user01 では userPassword 属性タイプが検索されないことも確認できます。
OpenLDAP を使用して Linux のログインを認証
Linux のログイン認証に OpenLDAP を利用するには、次の 2 つの認証システムのうち、どちらか 1 つを使用します。
- nslcd (Name Service LDAP Connection Daemon)
- sssd (System Security Services Daemon)
nslcd と sssd の比較は下記の記事が参考になります。
sssd のほうが良さげなので、今回は sssd を使用することにします。
Linux ログインの認証方法に sssd を使用するように設定
sssd を yum でインストールします。
sssd の認証では、デフォルトで file(/etc/shadow) を使用して認証します。sssd の認証に OpenLDAP を使用するように、authconfig コマンドを実行します。
authconfig で書き換えるファイルは次の 2 つです。うまく修正できてない場合は、手動で変更しても構いません。
- /etc/nsswitch (ネームサービススイッチ)
- パスワードの参照先を決定します。
- デフォルトでは、パスワードの参照先に file(/etc/shadow)を使用しますが、sssd も利用するように設定します。
- パスワードの参照先を決定します。
- /etc/pam.d/system-auth PAM(Pluggable Authentication Module)
sssd で LDAP を利用して認証するように設定
sssd の設定ファイル /etc/sssd/sssd.conf を変更して認証に LDAP を利用するようにする。
sssd.conf で下記の内容が不足している場合は追記してください。(デフォルトで記載されている内容は消さないでください。)
[sssd] domains = LDAP [domain/LDAP] id_provider = ldap auth_provider = ldap ldap_schema = rfc2307 ldap_uri = ldap://127.0.0.1 ldap_search_base = dc=hogetech,dc=com ldap_default_bind_dn = cn=admin,dc=hogetech,dc=com ldap_tls_reqcert = never ldap_default_authtok_type = obfuscated_password ldap_default_authtok = ******
ldap_default_authtok はバインド DN のパスワードです。下記のコマンドを実行することで、難読化したパスワードが /etc/sssd/sssd.conf に自動で書き込まれます。
Enter password: Re-enter password:
設定が完了したら、sssd サービスを起動します。
OpenLDAP を使用して user01 にログイン
user01 でログインする前に user01 のホームディレクトリを作成します。
次のコマンドで user01 にログイン可能なことを確認します。パスワードは initAll.ldif の userPassword 属性で指定した値です。この記事のパスワードは "hogetech" です。
パスワード: 最終ログイン: 2020/06/15 (月) 00:57:09 UTC日時 pts/1 -bash-4.2$
OpenLDAP に登録した user01 で Linux にログインできました!
このように、OpenLDAP に認証情報を集約することができました。これにより、社員の入社・退職に合わせて OpenLDAP のエントリーを追加・削除するだけで、Linux へのログイン権限を管理できます。
関連記事
関連記事:サーバー | ||||
---|---|---|---|---|