【Linux】OpenLDAPを利用したユーザ認証およびユーザ管理 - インストールから利用まで –

この記事では,OpenLDAPを使ったLinuxユーザアカウント管理とユーザ認証を目的とします.

OpenLDAPを使用することで,Linuxのユーザ管理するサーバを構築します.

LDAPサーバにより,ユーザ管理を一元化することで,サーバごとにユーザを作成する手間が省けます.

LDAPを使えば,ユーザ管理が楽になります!

この記事ではCLIでLDAP構築を行いますが,GUIによるLDAP構築は下記記事に記載してます.

目次

この記事でできるようになること

・OpenLDAPのインストール
・LDAPを利用したユーザアカウント管理とユーザ認証

今回実行した環境は,Ubuntu 20.04です.

Ubuntu 20.04(Debian系)以外の環境の場合インストール方法が異なりますが,使用方法はほとんど同じです.

最終的に,下記のようなディレクトリツリーを作成します.

  • ユーザ:hoge (uid:2000)
  • グループ:foo(gid:5000),bar(gid:5001)

OpenLDAPとは

OpenLDAPは,LDAPの機能を実装したオープンソースソフトウェアです.オープンソースソフトウェアのため,無料で使用可能です.OpenLDAPの公式サイトはこちらです.

あわせて読みたい
OpenLDAP, Main Page The Open Source for LDAP software and information. Home of OpenLDAP.

OpenLDAPのインストール

LDAPサーバとするマシンに下記パッケージをインストールします.


apt install slapd ldap-utils

slapd(Standalone LDAP Deamon)はスタンドアローンLDAPデーモンです.LDAPサーバ用のソフトウェアという理解で大丈夫です.

パスワードの入力を求められるので,適宜入力します.ドメインが設定されていない場合,警告がでますが,一旦無視します.

インストール時のslapdの設定は以下のコマンドで確認できます.


slapcat 

dn: dc=nodomain
objectClass: top
objectClass: dcObject
objectClass: organization
o: nodomain
dc: nodomain
structuralObjectClass: organization
entryUUID: f3ecf5d0-2c18-103c-850d-d5df5d0de8b0
creatorsName: cn=admin,dc=nodomain
createTimestamp: 20220227130016Z
entryCSN: 20220227130016.086916Z#000000#000#000000
modifiersName: cn=admin,dc=nodomain
modifyTimestamp: 20220227130016Z
dn: cn=admin,dc=nodomain
objectClass: simpleSecurityObject
objectClass: organizationalRole

cn: admin
description: LDAP administrator
userPassword:: e1NTSEF9U0t3bGtpTXZtbmJzTENGc25NVkUxSFlNRkxJeHhwNFo=
structuralObjectClass: organizationalRole
entryUUID: f3ed15f6-2c18-103c-850e-d5df5d0de8b0
creatorsName: cn=admin,dc=nodomain
createTimestamp: 20220227130016Z
entryCSN: 20220227130016.087773Z#000000#000#000000
modifiersName: cn=admin,dc=nodomain
modifyTimestamp: 20220227130016Z

dpkg-reconfigure slapd

DNSをexample.com,Organazationをexamole_orgとしましたが,適宜自分の環境に合わせてください.

slapcatは以下のようになります.さきほどのnodomainexample_orgexampleに変更されています.


dn: dc=example,dc=com
objectClass: top
objectClass: dcObject
objectClass: organization
o: example_org
dc: example
structuralObjectClass: organization
entryUUID: 8164f75e-2c1a-103c-88e3-2322d3e10ff2
creatorsName: cn=admin,dc=example,dc=com
createTimestamp: 20220227131122Z
entryCSN: 20220227131122.928856Z#000000#000#000000
modifiersName: cn=admin,dc=example,dc=com
modifyTimestamp: 20220227131122Z

dn: cn=admin,dc=example,dc=com
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: admin
description: LDAP administrator
userPassword:: e1NTSEF9dktkZHFrOVM4TjU2eGhZYW40Z0N6VGR1Q0VUTnZ0YkY=
structuralObjectClass: organizationalRole
entryUUID: 81651ffe-2c1a-103c-88e4-2322d3e10ff2
creatorsName: cn=admin,dc=example,dc=com
createTimestamp: 20220227131122Z
entryCSN: 20220227131122.929936Z#000000#000#000000
modifiersName: cn=admin,dc=example,dc=com
modifyTimestamp: 20220227131122Z

LDAPサーバ側の設定

ここから先は,ユーザ管理のための設定です.この記事では,CLIで操作しますが,GUIで設定を行うことも可能です.

人に関するエントリとグループに関するエントリを作成します.このエントリがユーザとグループを管理するものになります.

まず,テキストエディタで以下のようなLDIFファイルを作成します.LDIFファイルはエントリ情報が記述されたファイルであり,このファイルを用いてLDAPサーバにエントリを追加します

base.ldif


dn: ou=people,dc=example,dc=com
objectClass: organizationalUnit
ou: people
dn: ou=groups,dc=example,dc=com
objectClass: organizationalUnit
ou: groups

下記コマンドで,Rootエントリを追加します.


ldapadd -x -D "cn=admin,dc=example,dc=com" -W -f base.ldif 

Enter LDAP Password: 
adding new entry "ou=people,dc=example,dc=com"
adding new entry "ou=groups,dc=example,dc=com"

Linuxのユーザ管理に必須のスキーマはnis.schemacore.schemacosine.schemainetorgperson.schmaが必要になります.

設定ディレクトリ(configディレクトリ)を確認して,上記のスキーマが存在することを確認します.


ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b "cn=config" dn

dn: cn=config
dn: cn=module{0},cn=config
dn: cn=schema,cn=config
dn: cn={0}core,cn=schema,cn=config
dn: cn={1}cosine,cn=schema,cn=config
dn: cn={2}nis,cn=schema,cn=config
dn: cn={3}inetorgperson,cn=schema,cn=config
dn: olcDatabase={-1}frontend,cn=config
dn: olcDatabase={0}config,cn=config
dn: olcDatabase={1}mdb,cn=config

現時点のDITは,Root DNのみとなっています.

ユーザとグループを設定

ユーザの設定にはグループIDの設定が必要なため,まずはグループエントリから作成します.

グループの設定

例として,グループ名fooグループIDを5000のグループエントリを作成します.

下記のようにグループエントリ用のLDIFファイルを作成します.

group_foo.ldif


dn: cn=foo,ou=groups,dc=example,dc=com
objectClass: posixGroup
cn: foo
gidNumber: 5000

下記コマンドでエントリを追加します.


ldapadd -x -D "cn=admin,dc=example,dc=com" -W -f group_foo.ldif
Enter LDAP Password: 
adding new entry "cn=foo,ou=groups,dc=example,dc=com"

念のため,追加したグループの確認をします.


ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b "ou=groups,dc=example,dc=com" dn cn

dn: ou=groups,dc=example,dc=com
dn: cn=foo,ou=groups,dc=example,dc=com
cn: foo

現時点のDITは,グループが追加されて下記のようになっています.

ユーザの設定

グループの作成が完了したため,次にユーザエントリを作成します.

ここで,作成するユーザ名はhogeであり,ユーザIDは5000とします.

まず.ユーザのパスワードを生成します.


slappasswd 

打ち込んだパスワードが暗号化された形{SSHA}DGPs1L2hdZZ9kVsU2BNnJxOBSd1khfm8が生成されます.


New password: 
Re-enter new password: 
{SSHA}DGPs1L2hdZZ9kVsU2BNnJxOBSd1khfm8

下記のようなユーザエントリ用のLDIFファイルを作成します.objectclassに指定しているposixAccountはLinuxユーザ管理用に必須の項目になります.

user_hoge.ldif


dn: uid=hoge,ou=people,dc=example,dc=com
objectclass: inetOrgPerson
objectclass: posixAccount
sn: hoge
mail: hoge@example.com
uid: hoge
cn: hoge
uidNumber: 2000
gidNumber: 5000
homeDirectory: /home/hoge
loginShell: /bin/bash
userPAssword: {SSHA}DGPs1L2hdZZ9kVsU2BNnJxOBSd1khfm8

posixAccountは補助型(AUXILIARY)オブジェクトクラスのため,構造型(STRUCTUAL)オブジェクトクラスと一緒に使う必要があります.ここではinetOrgPersonオブジェクトクラスを使用します.inetOrgPersonでは,cn(Common Name)とsn(Surname)が必須属性になります.

作成したLDIFファイルを用いて,下記コマンドでユーザエントリを追加します.


ldapadd -x -D "cn=admin,dc=example,dc=com" -W -f user_hoge.ldif

Enter LDAP Password: 
adding new entry "uid=hoge,ou=people,dc=example,dc=com"

追加したユーザを確認します.


ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b "ou=people,dc=example,dc=com" dn uid
dn: ou=people,dc=example,dc=com
dn: uid=hoge,ou=people,dc=example,dc=com
uid: hoge

ユーザが追加され,現在のDITは下記のようになります.

セカンダリグループの設定

ユーザのプライマリグループはuid=hoge,ou=people,dc=example,dc=comgidNumberとなります.ユーザエントリではセカンダリグループを設定しません.

ユーザのセカンダリグループはグループエントリ側で設定します.

ユーザのセカンダリグループを登録は,グループエントリのmemberUidで指定します.memberUidに指定されたユーザのセカンダリグループがグループエントリのgidNumberとなるという仕組みです.

グループエントリのLDIFファイルは下記のようになります.

group_bar.ldif


dn: cn=bar,ou=groups,dc=example,dc=com
objectClass: posixGroup
cn: bar
gidNumber: 5001
memberUid: 2000

ldapadd -x -D "cn=admin,dc=example,dc=com" -W -f group_bar.ldif

hogeのプライマリグループは5000で,セカンダリグループが5001となります.

グループ一覧を表示すると,グループfoobarが確認できます.


ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b "ou=groups,dc=example,dc=com"

dn: ou=groups,dc=example,dc=com
objectClass: organizationalUnit
ou: groups

dn: cn=bar,ou=groups,dc=example,dc=com
objectClass: posixGroup
cn: bar
gidNumber: 5001
memberUid: 2000

dn: cn=foo,ou=groups,dc=example,dc=com
objectClass: posixGroup
gidNumber: 5000
cn: foo
Tips

クライアントサーバから接続する場合は,以下のコマンドで実行できます(暗号化なし).同様の結果が得られると思います.


ldapsearch -LLL -x -W -H ldap://example.com -D "cn=admin,dc=example,dc=com" -b "ou=groups,dc=example,dc=com"

現時点のDITは下記のようになっています.

LDAP通信を暗号化する

現時点までに行った通常の設定では,サーバとの通信が暗号化されません.当然ながら通信が暗号化しないとセキュリティ上問題となるので,LDAP通信を暗号化します

ここでは,自己証明書(いわゆるオレオレ証明書)を用いて暗号化を行います.

LDAPサーバをインターネット上の不特定多数に公開する場合は正式な証明書を取得すると良いでしょう.下記,記事を参照ください.

自己証明書の発行


openssl req -new -x509 -nodes -days 3650 -out ldap-server.pem -keyout ldap-server.key 

下記のように,適宜入力します.不要な部分はブランクで大丈夫です.


Generating a RSA private key
..+++++
...................+++++
writing new private key to 'ldap-server.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:JP
State or Province Name (full name) [Some-State]:Tokyo
Locality Name (eg, city) []:Chiyoda
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Example Ltd.
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:example.com
Email Address []:
  • -newオプションにより,新規に証明書を発行します.
  • -nodesオプションを指定することで,秘密鍵をパスフレーズによる暗号化を行いません.「nodes」ではなく「noDES」です.DESは「Data Encryption Standard」の略で,鍵の暗号化に使われる技術です.
  • -daysオプションで,証明書の有効期限を設定します.デフォルトでは30日です.

自己証明書の設定

作成した証明書を/etc/ldap/sasl2にコピーします.


cp ldap-server.key ldap-server.pem /etc/ldap/sasl2/

ファイルの所有者を変更します.


chown openldap:openldap /etc/ldap/sasl2/ldap-server.key /etc/ldap/sasl2/ldap-server.pem 

この手順を忘れるとエントリ追加時に下記のようなエラーがでます.Unknownエラー扱いなので原因がわからずにハマりました.


modifying entry "cn=config"
ldap_modify: Other (e.g., implementation specific) error (80)

下記コマンドで,証明書が正常に設定されたかを確認します.


ldapsearch -LLL -Y EXTERNAL -H ldapi:/// -b "cn=config" olcTLSCACertificateFile olcTLSCertificateFile olcTLSCertificateKeyFile

ハイライトされている部分が確認できればOKです.


SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
dn: cn=config
olcTLSCACertificateFile: /etc/ldap/sasl2/ldap-server.pem
olcTLSCertificateFile: /etc/ldap/sasl2/ldap-server.pem
olcTLSCertificateKeyFile: /etc/ldap/sasl2/ldap-server.key

dn: cn=module{0},cn=config

dn: cn=schema,cn=config

dn: cn={0}core,cn=schema,cn=config

dn: cn={1}cosine,cn=schema,cn=config

dn: cn={2}nis,cn=schema,cn=config

dn: cn={3}inetorgperson,cn=schema,cn=config

dn: olcDatabase={-1}frontend,cn=config

dn: olcDatabase={0}config,cn=config

dn: olcDatabase={1}mdb,cn=config

olcTLSCACertificateFileなどの項目が見つからない場合,下記設定を追加します.

ssl.ldif


dn: cn=config
changetype: modify
add: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/ldap/sasl2/ldap-server.pem
-
add: olcTLSCertificateFile
olcTLSCertificateFile: /etc/ldap/sasl2/ldap-server.pem
-
add: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/ldap/sasl2/ldap-server.key


ldapmodify -Y EXTERNAL -H ldapi:/// -f ssl.ldif

ldaps://の有効化

URIをldaps://を指定することで,通信の暗号化を強制します.

ldaps://接続を有効化するために,/etc/default/slapdを次のように書き換えます.

/etc/default/slapd


...
- SLAPD_SERVICES="ldap:/// ldapi:///"
+ SLAPD_SERVICES="ldap:/// ldapi:/// ldaps:///"
...

ldaps://を有効化すると,ポート636が開放されます(デーモンを再起動が必要です).


ss -natu | grep 636
tcp LISTEN 0 1024 0.0.0.0:636 0.0.0.0:*
tcp LISTEN 0 1024 [::]:636 [::]:*

LDAPデーモンを再起動

設定が一通り完了したら,デーモンを再起動して設定を反映します.


systemctl restart slapd.service 

動作確認のため,下記コマンドを実行します.anonymousと表示されれば成功です.


ldapwhoami -x -ZZ -H ldap://example.com
anonymous

もしくは


ldapwhoami -x -ZZ -H ldap://example.com
anonymous

自己証明書を使用するの場合,下記エラーが発生するようです.


ldap_sasl_bind(SIMPLE): Can't contact LDAP server (-1)

エラー回避のために,/etc/ldap/ldap.confに下記設定を追加します.

/etc/ldap/ldap.conf


...
+ TLS_REQCERT never

LDAPクライアントの設定

パッケージのインストール


apt install sssd libpam-sss libnss-sss

SSSD(System Security Services Daemon)は,暗号化された認証サービスです.そのため,SSL/TLS認証を使用します.サーバ側でSSL/TLS接続できることを確認してください.(SSL/TLS認証を使用しない設定も可能ですが,非推奨です.)


ldapsearch -LLL -x -W -H ldaps://example.com -D "cn=admin,dc=example,dc=com" -b "ou=people,dc=example,dc=com"

自己証明書を用いている場合は下記設定を追加します.

/etc/ldap/ldap.conf


...
+ TLS_REQCERT never

SSSDの設定

sssdの設定ファイルとして,次のような/etc/sssd/sssd.confを作成します.

/etc/sssd/sssd.conf


[sssd]
config_file_version = 2
domains = LDAP
services = nss, pam

[domain/LDAP]
id_provider = ldap
auth_provider = ldap
ldap_uri = ldaps://example.com
ldap_id_use_start_tls = True
ldap_tls_reqcert = never
ldap_tls_cacert = /etc/ldap/sasl2/ldap-server.pem
ldap_search_base = dc=example,dc=com

[nss]
filter_groups = root
filter_users = root
reconnection_retries = 3
entry_cache_timeout = 300

[pam]
reconnection_retries = 3
  • ldap_tls_reqcert = neverは自己証明書を使用しているため,neverを設定します.
  • ldap_tls_cacert=...は証明書の設置場所です.サーバ側で作成した自己証明書(ldap-server.pem)をクライアント側にコピーして持ってきます.ファイルの置き場所は任意ですが,今回はサーバ側と同じ/etc/ldap/sasl2に置くこととします.

SSL/TLSを使用しない場合,[domain/LDAP]のTLSに関連する部分を削除し,ldap_auth_disable_tls_never_use_in_production = trueを記述することで可能です.

権限を600に設定します.


chmod 600 /etc/sssd/sssd.conf

systemctl restart sssd.service

エラーがないことを確認してください.
証明書の設置場所等に不備があるとCould not start TLS encryption. (unknown error code)などエラーが表示されます.


systemctl status sssd.service

NSSの設定

/etc/nsswitch.confを開き,passwdgroupshadowsssが記述されていることを確認します.sssが見当たらない場合,追記してください.


passwd:         files systemd sss
group:          files systemd sss
shadow:         files sss

この設定が完了した時点で,システムはSSSDを経由して,LDAPを参照することができます.

PAMの設定

ホームディレクトリが存在しない場合は,自動的に作成するように設定します./etc/pam.d/common-sessionの末尾に下記設定を追記します.


...
+ session required pam_mkhomedir.so skel=/etc/skel umask=0022

LDAPユーザでログインしてみる

最後に,LDAPサーバに作成済みのユーザhogeでログインしてみます.


su - hoge

パスワードを入力します.ホームディレクトリが存在しない場合,自動的に作成されます.


Password: 
Creating directory '/home/hoge'.

>> アルゴリズムイントロダクション

まとめ

この記事では,LDAPのインストールと導入方法について記載しました.

また,細かなLDAPの各種設定に関しては,導入と同時に記載すると煩雑になるため省略しています.

今回はCLI(コンソール)を利用した設定方法を示しましたが,”LDAP Account Manager”などのGUIを利用した設定方法もあります.

LDAP Account Mangerを利用したLDAP構築は別記事にしています.下記記事をご覧ください.

よかったらシェアしてね!
目次