動機
社内利用のサーバー構築を考えていて、ユーザーやグループ管理は既存のActiveDirectoryサーバーを考えているんだけど、まずは検証のためにパソコン内に仮想マシンでActiveDirectoryサーバーを立てて好きにいじれる環境を構築しよう、という動機でサーバーを立てる。
実行環境
- 仮想化ホスト環境
- OSエディション:Windows 10 Pro
- OSバージョン:21H2
- ビルド:19044.1766
- プロセッサ:AMD Ryzen 5 Pro 4650U with Radeon Graphics 2.10GHz
- 実装RAM:8GB
- 仮想化環境: OS組み込みのHyper-V
- ネットワーク: 家庭用無線LANにデフォルト設定(DHCPでIPアドレス割り当て)で接続
- ゲスト(ActiveDirectoryサーバー)
- OS: Windows Server 2019
- インストーラーISOファイル: 17763.1158.200413-1759.rs5_release_svc_refresh_SERVER_EVAL_x64FRE_ja-jp.iso
方針
- 検証用なのでWindowsサーバーの評価版を利用するが、使用可能な期間が180日間なので、いらなくなったら削除して、必要になったらすぐ作り直せるようにスクリプト化する
- LDAPサーバーとして参照するだけなので、その必要最低限の設定のみ実施する
- Hyper-V上に他のサーバーも立てて検証するので、使用メモリは最小限にする
作業の流れ
- Windows Server 2019 評価用のISOファイルをダウンロード
- Active Directory のOU、セキュリティグループの設計
- Active Directory構築用スクリプトの作成
- OSインストール
- Active Directory構築用スクリプト実行
- 動作確認
1.Windows Server 2019 評価用のISOファイルをダウンロード
このサイトを参考にしました。
https://security-blog-it.com/8416/
2.Active Directory の設計
OUについては、自社の組織構造、OU設計に
- 最上位の組織構造は部である
- 部の下位構造として課がある
- 課を持たない部もある
- 課にも下位構造はあるが、OU上には表れない
- OU名は日本語を用いている
- セキュリティグループのオブジェクトはドメイン直下に専用のOUを作成して配置する
のような特徴があったため、今回は以下のように設計した。
DC=mycompany,DC=test
├── OU=総務部
├── OU=営業部
│ ├── OU=営業第一
│ └── OU=営業第二
├── OU=技術部
│ ├── OU=技術第一
│ └── OU=技術第二
└── Groups
最初はドメイン名はexample.co.jpにしてたのだが、後でActive Directoryのドメインを作成する際に「ドメイン コントローラーの昇格に関する前提条件の検証に失敗しました。NetBIOS ドメイン名を指定してください。」というエラーが出て失敗することが分かったのでmycompany.testに変更した。
.testのTLDはテスト用に予約されたTLDなので(RFC2060で規定)、インターネットに影響を与えることなくテストに用いることができる。
https://datatracker.ietf.org/doc/html/rfc2606#section-2
セキュリティグループについては、
- 組織構造によるものとして、部単位のセキュリティグループと、課単位のセキュリティグループを作成する
- 権限によるものとして、管理職のセキュリティグループと役員のセキュリティグループを作成する
という思想のもと、「総務部」、「営業部」、「営業第一」、「営業第二」、「技術部」、「技術第一」、「技術第二」、「管理職」、「役員」というセキュリティグループとする。
ユーザーについては、
- 課員、課長はOU構造でいうところの末端のOUに所属する
- 部長は特定の課への所属は明示されずに営業部や技術部の所属となることがある
- 社長はActive DirectoryのOU上は便宜上総務部所属とする
- ユーザー名(ログイン名)には日本語は用いない
- 他サーバーからのLDAP参照のためのユーザーとしてldap_bindというユーザーを作成する
と設計し、以下のパターンでユーザーを作成する
- President
- (GA|Salse|Tech)(SeniorManager|Manager|Staff)(A|B)
- ldap_bind
Presidentは社長で、他は「<所属部><役職><連番>」という名前付けルールでサンプルユーザーを作成する。
GA:総務部、Sales:営業部、Tech:技術部、SeniorManager:部長、Manager:課長、Staff:課員の意味である。
実環境ではユーザーは単純に人名で作っているんだけど、これはテスト環境なので機械的にかつどういう所属かわかるように作成した。
3.Active Directory構築用スクリプトの作成
設計をもとに、以下の通りActive Directory構築用スクリプトを作成した。
ad_config.ps1を編集すれば、OU、ユーザー、セキュリティグループを任意に変更できるようにした。
$domainName = "mycompany.test"
# OUは下位構造をハッシュテーブルで指定する。下位構造がないOUには空のハッシュテーブルを指定する。
$ou = @{
"営業部" = @{
"営業第一" = @{};
"営業第二" = @{}
};
"技術部" = @{
"技術第一" = @{};
"技術第二" = @{}
};
"総務部" = @{};
"Groups" = @{}
}
$securityGroups = @(
"営業部",
"営業第一",
"営業第二",
"技術部",
"技術第一",
"技術第二",
"総務部",
"管理職",
"役員"
)
$users = @{
"SalesStaffA" = @{
"ou" = "営業第一";
"securityGroups" = @( "営業第一" );
"password" = ConvertTo-SecureString "P@ssw0rd" -AsPlainText -Force
};
"SalesStaffB" = @{
"ou" = "営業第二";
"securityGroups" = @( "営業第二" );
"password" = ConvertTo-SecureString "P@ssw0rd" -AsPlainText -Force
};
"SalesManagerA" = @{
"ou" = "営業第一";
"securityGroups" = @( "営業第一"; "管理職" );
"password" = ConvertTo-SecureString "P@ssw0rd" -AsPlainText -Force
};
"SalesManagerB" = @{
"ou" = "営業第二";
"securityGroups" = @( "営業第二"; "管理職" );
"password" = ConvertTo-SecureString "P@ssw0rd" -AsPlainText -Force
};
"SalesSeniorManagerA" = @{
"ou" = "営業部";
"securityGroups" = @( "営業第一"; "営業第二"; "管理職" );
"password" = ConvertTo-SecureString "P@ssw0rd" -AsPlainText -Force
};
"TechStaffA" = @{
"ou" = "技術第一";
"securityGroups" = @( "技術第一" );
"password" = ConvertTo-SecureString "P@ssw0rd" -AsPlainText -Force
};
"TechStaffB" = @{
"ou" = "技術第二";
"securityGroups" = @( "技術第二" );
"password" = ConvertTo-SecureString "P@ssw0rd" -AsPlainText -Force
};
"TechManagerA" = @{
"ou" = "技術第一";
"securityGroups" = @( "技術第一"; "管理職" );
"password" = ConvertTo-SecureString "P@ssw0rd" -AsPlainText -Force
};
"TechManagerB" = @{
"ou" = "技術第二";
"securityGroups" = @( "技術第二"; "管理職" );
"password" = ConvertTo-SecureString "P@ssw0rd" -AsPlainText -Force
};
"TechSeniorManagerA" = @{
"ou" = "技術部";
"securityGroups" = @( "技術第一"; "技術第二"; "管理職" );
"password" = ConvertTo-SecureString "P@ssw0rd" -AsPlainText -Force
};
"GAStaffA" = @{
"ou" = "総務部";
"securityGroups" = @( "総務部" );
"password" = ConvertTo-SecureString "P@ssw0rd" -AsPlainText -Force
};
"GAManagerA" = @{
"ou" = "総務部";
"securityGroups" = @( "総務部"; "管理職" );
"password" = ConvertTo-SecureString "P@ssw0rd" -AsPlainText -Force
};
"GASeniorManagerA" = @{
"ou" = "総務部";
"securityGroups" = @( "総務部"; "管理職" );
"password" = ConvertTo-SecureString "P@ssw0rd" -AsPlainText -Force
};
"President" = @{
"ou" = "総務部";
"securityGroups" = @( "総務部"; "役員" );
"password" = ConvertTo-SecureString "P@ssw0rd" -AsPlainText -Force
};
"ldap_bind" = @{
"securityGroups" = @();
"password" = ConvertTo-SecureString "P@ssw0rd" -AsPlainText -Force
}
}
. .\ad_config.ps1
$ComputerSystem = Get-WmiObject Win32_ComputerSystem
if (! $ComputerSystem.PartOfDomain){
Write-Host "Install AD-Domain-Services"
Install-WindowsFeature -name AD-Domain-Services
Write-Host "Install Active Directory Forest: $domainName"
Install-ADDSForest -domainname $domainName
exit 0
}
$domainDN = "DC=" + $domainName -replace "\.", ",DC="
function CreateOUs {
param (
$ou,
$baseDn
)
foreach ($key in $ou.keys) {
Write-Host "Create OU: OU=$key,$baseDn"
New-ADOrganizationalUnit -Name $key -Path $baseDn
CreateOUs -ou $ou[$key] -baseDn "OU=$key,$baseDn"
}
}
CreateOUs -ou $ou -baseDn $domainDN
foreach ($sg in $securityGroups){
Write-Host "Create Active Directory Security Group: $sg"
New-ADGroup -Name $sg -GroupScope Global -Path "OU=groups,$domainDN"
}
foreach ($username in $users.keys) {
# $usersの定義にouが含まれていればそのOUにユーザーを配置し、なければデフォルトで存在するUsersコンテナに配置する
if ($users[$username].ContainsKey('ou')) {
$filter = 'Name -eq "{0}"' -f $users[$username]['ou']
$path = (Get-ADOrganizationalUnit -Filter $filter -SearchBase $domainDn).DistinguishedName
} else {
$path = "CN=Users,$domainDN"
}
Write-Host "Create Active Directory User: $username"
New-ADUser $username -AccountPassword $users[$username]['password'] -Path $path -Enabled $true
foreach ($sg in $users[$username]['securityGroups']){
Write-Host "Add $username to $sg"
Add-ADGroupMember -Identity $sg -Members $username
}
}
4.OSインストール
Windows 10 ProでのHyper-Vの有効化の方法については過去の記事にあるのでこちらを参照ください。
Hyper-Vマネージャーを起動し、[操作] > [新規] > [仮想マシン]を選択
メモリが少なすぎるとActive Directoryの初期構成時失敗するので、起動メモリを2048MBに変更し、動的メモリのチェックを外して次へ
ネットワークの構成は、後で他の仮想マシンからLDAP接続できるように、接続を[Default Switch]に変更して次へ
仮想ハードディスクの設定はデフォルトのままでも、気になるようなら名前、場所、サイズを適宜変更して次へ
インストールオプションは[ブートイメージファイルからオペレーティングシステムをインストールする]を選択し、ダウンロードしたISOファイルを[参照]から選んできて次へ
Hyper-Vマネージャから作成された仮想マシンを右クリックから[接続]する
仮想マシンのウィンドウが出るので、[起動]を押してしばらくすると"Press any key to boot from CD or DVD"と出るので、すぐに何かキーを押す。タイミングが遅いとPXEブートしようとして失敗してしまうので、そうなったらリセットしてリトライする。
また、起動時にPCの空きメモリが少ないと失敗することがあるので、仮想マシンの起動に失敗ブラウザなどのメモリを食うアプリを終了してから起動する。
インストーラーが起動したら[次へ] -> [今すぐインストール]
オペレーティングシステムは少ないリソースで動く、一番上のStandardのデスクトップエクスペリエンスなしを選択して次へ行き、ライセンス条項に[同意します]をONにして次へ
インストールの種類は初期インストールなのでカスタムの方を選択しドライブもそのままで[次へ]を押すと、インストールが始まるのでしばらく待つ
パスワード変更を促されるので、任意のパスワードを入力して更新すると、OSインストール完了。
ホスト名は自動生成されたものになっているので、wmicコマンドで適当なホスト名に変更する
C:\Users\Administrator>hostname
WIN-HNON1CCPM0M
C:\Users\Administrator>wmic computersystem where name="%computername%" call rename name="adsv01"
(\\WIN-HNON1CCPM0M\ROOT\CIMV2:Win32_ComputerSystem.Name="WIN-HNON1CCPM0M")->rename() を実行しています
メソッドが正しく実行しました。
出力パラメーター
instance of __PARAMETERS
{
ReturnValue = 0;
};
C:\Users\Administrator>hostname
WIN-HNON1CCPM0M <-再起動するまで未反映
この時点でOSをシャットダウンしてチェックポイントを作っておくと、後の作業で失敗したときにリトライしやすいので取っておく。
仮想マシン接続のウィンドウで[操作] > [チェックポイント] から作成できる。
5.Active Directory構築用スクリプト実行
まずはスクリプトをサーバー上に保存する。
サーバーにログインするとコマンドプロンプトの状態になるので、notepadと入力してメモ帳を立ち上げて、スクリプトをコピペして名前を付けて保存する。
C:\Users\Administrator>notepad ad_config.ps1
→ メモ帳が開くので、ad_config.ps1をコピペして保存して終了
C:\Users\Administrator>notepad ad_setup.ps1
→ 同様にad_setup.ps1をコピペして保存して終了
C:\Users\Administrator>powershell
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
PS C:\Users\Administrator> .\ad_setup.ps1
Install AD-Domain-Services
Success Restart Needed Exit Code Feature Result
------- -------------- --------- --------------
True No Success {Active Directory ドメイン サービス, リモ...
Install Active Directory Forest: mycompany.test
SafeModeAdministratorPassword: ************** <-Safe Mode用Administratorのパスワード入力
SafeModeAdministratorPassword を確認してください: ************** <-パスワード再入力
ターゲット サーバーは、ドメイン コントローラーとして構成され、この操作が完了すると再起動されます。
この操作を続行しますか?
[Y] はい(Y) [A] すべて続行(A) [N] いいえ(N) [L] すべて無視(L) [S] 中断(S) [?] ヘルプ (既定値は "Y"): Y
警告: Windows Server 2019 ドメイン コントローラーには、セキュリティ設定 "Windows NT 4.0
と互換性のある暗号化アルゴリズムを許可する" の既定値が設定されています。これにより、セキュリティ チャネル
セッションを確立するときに、セキュリティの弱い暗号化アルゴリズムの使用は許可されなくなります。
この設定の詳細については、サポート技術情報 (KB) の記事 942564 (http://go.microsoft.com/fwlink/?LinkId=104751)
を参照してください。
警告: このコンピューターには、IP プロパティに静的 IP アドレスが割り当てられていない物理ネットワーク
アダプターが、少なくとも 1 つあります。ネットワーク アダプターで IPv4 と IPv6
の両方が有効にされている場合、そのネットワーク アダプターの IPv4 および IPv6 プロパティの両方に、IPv4 と IPv6
の両方の静的 IP アドレスを割り当てる必要があります。ドメイン ネーム システム (DNS)
動作を信頼できるものにするために、このような静的 IP アドレスの割り当てを、すべての物理ネットワーク
アダプターに対して行う必要があります。
警告: 権限のある親ゾーンが見つからないか、Windows DNS サーバーが実行されていないため、この DNS
サーバーの委任を作成できません。既存の DNS インフラストラクチャと統合する場合は、ドメイン "mycompany.test"
外からの名前解決が確実に行われるように、親ゾーンでこの DNS
サーバーへの委任を手動で作成する必要があります。それ以外の場合は、何もする必要はありません。
警告: Windows Server 2019 ドメイン コントローラーには、セキュリティ設定 "Windows NT 4.0
と互換性のある暗号化アルゴリズムを許可する" の既定値が設定されています。これにより、セキュリティ チャネル
セッションを確立するときに、セキュリティの弱い暗号化アルゴリズムの使用は許可されなくなります。
この設定の詳細については、サポート技術情報 (KB) の記事 942564 (http://go.microsoft.com/fwlink/?LinkId=104751)
を参照してください。
警告: 権限のある親ゾーンが見つからないか、Windows DNS サーバーが実行されていないため、この DNS
サーバーの委任を作成できません。既存の DNS インフラストラクチャと統合する場合は、ドメイン "mycompany.test"
外からの名前解決が確実に行われるように、親ゾーンでこの DNS
サーバーへの委任を手動で作成する必要があります。それ以外の場合は、何もする必要はありません。
Message : 操作は正常に完了しました
Context : DCPromo.General.3
RebootRequired : False
Status : Success
PS C:\>
スクリプト実行の後、自動で再起動が行われる。
2つ目の警告は、Hyper-Vのネットワーク接続で設定した「Default Switch」がDHCPでIPアドレスを自動設定するために出ているものだが、今回は検証なので気にしないことにする。
起動後にはActive Directoryサーバーとして動いているので、Administratorで再度ログインし、OUやユーザーの設定をする。
ad_config.ps1を変更して再実行したいときのために、OUやユーザー設定の前にチェックポイントを作っておくとよい。
ad_setup.ps1スクリプトは、サーバーがADサーバーになっていたら後続の設定を実行するようになっているので、先ほどと同様にスクリプトを実行する。
ad_setup.ps1は冪等性をあまり考慮していないため、ad_config.ps1を変更したい場合やad_setup.ps1の実行に失敗した場合には一度チェックポイントに戻してから実行する方がよい。
C:\Users\Administrator>powershell
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
PS C:\Users\Administrator> .\ad_setup.ps1
Create OU: OU=総務部,DC=mycompany,DC=test
Create OU: OU=営業部,DC=mycompany,DC=test
Create OU: OU=営業第一,OU=営業部,DC=mycompany,DC=test
Create OU: OU=営業第二,OU=営業部,DC=mycompany,DC=test
Create OU: OU=技術部,DC=mycompany,DC=test
Create OU: OU=技術第一,OU=技術部,DC=mycompany,DC=test
Create OU: OU=技術第二,OU=技術部,DC=mycompany,DC=test
Create OU: OU=Groups,DC=mycompany,DC=test
Create Active Directory Security Group: 営業部
Create Active Directory Security Group: 営業第一
Create Active Directory Security Group: 営業第二
Create Active Directory Security Group: 技術部
Create Active Directory Security Group: 技術第一
Create Active Directory Security Group: 技術第二
Create Active Directory Security Group: 総務部
Create Active Directory Security Group: 管理職
Create Active Directory Security Group: 役員
Create Active Directory User: President
Add President to 総務部
Add President to 役員
Create Active Directory User: SalesSeniorManagerA
Add SalesSeniorManagerA to 営業第一
Add SalesSeniorManagerA to 営業第二
Add SalesSeniorManagerA to 管理職
Create Active Directory User: SalesManagerA
Add SalesManagerA to 営業第一
Add SalesManagerA to 管理職
Create Active Directory User: ldap_bind
Create Active Directory User: SalesStaffA
Add SalesStaffA to 営業第一
Create Active Directory User: TechManagerB
Add TechManagerB to 技術第二
Create Active Directory User: TechManagerA
Add TechManagerA to 技術第一
Add TechManagerA to 管理職
Create Active Directory User: TechStaffB
Add TechStaffB to 技術第二
Create Active Directory User: GAManagerA
Add GAManagerA to 総務部
Add GAManagerA to 管理職
Create Active Directory User: SalesStaffB
Add SalesStaffB to 営業第二
Create Active Directory User: GAStaffA
Add GAStaffA to 総務部
Create Active Directory User: TechStaffA
Add TechStaffA to 技術第一
Create Active Directory User: SalesManagerB
Add SalesManagerB to 営業第二
Create Active Directory User: GASeniorManagerA
Add GASeniorManagerA to 総務部
Add GASeniorManagerA to 管理職
Create Active Directory User: TechSeniorManagerA
Add TechSeniorManagerA to 技術第一
Add TechSeniorManagerA to 技術第二
Add TechSeniorManagerA to 管理職
PS C:\Users\Administrator>
スクリプトがエラーなく終了すれば、設定は成功。
最後に、メモリ節約のためにサーバーを一度シャットダウンして、メモリを512MBに設定し直す。
仮想マシンがOFFの状態で、仮想マシン接続ウィンドウから[ファイル] > [設定] > [メモリ] > RAMを512MB、動的メモリをOFFにして[OK]
6.動作確認
動作確認のためにLDAPクライアントでサーバーに接続し、想定通りにOUなどが作成されているかを確認する。
今回はLdapAdminというツールで確認する。
→https://ja.osdn.net/projects/sfnet_ldapadmin/
LdapAdmin.exeを起動し、[Start] > [Connect] でConnectionsというウィンドウが開いたら、[New connection]のアイコンをダブルクリックする。
Connection nameを適当に入力し、以下の通り設定を変更する
- Host: <サーバー名>.mshome.net
※Hyper-Vを設定変更せずにDefault Switchを使うとDHCPでIPアドレスがころころ変わるが、同じようにDHCPで動かしているホストOSやゲストOSからは"<サーバー名>.mshome.net" という名前で一定してアクセスすることができる。 - Base: DC=Mycompany,DC=test
- Anonymous connection: チェックを外す
- Username: CN=ldap_bind,CN=Users,DC=mycompany,DC=test
- Password: ad_config.ps1で設定したldap_bindユーザーのパスワード
[Test connection]を押して Connection is successfull. と出たら[OK] > [OK] とし、新しくできた接続用アイコンを選択して[OK]とすると、GUIでOU、ユーザー、グループなどの情報を見られるので想定通りになっているか確認する。
さいごに
この環境で、ホストOSや他に作ったゲストOSからLDAPの連携テストをすることができるようになった。
今回は別ホストからのアクセスは考慮していないため、そういったことをしたい場合にはIPアドレスを固定する設定をしたり外部からのアクセスを許可するような設定が必要だったり追加作業が必要になる。