OpenLDAPについて~LDAPで遊ぼう~ 

4月 5日 @ 22:00 ~ 23:00 主催者: shimarisu

資料

スライド 

講演

※音声録音に失敗したため、音声データはありません。

スピーカー

twitterアカウント @sakataz 

LADPという話の前に、認証情報の扱い方について・・・

認証情報(ID、パスワード)の取り扱い、どうしていますか?

  • DBに保存(暗号化は?)
  • まさか設定ファイルに直書き(.htaccess等)
  • もしかして管理者にはパスワードが丸見え?

そんな方々には、何かのヒントがあるかもしれません。

LDAPとは

  • Lightweight Directory Access Protocol
  • 軽量なディレクトリにアクセスするプロトコル
  • TCPです。
  • ポート番号 389(ldap) または、636 SSL (ldaps)
    HTTP(80番)とHTTPS(443番)と似ています。

DBにアクセスするプロトコルといえば

  • オラクル Oracle Net プロトコル(ポート番号:1521)
  • MySQL MySQLプロトコル(ポート番号:3306)
  • PostgreSQL (ポート番号:5432)

⇒データベースによってまちまちなプロトコルが使われている。
JavaのJDBCのように、ドライバで差異を吸収してあげないといけなくなる。
しかし、LDAPはRFC 2251で規定されているためベンダによる差がない。

LDAPの L ってなに?

大昔はDAP (X.500) というプロトコルがあったらしいが、
実装が難しくなったため 軽量(Lightweight)なDAPとしてLDAPが生まれた。
しかしLDAPv3ももはや軽量とは言えないかも。

LDAPの D ってなに?

ディレクトリ(=台帳、名簿)
結論から言うと

  • ID
  • パスワード
  • 名前
  • その他の情報(メール、電話番号、画像、役職など...)
    を蓄積するちょっと変わったデーターベース

ディレクトリのここが変わっている 1

RDBと異なりファイルシステムのような階層構造をもつデータベース

dc = tech └dc = infra-workshop   └ou = users    ├uid = redsasakou    ├uid = yutakakn    ├uid = dozonot    └uid = shimarisu

下から読んでいく。
uid=shimarisu,
ou=users,
dc=infra-workshop,
dc=tech
の部分がDBでいう主キーとなる。

この主キーのことを dn(Distinguished Name :識別名) と呼ぶ。(下の方で詳細説明あり)

ディレクトリのここが変わっている 2

自由にテーブル定義できない!(まじか)
あらかじめ定義されているテーブル(標準スキーマ)を使う
独自スキーマを作成するには国際的な管理機関からオブジェクト識別子(OID)を割り当ててもらう必要がある。

OIDの例:2.16.840.1.113730.3.2.2

ディレクトリのここが変わっている 3

一つのカラムに複数の値を入れることが可能

例)

telephoneNumber:03-1234-5678

telephoneNumber:090-1234-5678

ディレクトリのここが変わっている 4

オブジェクト指向的発想

テーブル(オブジェクトクラス)が階層構造である。

top:オブジェクトクラスの階層ルート抽象クラス 必須属性 objectClass └person: (人) 必須属性は sn,cn  └organizationalPerson:(組織人) オプション属性 title,telephoneNumber等   └inetOrgPerson:(インターネット組織人) オプション属性 mail等

一番上の階層が top になっている。
オプション属性とは、必須ではない属性のこと。

子オブジェクトクラスは親オブジェクトクラスの属性を引き継ぐ。

エントリの例(LDIF形式)

dn: uid=shimarisu,ou=users,dc=infra-workshop,dc=tech ←主キー
objectclass: top
objectclass: person
objectclass: organizationalperson
objectclass: inetorgperson
uid: shimarisu
cn: shimarisu
sn: 嶋
givenname: リス男
telephoneNumber: 03-1234-5678
telephoneNumber: 090-1234-5678
mail: shimarisu@example.com 
userPassword: {SSHA}HwqCeON7VjXJ7KXpqlzsszDwbgACTrCU

この形式は、LDIF(LDAP Data Interchange Format)形式。文字コードはUTF-8。
RDBでいうcsvのようなもの。

属性名にかなり短縮された名前がついている

これだけ覚えればOK

dn= distinguished name:識別名(主キー)
dc = Domain Component
(example.com ⇒ dc=example,dc=com)
o= organization:(組織,会社)
ou = organizationUnit:(部門)
sn= sur neme   :氏
cn= common name:一般の名前

証明書的のサブジェクトと似ています。

userPassword 属性について

userPassword: {SSHA}HwqCeON7VjXJ7KXpqlzsszDwbgACTrCU

OpenLDAPではパスワードは標準でsalt付きSHA-1+Base64で保管される。

SHA-1 ハッシュアルゴリズムは160ビット(20バイト)のハッシュ値を出力
salt(ランダムな値)をつけることで、同じパスワードでも違う値になる。
ハッシュは元には戻せないので、管理者にもパスワードはわからない

Base64はバイナリデータをテキストに変換する。

/usr/sbin/slappasswd コマンドで生成できる。

LDAPをサポートしたサーバーの例

  • ActiveDirectory  基本的にはドメインコントローラーだたLDAPサーバーの機能を持つ
  • OpenLDAP (slapd)
  • OpenDJ(JAVAによる実装、無料ではなくなった?)
  • Sun Identity Manager
  • まだまだある(詳しくはWikiPediaで)

LDAPクライアント(管理ツール)

  • Active DirectoryにはGUIがある(ユーザとコンピュータ)
  • phpLDAPadmin (WebベースのLDAP管理ソフト)
  • Softerra LDAP Browser(無償、参照のみ可能)
  • Softerra LDAP Administrator(有償$250.00~)
    書き込みも可能。
  • OpenLDAP(コマンドライン)

応用例

  • ApacheやnginxのBASIC認証

  • WEBアプリケーションの認証

  • Linuxのユーザー管理

  • アドレス帳として(最近は使われない)

  • Redmineのユーザー管理(オススメ)

ユーザ管理(IDとパスワード)を一元化できる。

Redmineの認証方式をLDAPに設定した例

⇒後半のデモ用の資料でした。

LDAPがコケると

全滅!!!

レプリケーションの仕組みを利用して冗長化できる。
2つ(マスター|スレーブ)のサーバーを見に行くLDAPクライアントもあるが、そうでない場合はロードバランサーのようなものが必要。
更新できるのはマスターのみ

  • slaveは複数保持できる(親1つ、子を複数で冗長化とか)
  • マルチマスターもあり

ここからOpenLDAPの話

OpenLDAPとは

http://www.openldap.org/ 

OpenLDAP Software is an open source implementation of the Lightweight Directory Access Protocol. The suite includes: slapd - stand-alone LDAP daemon (server) libraries implementing the LDAP protocol, and utilities, tools, and sample clients.

オープンソースによるLDAPの実装

  • LDAPサーバー(slapd)
  • LDAPの(C言語の)ライブラリ(←重要!!)
  • LDAPのクライアント(コマンドライン)
    ldapadd(追加)
    ldapmodify(変更)
    ldapdelete(削除)
    ldapsearch(検索)
    をまとめたもの。

現在のバージョンは 2.4.46 Release (2018/03/22)

OpenLDAPの構築

インストールは簡単

sudo apt install ldap-utils sudo apt install slapd

OpenLDAPの設定(LDAPサーバー側)

slapd.confで設定

  • 利用するスキーマの設定
  • AdminユーザのIDとパスワード
  • アクセスコントロール(重要!)
  • インデックス

等を定義する

See slapd.conf(5) for details on configuration options.

OpenLDAPの設定(クライアント側)

ldap.confで設定

\# See ldap.conf(5) for details \# This file should be world readable but not world writable. BASE   dc=infra-workshop,dc=tech URI    ldap://ldap1.infra-workshop.tech ldap://ldap2.infra-workshop.tech

URIに2つのURLが含まれていることに注目。
冗長化構成を、クライアント側で対応することができる。

OpenLDAPの起動

sudo /usr/sbin/slapd

slapdコマンドにはデバッグオプションがある。
起動しない時はデバッグオプション-d 4を付けて実行し原因を調査してみよう。

データの投入

LDIFファイル infra.ldif を用意して

ldapadd -f infra.ldif -D cn=Admin,dc=infra-workshop,dc=tech -W -v -c

デモ 1

上記コマンドの実施デモ

OpenLDAPだけでは機能しない

ユーザー情報(ID,パスワード,名前など)の登録、変更、削除する仕組みが必要。

ユーザー情報は人事システムのデータベースと連携するバッチ。

パスワードは初期パスワードの設定、変更、忘れた場合等にリアルタイムに対応できるWEBアプリ。

LDAPにはなるべく情報を持たないほうが良い(連携が面倒になるし、万一情報が漏れた場合の対策として)
uid,userPassword,cn,sn,givenName,mail くらいで十分ではないか。あとは必要に応じて・・・。

LDAP対応アプリをつくろう

LDAPにアクセスできるライブラリ

  • .net 系だと ADSI(標準)
  • JAVA系だとJNDI(標準)
  • Python ライブラリがある
  • Ruby ライブラリがある
  • PHP ライブラリがある

大抵の言語でLDAPにアクセスできる。しかし痒いところに手が届かない場合も...

そんな時OpenLDAPについているCのライブラリを使うとなんでもできる。

ただし脆弱性には気をつけよう (SQL Injection ならぬ LDAP Injection という攻撃法もある)

コード例

#include <ldap.h> int main ( void ) { LDAP *ld; ld = ldap_init ("ホスト名", 389 ); ldap\_simple\_bind_s( ld, ”ユーザーのDN”, “パスワード”); //バインド(接続) // 処理  (^_^;) bindに成功したら認証成功 ldap_unbind( ld ); //アンバインド return ( 0 ); }

推薦図書

LDAPハンドブック―ディレクトリ・サービス標準プロトコル Amazonの該当リンク 

まとめ

LDAPは認証情報を集中管理するのに大変便利

LDAPでどこまでできるか試してみよう

参加者の声

(Discord 上の発言で、なにか取り上げたいものがありましたら記載お願いします)

  • オブジェクト...。LDAPダンプした時、うまくCSV に書き出したい。。。と思ったのにうまくいかなかったことがあって涙目だった。

    • 確かに普通はcsvには吐き出せないですね。
  • SHAは暗号化じゃないです。ハッシュ化です。

  • × 暗号化 〇ハッシュ化。同一化してはいけない。

  • シード(seed)がないと、全員パスワードがPASSWORDだったらみんな同じハッシュになっちゃう。

  • apache directory studioってのもあるよ!

  • VScode、.ldifにもシンタックスハイライトかかるんですねぇ

  • 参考:userPasswordはあえて{CRYPT}  

  • 参考 OWASPの資料 

  • ADサーバはLinux側からLDAPサーバのように見せることも
    参考リンク 第4回 LDAPによる認証統合 

Q & A

(Discord 上に質問が流れたらピックアップお願いします)

  • Q.userPassword 属性は、SHA2には未対応なんですか?

    • A.現在、未対応のようです。
  • Q.slappasswdコマンドはLinuxのですか?

    • A.もともとはOpenLDAPのコマンド。でも、OpenLDAPがLinuxに吸収されて、デファクトスタンダードになっている、かな?
  • Q.LDAPは運用者側としてメリットありますか?DB使った認証と比べて

    • A.DBでハッシュして持ってもいいと思いますが分かりません。
  • Q.最近のトレンドとしてまだLDAP使われるケース多いですか?(観測範囲で)

    • A.
  • Q.社内システム系=OSログインがあるから、LDAP。インターネット上のWebシステム=DBの採用事例多そう?なイメージですが。

    • A.LDAPは社内システム向けかもしれません
  • Q.単純に登録されてる属性の値を取りたいだけなら LDAP でも良いんでないすかね。LDAPのツリー構造(ディレクトリ)で、登録するデータを表現するしかない制約でも良いよっていう条件で。

    • A.ツリー化されていることにあまり意味はないかと思っています。共通のプロトコル、共通のスキーマであることが重要かも。
  • Q.グループ的な事を頑張ろうとすると、RDBだとめんどいからLDAPなのかと思ってました。

    • A.グループはLDAPでもできるけれども面倒くさいからDBでやってというイメージです。LDAPは認証だけ。