Samba/Active Directory ドメインコントローラ
この記事では Samba を使って Active Directory のドメインコントローラをセットアップする方法を説明しています。全ての設定ファイルはインストール後のデフォルト状態になっていることが前提です。この記事で書かれていることは、IPv4 ネットワークの固定接続の設定と openssh と vim の追加以外は手を付けていない新規インストール時の環境でテストしています (Samba の設定は真っ白)。最後に、以下で使っているほとんどのコマンドは特権昇格を必要とします。必要に応じて権限を得るよりも root になってからコマンドを実行するほうが簡単です。
インストール
完全に機能する Samba ドメインコントローラを作るには様々なプログラムが必要になります。bind-tools, krb5, ntp, openldap, openresolv, samba パッケージをインストールしてください。
また、Samba にはフル機能の DNS サーバーが含まれていますが、管理者の多くは ISC BIND パッケージを使うことを好みます。外部ドメインの DNS ゾーンを管理する必要がある場合、特に bind を使うことが推奨されます。プリンターを共有する必要がある場合も、cups も必要です。必要に応じて bind や cups パッケージをインストールしてください。
新しいディレクトリの作成
プロビジョニング
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 の修正:
# copy /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.com や server は適当な値に置き換えてください):
# 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
You will also need to create a reverse lookup zone for each subnet in your environment in DNS. It is important that this is kept in Samba's DNS as opposed to BIND to allow for dynamic updates by cleints. For each subnet, create a reverse lookup zone with the following commands. Replace server.internal.domain.tld and xxx.xxx.xxx with appropriate values. For xxx.xxx.xxx, use the first three octets of the subnet in reverse order (for example: 192.168.0.0/24 becomes 0.168.192):
# samba-tool dns zonecreate server.internal.domain.tld xxx.xxx.xxx.in-addr.arpa -U Administrator
Now, add a record for you server (if your server is multi-homed, add for each subnet) again substituting appropriate values as above. zzz will be replaced by the fourth octet of the IP for the server:
# samba-tool dns add server.internal.domain.tld xxx.xxx.xxx.in-addr.arpa zzz PTR server.internal.domain.tld -U Administrator
Restart the samba
service. If using BIND for DNS, restart the named
service as well.
Finally, test the lookup. Replace xxx.xxx.xxx.xxx with the IP of your server:
# host -t PTR xxx.xxx.xxx.xxx
You should get output similar to the following:
xxx.xxx.xxx.xxx.in-addr.arpa domain name pointer server.internal.domain.tld.
TLS
TLS support is not enabled by default, however, a default certificate was created when the DC was brought up. With the release of Samba 4.3.8 and 4.2.2, unsecured LDAP binds are disabled by default, and you must configure TLS to use Samba as an authentication source (without reducing the security of your Samba installation). To use the default keys, append the following lines to the "[global]" section of the /etc/samba/smb.conf
file:
tls enabled = yes tls keyfile = tls/key.pem tls certfile = tls/cert.pem tls cafile = tls/ca.pem
If a trusted certificate is needed, create a signing key and a certificate request (see OpenSSL for detailed instructions). Get the request signed by your chosen certificate authority, and put into this directory. If your certificate authority also needs an intermediate certificate, concatenate the certs (server cert first, then intermediate) and leave tls cafile blank.
Restart samba
for the changes to take effect.
Tips and tricks
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 パッケージをインストールしてください。
Create an unprivileged user in AD for performing the updates. When prompted for password, use a secure password. 63 random, mixed case, alpha-numeric characters is sufficient. Optionally samba-tool also takes a random argument:
# samba-tool user create dhcp --description="Unprivileged user for DNS updates via DHCP server"
Since this is a service account, disabling password expiration on the user account is recommended, but not required:
# samba-tool user setexpiry dhcp --noexpiry
Give the user privileges to administer DNS:
# samba-tool group addmembers DnsAdmins dhcp
Export the users credentials to a private 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
Modify the dhcpd-update-samba-dns.conf
file with the following commands (substituting correct values for server, internal.domain.tld, and 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}"
Configure the dhcpd server following the dhcpd article and add the following to all subnet declarations in the /etc/dhcpd.conf
file that provide DHCP service:
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);
Here is a complete example /etc/dhcpd.conf
file for reference:
/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); } }
Finally, enable and start (or restart) the dhcpd4
service.
ユーザーを他のディレクトリに転送
Unfortunately, there is no built-in utility to export users from one directory to another. This is one way, albeit exceptionally ulgy, to get the user specific fields out of your existing SAM and into a suitable LDIF format for ldbmodify:
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.
To import, after editing the file and transferring to the new server, simply run the following command on your new samba domain controller:
ldbmodify -H /var/lib/samba/private/sam.ldb user-export.ldif
パスワードの複雑性
デフォルトでは、Samba は強固なパスワードを必要とします。複雑性のチェックを無効化するには、以下のコマンドを実行:
# samba-tool domain passwordsettings set --complexity=off