winbind で Linux の認証を ActiveDirectory にまかせる

一行まとめ

  • 複数ドメインの信頼関係を構築していない場合,winbind の idmap backend として rid を使うと便利

前フリ

サーバを立てるたびにユーザアカウントをメンテナンスするのが面倒だ,ということでようやく腰を据えて winbind について勉強しました。ネット上に有用な文書が多くて助かりました。

  • CentOS 5.0
  • samba-3.0.23c-2.el5.2.0.2

という環境で,以下のような名称を例として使います。

基礎知識

ユーザが *nix を利用しようとすると,

  • 認証
  • ユーザ情報,ホスト情報等の管理情報へのアクセス

が必要になります。

古典的な *nix ではこれらをすべて /etc/passwd, /etc/groups, /etc/shadow, /etc/hosts 等のローカルファイルとせいぜい DNS を使って行ってきました。んが,そういった認証システム・情報システムの設定が各マシンで分散することになり面倒です。

で,それらのシステムをプラガブルにして外部に委託したりできるようにしたのが,認証については PAM,管理情報についてが NSS という仕組みです*1(参照→【パスワードの管理と運用を考える (1/2):Linux管理者への道(1) - @IT】の前半)。

さて,winbind というのは Samba に付属するデーモンで,認証や管理情報をドメインコントローラから取得し,UNIX 上のユーザ ID 等とのマッピングを保持してくれるものです(参照→【Samba が動作する Linux マシンを Windows ドメインに参加させる方法 ― MIRACLE LINUX V2.1 における Samba Winbind 利用方法 ―:ミラクル・リナックス】)。

今回のお話は,PAM と NSS に winbind を登録することによって,認証等を ActiveDirectory に任せる,ということになります。

winbind の設定

らんすの本棚】さんの【ActiveDirectory+Linux‚É‚æ‚é•”“àƒT[ƒo\’z】記事内の【4.“‡”FØ‚̐ݒèiWinbind+Kerberosj】に従ってやってみました。できた!おしまい。

というくらい素晴らしい記事です。

個人的にはまったところ。ActiveDirectory に join しようとして

# net ads join
Using short domain name -- HOGE
Failed to set servicePrincipalNames. Please ensure that
the DNS domain of this server matches the AD domain,
Or rejoin with using Domain Admin credentials.
Disabled account for 'PENGUIN' in realm 'HOGE.EXAMPLE.COM'

のように怒られる場合,127.0.0.1 でいいので,ADS 名に対応する名前を /etc/hosts で解決するようにすればいけるようです。騙されたと思って

# /etc/hosts
127.0.0.1 penguin.hoge.example.com penguin localhost.localdomain localhost

みたいにすると幸せになれるかも。

いろんな紆余曲折をへて,

# wbinfo -u
Administrator
...

# wbinfo -g
NetShow Administrators
...

# wbinfo -t
checking the trust secret via RPC calls succeeded

# id dayflower
uid=10000(dayflower) gid=10000(Domain Users) groups=10000(Domain Users),10001(Domain Admins)

みたく,無事に ActiveDirectory のユーザを UNIXマッピングできるようになりました。

ssh 等でログインできるようにしたい

上記手順までで行ったことは,管理情報の取得経路(NSS)として winbind を使えるようになったことだけです。このままでも samba サーバ(NAS)として使えるのですが,認証システム(PAM)の設定をしていないので ssh 等でログインできません。ですので,PAM 用の設定をします。

といっても RedHat 系なら authconfig を使うと楽に設定できます。TUI の場合,authconfig-tui を使うとインタラクティブに設定できます。GUI の場合,system-config-authentication で「Authentication」タブの「Enable Winbind Support」をチェックすると /etc/pam.d/system-auth-ac ファイルが適宜書き換えられ,winbind を認証に利用するようになります。smb.conf が適切に設定されている場合,「Configure Winbind ...」ボタンの先も適切な内容になっているはずです。

あとは sshd の設定ですが,CentOS だと一応そのままで大丈夫でしたが,/etc/ssh/sshd_config の内容が

UsePAM yes

# 下記のいずれかの認証を yes にする必要あり
#PasswordAuthentication yes
#ChallengeResponseAuthentication yes

のようになっている必要があります。もちろんセキュリティ上の懸念がありますが詳しくは説明しません。

また,smb.conf の内容に

winbind use default domain = yes

が入っていることを確認しておきます。no の場合,認証を行う際に,ユーザ名にドメイン名をいちいちつけなくてはいけなくなってしまうので(たとえば winbind separator = _ の場合,「ssh -l HOGE_dayflower localhost」のように)。

ホームディレクトリを自動的に作成されるようにしたい

いざ,ssh でログインしてみようと思ったら…

# ssh -l dayflower localhost
password: ********
Could not chdir to home directory /home/dayflower: No such file or directory
$ 

ディレクトリがないって怒られます。自動的に作成されるわけではないんですね。と思って調べたところ,Samba-ML へのたかはしもとのぶさんの投稿が目に止まりました。(2008-11-13 追記: コメント欄の情報により引用元を改変して引用しています)

自動でホームディレクトリを作成するには、大きく

の設定を連携して行う必要があります。Sambaのすべてをお持ちであれば、
P.401 も参照してみてください。

[samba-jp:19138] Re: ホームディレクトリを作成できない

なるほど。「obey pam restrictions = yes」については,もともと上記の手順の設定に含まれていました。CentOS の場合,pam_mkhomedir.so を設定するだけでよいようです。

/etc/pam.d/system-auth(-ac) は先ほどの例のように authconfig によって書き換えられてしまうので直接いじるのには抵抗感があるのですが,しかたなく書き換えることにします。

具体的には session 項の末尾「session required pam_unix.so」の下に,

session required pam_mkhomedir.so skel=/etc/skel umask=0022

のように書き加えます。

# ssh -l dayflower localhost
Password: ********
Creating directory '/home/dayflower'.

[dayflower@penguin ~]$ 

無事,ホームディレクトリが自動生成されるようになりました。

なお sshd の場合,サーバ自体が root 権限で動作しているので pam_mkhomedir でうまくディレクトリが自動生成されましたが,実行時に権限を落とすアプリケーションの場合うまく働かない可能性があります。そのようなときは,oddjob と pam_oddjob_mkhomedir が使えるかもしれません(参照→【http://www.redhat.com/magazine/024oct06/features/tips_tricks/】)。検証してないですケド。

winbind の問題点と解決

先ほどの例からですが,

# id dayflower
uid=10000(dayflower) gid=10000(Domain Users) groups=10000(Domain Users),10001(Domain Admins)

winbind は idmap uid /gid に指定された番号から取得順に割り振っていきます。ですから,このような winbind を立ち上げたサーバが複数台あると,サーバ間で UNIX uid / gid の整合性をとることが難しくなります。

Samba 3 から,idmap のバックエンドとして LDAP サーバを指定できるようになりました(→【Active Directory参加機能とセキュリティ拡張 (2/3):Samba 3.0の全貌 改訂版(2) - @IT】)。でも LDAP サーバ立ち上げるの面倒だし…とドキュメントを読んでいたら,「rid」なるバックエンドもあるではないですか。

RID とは何か,の前に SID とは何か,というのを説明しなくてはいけませんね。SID というのは,Windows Server でリソースを示す Unique ID です。ユーザ,グループ,コンピュータ名,等々あらゆるリソースに ID が割り振られています。dayflower の SID を確認してみます。

# wbinfo -n dayflower
S-1-5-21-299502267-436374069-1708537768-1190 User (1)

このような文字列全体が SID です。で,前半の「S-1-〜」というとことはドメイン(or ローカルコンピュータ)で(たぶん)共通しているのですが,太字で示した「1190」という数値が,リソースごとに異なる ID であり,これを RID と呼ぶらしい。

ということで,さっそく backend として rid を指定してみます。詳しい設定については,なぜか日本語ドキュメントの充実している HP の文書【http://docs.hp.com/ja/B8725-90121/ch07s07.html】も参照してみてください。

# smb.conf(抜粋)
[global]
allow trusted domains = No

idmap backend = rid:HOGE=10000-19999
idmap uid = 10000-19999
idmap gid = 10000-19999

smb.conf のマニュアルにあるとおりに BUILTIN というドメインを含めておくとなぜかうまくいかなかったので,利用するドメインのみ指定してあります。また,ドキュメントにあるとおり,信頼関係のあるドメインをサポートするのはよくないらしいので(そりゃ RID 部分が衝突しそうですもんね),disable してあります*2

idmap 等の情報については CentOS の場合,/var/cache/samba 以下に格納されているので,一度 winbind を止めて削除します。

# service winbind stop

# cd /var/cache/samba

# rm -f *.tdb

# service winbind start

winbindd_idmap.tdb だけで十分だと思いますが,念のためにごっそり全部消しました。また,先ほど自動生成されたホームディレクトリも削除することをお忘れなく。

さて,backend として rid を使うとどうなるか…

# id dayflower
uid=11190(dayflower) gid=10513(Domain Users) groups=10513(Domain Users),10512(Domain Admins)

先ほどの RID=1190 に,ベースとなる 10000 を加えた 11190 が UNIX user ID として割り振られました。これでドメイン内の UNIX uid /gid を簡単に整合性をとることができます。スバラスイ。


ちなみに,SFU をインストールしたドメインコントローラの場合,idmap backend として「ad」を指定して,マッピングディレクトリサーバに投げることもできます。この場合,「winbind nss info」は「template」ではなく「sfu」としておくとさらに便利かと思います。

積み残し

触れませんでしたが,AD サーバが落ちてしまった場合に備える「winbind offline logon」というオプションもあります。詳しくは【[Sambaウォッチ]第6回 オフラインログオンの大幅改善など,Samba 3.0.25のさまざまな新機能 | 日経 xTECH(クロステック)】を参照してください。

今回の設定では sshd の設定を甘めにしてあるのでお気をつけください。イントラ用途ということでご容赦を。

あとは /etc/sudoers の設定についても積み残し。

設定例

自分用にメモメモ。

smb.conf

[global]
        workgroup = HOGE
        realm = HOGE.EXAMPLE.COM
        netbios name = PENGUIN
        security = ADS
        allow trusted domains = No
        obey pam restrictions = Yes
        password server = dc.hoge.example.com
        idmap backend = rid:HOGE=10000-19999
        idmap uid = 10000-19999
        idmap gid = 10000-19999
        template homedir = /home/%U
        template shell = /bin/bash
        winbind separator = !
        winbind use default domain = Yes

/etc/pam.d/system-auth

#%PAM-1.0
# This file is auto-generated.
# User changes will be destroyed the next time authconfig is run.
auth        required      pam_env.so
auth        sufficient    pam_unix.so nullok try_first_pass
auth        requisite     pam_succeed_if.so uid >= 500 quiet
auth        sufficient    pam_winbind.so use_first_pass
auth        required      pam_deny.so

(account は略)

password    requisite     pam_cracklib.so try_first_pass retry=3
password    sufficient    pam_unix.so md5 shadow nullok try_first_pass use_authtok
password    sufficient    pam_winbind.so use_authtok
password    required      pam_deny.so

session     optional      pam_keyinit.so revoke
session     required      pam_limits.so
session     [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session     required      pam_unix.so
session     required      pam_mkhomedir.so skel=/etc/skel umask=0002

/etc/nsswitch.conf

passwd:     files winbind
shadow:     files winbind
group:      files winbind

hosts:      files dns wins

*1:厳密には NSS だけでも認証をインプリメントすることは可能でしょうが,話を簡単にするためにあえて分業させました

*2:ドメイン毎に idmap の範囲を指定できるので trusted domains が on でもうまくいきそうな気がするのですが……未検証です。