Debian boxのユーザ認証をLDAPで一元化してみた。
注意:無保証。自分用のメモで誤りや抜けが多いし、あくまで隔離されたネット ワークでの実験で、公開されたネットワークでの運用に耐える設定ではない。
条件等
前提:
-
ドメインはexample.com
- 既にLDAPサーバが立っている(xxx.xxx.xxx.xxx)
- ベースはdc=example,dc=com
- 管理者はcn=admin,dc=example,dc=com (cn=manager,dc=example,dc=comのほうがよかったかもしれない)
- 次のいずれかを満たすユーザにloginを許す:
- LDAPデータベース上にアカウント情報がある
- そのマシンにローカルなUnixアカウントがある(管理用のアカウントなど)
大まかにいって、次の設定をすればよいらしい。
-
パッケージ
- libnss-ldap
- libpam-ldap
- nscd(パフォーマンス向上のため)
-
/etc/nsswitch.conf
passwd, group, shadowの各エントリにcompatに加えてldapを指定
-
/etc/libnss-ldap.conf
base, uri, ldap_version, rootbinddnなどを設定
-
/etc/pam_ldap.conf
-
LDAPサーバのURIを設定する
今回は別のホストでLDAPサーバが動いており、またSSLはまだ使っていない ので、スキームはldapiではなくldapとする。
-
照会時にLDAPにアクセスするアカウントを指定する (cn=manager,dc=example,dc=com)
-
-
/etc/pam.d/common-*
-
pam_ldap.soをsufficientとして追加
LDAPで認証できるようにする。
-
pam_unix.soをrequiredからsufficientに変更
Unixアカウントを必須ではなく任意にする。
-
-
サービスアプリケーションごとの設定
- さしあたってsshdとSamba
OSのセットアップ
libnss-ldapをインストールするとReccomends:にあるlibpam-ldapとnscdもインス トールされる。
% sudo apt-get install libnss-ldap
設定を直したければ、いつでもdpkg-reconfigure libnss-ldapで再設定できる。
libnss-ldapのインストール
LDAP server URI:
-ldapi:///
+ldap://xxx.xxx.xxx.xxx/
Distinguished name of the search base
-dc=example,dc=net
-dc=example,dc=com
LDAP version to use:
3
LDAP database require login?
No
Special LDAP privileges for root?
Yes
Make the configuration file readable/writable by its owner only?
-No
+Yes
LDAP account for root:
-cn=manager,dc=example,dc=net
+cn=admin,dc=example,dc=com
LDAP root account password
xxx
libpam-ldapのインストール
LDAP server URI:
-ldapi:///
+ldap://xxx.xxx.xxx.xxx/
Distinguished name of the search base:
-dc=example,dc=net
+dc=example,dc=com
LDAP version to use:
3
Make local root Database admin?
Yes
LDAP database require login?
No
LDAP account for root:
-cn=manager,dc=example,dc=net
+cn=admin,dc=example,dc=com
LDAP root account password
xxx
Local crypt to use when changing passwords
crypt
/etc/nsswitch.conf
/etc/nsswitch.confを編集し、passwd, group, shadowの各エントリにldapを追加 する。
--- a/nsswitch.conf
+++ b/nsswitch.conf
@@ -4,9 +4,9 @@
# If you have the `glibc-doc-reference' and `info' packages installed, try:
# `info libc "Name Service Switch"' for information about this file.
-passwd: compat
-group: compat
-shadow: compat
+passwd: compat ldap
+group: compat ldap
+shadow: compat ldap
hosts: files dns
networks: files
/etc/pam.d/common-*
/etc/pam.d/common-*を書き換える。順序に注意。 login時に~がない場合は作成するよう、sessionでpam_mkhomedir.soを指定。
--- a/pam.d/common-account
+++ b/pam.d/common-account
@@ -6,4 +6,5 @@
# the central access policy for use on the system. The default is to
# only deny service to users whose accounts are expired in /etc/shadow.
#
+account sufficient pam_ldap.so
account required pam_unix.so
--- a/pam.d/common-auth
+++ b/pam.d/common-auth
@@ -7,4 +7,5 @@
# (e.g., /etc/shadow, LDAP, Kerberos, etc.). The default is to use the
# traditional Unix authentication mechanisms.
#
-auth required pam_unix.so nullok_secure
+auth sufficient pam_ldap.so use_first_pass
+auth sufficient pam_unix.so nullok_secure
--- a/pam.d/common-password
+++ b/pam.d/common-password
@@ -21,7 +21,8 @@
#
# See the pam_unix manpage for other options.
+password sufficient pam_ldap.so
password required pam_unix.so nullok obscure md5
# Alternate strength checking for password. Note that this
# requires the libpam-cracklib package to be installed.
--- a/pam.d/common-session
+++ b/pam.d/common-session
@@ -6,4 +6,6 @@
# at the start and end of sessions of *any* kind (both interactive and
# non-interactive). The default is pam_unix.
#
+session required pam_mkhomedir.so skel=/etc/skel/ umask=0022
+session sufficient pam_ldap.so
session required pam_unix.so
設定をチェック
% grep -v '^#\|^$' /etc/pam_ldap.conf
base dc=example,dc=com
uri ldap://xxx.xxx.xxx.xxx/
ldap_version 3
rootbinddn cn=admin,dc=example,dc=com
pam_password crypt
% grep -v '^#\|^$' /etc/libnss-ldap.conf
base dc=example,dc=com
uri ldap://xxx.xxx.xxx.xxx/
ldap_version 3
rootbinddn cn=admin,dc=example,dc=com
% sudo cat /etc/libnss-ldap.secret
xxx
% sudo cat /etc/pam_ldap.secret
xxx
% (cd /etc/pam.d; grep -v '^#\|^$' common-*; cd -)
common-account: account sufficient pam_ldap.so
common-account: account required pam_unix.so
common-auth: auth sufficient pam_ldap.so use_first_pass
common-auth: auth sufficient pam_unix.so nullok_secure
common-password:password sufficient pam_ldap.so
common-password:password required pam_unix.so nullok obscure md5
common-session: session required pam_mkhomedir.so skel=/etc/skel/ umask=0022
common-session: session sufficient pam_ldap.so
common-session: session required pam_unix.so
テスト
うまくいかない場合(ホームディレクトリやシェルがない):
hostname% login: jdoe
password:
No directory, logging in with HOME=/
Cannot execute /usr/bin/zsh: No such file or directory
hostname% login:
うまくいった場合:
hostname% login: jdoe
password:
hostname%
注意点:
-
ユーザが使うシェルなどはあらかじめ用意しておくこと。
-
PAMの設定ファイルの記述は順序に注意。例えばpam_mkhomedir.soは pam_ldap.so やpam_unix.soに先立って書いておかないと、HOMEがないまま login することになる。
うまくいかないときは
% sudo tail /var/log/auth.log
して確認。
資料
- PAM (Pluggable Authentication Modules)
http://www.linux.or.jp/JF/JFdocs/User-Authentication-HOWTO/pam.html
日本語でPAMの概要を把握するときに。
- The Linux-PAM System Administrators’ Guide
http://www.kernel.org/pub/linux/libs/pam/Linux-PAM-html/Linux-PAM_SAG.html
本家。
- LDAP/PAM - Debian Wiki
http://wiki.debian.org/LDAP/PAM
Debianでの設定ファイルの配置などが参考になる。
OpenSSHのLDAP認証
注意:UsePAMを有効にすればPAMを使うようになるのだけど、PAMを使うというこ とはそれが抜け道にもなりかねないので、要注意。(せっかくパスワード認証を 殺していても、PAMの参照先が緩ければ意味がない。)
公開鍵認証をするにはパッチを当てる必要があるらしいので、とりあえずパスワー ド認証で実験。安全なネットワークでない限りやってはいけない。
% sudo vi /etc/ssh/sshd.conf
...
% sudo cat /etc/ssh/sshd.conf
...
PermitEmptyPassword no
...
ChallengeResponseAuthentication yes
...
PasswordAuthentication yes
...
UsePAM yes
...
%
% sudo /etc/init.d/ssh restart
...
%
注意点:
気づきにくい落とし穴がある。
-
ChallengeResponseAuthentication yes
-
PermitEmptyPassword no
参考:
openssh-server: Problem with pam_setcred() call
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=315040#10
Problem with “pam_setcred(): Permission denied” error message and normal login fixed by switching
PermitEmptyPassword yes
in /etc/ssh/sshd_config to
PermitEmptyPassword no
SambaのLDAP認証
-
Debian lenny
-
OpenLDAP server (slapd)とSamba server (smbd) は既にセットアップされて 正しく動いているものとする。
事前の準備
必要なパッケージをインストールする。
% sudo apt-get install samba-doc smbldap-tools
説明を読む。
% lv /usr/share/doc/smbldap-tools/README.Debian.gz
OpenLDAP server (slapd)の設定
samba-docに付属するLDAPスキーマをシステムにコピーする。
% sudo cp /usr/share/doc/samba-doc/examples/LDAP/samba.schema.gz \
/etc/ldap/schema/
% sudo gunzip /etc/ldap/schema/samba.schema.gz
slapdの設定ファイルにsamba-ldap向けの設定を追加する。
% sudo vi /etc/ldap/slapd.conf
diffふうに書くとこんな感じ。
+ include /etc/ldap/schema/samba.schema
-access to attrs=userPassword,shadowLastChange
+access to attrs=userPassword,shadowLastChange,sambaNTPassword,sambaLMPassword
by dn="cn=admin,dc=ohmsha,dc=co,dc=jp" write
by anonymous auth
by self write
by * none
README.Debianにはindexの設定もお好みで書いてよしとあるが、indexは後で書く。 先に書いてしまうと接続できなくなる。index対象の要素がまだDBにないせいだろ う。
後でSambaの認証をLDAPに向けたうえでsmbpasswdを使えば適当な値が書き込まれ るので、心配ない。
再起動して設定を反映。
% sudo /etc/init.d/slapd restart
クライアント側のSambaの設定
LDAPを参照するように設定ファイルを編集。
sudo vi /etc/samba/smb.conf
-passdb backend = tdbsam
+passdb backend = ldapsam:ldap://xxx.xxx.xxx.xxx/
...
-obey pam restrictions = yes
+obey pam restrictions = no
+ldap admin dn = cn=admin,dc=example,dc=com
+ldap suffix = dc=example,dc=com
+ldap group suffix = ou=Groups
+ldap user suffix = ou=Users
+ldap machine suffix = ou=Computers
+ldap idmap suffix = ou=Users
あとパスワード変更をsmbldap-toolsに任せる設定。
+ldap passwd sync = No
unix password sync = Yes
...
-passwd program = /usr/bin/passwd %u
+passwd program = /usr/sbin/smbldap-passwd -u %u
-passwd chat = *Enter\snew\s*\spassword:* %n\n *Retype\s*new\s*\spassword:* %n\n *password\supdated\ssuccessfully* .
+passwd chat = *New\s*\spassword* %n\n *Retype\snew\s*\spassword* %n\n *all*authentication*token*updated*
Windowsから操作するための設定はREADME.Debian参照。
LDAPサーバにアクセスするためにadminのパスワードを登録する。
% sudo smbpasswd -W
Setting stored password for "cn=admin,dc=example,dc=com" in secrets.tdb
New SMB password:
Retype new SMB password:
%
再起動する。
% sudo /etc/init.d/samba restart
smbldap-toolsの設定
クライアント側でsmbldap-toolsの設定をする。
標準のpasswdを使うところをsmbldap-passwdに変えたりしているので、 これをやらないと動かない。
まず設定ファイルの雛形をシステムにコピーする。 中にパスワードを平文で書くので権限に注意。
% sudo cp /usr/share/doc/smbldap-tools/examples/smbldap.conf.gz \
/etc/smbldap-tools/
% sudo gunzip /etc/smbldap-tools/smbldap.conf.gz
% sudo cp /usr/share/doc/smbldap-tools/examples/smbldap_bind.conf \
/etc/smbldap-tools/
% sudo chmod 0644 /etc/smbldap-tools/smbldap.conf
% sudo chmod 0600 /etc/smbldap-tools/smbldap_bind.conf
DomainではなくWorkgroup構成なら、どれでもいいので統一の 基準となるSambaサーバを決めて、そのSIDを調べておく。
% sudo net getlocalsid
SID for domain xxx is: S-1-5-21-yyyyyyyyy-yyyyyyyyyy-yyyyyyyyy
%
これを全Sambaサーバで共通のSIDとして使う(Windows Domain を設けるときは話が別)。
ローカルのSID設定はコメントアウトして、net getlocalsid 経由でLDAPに問い合わせるように設定。
-SID="S-1-5-21-xxxxxxxxx-xxxxxxxxxx-xxxxxxxxx"
+# SID="S-1-5-21-xxxxxxxxx-xxxxxxxxxx-xxxxxxxxx"
-sambaDomain="DOMSMB"
+#sambaDomain="DOMSMB"
...
-masterLDAP="127.0.0.1"
+masterLDAP="xxx.xxx.xxx.xxx"
...
-suffix="dc=company,dc=com"
+suffix="dc=example,dc=com"
smbldap_bind.confを編集。
% sudo vi /etc/smbldap-tools/smbldap_bind.conf
-slaveDN="cn=Manager,dc=company,dc=com"
+slaveDN="cn=admin,dc=example,dc=com"
-slavePw="secret"
+slavePw="xxx"
-masterDN="cn=Manager,dc=company,dc=com"
+masterDN="cn=admin,dc=example,dc=com"
-masterPw="secret"
+masterPw="xxx"
LDAP DB側の用意
smbpasswdでユーザを追加する。
% sudo smbpasswd -a jdoe
New SMB password:
Retype new SMB password:
Added user jdoe.
こんなエントリになる。
dn: uid=jdoe,ou=People,dc=example,dc=com
objectClass: account
objectClass: posixAccount
objectClass: sambaSamAccount
objectClass: shadowAccount
objectClass: top
cn: John Doe
gidNumber: 2001
homeDirectory: /home/jdoe
sambaSID: S-1-5-21-yyyyyyyyy-yyyyyyyyyy-yyyyyyyyy-5002
uid: hmorita
uidNumber: 2001
displayName: John Doe,,,
gecos: John Doe,,,
loginShell: /usr/bin/zsh
sambaAcctFlags: [U ]
sambaNTPassword: ...
sambaPasswordHistory: ...
sambaPwdLastSet: 1251358905
shadowLastChange: 11418
shadowMax: 99999
shadowWarning: 7
userPassword:: ...
試行錯誤の過程でsmbldap-populateしていろいろなエントリを登録 してしまったけれど、必須ではないと思われる。
そしてpopulateでいろいろ登録。
% sudo smbldap-populate -a admin
...
%
LDAP DBにSambaサーバを登録する。次はfile1.example.comという Sambaサーバがある場合のLDIFエントリ。他のサーバも同様に登録する。
dn: sambaDomainName=FILE1,dc=example,dc=com
objectClass: sambaDomain
sambaDomainName: FILE1
sambaSID: S-1-5-21-yyyyyyyyy-yyyyyyyyyy-yyyyyyyyy
sambaAlgorithmicRidBase: 1000
sambaForceLogoff: -1
sambaLockoutDuration: 30
sambaLockoutObservationWindow: 30
sambaLockoutThreshold: 0
sambaLogonToChgPwd: 0
sambaMaxPwdAge: -1
sambaMinPwdAge: 0
sambaMinPwdLength: 5
sambaNextUserRid: 1000
sambaPwdHistoryLength: 0
sambaRefuseMachinePwdChange: 0
これでどのSambaサーバにも同じアカウントでlogonできるはず。
確認:
file1% sudo pdbedit -d 3 -L
lp_load_ex: refreshing parameters
Initialising global parameters
params.c:pm_process() - Processing configuration file "/etc/samba/smb.conf"
Processing section "[global]"
smbldap_search_domain_info: Searching for:[(&(objectClass=sambaDomain)(sambaDomainName=FILE1))]
smbldap_open_connection: connection opened
ldap_connect_system: successful connection to the LDAP server
smbldap_search_domain_info: Searching for:[(&(objectClass=sambaDomain)(sambaDomainName=FILE1))]
smbldap_open_connection: connection opened
ldap_connect_system: successful connection to the LDAP server
smbldap_search_paged: base => [dc=example,dc=com], filter => [(&(uid=*)(objectclass=sambaSamAccount))],scope => [2], pagesize => [1024]
smbldap_search_paged: search was successfull
init_sam_from_ldap: Entry found for user: jdoe
jdoe:2001:John Doe,,,
...
file1%
トラブルシューティング
-
共有の競合
複数のユーザ名で同時に同じリソースにアクセスしようとするとWindowsが エラーを返す場合がある。 そういうときは
net use net use \\server\share /delete
で接続状況を表示させたり、適宜切断したりすればよい。
-
ネットワークパスが見つからない
「ネットワークパスが見つからない」と言われたら、そのユーザのホームディ レクトリが存在するか確認してみるとよい。
ls /home
-
SambaのSID
SIDはLDAPのDBに格納するもので、ローカルのsecrets.tdbに格納するもので はない。また、SambaがLDAPを参照するように設定されている場合、net getlocalsidはLDAPを見に行く。net setlocalsidなどとしても変更できない ので注意。
はまっている人の例(S-1-5-21-yyyを設定できない):
% sudo net getlocalsid SID for domain FILE1 is: S-1-5-21-xxx % sudo net setlocalsid S-1-5-21-yyy % sudo net getlocalsid SID for domain FILE1 is: S-1-5-21-xxx
こうなったらLDAPのほうを見ましょう。
雑感
それにしてもLDAP周りは手間がかかる。今までの振り返り:
-
OpenLDAPサーバ
仕組みや独特の概念を理解するのに時間がかかる。OSやディストリビューショ ンごとに細かく違うのも足を引っ張る。第一の関門。 -
PAMとNSS
資料が散らばっていて理解に時間がかかる。OSやディストリビューションご とに細かく違ううえ、順序に依存しているのがつらい。第二の関門。 -
OpenSSHサーバ
UsePAM = yesだけなので、手間はかからない。ただし ChallengeResponseAuthenticationに注意。 -
Sambaサーバ
1台なら簡単。ただし2台以上だと、SID周りでつまずくと遠回りしかねない。
試行錯誤に費やした時間を考えると、LDAPの本とSamba+LDAPの本を1冊ずつ手元に 用意しておいて損はなさそう。
資料
LDAP全般:
- UNIX USER 2002/1: LDAP特集 (draft)
http://ukai.jp/Articles/2002/uu-ldap/
LDAPに関する鵜飼さんの包括的な記事。知りたいことはたいてい載っている。 古くなった部分はドキュメントを読んでアップデートすればよい。
uidを調整する際の参考に:
- Debian Policy Manual - The Operating System
9.2.2 UID and GID classes
http://www.debian.org/doc/debian-policy/ch-opersys.html#s9.2.2
Samba+LDAPはこれで十分:
-
smbldap-tools for Debian
/usr/share/doc/smbldap-tools/README.Debian.gz -
ちょっとしたテストと覚え書き - SHIMI.INFO
DebianでOpenLDAP + Samba環境を作るメモ
http://shimi.info/pukiwiki/?Samba%2FDebian%2BLDAP
SIDの話:
- 【FreeBSD 5.3】Samba 3.x + OpenLDAP による PDC の設定
4.1 SID とドメインの話
http://www.abk.nu/~nabe/document/samba3.htm#4.1
Other Articles
- 13 Oct 2017: 『テスト駆動開発』
- 19 Oct 2016: 『新装版 達人プログラマー 職人から名匠への道』
- 19 Aug 2016: 『プログラミングElixir』
- 20 Oct 2015: Migrating from git-media to git-lfs
- 04 Oct 2015: Git Large File Storageクライアントのインストール
- 12 Aug 2015: isbn.rb
- 22 Apr 2015: 「なるのか、なすのか?」(To Be Or To Do?)