Samba4でADドメインコントローラ冗長化

既に構築済みのActive Directory環境に新たなドメインコントローラを構築して冗長化させるぜ。
Windowsサーバで構築するのではなく、Cent OS 6.4 に Samba 4.0.9 をインストールする。
WindowsはもちろんMacちゃんやLinuxたんもドメインの仲間に入れてあげる事を目標に。
端末以外でも、LDAP認証に対応したシステムは全て仲間入りさせて仲良しネットワーク作ろう。

標準リポジトリにSamba4.0があるんだけど、ドメインコントローラはまだパッケージにされてない?
妙に容量すくないんだよね。以前インストールした時も構築できなかったし。
だがだが、(たぶん)個人でリポジトリ公開してるサイトがあって、そこから4.0.9がyum installできるようになってた。

んでも今回はyum使ってのインストールは行わない。
gnutls-develがインストールされていない環境でコンパイルされたらしく、LDAPTLS (LDAPS) 対応していなかった。
実はこれに気づくまでに時間がかかってDLAP認証にしてたFedora18とかログインできなくて泣いた。
*1
今回は色々な環境の認証サーバとして頑張ってもらうから、自分でコンパイル&インストールをするんだぜ。

俺はTLS対応なんかされてなくても生きていける!って硬派な人は下のリンク先を参照するのお勧め。

ちょっと前に行ったFedora18で行ったドメイン構築の記録はここから!

この環境にスレーブとしてドメインコントローラを構築していく。
前置きが長くなったけど、早速開始だ!!

の前にw
今回のゴールを掲げておこう(大げさ

ドメイン:YOUR-DOMAIN.LOCAL

元々あるDC 今回構築するDC
IPアドレス 192.168.0.1 192.168.0.2
ホスト名 dc-server0 dc-server1

インストールの巻

インストール対象はCentOS6.4。
既にネットワーク設定などOSの基本的な事は終わっている事が前提で記録を残してるのよ。
コマンドが使えなかったら yum install するんだ。makeとかgccとかwgetとかね。(最小構成のインストールだと入ってないぞ)
管理者権限が必要なコマンド多数なので、rootでログインした状態で作業を進めるよ。

関連ツールのインストール

では。先ず始めに必要ヘッダー類のインストールを行う。
Samba 4/OS Requirements (日本語) | Case-of-T を参考にyumコマンド実行。

yum install libacl-devel libblkid-devel gnutls-devel readline-devel python-devel gdb pkgconfig krb5-workstation zlib-devel setroubleshoot-server setroubleshoot-plugins policycoreutils-python libsemanage-python setools-libs-python setools-libs popt-devel libpcap-devel sqlite-devel libidn-devel libxml2-devel libacl-devel libsepol-devel libattr-devel keyutils-libs-devel cyrus-sasl-devel

gnutls-develがインストールされていないと、TLS接続できない状態でコンパイルされちゃうぞ!

ソースコードのダウンロード

次は公式サイトからソースコードを取得するよ。
http://ftp.samba.org/pub/samba/ にアクセスして、最新版のtar.gzファイルを取得しよう。
この時点での最新版である samba-4.0.9.tar.gz をダウンロード。*2
そんでもってtarファイルを展開する。

wget http://ftp.samba.org/pub/samba/samba-4.0.9.tar.gz
tar -xzf samba-4.0.9.tar.gz
Make アンド Install

tarを展開したディレクトリに移動し、コンパイルからインストールまで一気に行っちゃう!
とは言っても、頑張るのはCPU。人様は待ってる時間が長い。どれだけかかるかはCPUの性能次第だ。
ちなみに、自身の仮想環境ではトータルで10分位だったかな。

標準では全て /var/local/samba にインストールされるんだけど。
色々考えた結果、データベース等のデータファイルは /var/lib/samba ディレクトリ内に、設定ファイルは /etc/samba ディレクトリ内にインストールされるようにする。
オプション等詳しくは、./configure --help コマンドで確認してね。

cd samba-4.0.9
./configure --sysconfdir=/etc/samba --localstatedir=/var --with-privatedir=/var/lib/samba/private --with-cachedir=/var/lib/samba/cache --with-lockdir=/var/lib/samba/lock --with-logfilebase=/var/log/samba
make
make install
ポート開放

以下のポートを開放せよ。じゃないと泣く事になるぞ。まじで・・・

番号 プロトコル
88 tcp
135 tcp
139 tcp
389 tcp
389 udp
445 tcp
464 tcp
636 tcp
636 udp
1024 tcp
3268 tcp

389:udpポート開放忘れると、Windows7にインストールされたAD関連の管理ツールが脅してくるぞ!!

名前付け情報を検索できません。
理由:セキュリティに危害を与える試みが検出されました。認証したサーバに連絡してください。
システム管理者に問い合わせ、ドメインが正しく構成されていて、現在オンラインであるかどうかを確認してください。

setup-toolとsystem-config-firewall-tuiがインストールされていれば、setupコマンドまたはsystem-config-firewall-tuiコマンドから楽に設定しやすいね。
iptablesを直接編集するって紳士にはこれ。

-A INPUT -m state --state NEW -m tcp -p tcp --dport 53 -j ACCEPT
-A INPUT -m state --state NEW -m udp -p udp --dport 53 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 88 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 135 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 139 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 389 -j ACCEPT
-A INPUT -m state --state NEW -m udp -p udp --dport 389 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 445 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 464 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 636 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 636 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 1024 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 3268 -j ACCEPT

ドメイン環境構築

ここからが本番だ!

ケルベロス設定

/etc/krb5.conf ファイルの以下の項目を設定する。

[libdefaults]
default_realm = YOUR-DOMAIN.LOCAL
dns_lookup_realm = true
dns_lookup_kdc = true

設定が正しく行えているかkinitコマンドで確認する。

kinit administrator@YOUR-DOMAIN.LOCAL
ドメイン参加

samba-toolコマンドの domain join を使用してドメイン参加処理を実行する。

samba-tool domain join your-domain.local DC -Uadministrator --dns-backend=BIND9_DLZ --realm=your-domain.local

ドメインのadministratorパスワードを聞かれるのでパスワードを入力してenterキーを「ッターーーン」と叩けばおっけーだ!
以下の感じで表示されていくはず。SIDの値とかは人によって違うから気にするな!!

Finding a writeable DC for domain 'your-domain.local'
Found DC dc-server0.your-domain.local
Password for [YOUR-DOMAIN.LOCAL\administrator]:
NO DNS zone information found in source domain, not replicating DNS
workgroup is YOUR-DOMAIN.LOCAL
realm is your-domain.local
checking sAMAccountName
Adding CN=DC-SERVER1,OU=Domain Controllers,DC=your-domain,DC=local
Adding CN=DC-SERVER1,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=your-domain,DC=local
Adding CN=NTDS Settings,CN=DC-SERVER1,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=your-domain,DC=local
Adding SPNs to CN=DC-SERVER1,OU=Domain Controllers,DC=your-domain,DC=local
Setting account password for DC-SERVER1$
Enabling account
Calling bare provision
No IPv6 address will be assigned
Provision OK for domain DN DC=your-domain,DC=local
Starting replication
Schema-DN[CN=Schema,CN=Configuration,DC=your-domain,DC=local] objects[402/1550] linked_values[0/0]
Schema-DN[CN=Schema,CN=Configuration,DC=your-domain,DC=local] objects[804/1550] linked_values[0/0]
Schema-DN[CN=Schema,CN=Configuration,DC=your-domain,DC=local] objects[1206/1550] linked_values[0/0]
Schema-DN[CN=Schema,CN=Configuration,DC=your-domain,DC=local] objects[1550/1550] linked_values[0/0]
Analyze and apply schema objects
Partition[CN=Configuration,DC=your-domain,DC=local] objects[402/1628] linked_values[0/0]
Partition[CN=Configuration,DC=your-domain,DC=local] objects[804/1628] linked_values[0/0]
Partition[CN=Configuration,DC=your-domain,DC=local] objects[1206/1628] linked_values[0/0]
Partition[CN=Configuration,DC=your-domain,DC=local] objects[1608/1628] linked_values[0/0]
Partition[CN=Configuration,DC=your-domain,DC=local] objects[1628/1628] linked_values[28/0]
Replicating critical objects from the base DN of the domain
Partition[DC=your-domain,DC=local] objects[99/99] linked_values[32/0]
Partition[DC=your-domain,DC=local] objects[476/377] linked_values[41/0]
Done with always replicated NC (base, config, schema)
Committing SAM database
Sending DsReplicateUpdateRefs for all the replicated partitions
Setting isSynchronized and dsServiceName
Setting up secrets database
Joined domain YOUR-DOMAIN.LOCAL (SID S-1-5-21-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx) as a DC

DNS登録

クライアントがドメインコントローラを探せるように、DNSに登録せねばならぬ。
まずはguidが必要になるので、ldbsearchコマンドを駆使してguidをゲットする。

/usr/local/samba/bin/ldbsearch -H /var/lib/samba/private/sam.ldb '(invocationid=*)' --cross-ncs objectguid

結果として以下の様に標準出力されるんだ。

# record 1
dn: CN=NTDS Settings,CN=DC-SERVER0,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=your-domain,DC=local
objectGUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

# record 2
dn: CN=NTDS Settings,CN=DC-SERVER1,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=your-domain,DC=local
objectGUID: yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy

今回必要なのはDC-SERVER1のguidなので、上記の例で言うところの yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy が必要になる。
クリップボードにコピーするなり、メモるなり暗記するなり好きな方法で。

んで、DNSに登録する。君のゾーンファイルを編集するんだ。
$ORIGN _msdcs.your-domain.local に元々のdc-server0が登録されてるので、その下にCNAMEを追加する。

$ORIGN _msdcs.your-domain.local
yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy CNAME dc-server1.your-domain.local

dc-server1.your-domain.local のAレコードがちゃんと登録されてなきゃダメだぞ!
なかったら、以下の内容を最後の方にでも追加しちゃいなさい。

$ORIGN your-domain.local
dc-server1 A 192.168.0.2

digコマンドでゾーン情報が引けるかな?

dig yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy._msdcs.your-domain.local

IPアドレスが取得できていれば登録大丈夫だ。

レプリケーション確認

samba-toolの drs showrepl コマンドでレプリケーション状態が確認できるのでお試しあれ。

/usr/local/samba/bin/samba-tool drs showrepl

Default-First-Site-Name\DC-SERVER1
DSA Options: 0x00000001
DSA object GUID: yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy
DSA invocationId: zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz

==== INBOUND NEIGHBORS ====

CN=Schema,CN=Configuration,DC=your-domain,DC=local
Default-First-Site-Name\DC-SERVER0 via RPC
DSA object GUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Last attempt @ Thu Oct 24 11:07:01 2013 JST was successful
0 consecutive failure(s).
Last success @ Thu Oct 24 11:07:01 2013 JST



DC=your-domain,DC=local
Default-First-Site-Name\DC-SERCER0 via RPC
DSA object GUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Last attempt @ Thu Oct 24 11:03:02 2013 JST was successful
0 consecutive failure(s).
Last success @ Thu Oct 24 11:03:02 2013 JST

CN=Configuration,DC=your-domain,DC=local
Default-First-Site-Name\DC-SERVER0 via RPC
DSA object GUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Last attempt @ Thu Oct 24 11:04:03 2013 JST was successful
0 consecutive failure(s).
Last success @ Thu Oct 24 11:04:03 2013 JST

==== OUTBOUND NEIGHBORS ====

CN=Schema,CN=Configuration,DC=your-domain,DC=local
Default-First-Site-Name\DC-SERVER0 via RPC
DSA object GUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Last attempt @ NTTIME(0) was successful
0 consecutive failure(s).
Last success @ NTTIME(0)

DC=your-domain,DC=local
Default-First-Site-Name\DC-SERVER0 via RPC
DSA object GUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Last attempt @ NTTIME(0) was successful
0 consecutive failure(s).
Last success @ NTTIME(0)

==== KCC CONNECTION OBJECTS ====

Connection --
Connection name: zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzz
Enabled : TRUE
Server DNS name : DC-SERVER0.your-domain.local
Server DN name : CN=NTDS Settings,CN=DC-SERVER0,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=your-domain,DC=local
TransportType: RPC
options: 0x00000001
Warning: No NC replicated for Connection!

各項目が was successful ってなっていればいいんだが、failed とかあっちゃうとレプリケーション失敗してる。
失敗していれば、ネットワーク構成とかDNSとかポートを再度確認するなりして障害となっている箇所の原因特定と解決するしかない。

ちなみに。Windowsの「Active Directory ユーザとコンピュータ」管理ツールからも確認できる。
該当のドメインコントローラ(デフォではDomain Controllersに所属)のプロパティを開いて NTDSの設定 を開く。
接続タブに レプリケート元・レプリケート先 の一覧があるので双方にレプリケーション相手がいればいいのだよ。

GPOレプリケーション

GPO、それはグループポリシーオブジェクトの事だ。
だが、これから話す内容はとてもショッキングな出来事だ。落ち着いて聞いてほしい。

新規に追加したサーバのGPOファイルを見るんだ。
どこにあるかは、/etc/samba/smb.conf ファイルの [sysvol] セッション内にある path に指定されている。
今回の環境では /var/lib/samba/sysvol になる。そのディレクトリ内にドメイン名のディレクトリが存在する。そのドメインディレクトリに Policies って名前で存在している。
つまりは、 ls -l /var/lib/samba/sysvol/your-domain.local/ コマンドを実行すれば表示されるわけだ。

な?表示されないだろ??

それってどういう事か、わかるか?!

そうだ。GPOが同期されてないー!!って事だ。
これは一大事だ。そんな状況下で以下の記事を見つけた。 8. Active Directory各種設定 — samba4 AD mini HowTo 1.0 documentation
挙動といいネット情報といい、「GPOが同期されないのは仕様です(キリッ」で間違えなさそうだ。

だからと言って諦めてはダメだ!人間諦めたら終わりだ。
同期されないのであれば、自力でどうきさせてしまえばいいのだよ。

rsyncコマンドを駆使してやればいけそうだから安心したまえ!
対象のファイルはroot権限が必要なのでrootアカウントでssh経由のrsyncを鍵認証で行う。

鍵作成

サーバ間のファイル同期のために ssh接続でのrsyncコマンドで行う。
実行はcronに登録して行う予定なので、同期先でパスワードなしの鍵作成を行う。rootユーザーで/rootディレクトリ内で作業を実施。

ssh-keygen -t rsa -N "" -f .ssh/rsync-gpo

これで .sshディレクトリ内にrsync-gpoって名の秘密鍵と公開鍵の二つが作成される。この公開鍵を同期元のサーバに配置する。
scpコマンドで同期元にコピーを作成するが、通常はrootアカウントはSSH接続できなくしてると思うので、SSH接続できるユーザ user でログインしてホームディレクトリに一旦置く。

scp .ssh/rsync-gpo.pub user@dc-server0:~/
同期元サーバ設定

rootアカウントでもSSHでログイン可能にする。ただし、セキュリティを考慮して実行できるコマンドを限定した設定にする。
/etc/ssh/sshd_config ファイルの以下の項目を変更とする。

PermitRootLogin forced-commands-only

設定を変更したらsshdを再起動。

/etc/init.d/sshd restart

先程コピーした公開鍵をauthorized_keysに登録する。
あと、パーミッションを変更してrootのみが読み書き出きるようにする。

cat /home/user/rsync-gpo.pub >> /root/.ssh/authorized_keys
chmod 600 /root/.ssh/authorized_keys

実行できるコマンドを限定するため、authorized_keysに登録する。
とその前に、rsyncコマンドがコピー先サーバでどのように実行されるのか調べる。
同期先から実行予定のrsyncコマンドに-vvオプションを追加して実行する。この時点では同期先の設定ができていないのでエラーを吐いて終了してしまうが必要な情報は取得できるので気にしない。

rsync -aAXu -e "ssh -i /root/.ssh/rsync-gpo" user@dc-server0:/var/lib/samba/sysvol/your-domain.local/ /var/lib/samba/sysvol/your-domain.local/ --vv

想定通りエラーでこける。こけなきゃおかしい。それで、標準出力つまり画面に opening connection using: ssh ... なるメッセージがある。以下のような感じだ。

opening connection using: ssh -i /root/.ssh/rsync-gpo -l root dc-server1 rsync --server --sender -vvulogDtpAXre.iLs . /var/lib/samba/sysvol/your-domain.local/

このケースでは、 rsync --server -vvulogDtpAXre.iLs . /var/lib/samba/sysvol/your-domain.local/ の部分が該当する。
このコマンドを同期先のauthorized_keysにcommandオプションとして登録する。
同期先の /root/.ssh/authorized_keys の該当公開鍵情報の前にvim等のエディタで追加する。-vvオプションは実際の同期処理では必要ないので除外した。
ついでにアクセス元を限定し、万一に備えて他のサーバからはアクセス出来ないようにした。

command="rsync --server --sender -ulogDtpAXre.iLs . /var/lib/samba/sysvol/your-domain.local/",from="192.168.0.2" ssh-rsa AAAA.... root@dc-server1

ssh-rsa より前に記載する。commandとfromはカンマ区切りとし、スペースを含めてはならない。ssh-rsaの前に必ずスペースを含めればよい。

同期先からrsyncコマンド叩いて同期できればグッジョブだ。

できなければ、authorized_keysを疑おう。commandの内容を"ls"だけにして、単純にsshコマンドで接続してみる。
/rootディレクトリの内容が表示されて接続が切れれば commandオプション内のrsyncコマンドの記載(特にオプション関連怪しい)が違っている事になる。
接続出来ないとかだと、authorized_keysへの書き方が違うか、違う公開鍵情報に設定してしまったかだ・・・

自動同期設定

crontabに登録して定期的に同期させる。今回は15分に一度同期する様に設定したぜ。
まずは、同期先から同期元へrsyncコマンドを実行させるので、同期先のcrontabに登録する。
同期した後、権限の設定反映を行わないといけないので、合わせてsamba-toolコマンドも登録する。

 */15 * * * * rsync -aAXu -e "ssh -i /root/.ssh/rsync-gpo" root@dc-server0:/var/lib/samba/sysvol/your-domain.local/ /var/lib/samba/sysvol/your-domain.local/
 1-59/15 * * * * /usr/local/samba/bin/samba-tool ntacl sysvolreset

規程の時間に実行されていればおkだ。
時間をずらして反対方向の同期処理も実行した方がいいな。


構築した環境では、同期を行うようになってから administrator 意外GPO編集できなくなってしまったのはなんでなんだぜ?
これについては調べなければ・・・今のところ原因不明
(2013-12-13追記) グループポリシー管理ツールのファイルメニューからオプションを選択し、ファイルの削除ボタンをクリックしてツール再起動で直った。

*1:2014/02/24追記:どうやら対応された見たいですが時間がなくて実施できず

*2:この記事を作成時点でリンクを確認したら4.0.10がアップされてた。恐らく同じ手順でいけるはず。バージョン番号は適時読み替えて!