Ubuntu Weekly Recipe

第853回Sambaで作るActive Directory互換環境
(2) 2台目のドメインコントローラーの作成とSYSVOLフォルダの同期設定

Sambaを使ったActive Directory(以下、AD)互換環境の構築方法を複数回に分けて解説しています。前回はSambaでドメインコントローラー(以下、DC)を1台展開し、AD互換環境を作成しました。今回は冗長化のために2台目のDCを作成します。

2台目(以降)のDCの展開

まずは今回の構成のおさらいです。

  • ドメイン名: example.com
    • 1台目のDC(前回構築したもの⁠
      • ホスト名: samba-ad-dc01
      • IPアドレス: 192.168.1.150
    • 2台目のDC(今回構築するもの⁠
      • ホスト名: samba-ad-dc02
      • IPアドレス: 192.168.1.151
  • OS: Ubuntu Server 24.04 LTS

2台目(以降)のDCの展開については1台目と似たところが多いです。

まず、必要なパッケージは1台目と同じです。また、無効にするサービスや/etc/samba/smb.confの削除(移動)が必要なのも同じです。

samba-ad-dc02$ sudo apt install -y samba-ad-dc krb5-user bind9-dnsutils
samba-ad-dc02$ sudo systemctl disable --now smbd nmbd winbind
samba-ad-dc02$ sudo systemctl mask smbd nmbd winbind
samba-ad-dc02$ sudo rm /etc/samba/smb.conf

/etc/resolv.confを編集し、1台目のDCを参照できるようにします。

samba-ad-dc02$ sudo unlink /etc/resolv.conf
samba-ad-dc02$ cat << EOF | sudo tee /etc/resolv.conf
> nameserver 192.168.1.150
> search example.com
> EOF

事前準備が完了したら、ドメインにDCとして参加します。次はAdministrator@example.comの権限でexample.comドメインにDCとして参加するというコマンドです。

samba-ad-dc02$ sudo samba-tool domain join example.com DC -U '[email protected]'
...
INFO 2025-02-25 13:12:29,011 pid:3843 /usr/lib/python3/dist-packages/samba/join.py #106: Finding a writeable DC for domain 'example.com'
INFO 2025-02-25 13:12:29,015 pid:3843 /usr/lib/python3/dist-packages/samba/join.py #108: Found DC samba-ad-dc01.example.com
Password for [[email protected]]:
...
INFO 2025-02-25 13:12:32,248 pid:3843 /usr/lib/python3/dist-packages/samba/provision/__init__.py #2432: A Kerberos configuration suitable for Samba AD has been generated at /var/lib/samba/private/krb5.conf
INFO 2025-02-25 13:12:32,248 pid:3843 /usr/lib/python3/dist-packages/samba/provision/__init__.py #2434: Merge the contents of this file with your system krb5.conf or replace it with this one. Do not create a symlink!
...
INFO 2025-02-25 13:12:34,681 pid:3843 /usr/lib/python3/dist-packages/samba/join.py #1631: Joined domain EXAMPLE (SID S-1-5-21-1227575069-1623886296-1303063441) as a DC

また、これも1台目同様ですがログの抜粋箇所で指示があるように、/etc/krb5.confを置き換えます。

samba-ad-dc02$ sudo cp -f /var/lib/samba/private/krb5.conf /etc/krb5.conf

作成された/etc/samba/smb.confを見ると、DNSフォワーダーなど、1台目のADと設定が揃っていない部分があります。DC同士は同じ設定を持つべきであるため、次のように1台目と内容を揃えておきます。

samba-ad-dc02$ cat /etc/samba/smb.conf
# Global parameters
[global]
        dns forwarder = 192.168.1.1     # 追加
        netbios name = SAMBA-AD-DC02
        realm = EXAMPLE.COM
        server role = active directory domain controller
        workgroup = EXAMPLE
        idmap_ldb:use rfc2307 = yes     # 追加

[sysvol]
        path = /var/lib/samba/sysvol
        read only = No

[netlogon]
        path = /var/lib/samba/sysvol/example.com/scripts
        read only = No

そして、1台目同様、systemd-resolvedを無効化・停止して、Samba AD DCサービスを有効化・起動します。

samba-ad-dc02$ sudo systemctl disable systemd-resolved --now
samba-ad-dc02$ sudo systemctl enable samba-ad-dc --now

2台目のDCの動作を確認します。

samba-ad-dc02$ kinit Administrator
Password for [email protected]:
Warning: Your password will expire in 41 days on Mon 07 Apr 2025 02:04:04 PM UTC
samba-ad-dc02$ klist
Ticket cache: FILE:/tmp/krb5cc_1000
Default principal: [email protected]

Valid starting       Expires              Service principal
02/25/2025 13:13:56  02/25/2025 23:13:56  krbtgt/[email protected]
        renew until 02/26/2025 13:13:54

samba-ad-dc02$ for srv in _ldap._tcp _kerberos._tcp _kerberos._udp _kpasswd._udp; do echo -n "${srv}.example.com: "; dig @localhost +short -t SRV ${srv}.example.com; done
_ldap._tcp.example.com: 0 100 389 samba-ad-dc01.example.com.
0 100 389 samba-ad-dc02.example.com.
_kerberos._tcp.example.com: 0 100 88 samba-ad-dc01.example.com.
0 100 88 samba-ad-dc02.example.com.
_kerberos._udp.example.com: 0 100 88 samba-ad-dc01.example.com.
0 100 88 samba-ad-dc02.example.com.
_kpasswd._udp.example.com: 0 100 464 samba-ad-dc01.example.com.
0 100 464 samba-ad-dc02.example.com.

また、上で見られるように2台目のDCもDNSサーバーとして動作しています。そのため、今後は2台目のDCも自身のDNSサーバーで名前解決させられるよう、最後に/etc/resolv.conf(再)編集します[1]

samba-ad-dc02$ cat << EOF | sudo tee /etc/resolv.conf
> nameserver 127.0.0.1
> search example.com
> EOF

ドメインにすでに参加しているコンピューターは2台目のDCもDNSサーバーとして参照するように設定変更します。

SYSVOLフォルダのレプリケート

ドメインに参加した時点で、1台目のDCから2台目のDCにドメインのユーザーやコンピューターなどのLDAPの情報はレプリケートされています[2]。一方、グループポリシーオブジェクト(GPO)に関する情報が収められているSYSVOLフォルダはSamba AD DCではレプリケートされません[3]

状況説明のため、本家のWindows Serverのディレクトリサービス(ADDS)の場合はどうかというと、Distributed File System Replication(DFS ReplicationあるいDFSR)という機能によりDC間でSYSVOLフォルダの内容が(双方向に)レプリケーションされています。しかし、SambaではDFSRの互換機能が未実装という状況です[4]

実際に確認してみると1台目のDCにはPoliciesディレクトリがありますが、2台目のDCにはありません。

samba-ad-dc01$ sudo ls -la /var/lib/samba/sysvol/example.com
total 32
drwxrwx---+ 4 root BUILTIN\administrators 4096 Nov 29 04:47 .
drwxrwx---+ 3 root BUILTIN\administrators 4096 Nov 29 04:47 ..
drwxrwx---+ 4 root BUILTIN\administrators 4096 Nov 29 04:47 Policies
drwxrwx---+ 2 root BUILTIN\administrators 4096 Nov 29 04:47 scripts
samba-ad-dc02$ sudo ls -la /var/lib/samba/sysvol/example.com
total 12
drwxr-xr-x 3 root root 4096 Dec  1 05:35 .
drwxr-xr-x 3 root root 4096 Dec  1 05:35 ..
drwxr-xr-x 2 root root 4096 Dec  1 05:35 scripts

つまり、接続するDCによってSYSVOLフォルダの中身(≒GPO関連の情報)が違うということになります。しかしながら、DCを2台構成にしている理由は冗長化のためなので、SYSVOLフォルダの内容も同期されていてほしいところです[5]

この状況に対し、Sambaの公式Wikiでは回避策の1つとして「PDCエミュレーターFSMOロールを持つDCでrsyncdを稼働させて、他のDCからrsyncでSYSVOLフォルダの内容を一方向に同期する」という方法を紹介しています。シンプルな方法なので本稿でもこれを採用することにします。なお、GPOを一切使わないのであれば、本節の作業は不要です。

その前に、⁠PDCエミュレーターFSMOロール」という言葉が唐突に出てきました。ADに馴染みのない方のために、この言葉を構成要素ごとに分解して順番に解説します。

まずは「FSMOロール」です。ADはマルチマスター対応データベースであり、そのデータベースを保持するDC同士は本来対等な立場といえます。ただ、対等だからといって個別のDCに対して一斉にデータベースに更新をかけるとそれはそれで操作の競合(不整合)が発生するリスクが高まります。そのため、ADでは一部の操作については単一マスターモデルをとります。これは操作グループごとに「FSMO(Flexible Single Master Operation)ロール」というものを1台のDCに割り当て、その操作はこのロールを持つDCだけがおこなうというルールで、操作の競合(不整合)を回避します。FSMOロールは特定DCに固定されておらず(ゆえに"Flexible"⁠⁠、適宜、転送(強制転送含む)が可能です。

続いて、⁠PDCエミュレーター」です。ADの前身であるNTドメインではプライマリDC(PDC)というものが1台設定されて原本となるデータベースを持ち、残りのDCはそのデータベースのコピーを持つバックアップDC(BDC)位置づけられていました。NTドメインの後継であるADは前述の通り「マルチマスター型」のデータベースのため、DC同士は対等で、PDC/BDCという考え方は基本的にありません。しかし、⁠特に過渡期において)後方互換性を維持するために、ADにはNTドメインのようにも振る舞うことも求められました。その結果として生まれたのがNTドメイン時代のPDCのように振る舞う=エミュレーションする「PDCエミュレーター」というFSMOロールです。つまり、⁠PDCエミュレーターFSMOロール」とは、原義的には「NTドメインだと思ってADドメインに接続してくるアプリケーションのためにPDCをエミュレーションする役回りを割り当てられているDC」ということになります。

ただ、実際には「PDCエミュレーターFSMOロール」を持つDCはなにかにつけて重要な役回りを担っていることが多いという理解です。その1つが「"グループ ポリシー管理エディター"のデフォルトではPDCエミュレーターFSMOロールを持つDCに接続する」というものです[6]。これを今回の回避策の観点で見ると、⁠デフォルトでは、まず最初にPDCエミュレーターFSMOロールを持つDCが抱えるSYSVOLフォルダにGPOの変更が反映される(そして、ADDSの場合はその変更内容がDFSRで他のDCにレプリケートされる⁠⁠」といえます。

今回は前述の通り、1台目のDCから2台目のDCの一方向にSYSVOLフォルダをレプリケートすることで、DFSRを使わずに同様のことを実現します。ただし、DFSRが双方向レプリケーションなのに対し、この方式は一方向のレプリケーションとなるため、次のような前提・想定(あるいは、制限・制約)の下でドメインの運用をおこないます。

  • 基本的には1台目のDCにPDCエミュレーターFSMOロールをもたせるようにする。
  • GPOの管理者はPDCエミュレーターFSMOロールを持つDCに接続して(⁠⁠グループ ポリシー管理エディター」の場合はデフォルトの挙動のまま操作して⁠⁠、GPO関連の操作をする。
  • PDCエミュレーターFSMOロールを移動させるときはSYSVOLフォルダのレプリケーションについても適宜対応(例:レプリケーションの方向を変えるor停止するといった対応)を取る。

前置きが長くなりましたが、実際に設定を進めていきます。

まずは、1台目のDC側の設定です。次のような内容でrsyncdを構成、動作させます[7]

samba-ad-dc01$ cat << EOF | sudo tee /etc/rsyncd.conf    # rsyncdの設定
[SYSVOL]
path = /var/lib/samba/sysvol
hosts allow = 192.168.1.151 # レプリケート先のDCのIPアドレス
hosts deny = *
list = true
uid = root
gid = root
read only = yes
auth users = sysvol-replication
secrets file = /etc/samba/rsyncd.secret
EOF

samba-ad-dc01$ cat << EOF | sudo tee /etc/samba/rsyncd.secret # 接続ユーザーとパスワード情報の配置
sysvol-replication:P@ssw0rd
EOF

samba-ad-dc01$ sudo chmod 600 /etc/samba/rsyncd.secret   # パーミッションの設定

samba-ad-dc01$ sudo systemctl enable rsync.service --now # rsyncdの有効化・起動

また、SYSVOLフォルダはSMB/CIFS共有フォルダとして見えるため、Windowsのユーザー・グループ管理で使用されるセキュリティ識別子(SID)というものとLinuxのユーザー・グループ管理で使用されるUID/GIDとでマッピングする必要があります。Samba AD DCのデータベースのうちこのIDのマッピングを収めているのがidmap.ldbというファイルなのですが、同じドメインのDC間でもビルトインのユーザー・グループについて、SIDとUID/GIDのマッピングが揃うことは保証されていません。このIDマッピングにDC間で差異があると、意図しないアクセスを許可してしまう可能性があるため、1台目のDCからidmap.ldbを取得し、2台目のDCと同期させます。

まずは準備として、次のコマンドで1台目のDCからidmap.ldbを取得しておきます。

samba-ad-dc01$ sudo tdbbackup -s .bak /var/lib/samba/private/idmap.ldb

コマンドを実行すると/var/lib/samba/private/idmap.ldb.bakというファイルが作成されるため、これを2台目のDCの任意の場所に任意の方法でコピーします。これで、1台目の準備は完了です。

続いて2台目のDC側の設定です。先ほどコピーしてきたidmap.ldbで2台目のDCのidmap.ldbを上書きし、キャッシュをクリアしてIDマッピングを同期します。

samba-ad-dc02$ sudo cp idmap.ldb.bak /var/lib/samba/private/idmap.ldb
samba-ad-dc02$ sudo net cache flush

これでDC間のSIDとUID/GIDのマッピングが揃いました[8]

続いて、rsyncコマンドで1台目のDCへ接続する際に使用する認証情報ファイルを配置します。

samba-ad-dc02$ cat << EOF | sudo tee /etc/samba/rsync-sysvol.secret
P@ssw0rd
EOF
samba-ad-dc02$ sudo chmod 600 /etc/samba/rsync-sysvol.secret

SYSVOLフォルダの同期をおこなうサービスユニット[9]とそれを定期的(5分おき)にトリガーするタイマーユニットを作成します。

samba-ad-dc02$ cat << EOF | sudo tee /etc/systemd/system/sysvol-replication.service
[Unit]
Description=SYSVOL synchronization service

[Service]
ExecStart=/usr/bin/rsync -XAavz --delete-after --password-file=/etc/samba/rsync-sysvol.secret rsync://[email protected]/SYSVOL /var/lib/samba/sysvol
EOF

samba-ad-dc02$ cat << EOF | sudo tee /etc/systemd/system/sysvol-replication.timer
[Unit]
Description=Synchronize SYSVOL every 5 minutes

[Timer]
OnBootSec=5min
OnUnitActiveSec=5min

[Install]
WantedBy=timers.target
EOF

最後にユニットファイルをリロードし、タイマーを有効化します。

samba-ad-dc02$ sudo systemctl daemon-reload
samba-ad-dc02$ sudo systemctl enable sysvol-replication.timer --now

これでSYSVOLフォルダが1台目のDCから2台目のDCに定期的にレプリケートされるようになりました。Ubuntuマシンであればadsysを使ってGPOを適用できるようになります。

なお、2台目以降のDCを作成する場合も同じ作業を繰り返します。


今回までの作業でSambaを使ったDC2台構成のAD互換環境を作成できました。次回はSamba ADの基本的な操作などについて解説します。

おすすめ記事

記事・ニュース一覧