この記事では,OpenLDAPを使ったLinuxユーザアカウント管理とユーザ認証を目的とします.
OpenLDAPを使用することで,Linuxのユーザ管理するサーバを構築します.
LDAPサーバにより,ユーザ管理を一元化することで,サーバごとにユーザを作成する手間が省けます.
LDAPを使えば,ユーザ管理が楽になります!
この記事ではCLIでLDAP構築を行いますが,GUIによるLDAP構築は下記記事に記載してます.
この記事でできるようになること
今回実行した環境は,Ubuntu 20.04です.
Ubuntu 20.04(Debian系)以外の環境の場合インストール方法が異なりますが,使用方法はほとんど同じです.
最終的に,下記のようなディレクトリツリーを作成します.
- ユーザ:hoge (uid:2000)
- グループ:foo(gid:5000),bar(gid:5001)
OpenLDAPとは
OpenLDAPは,LDAPの機能を実装したオープンソースソフトウェアです.オープンソースソフトウェアのため,無料で使用可能です.OpenLDAPの公式サイトはこちらです.
OpenLDAPのインストール
LDAPサーバとするマシンに下記パッケージをインストールします.
apt install slapd ldap-utils
パスワードの入力を求められるので,適宜入力します.ドメインが設定されていない場合,警告がでますが,一旦無視します.
インストール時の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
は以下のようになります.さきほどのnodomain
がexample_org
やexample
に変更されています.
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.schema
,core.schema
,cosine.schema
,inetorgperson.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
作成した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=com
のgidNumber
となります.ユーザエントリではセカンダリグループを設定しません.
ユーザのセカンダリグループはグループエントリ側で設定します.
ユーザのセカンダリグループを登録は,グループエントリの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
となります.
グループ一覧を表示すると,グループfoo
とbar
が確認できます.
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
クライアントサーバから接続する場合は,以下のコマンドで実行できます(暗号化なし).同様の結果が得られると思います.
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
に置くこととします.
権限を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
を開き,passwd
,group
,shadow
にsss
が記述されていることを確認します.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構築は別記事にしています.下記記事をご覧ください.