マルチマスタOpenLDAPによるLinuxとRedmineの認証統合

(参考)https://www.openldap.org/doc/admin24/index.html

OpenLDAP基本設定

  1. パッケージ導入
  2. # yum install openldap-servers openldap-clients
  3. DB設定を適用
  4. # cp -p /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG
  5. システム起動設定、手動起動
  6. # systemctl enable slapd
    # systemctl start slapd
    
  7. rootパスワードのハッシュ値を生成
  8. 控えておいて、以降、監視者パスワードを必要とするldifに埋め込む。
    # slappasswd
  9. configデータベースにroot用ハッシュ値を設定
  10. # cat add_rootpw.ldif
    dn: olcDatabase={0}config,cn=config
    changetype: modify
    add: olcRootPW
    olcRootPW: {SSHA}〜
    
    # ldapadd -Y EXTERNAL -H ldapi:// -f ./add_rootpw.ldif
      :
    modifying entry "olcDatabase={0}config,cn=config"
    
  11. BaseDN、管理者DNなどを設定する
  12. # cat basedn.ldif
    #
    # BaseDN, 管理者DN の設定
    #
    dn: olcDatabase={1}monitor,cn=config
    changetype: modify
    replace: olcAccess
    olcAccess: {0}to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" read by dn.base="cn=admin,dc=hoge,dc=local" read by * none
    
    #
    # ベースサフィックス=BaseDN
    #
    dn: olcDatabase={2}hdb,cn=config
    changetype: modify
    replace: olcSuffix
    olcSuffix: dc=hoge,dc=local
    
    #
    # 管理者DN
    #
    dn: olcDatabase={2}hdb,cn=config
    changetype: modify
    replace: olcRootDN
    olcRootDN: cn=admin,dc=hoge,dc=local
    
    #
    # 管理者DN のパスワード
    #
    dn: olcDatabase={2}hdb,cn=config
    changetype: modify
    add: olcRootPW
    olcRootPW: {SSHA}〜
    
    # ldapmodify -x -D cn=config -w 〜 -f ./basedn.ldif
    	:
    modifying entry "olcDatabase={1}monitor,cn=config"
    modifying entry "olcDatabase={2}hdb,cn=config"
    modifying entry "olcDatabase={2}hdb,cn=config"
    modifying entry "olcDatabase={2}hdb,cn=config"
    
  13. 基本ou(PeopleとGroup)を作成
  14. # cat add_ouPeopleGroup.ldif
    #
    # ou, People, Group を追加
    #
    dn: dc=hoge,dc=local
    objectClass: dcObject
    objectClass: organization
    dc: hoge
    o: hoge corporation
    
    dn: ou=People,dc=hoge,dc=local
    objectClass: organizationalUnit
    ou: People
    
    dn: ou=Group,dc=hoge,dc=local
    objectClass: organizationalUnit
    ou: Group
    
    # ldapadd -x -D "cn=admin,dc=hoge,dc=local" -w 〜 -f ./add_ouPeopleGroup.ldif
    	:
    adding new entry "dc=hoge,dc=local"
    adding new entry "ou=People,dc=hoge,dc=local"
    adding new entry "ou=Group,dc=hoge,dc=local"
    
  15. NISスキーマの取り込み(for OS認証)
  16. # ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/cosine.ldif
    	:
    adding new entry "cn=cosine,cn=schema,cn=config"
    # ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/nis.ldif
    	:
    adding new entry "cn=nis,cn=schema,cn=config"
    
  17. 公開鍵格納用スキーマの取り込み(for OS認証)
  18. # yum install openssh-ldap
    
    # ldapadd -Y EXTERNAL -H ldapi:/// -f /usr/share/doc/openssh-ldap-7.4p1/openssh-lpk-openldap.ldif
    	:
    adding new entry "cn=openssh-lpk,cn=schema,cn=config"
    
  19. inetOrgPersonスキーマの取り込み(for Redmine認証)
  20. Redmineが必要とする情報にメールアドレスがあるので、inetOrgPsersonスキーマで定義されているmail属性を利用する。
    # ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/inetorgperson.ldif
    	:
    adding new entry "cn=inetorgperson,cn=schema,cn=config"
    
  21. memberOfモジュールの取り込み(for OS認証, Redmine認証のアクセス制御)
  22. # cat add_memberof.ldif
    #
    # アクセス制御用モジュール追加
    #
    dn: cn=module,cn=config
    objectClass: olcModuleList
    cn: module
    olcModulePath: /usr/lib64/openldap
    olcModuleLoad: memberof
    
    # ldapadd -Y EXTERNAL -H ldapi:/// -f ./add_memberof.ldif
    	:
    adding new entry "cn=module,cn=config"
    
  23. memberOfオーバレイ設定
  24. # cat config_memberof.ldif
    #
    # モジュール memberof の設定
    #
    dn: olcOverlay=memberof,olcDatabase={2}hdb,cn=config
    objectClass: olcMemberOf
    objectClass: olcOverlayConfig
    objectClass: olcConfig
    objectClass: top
    olcOverlay: memberof
    olcMemberOfDangling: ignore
    olcMemberOfRefInt: TRUE
    olcMemberOfGroupOC: groupOfNames
    olcMemberOfMemberAD: member
    olcMemberOfMemberOfAD: memberOf
    
    # ldapadd -Y EXTERNAL -H ldapi:/// -f ./config_memberof.ldif
    	:
    adding new entry "olcOverlay=memberof,olcDatabase={2}hdb,cn=config"
    
  25. phpLDAPadmin管理ユーザを作成
  26. # cat add_phpldapadmin.ldif
    #
    # ユーザ登録(phpldapadmin)
    #
    dn: cn=phpldapadmin,ou=People,dc=hoge,dc=local
    objectClass: top
    objectClass: inetOrgPerson
    sn: phpLDAPadmin管理ユーザ
    mail: dummy_phpldapadmin@hoge.local
    userPassword: {SSHA}〜
    cn: phpldapadmin
    
    # ldapadd -x -D "cn=admin,dc=hoge,dc=local" -W 〜 -f ./add_phpldapadmin.ldif
    	:
    adding new entry "cn=phpldapadmin,ou=People,dc=hoge,dc=local"
    
  27. LDAPアクセス制御
  28. 次のように設定(詳細はコメントを参照)
    # cat acl.ldif
    #
    # ACL
    #
    # --------------
    #
    # 0. パスワードハッシュ値属性については、
    #    本人認証済みの場合のみ、自分のものだけ変更可
    #
    # 1. ou=People 以下のユーザエントリについては、
    #    自身のみ参照でき、
    #    他の認証済みユーザは参照できない
    #
    # 2. 管理者は書き込み可能、その他のユーザは読み取り専用
    #
    # 1つのエントリに対して複数の属性操作をする際に
    # ハイフン行をはさんで列挙する
    #
    dn: olcDatabase={2}hdb,cn=config
    changetype: modify
    add: olcAccess
    olcAccess: {0}to attrs=userPassword
      by dn="cn=admin,dc=hoge,dc=local" write
      by dn="cn=phpldapadmin,ou=People,dc=hoge,dc=local" write
      by self write
      by anonymous auth
      by * none
    -
    add: olcAccess
    olcAccess: {1}to dn.children="ou=People,dc=hoge,dc=local"
      by dn="cn=admin,dc=hoge,dc=local" write
      by dn="cn=phpldapadmin,ou=People,dc=hoge,dc=local" write
      by self read
      by dn.subtree="ou=People,dc=hoge,dc=local" none
      by * read
    -
    add: olcAccess
    olcAccess: {2}to *
      by dn="cn=admin,dc=hoge,dc=local" write
      by dn="cn=phpldapadmin,ou=People,dc=hoge,dc=local" write
      by * read
    
    # ldapmodify -Y EXTERNAL -H ldapi:/// -f ./acl.ldif
    	:
    modifying entry "olcDatabase={2}hdb,cn=config"
    

OpenLDAPパスワードポリシー設定(参考)

ppolicyというオーバレイ機能を利用。

(参考)https://www.openldap.org/doc/admin24/overlays.html#Password%20Policies

(参考)http://arinux.net/?eid=48

が、文字数チェック等がcleartextで格納する場合のみ機能するため、ハッシュ値で格納する一般的な使い方では、この設定はまったく役に立たない。

  1. ou作成
  2. # cat add_ou_policies.ldif
    #
    # パスワードポリシー格納用 ou=policies 追加
    #
    dn: ou=policies,dc=hoge,dc=local
    objectClass: organizationalUnit
    objectClass: top
    ou: policies
    
    # ldapadd -x -D "cn=admin,dc=hoge,dc=local" -W 〜 ./add_ou_policies.ldif
    	:
    adding new entry "ou=policies,dc=hoge,dc=local"
    
  3. パスワードポリシー用スキーマ取り込み
  4. # ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/ppolicy.ldif
    	:
    adding new entry "cn=ppolicy,cn=schema,cn=config"
    
  5. モジュールロード
  6. # cat ModuleLoad_ppolicy.ldif
    #
    # ppolicy モジュールをロードする
    #
    dn: cn=module,cn=config
    objectClass: olcModuleList
    cn: module
    olcModulePath: /usr/lib64/openldap
    olcModuleLoad: ppolicy
    
    # ldapadd -Y EXTERNAL -H ldapi:/// -f ./ModuleLoad_ppolicy.ldif
    	:
    adding new entry "cn=module,cn=config"
    
  7. オーバレイ設定
  8. # cat add_ppolicy_overlay.ldif
    #
    # ppolicy オーバレイ設定
    #
    dn: olcOverlay=ppolicy,olcDatabase={2}hdb,cn=config
    changetype: add
    objectClass: olcPPolicyConfig
    olcOverlay: ppolicy
    olcPPolicyDefault: cn=default,ou=policies,dc=hoge,dc=local
    
    # ldapadd -Y EXTERNAL -H ldapi:/// -f ./add_ppolicy_overlay.ldif
    	:
    adding new entry "olcOverlay=ppolicy,olcDatabase={2}hdb,cn=config"
    
  9. 実ポリシー登録
  10. # cat add_passwd_policies.ldif
    #
    # デフォルトパスワードポリシー追加
    #
    # pwdAllowUserChange, ユーザによる変更を許可
    # pwdAttribute, パスワードハッシュ値格納属性
    # pwdCheckQuality,
    #   チェック動作
    #   1.クライアント側でハッシュ化されて渡ってきた場合は
    #   チェックせずに受け入れる
    # pwdLockout, ロックアウト機能
    # pwdMaxAge, パスワードの有効期限(定期変更強制)、0 で制限なし
    # pwdMinAge, パスワードの N 秒間変更禁止、0 で制限なし
    # pwdMinLength, パスワードの最小文字数
    #
    dn: cn=default,ou=policies,dc=hoge,dc=local
    objectClass: pwdPolicy
    objectClass: person
    objectClass: top
    cn: default
    pwdAllowUserChange: TRUE
    pwdAttribute: userPassword
    pwdCheckQuality: 1
    pwdLockout: FALSE
    pwdMaxAge: 0
    pwdMinAge: 0
    pwdMinLength: 6
    pwdMustChange: FALSE
    pwdSafeModify: FALSE
    sn: dummy value
    
    # ldapadd -x -D "cn=admin,dc=hoge,dc=local" -W 〜 -f ./add_passwd_policies.ldif
    	:
    adding new entry "cn=default,ou=policies,dc=hoge,dc=local"
    

マルチマスタ設定

ここまでを、1号機と2号機のそれぞれで設定実装をしておく。 ここで最後に両機に、syncprovモジュールで同期の設定を行う。

(参考)https://www.openldap.org/doc/admin24/replication.html#N-Way%20Multi-Master

(参考)https://toe.bbtower.co.jp/20160721/130/

  1. slapdの通信を管理LAN側で行うようにする
  2. sysconfigのslapd起動設定ファイル(/etc/sysconfig/slapd)のURLを、次のように修正する(2号機ではserver2mとする)。
    	:
    SLAPD_URLS="ldapi:/// ldap:///"
    	:
    
    	:
    SLAPD_URLS="ldapi:/// ldap://127.0.0.1/ ldap://server1m/"
    	:
    
  3. syncprovモジュールをロードする
  4. # cat ModuleLoad_syncprov.ldif
    #
    # syncprov モジュールをロードする
    #
    dn: cn=module,cn=config
    objectClass: olcModuleList
    cn: module
    olcModulePath: /usr/lib64/openldap
    olcModuleLoad: syncprov
    
    # ldapadd -Y EXTERNAL -H ldapi:// -f ./ModuleLoad_syncprov.ldif
    	:
    adding new entry "cn=module,cn=config"
    
  5. サーバIDをセットする
  6. 管理LAN側ホスト名を指定する。
    # cat set_ServerID.ldif
    #
    # ServerID をセットする
    #
    dn: cn=config
    changetype: modify
    replace: olcServerID
    olcServerID: 1 ldap://server1m/
    olcServerID: 2 ldap://server2m/
    
    # ldapmodify -Y EXTERNAL -H ldapi:/// -f ./set_ServerID.ldif
    	:
    modifying entry "cn=config"
    
  7. 同期設定を入れる
  8. CREDENTIALSのところには、plainな管理者パスワードを記述する。
    # cat set_SyncRepl.ldif
    #
    # 同期設定
    #
    dn: olcOverlay=syncprov,olcDatabase={2}hdb,cn=config
    changetype: add
    objectClass: olcOverlayConfig
    objectClass: olcSyncProvConfig
    olcOverlay: syncprov
    
    dn: olcDatabase={2}hdb,cn=config
    changetype: modify
    add: olcSyncRepl
    olcSyncRepl: rid=001 provider=ldap://server1m/ bindmethod=simple
      binddn="cn=admin,dc=hoge,dc=local"
      credentials=CREDENTIALS searchbase="dc=hoge,dc=local"
      type=refreshAndPersist
      retry="5 5 300 5" timeout=1
    olcSyncRepl: rid=002 provider=ldap://server2m/ bindmethod=simple
      binddn="cn=admin,dc=hoge,dc=local"
      credentials=CREDENTIALS searchbase="dc=hoge,dc=local"
      type=refreshAndPersist
      retry="5 5 300 5" timeout=1
    -
    add: olcMirrorMode
    olcMirrorMode: TRUE
    
    # ldapmodify -Y EXTERNAL -H ldapi:/// -f ./set_SyncRepl.ldif
    	:
    adding new entry "olcOverlay=syncprov,olcDatabase={2}hdb,cn=config"
    modifying entry "olcDatabase={2}hdb,cn=config"
    
  9. slapd再起動
  10. systemctl restart slapd
    
  11. 同期動作の確認(テストユーザ作成)
  12. テストユーザのパスワードハッシュ値は、LDAP管理者とは別のものを生成しておき、それを設定する。
    # cat add_tuser1.ldif
    #
    # ユーザ登録
    # Redmine & Linux
    #
    dn: cn=tuser1,ou=People,dc=hoge,dc=local
    objectClass: top
    objectClass: inetOrgPerson
    objectClass: posixAccount
    sn: テストユーザ
    givenName: 1
    mail: tuser1@hoge.co.jp
    userPassword: {SSHA}〜
    cn: tuser1
    uid: tuser1
    uidNumber: 9991
    gidNumber: 9991
    gecos: test user 1
    homeDirectory: /home/tuser1
    loginShell: /bin/bash
    
    #
    # Linux 向けプライベートグループ
    #
    dn: cn=tuser1,ou=Group,dc=hoge,dc=local
    objectClass: top
    objectClass: posixGroup
    cn: tuser1
    gidNumber: 9991
    
    # ldapadd -x -D "cn=admin,dc=hoge,dc=local" -W 〜 -f ./add_tuser1.ldif
    	:
    adding new entry "cn=tuser1,ou=People,dc=hoge,dc=local"
    adding new entry "cn=tuser1,ou=Group,dc=hoge,dc=local"
    
    しばらくしてから(数秒〜十数秒後)、2号機で確認してみる。
    # ldapserach -LLL -Y EXTERNAL -H ldapi:/// -b 'dc=hoge,dc=com' 'cn=tuser1'
    SASL/EXTERNAL ...
    	:
    dn: cn=tuser1,ou=People,dc=hoge,dc=local
    cn: tuser1
    sn:: 〜
    givneName: 1
    mail: tuser1@hoge.co.jp
    

Linux OS認証設定

従来は、nss、nscd、pamのさまざまな設定ファイルを手動で整えて実装。しかし、最近のRHEL/CentOSは、SSSD(System Security Service Daemon)を使用するようなので、この作法に従う。
  1. パッケージが導入されてることを確認
  2. # yum list installed | grep sssd
    python-sssdconfig.noarch              1.15.2-50.el7_4.11               @updates
    sssd.x86_64                           1.15.2-50.el7_4.11               @updates
    sssd-ad.x86_64                        1.15.2-50.el7_4.11               @updates
    sssd-client.x86_64                    1.15.2-50.el7_4.11               @updates
    sssd-common.x86_64                    1.15.2-50.el7_4.11               @updates
    sssd-common-pac.x86_64                1.15.2-50.el7_4.11               @updates
    sssd-ipa.x86_64                       1.15.2-50.el7_4.11               @updates
    sssd-krb5.x86_64                      1.15.2-50.el7_4.11               @updates
    sssd-krb5-common.x86_64               1.15.2-50.el7_4.11               @updates
    sssd-ldap.x86_64                      1.15.2-50.el7_4.11               @updates
    sssd-proxy.x86_64                     1.15.2-50.el7_4.11               @updates
    
  3. SSSD基本設定
  4. /etc/sssd/sssd.confを次のように設定。 今回sudoに関してはLDAP管理しないことにしたので、services行にはsudoを列挙せず。2号機では、ldap_uri = ldap://server2m。
    [sssd]
    debug_level = 0
    config_file_version = 2
    services = nss, pam, ssh
    domains = default
    
    [domain/default]
    id_provider = ldap
    auth_provider = ldap
    chpass_provider = ldap
    sudo_provider = none
    ldap_uri = ldap://server1m
    ldap_search_base = dc=hoge,dc=local
    ldap_id_use_start_tls = False
    ldap_search_timeout = 3
    ldap_network_timeout = 3
    ldap_opt_timeout = 3
    ldap_enumeration_search_timeout = 60
    ldap_enumeration_refresh_timeout = 300
    ldap_connection_expire_timeout = 600
    entry_cache_timeout = 1200
    cache_credentials = True
    ldap_tls_reqcert = never
    enumerate = True
    
    [nss]
    homedir_substring = /home
    entry_negative_timeout = 20
    entry_cache_nowait_percentage = 50
    
    [pam]
    
    [sudo]
    
    [autofs]
    
    [ssh]
    
    [pac]
    
    # systemctl enable sssd
    # systemctl start sssd
    
  5. 認証をSSSDに変更
  6. 事前に念のためバックアップしつつ。
    authconfig --savebackup=YYYYMMDD
    authconfig --enablesssd --enablesssdauth --enablelocauthorize --disalbeldap --disableldapauth --disableldaptls --update
    
  7. ホームディレクトリ自動作成の設定
  8. # yum list installed | grep mkhomedir
    oddjob-mkhomedir.x86_64               0.31.5-4.el7                     @base
    # authconfig --enablemkhomedir --update
    
  9. LDAPユーザが、OSユーザとして認識されることを確認
  10. # id tuser1
    uid=9991(tuser1) gid=9991(tuser1) groups=9991(tuser1)
    # getent passwd | grep tuser1
    tuser1:*:9991:9991:test user 1:/home/tuser1:/bin/bash
    

OS公開鍵認証の設定

  1. 公開鍵格納
  2. LDAPのtuser1エントリに公開鍵を格納する。
    # cat add_publickey.ldif
    #
    # 公開鍵追加
    #
    changetype: modify
    dn: cn=tuser1,ou=People,dc=hoge,dc=local
    add: objectClass
    objectClass: ldapPublicKey
    -
    add: sshPublicKey
    sshPublicKey: ssh-25519 〜
    
    # ldapmodify -x -D "cn=admin,dc=hoge,dc=local" -W 〜 -f ./add_publickey.ldif
    	:
    modifying entry "cn=tuser1,ou=People,dc=hoge,dc=local"
    
  3. SSSDの公開鍵認証コマンドをsshdに設定
  4. /etc/sshd/sshd_configを次のように修正。server1, server2の両機で実施。
    	:
    #AuthorizedKeyCommand none
    #AuthorizedKeyCommandUser nobody
    	:
    
    	:
    AuthorizedKeyCommand /usr/bin/sss_ssh_authorizedkeys
    AuthorizedKeyCommandUser root
    	:
    
    # systemctl restart sshd
    
    公開鍵でssh接続し成功すると次のような応答に。
    Using username "tuser1".
    Authenticating with public key "tuser1@server1"
    Passphrase for key "tuser1@server1":
    Last login: Mon Jun 1 10:00:00 2099
    [tuser1@server1 ~]$
    

Linux OS認証の冗長化

  1. SSSDの設定
  2. 両サーバの/etc/sssd/sssd.confを次のように設定。

    1号機

    	:
    ldap_uri = ldap://server1m
    	:
    
    	:
    ldap_uri = ldap://server1m, ldap://server2m
    	:
    
    # systemctl restart sssd
    
    2号機
    	:
    ldap_uri = ldap://server2m
    	:
    
    	:
    ldap_uri = ldap://server2m, ldap://server1m
    	:
    
    # systemctl restart sssd
    
  3. 冗長性の動作確認
  4. 1号機でslapdを止め、キャッシュをクリア、sssd再起動し、passwdエントリを引いてみると引ける。
    # systemctl stop slapd
    # sss_cache -d default -UG
    # systemctl restart sssd
    # getent passwd | grep tuser1
    tuser1:*:9991:9991:test user 1:/home/tuser1:/bin/bash
    
    2号機のログを確認すると当該の問い合わせに応答したことがわかる。
    # journalctl -u slapd
    	:
     9月 25 14:30:01 server2 slapd[12693]: slap_client_connect: URI=ldap://server1m/ DN="cn=admin,dc=hoge,dc=local" ldap_sasl_bind_s failed (-1)
     9月 25 14:30:01 server2 slapd[12693]: do_syncrepl: rid=002 rc -1 retrying (4 retries left)
     9月 25 14:30:05 server2 slapd[12693]: conn=4760 fd=13 ACCEPT from IP=192.168.200.11:34550 (IP=192.168.200.12:389)
     9月 25 14:30:05 server2 slapd[12693]: conn=4760 op=0 SRCH base="" scope=0 deref=0 filter="(objectClass=*)"
     9月 25 14:30:05 server2 slapd[12693]: conn=4760 op=0 SRCH attr=* altServer namingContexts supportedControl supportedExtension supportedFeatures supportedLDAPVersion supportedSASLMechanisms domainControllerFunctionality defaultNamingContext lastUSN highestCommittedUSN
     9月 25 14:30:05 server2 slapd[12693]: conn=4760 op=0 SEARCH RESULT tag=101 err=0 nentries=1 text=
     9月 25 14:30:05 server2 slapd[12693]: conn=4760 op=1 SRCH base="dc=hoge,dc=local" scope=2 deref=0 filter="(&(objectClass=posixAccount)(uid=*)(uidNumber=*)(gidNumber=*))"
     9月 25 14:30:05 server2 slapd[12693]: conn=4760 op=1 SRCH attr=objectClass uid userPassword uidNumber gidNumber gecos homeDirectory loginShell krbPrincipalName cn modifyTimestamp modifyTimestamp shadowLastChange shadowMin shadowMax shadowWarning shadowInactive shadowExpire shadowFlag krbLastPwdChange krbPasswordExpiration pwdAttribute authorizedService accountExpires userAccountControl nsAccountLock host loginDisabled loginExpirationTime loginAllowedTimeMap sshPublicKey mail
     9月 25 14:30:05 server2 slapd[12693]: conn=4760 op=1 SEARCH RESULT tag=101 err=0 nentries=5 text=
     9月 25 14:30:05 server2 slapd[12693]: conn=4760 op=2 SRCH base="dc=hoge,dc=local" scope=2 deref=0 filter="(&(objectClass=posixGroup)(cn=*)(&(gidNumber=*)(!(gidNumber=0))))"
     9月 25 14:30:05 server2 slapd[12693]: conn=4760 op=2 SRCH attr=objectClass cn userPassword gidNumber memberuid modifyTimestamp modifyTimestamp
     9月 25 14:30:05 server2 slapd[12693]: conn=4760 op=2 SEARCH RESULT tag=101 err=0 nentries=5 text=
     9月 25 14:30:05 server2 slapd[12693]: conn=4760 op=3 SRCH base="dc=hoge,dc=local" scope=2 deref=0 filter="(&(objectClass=ipService)(cn=*)(ipServicePort=*)(ipServiceProtocol=*))"
     9月 25 14:30:05 server2 slapd[12693]: conn=4760 op=3 SRCH attr=objectClass cn ipServicePort ipServiceProtocol modifyTimestamp
     9月 25 14:30:05 server2 slapd[12693]: conn=4760 op=3 SEARCH RESULT tag=101 err=0 nentries=0 text=
    	:
    
    動作が確認できたら、1号機のslapdを起動しておく。
    # systemctl start slapd
    

Linuxアクセス制御

LDAPに登録されてるユーザすべてが、そのLDAPを引いてるサーバにログインできてはまずいので、必要なユーザが必要なサーバにログインできるようにする。

(参考) https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/6/html/deployment_guide/config-sssd-domain-access

上記の、「11.2.21.1 Simple Access Provider」「11.2.21.2 LDAPアクセスフィルター」のいずれかでアクセス制御ができる。今回は後者のmemberOfモジュールを用いた方法で実装。(Redmineのアクセス制御も同様となりわかりやすい)

  1. tuser2作成
  2. 詳細省略(tuser1同様)
  3. 許可ユーザを列挙するグループ作成
  4. LDAP上にグループLinuxServer1Users、LinuxServer2Usersを作る。あわせて許可するユーザをmemberで列挙しておく。※実運用では、サーバ1台毎のグループではなく、「○○システムサーバ群」や「DBサーバ群」といった具合の粒度でグループを作ることになる。
    # cat add_linuxgroup1.ldif
    #
    # Linux アクセス制御用グループ1
    #
    dn: cn=LinuxServer1Users,ou=Group,dc=hoge,dc=local
    objectclass: top
    objectclass: groupOfNames
    cn: LinuxServer1Users
    description: Members allowed to login to server1
    member: cn=tuser1,ou=People,dc=hoge,dc=local
    
    # ldapadd -x -D "cn=admin,dc=hoge,dc=local" -W 〜 -f ./add_linuxgroup1.ldif
    	:
    adding new entry "cn=LinuxServer1Users,ou=Group,dc=hoge,dc=local"
    
    # cat add_linuxgroup2.ldif
    #
    # Linux アクセス制御用グループ2
    #
    dn: cn=LinuxServer2Users,ou=Group,dc=hoge,dc=local
    objectclass: top
    objectclass: groupOfNames
    cn: LinuxServer2Users
    description: Members allowed to login to server1
    member: cn=tuser2,ou=People,dc=hoge,dc=local
    
    # ldapadd -x -D "cn=admin,dc=hoge,dc=local" -W 〜 -f ./add_linuxgroup2.ldif
    	:
    adding new entry "cn=LinuxServer2Users,ou=Group,dc=hoge,dc=local"
    
  5. SSSDへのフィルタ設定
  6. /etc/sssd/sssd.confの[domain/default]セクションに次を追加しsssdを再起動。2号機には〜cn=LinuxServer2Users,〜。
    access_provider = ldap
    ldap_access_filter = memberOf=cn=LinuxServer1Users,ou=Group,dc=hoge,dc=local
    
    # systemctl restart sssd
    
  7. アクセス制御の動作確認
  8. server1にはtuser1のみ、server2にはtuser2のみログインできる。tuser2がserver1に接続すると、server1に次のような拒否のログが残る。
    # less /var/log/secure
    	:
    Sep 25 15:46:18 server1 sshd[16582]: pam_sss(sshd:auth): authentication success; logname= uid=0 euid=0 tty=ssh ruser= rhost=server2 user=tuser2
    Sep 25 15:46:18 server1 sshd[16582]: pam_sss(sshd:account): Access denied for user tuser2: 6 (Permission denied)
    Sep 25 15:46:18 server1 sshd[16582]: Failed password for tuser2 from 192.168.0.102 port 57998 ssh2
    Sep 25 15:46:18 server1 sshd[16582]: fatal: Access denied for user tuser2 by PAM account configuration [preauth]
    	:
    
    # journalctl -u slapd
    	:
     9月 25 15:46:18 server1 slapd[12693]: conn=4778 op=4 SRCH base="dc=hoge,dc=local" scope=2 deref=0 filter="(&(uid=tuser2)(objectClass=posixAccount)(&(uidNumber=*)(!(uidNumber=0))))"
     9月 25 15:46:18 server1 slapd[12693]: conn=4778 op=4 SRCH attr=objectClass uid userPassword uidNumber gidNumber gecos homeDirectory loginShell krbPrincipalName cn modifyTimestamp modifyTimestamp shadowLastChange shadowMin shadowMax shadowWarning shadowInactive shado wExpire shadowFlag krbLastPwdChange krbPasswordExpiration pwdAttribute authorizedService accountExpires userAccountControl nsAccountLock host loginDisabled loginExpirationTime loginAllowedTimeMap sshPublicKey mail
     9月 25 15:46:18 server1 slapd[12693]: <= bdb_equality_candidates: (uid) not indexed
     9月 25 15:46:18 server1 slapd[12693]: conn=4778 op=4 SEARCH RESULT tag=101 err=0 nentries=1 text=
     9月 25 15:46:18 server1 slapd[12693]: conn=4778 op=5 SRCH base="dc=hoge,dc=local" scope=2 deref=0 filter="(&(memberUid=tuser2)(objectClass=posixGroup)(cn=*)(&(gidNumber=*)(!(gidNumber=0))))"
     9月 25 15:46:18 server1 slapd[12693]: conn=4778 op=5 SRCH attr=objectClass cn userPassword gidNumber modifyTimestamp modifyTimestamp
     9月 25 15:46:18 server1 slapd[12693]: <= bdb_equality_candidates: (memberUid) not indexed
     9月 25 15:46:18 server1 slapd[12693]: conn=4778 op=5 SEARCH RESULT tag=101 err=0 nentries=0 text=
     9月 25 15:46:18 server1 slapd[12693]: conn=4779 fd=29 ACCEPT from IP=192.168.200.11:40776 (IP=192.168.200.11:389)
     9月 25 15:46:18 server1 slapd[12693]: conn=4779 op=0 EXT oid=1.3.6.1.4.1.1466.20037
     9月 25 15:46:18 server1 slapd[12693]: conn=4779 op=0 STARTTLS
     9月 25 15:46:18 server1 slapd[12693]: conn=4779 op=0 RESULT oid= err=0 text=
     9月 25 15:46:18 server1 slapd[12693]: conn=4779 fd=29 TLS established tls_ssf=256 ssf=256
     9月 25 15:46:18 server1 slapd[12693]: conn=4779 op=1 BIND dn="cn=tuser2,ou=People,dc=hoge,dc=local" method=128
     9月 25 15:46:18 server1 slapd[12693]: conn=4779 op=1 BIND dn="cn=tuser2,ou=People,dc=hoge,dc=local" mech=SIMPLE ssf=0
     9月 25 15:46:18 server1 slapd[12693]: conn=4779 op=1 RESULT tag=97 err=0 text=
     9月 25 15:46:18 server1 slapd[12693]: conn=4779 op=2 UNBIND
     9月 25 15:46:18 server1 slapd[12693]: conn=4779 fd=29 closed
     9月 25 15:46:18 server1 slapd[12693]: conn=4778 op=6 SRCH base="cn=tuser2,ou=People,dc=hoge,dc=local" scope=0 deref=0 filter="(&(uid=tuser2)(objectClass=posixAccount)(memberOf=cn=linuxserver1users,ou=group,dc=hoge,dc=local))"
     9月 25 15:46:18 server1 slapd[12693]: conn=4778 op=6 SEARCH RESULT tag=101 err=0 nentries=0 text= 
    	:
    

Redmineアクセス制御

LDAPに登録されてるユーザすべてが、そのLDAPを引いてるRedmineにログインできてはまずいので、必要なユーザが必要なRedmineインスタンスにログインできるようにする。

(参考) http://www.redmine.org/projects/redmine/wiki/RedmineLDAP/23

  1. 許可ユーザを列挙するグループ作成
  2. LDAP上にグループRedmineUsersを作る。あわせて許可するユーザをmemberで列挙しておく。
    # cat add_redminegroup.ldif
    #
    # redmine メンバーを定義するグループを作る
    #
    dn: cn=RedmineUsers,ou=Group,dc=hoge,dc=local
    objectclass: top
    objectclass: groupOfNames
    cn: RedmineUsers
    description: Members allowed to login to redmine
    member: cn=tuser1,ou=People,dc=hoge,dc=local
    
    # ldapadd -x -D "cn=admin,dc=hoge,dc=local" -W 〜 -f ./add_redminegroup.ldif
    	:
    adding new entry "cn=RedmineUsers,ou=Group,dc=hoge,dc=local"
    
  3. Redmine側のLDAP認証設定
  4. 管理者でログインし、管理>LDAP認証と進み、「新しい認証方式」のページで次のように登録する。
    項目備考
    名称ldap_server1適当な名称で
    ホストserver1Redmine稼働サーバで名前解決できること
    ポート389
    アカウントcn=admin,dc=hoge,dc=local
    パスワード********
    検索範囲ou=People,dc=hoge,dc=local
    LDAPフィルタ(&(objectClass=inetOrgPerson)(memberOf=cn=RedmineUsers,ou=Group,dc=hoge,dc=local))
    あわせてユーザを作成(チェックする)
    残念ながら、マルチマスタの複数インスタンスを引くようにRedmine側で冗長設定する方法が見当たらない。(ソースを眺めてみると、「ホスト欄」に複数列挙されたサーバをハンドルするようなことは想定されていないようだ)

    属性
    項目備考
    ログイン名属性cn
    名前属性givenName
    苗字属性sn
    メール属性mail


「OpenLDAPとphpLDAPadminによるLinuxとRedmineの認証基盤」に戻る
2018/10/11 Taikou Yamada (t-yamada _at ceres.dti.ne.jp)