FreeRADIUSのLDAP連携

概要

今回は、前回の記事で構築したFreeRADIUSに対して、LDAPサーバと連携する設定を行い、認証のテストまで実施したいと思います。

389 Directory Server

今回はLDAPサーバとしてRHEL7.4以降推奨されるようになった389 Directory Serverを利用したいと思います。

インストール

まずはパッケージのインストールを行います。389 Directory Serverは依存関係で「openldap-clients」もインストールされるため、別途インストールを行わずとも「ldapsearch」などのLDAPのクライアントコマンドを実行可能です。

# dnf install 389-ds-base
メタデータの期限切れの最終確認: 3:15:01 前の 2025年07月10日 07時23分05秒 に実施しました。
依存関係が解決しました。
================================================================================
 パッケージ                     Arch     バージョン           Repo        サイズ
================================================================================
インストール:
 389-ds-base                    x86_64   2.6.1-10.el9_6       appstream   2.8 M
アップグレード:
 audit                          x86_64   3.1.5-4.el9          baseos      253 k
 audit-libs                     x86_64   3.1.5-4.el9          baseos      121 k
 libdb                          x86_64   5.3.28-57.el9_6      baseos      736 k
 libselinux                     x86_64   3.6-3.el9            baseos       85 k
 libselinux-utils               x86_64   3.6-3.el9            baseos      164 k
 libsemanage                    x86_64   3.6-5.el9_6          baseos      117 k
 openldap                       x86_64   2.6.8-4.el9          baseos      266 k
 python3-libselinux             x86_64   3.6-3.el9            appstream   186 k
依存関係のインストール:
 389-ds-base-libs               x86_64   2.6.1-10.el9_6       appstream   1.5 M
 checkpolicy                    x86_64   3.6-1.el9            appstream   351 k
 cyrus-sasl-gssapi              x86_64   2.1.27-21.el9        baseos       26 k

   ~中略~

  python3-pycparser-2.20-6.el9.noarch                                           
  python3-setools-4.4.4-1.el9.x86_64                                            
  python3-setuptools-53.0.0-13.el9_6.1.noarch                                   

完了しました!

設定

では続いて、インスタンスの作成を行っていきます。

インスタンス作成には、対話ベースで行う方法と設定用テンプレートを利用した方法がありますが、今回は前者で行っていきます。

基本的にはデフォルトで大丈夫ですが、「database suffix」など要件に合わせて指定をしてください。

# dscreate interactivedscreate interactive
Install Directory Server (interactive mode)
===========================================
SELinux is disabled, will not relabel ports or files.

SELinux labels will not be applied, continue? [yes]: 

Enter system's hostname [redis-server]: 

Enter the instance name [redis-server]: ldap-test

Enter port number [389]: 

Create self-signed certificate database [yes]: 

Enter secure port number [636]: 

Enter Directory Manager DN [cn=Directory Manager]: 

Enter the Directory Manager password: 
Confirm the Directory Manager Password: 

Choose whether mdb or bdb is used. [bdb]: 

Enter the database suffix (or enter "none" to skip) [dc=redis-server]: dc=example,dc=com

Create sample entries in the suffix [no]: 

Create just the top suffix entry [no]: yes

Do you want to start the instance after the installation? [yes]: 

Are you ready to install? [no]: yes
Starting installation ...
Validate installation settings ...
Create file system structures ...
Create self-signed certificate database ...
SELinux is disabled, will not relabel ports or files.
SELinux is disabled, will not relabel ports or files.
Create database backend: dc=example,dc=com ...
Perform post-installation tasks ...
Completed installation for instance: slapd-ldap-test

「Completed installation」と出力されればインスタンス作成が無事完了です。

また、「/etc/dirsrv」配下にインスタンス用のディレクトリが作成され、サービスも起動された状態になっていることを確認できます。

# ls -la /etc/dirsrv
合計 28
drwxr-xr-x    7 root   root    127  7月 15 23:10 .
drwxr-xr-x. 107 root   root   8192  7月 17 09:44 ..
drwxr-xr-x    2 root   root     55  7月 10 10:38 config
drwxr-xr-x    2 root   root     25  7月 10 10:38 schema
drwxrwx---    3 dirsrv dirsrv  325  7月 17 09:44 slapd-ldap-test
drwxrwx---    2 root   root    156  7月 15 23:10 ssca
# systemctl restart dirsrv@ldap-test systemctl status
● dirsrv@ldap-test.service - 389 Directory Server ldap-test.
     Loaded: loaded (/usr/lib/systemd/system/dirsrv@.service; enabled; preset: >
    Drop-In: /usr/lib/systemd/system/dirsrv@.service.d
             └─custom.conf
     Active: active (running) since Wed 2025-07-16 17:07:47 JST; 3s ago
    Process: 2365826 ExecStartPre=/usr/libexec/dirsrv/ds_systemd_ask_password_a>
    Process: 2365831 ExecStartPre=/usr/libexec/dirsrv/ds_selinux_restorecon.sh >
   Main PID: 2365836 (ns-slapd)
     Status: "slapd started: Ready to process requests"
      Tasks: 29 (limit: 61742)
     Memory: 65.1M
        CPU: 2.478s
     CGroup: /system.slice/system-dirsrv.slice/dirsrv@ldap-test.service
             └─2365836 /usr/sbin/ns-slapd -D /etc/dirsrv/slapd-ldap-test -i /ru>

 7月 16 17:07:47 redis-server ns-slapd[2365836]: [16/Jul/2025:17:07:47.45839504>
 7月 16 17:07:47 redis-server ns-slapd[2365836]: [16/Jul/2025:17:07:47.45926320>
 7月 16 17:07:47 redis-server ns-slapd[2365836]: [16/Jul/2025:17:07:47.46025901>
 7月 16 17:07:47 redis-server ns-slapd[2365836]: [16/Jul/2025:17:07:47.46118579>
 7月 16 17:07:47 redis-server ns-slapd[2365836]: [16/Jul/2025:17:07:47.60776760>
 7月 16 17:07:47 redis-server ns-slapd[2365836]: [16/Jul/2025:17:07:47.64764653>
 7月 16 17:07:47 redis-server ns-slapd[2365836]: [16/Jul/2025:17:07:47.64891528>
 7月 16 17:07:47 redis-server ns-slapd[2365836]: [16/Jul/2025:17:07:47.65001350>
lines 1-23

では続いて、LDAPサーバにエントリを追加します。

尚、今回は一般ユーザとして「test-user01」と「test-user02」、認証用のユーザとして「auth-user」を作成しています。

また、FreeRADIUSからバインドする際パスワードの暗号化方式によっては読み込めない場合がありますので、今回はSSHAを指定しています。

# mkdir /etc/dirsrv/ldif
# vi /etc/dirsrv/ldif/entry.ldif
# cat /etc/dirsrv/ldif/entry.ldif 
dn: ou=user,dc=example,dc=com
objectClass: organizationalUnit
objectClass: top
ou: user
aci: (target="ldap:///ou=user,dc=example,dc=com")
  (targetattr="*")
  (version 3.0; acl "Allow auth-user to read user entries";
  allow (read, search, compare)
  userdn="ldap:///uid=auth-user,ou=user,dc=example,dc=com";)

dn: uid=test-user01,ou=user,dc=example,dc=com
objectClass: posixAccount
objectClass: inetOrgPerson
uid: test-user01
cn: test-user01
sn: test-user01
uidNumber: 1001
gidNumber: 1001
homeDirectory: /home/test-user01
loginShell: /bin/bash
userPassword: {SSHA}K9xsXD9ac0720y+LptyKWuwl+OmK6FV4HCwi8Q==

dn: uid=test-user02,ou=user,dc=example,dc=com
objectClass: posixAccount
objectClass: inetOrgPerson
uid: test-user02
cn: test-user02
sn: test-user02
uidNumber: 1002
gidNumber: 1002
homeDirectory: /home/test-user02
loginShell: /bin/bash
userPassword: {SSHA}aFRiVieHV58wB0u9h3MmMQzX2LpaduDctePyiQ==

dn: uid=auth-user,ou=user,dc=example,dc=com
objectClass: posixAccount
objectClass: inetOrgPerson
cn: auth-user
sn: auth-user
uid: auth-user
uidNumber: 10000
gidNumber: 10000
homeDirectory: /home/auth-user
loginShell: /bin/bash
userPassword: {SSHA}K9xsXD9ac0720y+LptyKWuwl+OmK6FV4HCwi8Q==
# ldapadd -x -H ldap://localhost -D "cn=Directory Manage r" -W -f /etc/dirsrv/ldif/entry.ldif
Enter LDAP Password: 
adding new entry "ou=user,dc=example,dc=com"

adding new entry "uid=test-user01,ou=user,dc=example,dc=com"

adding new entry "uid=test-user02,ou=user,dc=example,dc=com"

adding new entry "uid=auth-user,ou=user,dc=example,dc=com"

ldapsearchコマンドにて実際にエントリが追加されたことを確認します。

# ldapsearch -x -H ldap://localhost -D "cn=Directory Manager" -W -b "dc=example,dc=com"
Enter LDAP Password: 
# extended LDIF
#
# LDAPv3
# base <dc=example,dc=com> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

# example.com
dn: dc=example,dc=com
objectClass: top
objectClass: domain
dc: example
description: dc=example,dc=com

# user, example.com
dn: ou=user,dc=example,dc=com
objectClass: organizationalUnit
objectClass: top
ou: user

# test-user01, user, example.com
dn: uid=test-user01,ou=user,dc=example,dc=com
objectClass: posixAccount
objectClass: inetOrgPerson
objectClass: top
objectClass: organizationalPerson
objectClass: person
uid: test-user01
cn: test-user01
sn: test-user01
uidNumber: 1001
gidNumber: 1001
homeDirectory: /home/test-user01
loginShell: /bin/bash
userPassword:: e1BCS0RGMi1TSEE1MTJ9MTAwMDAwJEZ2ZGkvUUlkQWx1WE8yejJaRDBwaFpNQVh
 GTUdMdTRxJHZXQ0xLWmtrVHAxckg1aXI5bHpEM1QwMTZyR1VTQ25IOTY5bElEYVR4TzZLVDl4dERl
 dnBoS2dYMStGeEZyT2k2TFFkM3RoYmtBN0dBTlFwQVlEd2NnPT0=

# test-user02, user, example.com
dn: uid=test-user02,ou=user,dc=example,dc=com
objectClass: posixAccount
objectClass: inetOrgPerson
objectClass: top
objectClass: organizationalPerson
objectClass: person
uid: test-user02
cn: test-user02
sn: test-user02
uidNumber: 1002
gidNumber: 1002
homeDirectory: /home/test-user02
loginShell: /bin/bash
userPassword:: e1NTSEF9YUZSaVZpZUhWNTh3QjB1OWgzTW1NUXpYMkxwYWR1RGN0ZVB5aVE9PQ=
 =

# auth-user, user, example.com
dn: uid=auth-user,ou=user,dc=example,dc=com
objectClass: posixAccount
objectClass: inetOrgPerson
objectClass: top
objectClass: organizationalPerson
objectClass: person
cn: auth-user
sn: auth-user
uid: auth-user
uidNumber: 10000
gidNumber: 10000
homeDirectory: /home/auth-user
loginShell: /bin/bash
userPassword:: e1BCS0RGMi1TSEE1MTJ9MTAwMDAwJGszNDJzakNPZitDNzhuY21jbDhXTGJKbHJ
 qQUU1K0RnJG9aTjh6ZFY5NS9kMzhUdEp5QjBxMjdzK0Y5NFFZc3lRVG1VUStQVEtJYkUyTjNDL3Ur
 SzR2V1h2eUdIQjg5R3Bzcm5nWXIwa2ljTlk2SWFZZWNha0NRPT0=

# search result
search: 2
result: 0 Success

# numResponses: 6
# numEntries: 5

# ldapsearch -x -H ldap://localhost -D "cn=Directory Manager" -w P@ssword -b "dc=example,dc=com" aci
# extended LDIF
#
# LDAPv3
# base <dc=example,dc=com> with scope subtree
# filter: (objectclass=*)
# requesting: aci
#

# example.com
dn: dc=example,dc=com
aci: (targetattr="dc || description || objectClass")(targetfilter="(objectClas
 s=domain)")(version 3.0; acl "Enable anyone domain read"; allow (read, search
 , compare)(userdn="ldap:///anyone");)

# user, example.com
dn: ou=user,dc=example,dc=com
aci: (target="ldap:///ou=user,dc=example,dc=com") (targetattr="*") (version 3.
 0; acl "Allow auth-user to read user entries"; allow (read, search, compare)
 userdn="ldap:///uid=auth-user,ou=user,dc=example,dc=com";)

# test-user01, user, example.com
dn: uid=test-user01,ou=user,dc=example,dc=com

# test-user02, user, example.com
dn: uid=test-user02,ou=user,dc=example,dc=com

# auth-user, user, example.com
dn: uid=auth-user,ou=user,dc=example,dc=com

# search result
search: 2
result: 0 Success

# numResponses: 6
# numEntries:

接続テスト

バインドユーザとして使用する「auth-user」でもユーザ検索が出来ることを確認します。

# ldapsearch -x -H ldap://localhost -D "uid=auth-user,ou=user,dc=example,dc=com" -W -b "dc=example,dc=com"
Enter LDAP Password:
# extended LDIF
#
# LDAPv3
# base <dc=example,dc=com> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

# example.com
dn: dc=example,dc=com
objectClass: top
objectClass: domain
dc: example
description: dc=example,dc=com

# user, example.com
dn: ou=user,dc=example,dc=com
objectClass: organizationalUnit
objectClass: top
ou: user

# test-user01, user, example.com
dn: uid=test-user01,ou=user,dc=example,dc=com
objectClass: posixAccount
objectClass: inetOrgPerson
objectClass: top
objectClass: organizationalPerson
objectClass: person
uid: test-user01
cn: test-user01
sn: test-user01
uidNumber: 1001
gidNumber: 1001
homeDirectory: /home/test-user01
loginShell: /bin/bash
userPassword:: e1NTSEF9Szl4c1hEOWFjMDcyMHkrTHB0eUtXdXdsK09tSzZGVjRIQ3dpOFE9PQ=
 =

# test-user02, user, example.com
dn: uid=test-user02,ou=user,dc=example,dc=com
objectClass: posixAccount
objectClass: inetOrgPerson
objectClass: top
objectClass: organizationalPerson
objectClass: person
uid: test-user02
cn: test-user02
sn: test-user02
uidNumber: 1002
gidNumber: 1002
homeDirectory: /home/test-user02
loginShell: /bin/bash
userPassword:: e1NTSEF9YUZSaVZpZUhWNTh3QjB1OWgzTW1NUXpYMkxwYWR1RGN0ZVB5aVE9PQ=
 =

# auth-user, user, example.com
dn: uid=auth-user,ou=user,dc=example,dc=com
objectClass: posixAccount
objectClass: inetOrgPerson
objectClass: top
objectClass: organizationalPerson
objectClass: person
cn: auth-user
sn: auth-user
uid: auth-user
uidNumber: 10000
gidNumber: 10000
homeDirectory: /home/auth-user
loginShell: /bin/bash
userPassword:: e1BCS0RGMi1TSEE1MTJ9MTAwMDAwJHhmREE3aC85RjAybFc4YUd3Ni8vL2VQNGN
 rQmR3Qy9qJGZWcDZuVW1sVGhNM3lCRG9Qd1JzWU9sNExPdFFPeTBkak5DZlF5Q3pwMFM4aU9BRHh0
 S0ZGZk4rQ2FOeEpwbGhwaURJcXBvZHR6R1FFOGtoQmlIZkp3PT0=

# search result
search: 2
result: 0 Success

# numResponses: 6
# numEntries: 5

FreeRADIUSの追加設定

LDAPサーバの準備が整いましたので、FreeRADIUSに必要な設定を追加していきます。

まずはLDAP連携を行うために必要なパッケージのインストールを行います。

# dnf install freeradius-ldap
メタデータの期限切れの最終確認: 1:23:30 前の 2025年07月15日 17時06分06秒 に実施しました。
依存関係が解決しました。
================================================================================
 パッケージ           Arch        バージョン           リポジトリー       サイズ
================================================================================
インストール:
 freeradius-ldap      x86_64      3.2.7-1.el9          networkradius       41 k
依存関係のインストール:
 cyrus-sasl           x86_64      2.1.27-21.el9        baseos              71 k

トランザクションの概要
================================================================================
インストール  2 パッケージ

ダウンロードサイズの合計: 113 k
インストール後のサイズ: 251 k
これでよろしいですか? [y/N]: y
パッケージのダウンロード:
                         [===                 ] ---  B/s |   0  B     --:-- ETA                         [===                 ] ---  B/s |   0  B     --:-- ETA(1/2): cyrus-sasl-2.  0% [                    ] ---  B/s |   0  B     --:-- ETA(1/2): cyrus-sasl-2.1.27-21.el9.x86_64.rpm      627 kB/s |  71 kB     00:00    
(2/2): freeradius-ld 63% [============-       ] 627 kB/s |  71 kB     00:00 ETA(2/2): freeradius-ld 63% [============-       ] 627 kB/s |  71 kB     00:00 ETA(2/2): freeradius-ld 63% [============-       ] 627 kB/s |  71 kB     00:00 ETA(2/2): freeradius-ld 76% [===============     ] 564 kB/s |  86 kB     00:00 ETA(2/2): freeradius-ldap-3.2.7-1.el9.x86_64.rpm    21 kB/s |  41 kB     00:01    
--------------------------------------------------------------------------------
合計                                             43 kB/s | 113 kB     00:02     
トランザクションを確認しています
トランザクションの確認に成功しました。
トランザクションをテストしています
トランザクションのテストに成功しました。
トランザクションを実行しています
  準備中           :  [=========================                          ] 1/1  準備中           :                                                        1/1 
  scriptletの実行中: cyrus-sasl-2.1.27-21.el9.x86_64                        1/2 
  インストール中   : cyrus-sasl-2.1.27-21.el9. [                          ] 1/2  インストール中   : cyrus-sasl-2.1.27-21.el9. [===                       ] 1/2  インストール中   : cyrus-sasl-2.1.27-21.el9. [=========                 ] 1/2  インストール中   : cyrus-sasl-2.1.27-21.el9. [===============           ] 1/2  インストール中   : cyrus-sasl-2.1.27-21.el9. [===================       ] 1/2  インストール中   : cyrus-sasl-2.1.27-21.el9. [======================    ] 1/2  インストール中   : cyrus-sasl-2.1.27-21.el9. [=======================   ] 1/2  インストール中   : cyrus-sasl-2.1.27-21.el9. [========================  ] 1/2  インストール中   : cyrus-sasl-2.1.27-21.el9. [========================= ] 1/2  インストール中   : cyrus-sasl-2.1.27-21.el9.x86_64                        1/2 
  scriptletの実行中: cyrus-sasl-2.1.27-21.el9.x86_64                        1/2 
  インストール中   : freeradius-ldap-3.2.7-1.e [                          ] 2/2  インストール中   : freeradius-ldap-3.2.7-1.e [=======                   ] 2/2  インストール中   : freeradius-ldap-3.2.7-1.e [===============           ] 2/2  インストール中   : freeradius-ldap-3.2.7-1.e [=======================   ] 2/2  インストール中   : freeradius-ldap-3.2.7-1.e [========================= ] 2/2  インストール中   : freeradius-ldap-3.2.7-1.el9.x86_64                     2/2 
  scriptletの実行中: freeradius-ldap-3.2.7-1.el9.x86_64                     2/2 
  検証中           : cyrus-sasl-2.1.27-21.el9.x86_64                        1/2 
  検証中           : freeradius-ldap-3.2.7-1.el9.x86_64                     2/2 

インストール済み:
  cyrus-sasl-2.1.27-21.el9.x86_64       freeradius-ldap-3.2.7-1.el9.x86_64      

完了しました!

次にLDAP連携用の設定を行います。

設定ファイルは「/etc/raddb/mods-available/ldap」であり、こちらのシンボリックリンクを「/etc/raddb/mods-enable/」配下に作成します。

また、今回は簡易的なテストを行うだけですので、設定値は以下のみを変更しています。

identityバインドするユーザを指定
passwordバインドするユーザのパスワード
base_dnバインドするDNの指定
# cp -p mods-enabled/available/ldap mods-available/ldap.org
# vi /etc/raddb/mods-available/ldap
# diff -u /etc/raddb/mods-available/ldap.org /etc/raddb/mods-available/ldap
--- mods-available/ldap.org     2025-01-31 21:36:50.000000000 +0900
+++ mods-available/ldap 2025-07-16 17:17:47.418370719 +0900
@@ -27,10 +27,12 @@
        #  If using SASL + KRB5 these should be commented out.
 #      identity = 'cn=admin,dc=example,dc=org'
 #      password = mypass
+       identity = 'uid=auth-user,ou=user,dc=example,dc=com'
+       password = password

        #  Unless overridden in another section, the dn from which all
        #  searches will start from.
-       base_dn = 'dc=example,dc=org'
+       base_dn = 'ou=user,dc=example,dc=com'

        #
        #  You can run the 'ldapsearch' command line tool using the

# ln -s /etc/raddb/mods-available/ldap /etc/raddb/mods-enabled/ldap

上記でFreeRADIUSとLDAPの連携設定は完了です。

radiusdをデバックモードで起動し設定に問題がない事を確認します。

# radiusd -X
FreeRADIUS Version 3.2.7
Copyright (C) 1999-2023 The FreeRADIUS server project and contributors
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE
You may redistribute copies of FreeRADIUS under the terms of the
GNU General Public License
For more information about these matters, see the file named COPYRIGHT
Starting - reading configuration files ...
including dictionary file /usr/share/freeradius/dictionary
including dictionary file /usr/share/freeradius/dictionary.dhcp
~ 中略 ~
Listening on auth address * port 1812 bound to server default
Listening on acct address * port 1813 bound to server default
Listening on auth address :: port 1812 bound to server default
Listening on acct address :: port 1813 bound to server default
Listening on auth address 127.0.0.1 port 18120 bound to server inner-tunnel
Listening on proxy address * port 58584
Listening on proxy address :: port 41314
Ready to process requests

「Ready to process requests」と出力されることが確認できました。

FreeRADIUSとLDAPの連携テスト

では実際にLDAPに登録したユーザでFreeRADIUSの認証が出来るかを確認します。radtestコマンドの引数については前回の記事をご参照ください。

# radtest test-user01 password localhost 0 testing123
Sent Access-Request Id 243 from 0.0.0.0:44638 to 127.0.0.1:1812 length 81
        User-Name = "test-user01"
        User-Password = "password"
        NAS-IP-Address = 10.15.1.15
        NAS-Port = 0
        Message-Authenticator = 0x00
        Cleartext-Password = "password"
Received Access-Accept Id 243 from 127.0.0.1:1812 to 127.0.0.1:44638 length 38
        Message-Authenticator = 0x3df5de11e6ea76a739e59f723bbd57d0

「Received Access-Accept」と出力され、無事LDAPのユーザで認証出来ることを確認できました。

まとめ

以上のことから、LDAPサーバさえ準備すればFreeRADIUSとの連携はとても簡単に出来ることが分かったかと思います。

次回は、このRADIUSサーバとVPNサーバを連携し、LDAPユーザを認証情報として利用しVPN接続を行いたいと思います。

お問い合わせ

弊社では様々なサービスを取り扱っております。
詳細はサービス一覧からご覧ください。

お気軽にお問い合わせください。応対時間 9:30-17:30 [ 土・日・祝日除く ]

お問い合わせ