Samba/Active Directory ドメインコントローラ

提供: ArchWiki
移動先: 案内検索

この記事では Samba を使って Active Directory のドメインコントローラをセットアップする方法を説明しています。全ての設定ファイルはインストール後のデフォルト状態になっていることが前提です。この記事で書かれていることは、IPv4 ネットワークの固定接続の設定と openssh と vim の追加以外は手を付けていない新規インストール時の環境でテストしています (Samba の設定は真っ白)。最後に、以下で使っているほとんどのコマンドは特権昇格を必要とします。必要に応じて権限を得るよりも root になってからコマンドを実行するほうが簡単です。

インストール

ノート: ホストネームを使ってネットワーク内のマシンにアクセスできることを確認してください。詳しくはネットワーク設定#ローカルネットワークのホストネーム解決を参照。

完全に機能する Samba ドメインコントローラを作るには様々なプログラムが必要になります。bind-tools, krb5, ntp, openldap, openresolv, samba パッケージをインストールしてください。

また、Samba にはフル機能の DNS サーバーが含まれていますが、管理者の多くは ISC BIND パッケージを使うことを好みます。外部ドメインの DNS ゾーンを管理する必要がある場合、特に bind を使うことが推奨されます。プリンターを共有する必要がある場合も、cups も必要です。必要に応じて bindcups パッケージをインストールしてください。

新しいディレクトリの作成

プロビジョニング

Active Directory ドメインを作成する最初のステップはプロビジョニングです。内部の LDAP, Kerberos, DNS サーバーを設定してディレクトリに必要な基本設定を全て実行します。以前にディレクトリサーバーを立ち上げた経験があるのであれば、個別のコンポーネントを単体のユニットとして動作させるときに起こり得る誤りを知っているはずです。それは Samba の開発者が MIT や Heimdal の Kerberos サーバーや OpenLDAP サーバーを使用するのではなく、各プログラムの内部バージョンを選択した理由でもあります。上記でインストールするサーバーパッケージはクライアントユーティリティのためだけに使います。Samba ではプロビジョニングはとても簡単です。以下のコマンドを実行してください:

# samba-tool domain provision --use-rfc2307 --use-xattrs=yes --interactive

引数の説明

--use-rfc2307
この引数は AD スキーマに POSIX 属性 (UID/GID) を追加します。Microsoft Windows に加えて Linux, BSD, macOS クライアント (ローカルマシン含む) を認証する場合に必須になります。
--use-xattrs=yes
この引数はサーバー上でホストするファイルの UNIX 拡張属性 (ACL) の使用を有効にします。ドメインコントローラでファイルを共有しない場合、このスイッチは不要です (ただし使用を推奨します)。Samba の共有をホストするファイルシステムが ACL のサポートを有効にしてマウントされていることを確認してください。
--interactive
この引数はプロビジョニングスクリプトを対話式で実行します。また、samba-tool domain provision --help を実行することでプロビジョニングの手順のヘルプを見ることができます。

対話式のプロビジョニングの説明

Realm
INTERNAL.DOMAIN.COM - DNS ドメインを全て大文字で表記したものにしてください。サブドメインを使用して外部 DNS ドメインと内部ドメインを分けるのが普通ですが、必須ではありません。
Domain
INTERNAL - NetBIOS ドメイン名になります。通常は一番左の DNS サブドメインにしますが好きに名前をつけてかまいません。INTERNAL という名前はちょっとわかりにくいです。会社名や頭文字などがふさわしいでしょう。全て大文字で入力する必要があり、古いクライアントとの互換性を保つために文字数は最大で15文字となります。
Server Role
dc - この記事では新しいドメインに最初の DC をインストールします。別のものを選択した場合、この記事の大部分が役に立たなくなります。
DNS Backend
BIND9_DLZ または SAMBA_INTERNAL - サーバー管理者の個人的な好みによります。外部ドメインの DNS をホストする場合、BIND9_DLZ バックエンドを使用することを強く推奨します。フラットゾーンファイルを使い続けて既存の転送ルールを内部 DNS サーバーと共存できます。よくわからない場合は SAMBA_INTERNAL バックエンドを使ってください。
Administrator password
xxxxxxxx - 管理者アカウントには強固なパスワードを選択してください。大文字と数字がそれぞれ1文字含まれていて8文字以上であることが最低条件です。要件を満たさないパスワードを使用した場合、プロビジョニングは失敗します。

デーモンの設定

NTPD

適当な NTP 設定を作成してください。詳しくは Network Time Protocol daemon を見てください。

デフォルトファイルのバックアップコピーを作成:

# cp /etc/ntp.conf{,.default}

/etc/ntp.conf ファイルを以下の内容で修正:

/etc/ntp.conf
# Please consider joining the pool:
#
#     http://www.pool.ntp.org/join.html
#
# For additional information see:
# - https://wiki.archlinux.org/index.php/Network_Time_Protocol_daemon
# - http://support.ntp.org/bin/view/Support/GettingStarted
# - the ntp.conf man page

# Associate to Arch's NTP pool
server 0.arch.pool.ntp.org
server 1.arch.pool.ntp.org
server 2.arch.pool.ntp.org
server 3.arch.pool.ntp.org

# Restrictions
restrict default kod limited nomodify notrap nopeer mssntp
restrict 127.0.0.1
restrict ::1
restrict 0.arch.pool.ntp.org mask 255.255.255.255 nomodify notrap nopeer noquery
restrict 1.arch.pool.ntp.org mask 255.255.255.255 nomodify notrap nopeer noquery
restrict 2.arch.pool.ntp.org mask 255.255.255.255 nomodify notrap nopeer noquery
restrict 3.arch.pool.ntp.org mask 255.255.255.255 nomodify notrap nopeer noquery

# Location of drift file
driftfile /var/lib/ntp/ntpd.drift

# Location of the update directory
ntpsigndsocket /var/lib/samba/ntp_signd/

状態ディレクトリを作成してパーミッションを設定:

# install -d /var/lib/samba/ntp_signd
# chown root:ntp /var/lib/samba/ntp_signd
# chmod 0750 /var/lib/samba/ntp_signd

設定できたら ntpd.service ユニットを起動・有効化してください。

BIND

BIND9_DLZ DNS バックエンドを使用することを選択した場合、bind パッケージをインストールして以下の BIND 設定を作成してください。詳しくは BIND を見てください。x は適当な値に置き換えるようにしてください:

まずデフォルト設定ファイルのバックアップを作成:

# mv /etc/named.conf{,.default}

/etc/named.conf ファイルを作成:

/etc/named.conf
 
// vim:set ts=4 sw=4 et:

options {
    directory "/var/named";
    pid-file "/run/named/named.pid";

    // Uncomment these to enable IPv6 connections support
    // IPv4 will still work:
    //  listen-on-v6 { any; };
    // Add this for no IPv4:
    //  listen-on { none; };

    auth-nxdomain yes;
    datasize default;
    empty-zones-enable no;
    tkey-gssapi-keytab "/var/lib/samba/private/dns.keytab";
    forwarders { xxx.xxx.xxx.xxx; xxx.xxx.xxx.xxx; };

    //  Add any subnets or hosts you want to allow to use this DNS server (use "; " delimiter)
    allow-query     { xxx.xxx.xxx.xxx/xx; 127.0.0.0/8; };

    //  Add any subnets or hosts you want to allow to use recursive queries
    allow-recursion { xxx.xxx.xxx.xxx/xx; 127.0.0.0/8; };

    //  Add any subnets or hosts you want to allow dynamic updates from
    allow-update    { xxx.xxx.xxx.xxx/xx; 127.0.0.0/8; };

    allow-transfer { none; };
    version none;
    hostname none;
    server-id none;
};

zone "localhost" IN {
    type master;
    file "localhost.zone";
};

zone "0.0.127.in-addr.arpa" IN {
    type master;
    file "127.0.0.zone";
};

zone "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa" {
    type master;
    file "localhost.ip6.zone";
};

zone "255.in-addr.arpa" IN {
    type master;
    file "empty.zone";
};

zone "0.in-addr.arpa" IN {
    type master;
    file "empty0.zone";
};

zone "." IN {
    type hint;
    file "root.hint";
};

//Load AD integrated zones
dlz "AD DNS Zones" {
    database "dlopen /usr/lib/samba/bind9/dlz_bind9_10.so";
};

//zone "example.org" IN {
//    type slave;
//    file "example.zone";
//    masters {
//        192.168.1.100;
//    };
//    allow-query { any; };
//    allow-transfer { any; };
//};

logging {
    channel xfer-log {
        file "/var/log/named.log";
            print-category yes;
            print-severity yes;
            severity info;
        };
        category xfer-in { xfer-log; };
        category xfer-out { xfer-log; };
        category notify { xfer-log; };
};

パーミッションを設定:

# chgrp named /var/lib/samba/private/dns.keytab
# chmod g+r /var/lib/samba/private/dns.keytab
# touch /var/log/named.log
# chown root:named /var/log/named.log
# chmod 664 /var/log/named.log

最新バージョンの bind の修正:

# cp /var/named/empty.zone /var/named/empty0.zone
# chown root:named /var/named/empty0.zone

named.service ユニットを有効化・起動してください。

フォワーダーは ISP の DNS サーバーにするとよいでしょう。Google (8.8.8.8, 8.8.4.4, 2001:4860:4860::8888, and 2001:4860:4860::8844) や OpenDNS (208.67.222.222, 208.67.220.220, 2620:0:ccc::2 and 2620:0:ccd::2) は無料のパブリック DNS サーバーを提供しています。サブネットに指定する値はネットワークによって変わります。

Kerberos クライアントユーティリティ

上記のプロビジョニングで Samba ドメインコントローラで使うための krb5.conf ファイルが作成されます。以下のコマンドでインストールしてください:

# mv /etc/krb5.conf{,.default}
# cp /var/lib/samba/private/krb5.conf /etc

DNS

ここから ローカルの DNS サーバーを使うようにしてください。DNS ルックアップでローカルホストしか使わないように resolv.conf を設定します。/etc/resolv.conf.tail を作成してください (internal.domain.tld はあなたの使用している内部ドメインに置き換えてください):

# Samba configuration
search internal.domain.tld
# If using IPv6, uncomment the following line
#nameserver ::1
nameserver 127.0.0.1

パーミッションを設定して /etc/resolv.conf ファイルを再生成:

# chmod 644 /etc/resolv.conf.tail
# resolvconf -u

Samba

samba.service ユニットを起動・有効化してください。LDB ユーティリティを使用する場合、/etc/profile.d/sambaldb.sh ファイルを作成して LDB_MODULES_PATH を設定する必要があります:

export LDB_MODULES_PATH="${LDB_MODULES_PATH}:/usr/lib/samba/ldb"

ファイルのパーミッションを設定して実行:

# chmod 0755 /etc/profile.d/sambaldb.sh
# . /etc/profile.d/sambaldb.sh

インストールのテスト

DNS

まず DNS が機能していることを確認してください。以下のコマンドを実行します (internal.domain.comserver は適当な値に置き換えてください):

# host -t SRV _ldap._tcp.internal.domain.com.
# host -t SRV _kerberos._udp.internal.domain.com.
# host -t A server.internal.domain.com.

以下のような出力が得られるはずです:

_ldap._tcp.internal.domain.com has SRV record 0 100 389 server.internal.domain.com.
_kerberos._udp.internal.domain.com has SRV record 0 100 88 server.internal.domain.com.
server.internal.domain.com has address xxx.xxx.xxx.xxx

NT 認証

次にパスワード認証が機能することを確認します:

# smbclient //localhost/netlogon -U Administrator -c 'ls'

(先に設定した) パスワードが要求され、以下のようにディレクトリが表示されます:

Domain=[INTERNAL] OS=[Unix] Server=[Samba 4.1.2]
  .                                   D        0  Wed Nov 27 23:59:07 2013
  ..                                  D        0  Wed Nov 27 23:59:12 2013

		50332 blocks of size 2097152. 47185 blocks available

Kerberos

そして KDC が機能することを確認します。INTERNAL.DOMAIN.COM は適当な値に置き換えてください:

# kinit administrator@INTERNAL.DOMAIN.COM

パスワードが要求され以下のような出力がされるはずです:

Warning: Your password will expire in 41 days on Wed 08 Jan 2014 11:59:11 PM CST

チケットが得られたことを確認:

# klist

以下のように出力されます:

Ticket cache: FILE:/tmp/krb5cc_0
Default principal: administrator@INTERNAL.DOMAIN.COM

Valid starting       Expires              Service principal
11/28/2013 00:22:17  11/28/2013 10:22:17  krbtgt/INTERNAL.DOMAIN.COM@INTERNAL.DOMAIN.COM
	renew until 11/29/2013 00:22:14

最後に得られたチケットを smbclient で使ってみます。server は適当なサーバー名に置き換えてください:

# smbclient //server/netlogon -k -c 'ls'

上のパスワード認証と同じ出力がされるはずです。

追加設定

DNS

使用している環境の各サブネットに対して DNS の逆引きゾーンを作成する必要があります。クライアントによる動的な更新ができる BIND とは対照的に Samba の DNS では保持しなければなりません。各サブネットに対して、以下のコマンドで逆引きゾーンを作成してください。server.internal.domain.tldxxx.xxx.xxx は適切な値に置き換えてください。xxx.xxx.xxx についてはサブネットのオクテットを逆順に指定します (例: 192.168.0.0/24 の場合は 0.168.192 となります):

# samba-tool dns zonecreate server.internal.domain.tld xxx.xxx.xxx.in-addr.arpa -U Administrator

それから、サーバーのレコードを追加してください (マルチホームサーバーの場合、サブネットごとに追加してください)。上記の同じように適切な値に置き換えてください。zzz はサーバーの IP の4番目のオクテットに置き換えます:

# samba-tool dns add server.internal.domain.tld xxx.xxx.xxx.in-addr.arpa zzz PTR server.internal.domain.tld -U Administrator

samba サービスを再起動してください。BIND の DNS サービスを使っている場合、named サービスも再起動してください。

最後に、ルックアップをテストしてください (xxx.xxx.xxx.xxx はあなたのサーバーの IP に置き換えてください):

# host -t PTR xxx.xxx.xxx.xxx

以下のような出力がされるはずです:

xxx.xxx.xxx.xxx.in-addr.arpa domain name pointer server.internal.domain.tld.

TLS

TLS のサポートはデフォルトでは有効になっていませんが、DC が立ち上げられるとデフォルトの証明書が作成されます。Samba 4.3.8 と 4.2.2 から、セキュアでない LDAP のバインドはデフォルトで無効になっており、Samba を使って認証するには TLS を設定する必要があります (もしくは Samba のセキュリティを落とさなければなりません)。デフォルトの鍵を使用する場合、/etc/samba/smb.conf ファイルの "[global]" セクションに以下の行を追加してください:

        tls enabled  = yes
        tls keyfile  = tls/key.pem
        tls certfile = tls/cert.pem
        tls cafile   = tls/ca.pem

信頼された証明書が必要な場合、署名鍵と証明書リクエストを作成してください (詳しくは OpenSSL を参照)。認証局からリクエストに署名してもらったら、ディレクトリに配置してください。認証局が中間証明書も必要とする場合、証明書 (サーバー証明書を最初に、それから中間証明書) を結合して tls cafile を空にしてください。

samba を再起動すると変更が適用されます。

ヒントとテクニック

DHCP とダイナミック DNS の更新

It should be noted that using this method will affect functionality of windows clients, as they will still attempt to update DNS on their own. When this occurs, the machine will be denied permission to do so as the record will be owned by the dhcp user rather than the machine account. While this is essentially harmless, it will generate warnings in the system log of the offending machine. You should create a GPO to overcome this, but unfortunately, Samba does not yet have a command line utility to modify GPOs. You will need a Windows PC with the RSAT tools installed. Simply create a dedicated GPO with the Group Policy Editor, and apply only to OUs that contain workstations (so that servers can still update using 'ipconfig /registerdns') and configure the following settings:

Computer Configuration
  Policies
    Administrative Templates
      Network
        DNS Client
          Dynamic Update = Disabled
          Register PTR Records = Disabled

dhcp パッケージと samba-dhcpd-updateAUR パッケージをインストールしてください。

アップデートを実行するための非特権ユーザーを AD に作成します。パスワードを要求されたら、セキュアなパスワードを使ってください。63文字のランダムな大文字・小文字を含んだ英数字で良いでしょう。任意で samba-tool にランダム引数を指定できます:

# samba-tool user create dhcp --description="Unprivileged user for DNS updates via DHCP server"

サービスアカウントになるため、ユーザーアカウントのパスワードの有効期限は無効にすることを推奨します (必須ではありません):

# samba-tool user setexpiry dhcp --noexpiry

ユーザーに DNS を管理する権限を付与:

# samba-tool group addmembers DnsAdmins dhcp

ユーザーの認証情報を keytab にエクスポート:

# samba-tool domain exportkeytab --principal=dhcp@INTERNAL.DOMAIN.TLD dhcpd.keytab
# install -vdm 755 /etc/dhcpd
# mv dhcpd.keytab /etc/dhcpd
# chown root:root /etc/dhcpd/dhcpd.keytab
# chmod 400 /etc/dhcpd/dhcpd.keytab

dhcpd-update-samba-dns.conf ファイルを以下のように編集 (server, internal.domain.tld, INTERNAL.DOMAIN.TLD は適当な値に置き換えてください):

/etc/dhcpd/dhcpd-update-samba-dns.conf
# Variables
KRB5CC="/run/dhcpd4.krb5cc"
KEYTAB="/etc/dhcpd/dhcpd.keytab"
DOMAIN="internal.domain.tld"
REALM="INTERNAL.DOMAIN.TLD"
PRINCIPAL="dhcp@${REALM}"
NAMESERVER="server.${DOMAIN}"
ZONE="${DOMAIN}"

dhcpd の記事に従って dhcpd サーバーを設定して、/etc/dhcpd.conf ファイルの全ての subnet 定義に以下を追加して DHCP サービスを供給:

  on commit {
    set ClientIP = binary-to-ascii(10, 8, ".", leased-address);
    set ClientName = pick-first-value(option host-name, host-decl-name);
    execute("/usr/bin/dhcpd-update-samba-dns.sh", "add", ClientIP, ClientName);
  }

  on release {
    set ClientIP = binary-to-ascii(10, 8, ".", leased-address);
    set ClientName = pick-first-value(option host-name, host-decl-name);
    execute("/usr/bin/dhcpd-update-samba-dns.sh", "delete", ClientIP, ClientName);
  }

    on expiry {
    set ClientIP = binary-to-ascii(10, 8, ".", leased-address);
    set ClientName = pick-first-value(option host-name, host-decl-name);
    execute("/usr/bin/dhcpd-update-samba-dns.sh", "delete", ClientIP, ClientName);

/etc/dhcpd.conf ファイルの完全な例:

/etc/dhcpd.conf
subnet 192.168.1.0 netmask 255.255.255.0 {
  range 192.168.1.100 192.168.1.199;
  option subnet-mask 255.255.255.0;
  option routers 192.168.1.254;
  option domain-name "internal.domain.tld";
  option domain-name-servers 192.168.1.1;
  option broadcast-address 192.168.1.255;
  default-lease-time 28800;
  max-lease-time 43200;
  authoritative;

  on commit {
    set ClientIP = binary-to-ascii(10, 8, ".", leased-address);
    set ClientName = pick-first-value(option host-name, host-decl-name);
    execute("/usr/bin/dhcpd-update-samba-dns.sh", "add", ClientIP, ClientName);
  }

  on release {
    set ClientIP = binary-to-ascii(10, 8, ".", leased-address);
    set ClientName = pick-first-value(option host-name, host-decl-name);
    execute("/usr/bin/dhcpd-update-samba-dns.sh", "delete", ClientIP, ClientName);
  }

    on expiry {
    set ClientIP = binary-to-ascii(10, 8, ".", leased-address);
    set ClientName = pick-first-value(option host-name, host-decl-name);
    execute("/usr/bin/dhcpd-update-samba-dns.sh", "delete", ClientIP, ClientName);
  }
}

最後に dhcpd4 サービスを有効化・起動(または再起動)してください。

ユーザーを他のディレクトリに転送

残念ながら別のディレクトリにユーザーをエクスポートするユーティリティは存在しません。以下は既存の SAM からユーザーフィールドを抽出して ldbmodify から使えるように LDIF 形式にするコマンドです:

ldbsearch -H /var/lib/samba/private/sam.ldb \
    -s sub -b cn=Users,dc=internal,dc=domain,dc=tld '(objectClass=user)' | \
    grep -e "^\# record" -e "^accountExpires:" -e "^c:" -e "^cn:" -e "^co:" -e "^codePage:" \
         -e "^comment:" -e "^company:" -e "^countryCode:" -e "^department:" \
         -e "^description:" -e "^displayName" -e "^displayNamePrintable:" \
         -e "^distinguishedName" -e "^division:" -e "^dn:" -e "^employeeID:" \
         -e "^facsimileTelephoneNumber:" -e "^generationQualifier:" \
         -e "^givenName" -e "^homeDirectory:" -e "^homeDrive:" -e "^homePhone:" \
         -e "^homePostalAddress:" -e "^info:" -e "^initials:" \
         -e "^internationalISDNNumber:" -e "^ipPhone:" -e "^l:" -e "^mail:" \
         -e "^manager:" -e "^middleName:" -e "^mobile:" -e "^name:" -e "^o:" \
         -e "^objectClass" -e "^otherFacsimileTelephoneNumber:" \
         -e "^otherHomePhone:" -e "^otherIpPhone:" -e "^otherMailbox:" \
         -e "^otherMobile:" -e "^otherPager:" -e "^otherTelephone:" -e "^pager:" \
         -e "^personalTitle:" -e "^physicalDeliveryOfficeName:" -e "^postalAddress:" \
         -e "^postalCode:" -e "^postOfficeBox:" -e "^proxyAddresses\: SMTP" \
         -e "^proxyAddresses: smtp" -e "^referredDeliveryMethod:" \
         -e "^primaryInternationalISDNNumber:" -e "^primaryTelexNumber:" \
         -e "^profilePath:" -e "^registeredAddress:" -e "^sAMAccountName:" \
         -e "^scriptPath:" -e "^sn:" -e "^st:" -e "^street:" -e "^streetAddress:" \
         -e "^telephoneNumber:" -e "^teletexTerminalIdentifier:" \
         -e "^telexNumber:" -e "^title:" -e "^userAccountControl:" -e "^userPrincipalName:"\
         -e "^url:" -e "^userSharedFolder:" -e "^userSharedFolderOther:" -e "^wWWHomePage:" | \
    sed '/^dn:.*/ a\changetype: add' | sed '/^# record/ i\\n' > user-export.ldif

Explanation: Run an ldbsearch in the users container only, using sub-tree search for objectclass=user. If you need the whole directory, you can modify the search base to use the root or some other OU. The output from ldbsearch is then piped into a really long grep command that returns only appropriate attributes to keep in the new directory. This is obviously subjective, and probably should be tailored to your specific use case. Finally, we use sed to insert the changetype line (needed to tell ldbmodify that we are adding a user), and prefix with a blank line (to make it easier to read) for each exported object.

ノート: You will need to modify the output file and remove any objects that you don't want transferred. The output file will contain objects (service users, built-ins, etc.) that can break your new directory if you fail to remove them! It will also contain the old domain in both the "dn" and "distinguishedName" attributies that must be changed before import.

インポートするには、ファイルを編集して新しいサーバーに転送した後、新しい samba ドメインコントローラで以下のコマンドを実行してください:

ldbmodify -H /var/lib/samba/private/sam.ldb user-export.ldif

パスワードの複雑性

デフォルトでは、Samba は強固なパスワードを必要とします。複雑性のチェックを無効化するには、以下のコマンドを実行:

# samba-tool domain passwordsettings set --complexity=off