samba_with_ldap.html written by Ryo SHIMIZU
2003/07/21 Ver2.0β: 嘘ドキュメントから一新 & Debianize

0.このドキュメントについて

このドキュメントにおいて、太字でかかれているところは、実際に設定ファイルに書き込む文字列を、 イタリック体でかかれているところは、シェルで入力するコマンドを意味して書いています。
設定ファイルに書き込むっぽいようなことが書いてあっても、そこが太字になっていなければ、それはあくまでも例としてあげているだけのところなので、太字になっているところのみを設定ファイルに記入してください。

また、当たり前ですが、このドキュメントに書かれていることが正しいという保証はまったくありません。よってこのドキュメントに書かれていることを行って何らかの損害が生じても一切の責任を負いません。というか負えません。

1.前提条件

Samba と OpenLDAP を使って ActiveDirectory サーバを構築することによって OS をまたぐ形でのユーザの一元管理が楽に行えるようになります。しかし、現在運用しているサーバの構成を変えて、ActiveDirectory に移行することは非常に困難です。このドキュメントは 1 からサーバを構築することを前提に書かれています。

サーバのホスト名とドメイン名はActiveDirectory を構築する上で重要なパラメータとなります。このドキュメントでは
ドメイン名: testnet
サーバのホスト名: test001
としています。違う名前を使ってサーバを運用する場合は、適宜文章を読み替えて下さい。

2.実行環境

OS: Debian GNU/Linux woody
Samba: Version 2.2.6(セキュリティ上問題があるバージョンです。もしこのバージョンを使う場合はきちんとパッチを当ててからにしましょう)

3.前準備

システムの構築に必要なパッケージをインストール

このシステムに必要なパッケージの大部分は雑誌に収録されているインストール CD に含まれていないものが多いので、インターネットに接続されたサーバを使うことを推奨します。

必要なパッケージは以下のものです。


slapd を apt-get でインストールすると、LDAP の dc名や管理者となる rootdn の cn 名とパスワードの設定 debconf を行えます。このドキュメントでは
dc=test,dc=com
rootdn: cn=admin,dc=test,dc=com
rootdnのパスワード: rootroot
として話を進めます。

dc や rootdn などの説明は4章にあるので参考にして下さい。


Samba のインストール

LDAP に対応させるため、ソースからのコンパイルをします。
Samba-2.2.6 の場合

configure スクリプトで LDAP 対応を指定。

./configure --with-pam --with-ldapsam --with-syslog
で、LDAP に対応する。
あとは普通に make;make install

configure スクリプトでインストール先を指定しなければ、/usr/local/samba 以下にインストールされます。
また、smb.conf は /usr/local/samba/lib/ に設置します。

4. 運営ポリシー

LDAP は、その情報を階層構造で保持します。一番下の階層には、個体(ユーザなど)の情報があります。

DNS の階層構造と似たようなものだと思ってください。
DNS の階層構造には「ルート」となる起点があります。LDAP にも同様に起点を指定してやる必要があります。

LDAP での階層構造の区切りには「 dc 」という文字を使用します。DNS において「 . 」を使うのとほぼ同じ意味を持ちます。
よって、管理したいグループの名前として dc=test,dc=com のような感じで指定することができます。

※ここでの com は DNS における .com とはまったく無関係です。test.com は実際に予約されているドメインですが、 LDAP で dc=test,dc=com という名前を使うことにまったく問題はありません。

dc=test,dc=com という階層のしたにさらに階層を作ることも可能です。
その場合は「 ou=hoge 」という階層の指定をすることにより、hoge というグループを dc=test,dc=com のしたに作ることができます。
hoge グループを絶対表記する場合は「 ou=hoge,dc=test,dc=com 」という指定の仕方になります。


今回の Samba with LDAP の設定の仕方はもっとも単純な構造で構成します。
分かりやすいように、dc=test,dc=com を唯一のグループとし、その下にすべての情報を格納します。

OpenLDAP では、通信内容を暗号化するために SSL を使用することが可能ですが、LDAPを構成する要素が増えれば増える程、問題が発生した際に、問題の所在を明らかにすることが難しくなるため今回は SSL を使いません。


5. LDAP の情報の形

LDAP は最終的にユーザやグループなどの情報を保持することを目的としています。
ユーザの情報一つとっても、UNIX における UID や パスワードなど保持すべき情報は
多く存在します。
LDAP において、あるひとつのデータ(例えばユーザ hoge のデータ)を指すための識別子として dn というものがあります。 また、あるユーザを示すために cn(common name)というパラメータを用いることができます。
dc と同じように、「 cn=hoge 」という指定の仕方をします。
cn=hoge,dc=test,dc=com という指定は dc=test,dc=com に属す、ある個体 hoge を指すことになります。

hoge が UNIX ユーザであった場合、hoge の属性として UID , パスワード等が存在します。
その属性のことを「 attribute 」といいます。この attribute は、schema と呼ばれるものによって定義されます。

LDAP のパッケージをインストールすると、スキーマも同時にインストールされるので、スキーマの細かい内容について今回は特に意識する必要はありません。


6. LDAP サーバの設定

LDAP 周りの設定

LDAP サーバの挙動を決めるのは /etc/ldap/slapd.conf です。

まずは、Samba 用のスキーマを読み込むように指定します。
Samba のソースを展開したディレクトリ中に /PATH/TO/SAMBA_SOURCE/example/LDAP/samba.schema というファイルがあるので、それを /etc/ldap/schema/ にコピーします。

slapd.conf の最初の方にある、include で始まる行がスキーマ読み込みの指定の部分です。
他の行を真似し
include /etc/ldap/schema/samba.schema
と指定すれば、Samba 用のスキーマが適用されます。

LDAP データベースはデフォルトでは /var/lib/ldap 以下に保存されるように設定されています。
この設定で特に問題がないので、このままにします。


replogfile で始まる行は LDAP のセカンダリサーバを設ける際に必要な設定です。ここでは必要ないのでコメントアウトします。また、設定ファイルの一番最後にある Roming から始まる設定ブロックも必要ないのですべてコメントアウトします。


LDAPに登録されているユーザから LDAP にアクセスがあった場合に、自分の設定を書き換えられるように、また、LDAP における管理者からのアクセスの場合はすべての処理(読み書き)を許す、ということを設定するために、以下の内容を slapd.conf に追加します。

access to attribute=userPassword
by self write
by dn="cn=admin,dc=test,dc=com" write
by anonymous auth
by * none


access to *
by dn="cn=admin,dc=test,dc=com" write
by self write
by * read



管理するグループを指定するために
suffix
で始まる行を変更します。
今回は dc=test,dc=com のグループしか用いないため

suffix "dc=test,dc=com"

と指定します。

次に、LDAP における管理者を指定するために
rootdn
で始まる行を変更します。
これは UNIX の管理者とは関係なく、LDAP での個体表記(dn) cn=hoge,dc=test,dc=com の形で指定します。

rootdn "cn=admin,dc=test,dc=com"

次に、管理者ユーザのパスワードを決定するために
rootpw
で始まる行を変更します。
パスワードは rootroot にします。セキュアでない書き方としては、設定ファイルに rootdn のパスワードを平文で記述します。

rootpw "rootroot"

MD5 で暗号化されたパスワードを設定ファイルに書く方法もあります。この方法をとれば、万が一設定ファイルを第三者に見られたとしても、容易にパスワードを知ることはできません。
slapd パッケージをインストールすると、/usr/sbin/slappasswd というコマンドも同時にインストールされます。
slappasswd -s パスワード -h {MD5}
とコマンドすれば、slapd.conf に書くべき文字列がそのままでてきます。
slappasswd -s rootroot -h {MD5}

その文字列を
rootpw {MD5}tLja9LjqnTlWhxnh4yAHbw==
のように設定ファイルに書き込むことで、平文のパスワードをそのまま書くことを回避できます。


変更点はこれだけです。編集した設定ファイルの最終的な形はこのようになります。



LDAP サーバの起動、停止、再起動

/etc/rc.d/init.d/ldap
というスクリプトがあり、通常の init.d スクリプトと使い方は同じです。
引数: start , stop , restart



LDAP クライアントとしての設定

LDAP サーバになるマシンは同時に LDAP クライアントにもなります。
ここでは LDAP クライアントとして必要な情報を設定します。

まず LDAP サーバのホスト名を指定するために /etc/ldap.conf を編集します。
URI から始まる行を
URL ldap://localhost
とします。これで LDAP サーバへの接続に必要な情報の設定は終了です。

次に LDAP サーバにアクセスし、情報を取り出すための設定をします。
/etc/libnss-ldap.conf の
rootbinddn から始まる行を
rootbinddn "cn=admin,dc=test,dc=com"
とします。
次に /etc/libnss-ldap.conf のパーミッションを 644 に変えます。
# chmod 644 /etc/libnss-ldap.conf

この作業で LDAP クライアントとしての設定は終わりです。

8. NSS および認証システム(PAM)の設定

Unix では、コアの部分の設定(ユーザ、名前解決など)がどこに保持されているかを動的にし、システムをより柔軟に動かすための NSS(Name Service Switch)という機構があります。
普通のシステムではユーザ情報は /etc/passwd というファイルを使って行っていますが、LDAP にユーザ情報を格納してある場合 LDAP サーバからその情報を取り寄せなければいけません。 よって NSS の設定を変えてやる必要があります。

/etc/nsswitch.conf にその設定は書かれています。今回 LDAP で管理する情報はユーザ情報のみなので、ユーザ情報に関する部分の設定を変えます。
おそらくデフォルトでは
passwd compat
となっているはずです。compat というパラメータは /etc/passwd と NIS の連携を使うための設定です。

LDAP をユーザ情報のデータベースとして使うには

passwd ldap files

と書くことで実現できます。nsswitch.conf は
サービス パラメータ
という形で記述されており、パラメータに複数与えられた場合は、書かれた順で処理を行います。つまり
passwd ldap files
と書いた場合は、まず LDAP サーバでユーザ情報を取得しようとし、それに失敗した場合は /etc/passwd を見に行くという処理の流れになります。

/usr/share/doc/libnss-ldap/examples/nsswitch.ldap というファイルに LDAP を用いる場合の nsswitch.conf の雛形があります。既存の /etc/nsswitch.conf の編集が面倒くさい場合はこれをコピーしてもいいでしょう。
ただし、
host
から始まる行は
host files dns
に書き換えて下さい。そうしないと DNS が無いネットワーク構成においてネットワークの名前解決ができなくなってしまいます。
7. 既存情報の LDAP への移行

/etc/passwd などに登録されているシステムの既存の情報を LDAP に反映させます。

/etc/passwd , /etc/group などの情報をLDAP に登録するには、MigrationTools を使います。MigrationTools は /usr/share/migrationtools ディレクトリ以下にある Perl スクリプト群です。

MigrationTools で共通に必要となる LDAP の設定(dc=test,dc=com など)を migrate_common.ph において定義する必要があります。
変数として宣言されている

$DEFAULT_MAIL_HOST
$DEFAULT_BASE
$DEFAULT_MAIL_DOMAIN

の3つに自分の環境にあった文字列を代入することで、自分の環境が 反映された形で、ユーザ情報の LDAP への移行を行うことができる。 今回の場合は、
$DEFAULT_MAIL_HOST="";
$DEFAULT_BASE="dc=test,dc=com";
$DEFAULT_MAIL_DOMAIN="";
となります。
MigrationTools を使ってユーザ情報を LDAP に登録すると、uid=hoge,ou=People,dc=test,dc=com という形になってしまいます。
僕の好みで ou=People というのを無くしたかったので、MigrationTools をちょっとだけ書き換えました。

46行目の
$NAMINGCONTEXT{'passwd'} = "ou=People";
となっている行をコメントアウトします。
また同じく 59行目もコメントアウトします。これで ou=People がない形でユーザ情報を LDAP に格納できます。

/etc/passwd を情報源とし、ユーザデータを移行するには
/usr/share/migrationtools/migrate_passwd.pl /etc/passwd >user.ldif
とコマンドします。そうするとカレントディレクトリに user.ldif というファイルができています。そのファイルには LDIF 形式で LDAP 情報が書き込まれています。
LDIF 形式とは
パラメータ: 値
という単純な形で書かれている LDAP の情報を保持するフォーマットのことです。基本的には LDAP に登録されているユーザの情報を見るときは LDIF 形式で見るので、この形式に慣れておくと楽です。

LDAP サーバがきちんと認証を行っているかどうかをチェックするために、あらかじめテスト用のユーザを作っておくと便利です。
上記の migrate_passwd.pl を実行する前に、テスト用のユーザ情報を /etc/passwd に登録しておきます。
useradd test_user
paswd test_user
テスト用ユーザのパスワードを適当に決める


テスト用のユーザを含んだすべてのユーザ情報を LDAP に登録する。
テスト用のユーザの情報を /etc/passwd を消す。
userdel test_user
この作業を行うと、テスト用のユーザである test_user は LDAP データベースにしかユーザ情報がない状態になります。ここで test_user としてシステムにログインできれば、LDAP の動作としては完璧です。
ここまでできていれば、LDAP サーバの設定、動作にはまったく問題無いことが確認できます。
もしうまく行かない場合は、一度システムをリブートしてみてください。リブート後もうまく行かない場合は OpenLDAP の設定をどこか間違っています。


MigrationTools によって既存のユーザの情報を LDIF 形式のテキストファイルにすることができたので、そのファイルを使って LDAP サーバに実際にユーザ情報を登録します。

# ldapadd -x -W -D "cn=admin,dc=hri,dc=com" -f user.ldif

とすることで簡単に LDIF 形式で書かれたテキストファイルを利用して LDAP サーバに情報を登録することができます。

MigrationTools は LDAP のみに使われることを想定して作ってあるので、Samba との連動を視野に入れていません。このツールによって LDAP に登録されたユーザが Samba にアクセスすることはできません。
これが1章で「1からサーバを構築する」で書いた理由です。既存ユーザをそのまま ActiveDirectory のユーザとして移行することは MigrationTools を改造しないとできません。
"Samba のユーザである" という情報を含んだ形でユーザを登録する場合は 後述するsmbldap-useradd.pl によってユーザ登録を行わなければなりません。


8. Samba の設定

/usr/local/samba/lib/smb.conf の内容は以下の通りにします。

===LDAP 対応 smb.conf===

# Global parameters
[global]
coding system = euc
client code page = 932
workgroup = TEST
server string = %L: Samba %v on %h
security = USER
encrypt passwords = Yes
update encrypted = Yes
unix password sync = Yes
#allow hosts = 192.168.10.0/255.255.255.0
passwd program = /usr/sbin/smbldap-passwd.pl -o %u
passwd chat = *New* %n\n *Retype* %n\n *success*
log file = /var/log/samba/log.%m
max log size = 50
deadtime = 15
read size = 65536
socket options = TCP_NODELAY SO_RCVBUF=8192 SO_SNDBUF=8192
add user script = /usr/sbin/smbldap-useradd.pl -m -a %u
domain logons = Yes
os level = 65
domain master = Yes
domain admin group = admin
preferred master = True
dns proxy = No
wins support = Yes
dos filetimes = Yes
dos filetime resolution = Yes

logon home = /var/samba/profiles/%U
logon path = /var/samba/profiles/%U

#LDAP に関する必要項目
ldap server = 192.168.10.41
ldap port = 389
ldap suffix = "dc=test,dc=com"

ldap admin dn = "cn=admin,dc=test,dc=com"
ldap filter="(&(uid=%u)(objectClass=sambaAccount))"
ldap ssl = no


[homes]
comment = %U's Home Directory
writeable = Yes
browseable = No

[NETLOGON]
comment = Script for Domain Logon
path = /var/samba/netlogon
admin users = root
write list = root
guest ok = Yes

[profiles]
path=/var/samba/profiles/%U/%m
writeable = yes
browseable = no
create mode = 0600
directory mode = 0700


===smb.conf 終わり ===


また、Samba に対して、LDAP 管理者のパスワードを教えておく必要があるので、以下のコマンドを実行します。

/usr/local/samba/bin/smbpasswd -w 管理者のパスワード

今回は、管理者のパスワードが rootroot なので、実際には

/usr/local/samba/bin/smbpasswd -w rootroot

となります。

9. smbldap ツールの使い方

Samba-2.2.6 には、LDAP の情報の操作、作成を行うことができるフロントエンド的なツールが多く付属しています。

このツールは Perl で記述されており、LDAP の複雑な手順をユーザが意識すること無く、ユーザの追加等を簡単に行えるように設計されています。
samba-2.2.6/examples/LDAP/smbldap-tools/ ディレクトリに、そのツール群はインストールされます。

MigrationTools のときと同様、管理する LDAP の設定(dc を何にするか等) を、このツールで作る LDAP 情報に採り入れるために smbldap_conf.pm というファイルを編集する必要があります。
今回の環境に合わせた設定としては、

$UID_START = 1000;
$GID_START = 1000;
$slaveLDAP = "192.168.0.2";
$masterLDAP = "192.168.0.1";
$suffix = "dc=test,dc=com";
$usersou=''
$usersdn = "$suffix";
$computersou = q(TEST);
$scope = "sub";
$binddn = "cn=admin,dc=test,dc=com";
$bindpasswd = "rootroot";
$_userLoginShell = q(/bin/bash);
$_userHomePrefix = q(/home/);
$_userGecos = q(System User);
$_userSmbHome = q(\\\\test001\\homes);
$_userProfile = q(\\\\test001\\profiles\\);
$_userHomeDrive = q(z:);


のようになります。

samba-2.2.6/examples/LDAP/smbldap-tools/ にインストールされたままだと使い勝手が悪いので、これらのツールを /usr/sbin/ にコピーします。
サフィックスが .pl のファイルはそのままコピーします。
#cp samba-2.2.6/examples/LDAP/smbldap-tools/*.pl /usr/sbin

サフィックスが .pm のファイルはモジュールとなるので、Perl のモジュールがインストールされているディレクトリにコピーします。

#cp samba-2.2.6/examples/LDAP/smbldap-tools/*.pm /usr/lib/perl5/5.6.1

これで、 /usr/sbin にパスが通っていれば、このツール群を簡単に実行することができます。
Samba に付属する LDAP フロントエンド smbldap ツールの中で良く使うものの使い方を説明します。
基本的にはどのスクリプトも
-?
という引数を与えることで、簡単な使い方のヘルプが出て来ます。



smbldap-populate.pl

Active Directory の管理上、あると便利な管理用 dn などの作成を行います。
引数は特に必要ありません。


smbldap-useradd.pl

ユーザを追加するためのスクリプトです。通常の useradd プログラムと同様の挙動をします。
ここでの特殊なオプションは、
-m : ユーザのホームディレクトリを作る。
-a : 追加するユーザが Samba にアクセスすることを許可する。
-w : ActiveDirectory に参加を許すマシンを登録する

普通は、ユーザを追加する際、ホームディレクトリを設け、Samba に参加させると思うので
-m -a オプションは常に指定しておくものです。

ユーザ hoge を追加し、/home/hoge を作成し、hoge の Samba へのアクセスを許す場合は
#smbldap-useradd.pl -a -m hoge

また、ActiveDirectory に参加させるマシンを登録するには # smbldap-useradd.pl -w NETBIOS名
とします。


smbldap-passwd.pl

ユーザのパスワードを変更するためのスクリプトです。通常の passwd プログラムと同様の挙動をします。
引数にユーザ名をとりますが、引数が無かった場合、実行したユーザのパスワードを変更します。


smbldap-usermod.pl

ユーザの情報を変更するためのスクリプトです。
引数としてオプションと、最後にユーザ名をとります。
ユーザ hoge のシェルを変更する場合は
#smbldap-usermod.pl -s /bin/bash hoge


smbldap-groupadd.pl

グループを追加するためのスクリプトです。
引数としてグループの名前をとります。
グループ samba-users を追加する場合は
#smbldap-groupadd.pl samba-users
となります。

特定の複数ユーザを、ひとつのグループにまとめたい場合は、smbldap-groupadd.pl と smbldap-usermod.pl を使うことで実現できます。

#smbldap-groupadd.pl samba-users
samba-users というグループを追加

samba1 ,samba2 ,samba3 というユーザを samba-users に属させる場合
#smbldap-usermod.pl -G samba-users,samba1 samba1
#smbldap-usermod.pl -G samba-users,samba2 samba2
#smbldap-usermod.pl -G samba-users,samba3 samba3

とやることで、samba1 というユーザは samba-users と samba1 というグループに属すことになります。



smbldap-usershow.pl

ユーザの情報を確認するためのスクリプトです。
ユーザ名を引数にとり、そのユーザの LDAP 情報を LDIF 形式で出力します。

10. Windows からのドメイン参加のための設定

Windows マシンからのドメインログオンを行うために LDAP データベース上に必要なものは

1. Windows マシンのホスト名 のアカウント
2. Windows のログイン画面に入力した、ユーザ情報。

です。
1. は正確には Windows マシンのホスト名に「 $ 」が最後についたもの、になります。
Windows のホスト名が win だった場合、LDAP には win$ というユーザが存在している必要があります。

Windows からのドメイン参加の操作をすると、LDAP に上記のアカウントは作成されますが、このままではWindows マシンはドメインに参加することができません。

win$ の attribute に「 domain 」というものがあります。この attribute に、参加させるドメインを格納する必要があります。

やり方は少々面倒ですが、以下のとおりになります。

smbldap-usershow.pl win$ > win.ldif
を実行。win.ldif というファイルでできていて、その中身はテキストで、LDIF というフォーマットになっています。
win.ldif の
domain:
と空になっている domain attribute に TEST を入力してやります。

domain: TEST

その他は変更点はないので、他の行は一切いじらないでください。

変更が終わったら、ファイルを保存します。
以下のコマンドを実行して、この変更を LDAP データベースに反映させます。

#ldapmodify -x -W -D "cn=root,dc=test,dc=com" -f win.ldif
ENTER LDAP PASSWORD (rootroot と入力)

これで先程の変更が LDAP に反映されます。

もう一度 Windows からドメインログオンの操作をしてやれば今度はドメインに参加することができます。


11. LDAP のスレーブサーバのための設定

マスタとしている LDAP サーバのデータベースに変更があった場合はその変更をファイルとして保存し、それをそのままスレーブ側のサーバに普通の LDAP のアクセスとして送信します。

この作業によってマスタとスレーブの情報の同期を取ることができます。

この作業を行うのが、slurpd というデーモンです。slapd.conf の中に
replogfile
という文字列があった場合、そのサーバは情報を送信する側になるので、/etc/init.d/ldap スクリプトを用いた場合、自動的に slurpd が起動されます。

replica というセクションで、マスタサーバの LDAP データベースの変更を伝える相手(LDAP サーバ)を指定します。
ここでは、スレーブサーバのホスト名、スレーブサーバに変更伝えるとき、どのユーザ権限でアクセスするか、接続の方法はどうするか、また、アクセスするときのパスワードを指定しておきます。

スレーブサーバのホストネームが test002 であったとすると、マスタ側 のslapd.conf に
replogfile /var/lib/ldap/replog

replica host=test002:389
binddn="cn=root,dc=test,dc=com"
suffix="dc=test,dc=com"
bindmethod=simple credentials=rootroot


を追加。

スレーブ側の slapd.conf に

rootdn "cn=root,dc=test,dc=com"
rootpw rootroot
updatedn "cn=root,dc=test,dc=com"
updateref ldap://test001/dc=test,dc=com

を追加。
rootdn は、スレーブサーバにおける管理者権限の dn。rootpw はその dn のパスワード。
updatedn は、スレーブサーバ内のデータベースの変更を許すユーザを示し、これはマスタの slapd.conf で binddn として設定した dn と一致していなければいけません。
updateref はスレーブが更新要求を受け付けたときに返す URL を定義します。


もしマスタ側の LDAP サーバのデータベースに変更が加えられると、その変更は replogfile で指定したファイルにいったん書き込まれ、その後 スレーブ側の LDAP サーバに送信されます。
「その後」と書きましたが、この作業は一瞬です。replogfile のサイズが 0 以外の場面はなかなか見られないはずです。