はじめに
こんにちは、IaC技術推進部の山路です。オンプレミスにある現在のシステムをクラウドへ移行したい、と考えている方は少なくないかと思いますが、クラウドへ移行をする場合はオンプレと異なる観点で考慮しなければならない事項がいくつかあります。そのような考慮次項のひとつとして、ファイルサーバーをどのように構成するか、という点で悩む方も多いかと思います。
先日、Azureのマネージドファイル共有サービスであるAzure Filesにおいて、オンプレのAD DS(Active Directory Domain Service)によるID認証をサポートする機能がGAとなりました。今回はAzure FilesとActive Directoryとを連携させてID認証を利用し、Active Directory上のID情報を用いてAzure Filesにアクセスする方法について紹介します。また従来オンプレミスで利用することの多いWindowsファイルサーバーと比べて、Azure Filesは何ができて何ができないかについても紹介いたします。
Azure Filesとは
Azure FilesはAzureが提供するマネージドファイル共有サービスです。Azure FilesはAzure Storageに含まれる機能の一つであり、クラウド・オンプレミスのマシンからSMBプロトコルによってアクセスすることが可能です。Azure Filesは以下のような特徴を備えています。
- マネージドサービスである:マネージドサービスのため、利用者はハードウェアやOSの管理をする必要はありません。
- Windows/Linux/Macに対応:Azure FilesはWindows/Linux/Macで利用可能であり、同じAzure Filesに対して異なるOS(WindowsとLinuxなど)から同時に接続することも可能です。
- 2つのプランから選択:Azure Storageは
Standard
Premium
の2つから選択することができます。Azure Filesは選択したプランによって性能やコストが変化します。Standard
はHDDベース、Premium
はSSDベースのハードウェアでサービスが提供されます。 - 冗長性:Azure FilesはAzure Storageに含まれるサービスの一つです。Azure Storageは冗長性オプションのタイプが複数用意されており、
LRS(Local Redundanct Storage)
やGZRS(Geo Zone Redundancy Storage)
など、様々なスケールのデータ冗長性を提供するオプションを選択することが可能です。 - 複数の接続方法がある:Azure Filesは、物理・仮想マシンからネットワークドライブをマウントする、Azure Storage Explolerを利用する、REST API経由でアクセスするなど、様々な方法でアクセスすることが可能です。
- Backupに対応:Azure FilesはAzure BackupやSnapshotに対応しており、データのバックアップを容易に取得することが可能です。
一方で、Azure Filesには制限事項もいくつか含まれます。
- 利用プロトコル:Azure FilesはSMB3.0にのみ対応しています。そのためWindows 7やWindows 2008といった古いバージョンのクライアントは利用することができません。
- 容量:Azure Filesでは最大100TBまでスケールアップすることができます。
Premium
プランでは利用開始時点から100TBまでスケールアップすることができますが、Standard
プランは利用開始時点で5TBまでしか利用できず、100TBまで利用するにはStorage Accountでの設定変更が必要です。また本記事執筆の時点では、100TBまで利用する場合、データ冗長性オプションはGeoスケールの冗長性を提供するものが利用できません。 - ポート:Azure FilesはSMBプロトコルを利用するため、クライアント側で445番ポートを開放する必要があります。オンプレミスのクライアントから接続する場合は、Virtual Network GatewayやExpressRouteを経由してAzure Filesにアクセスすることも可能です。
※参考リンク:
Azure FilesとAD DSを連携する
Azure FilesはオンプレミスのAD DS、もしくはAzure Active Directory Domain Services(Azure AD DS)を利用した、IDベースの認証を利用することができます。通常Azure Filesの提供するネットワークドライブをマウントする場合、Storage Accountへアクセスするのに必要なアクセスキーを指定する必要があるのですが、IDベースの認証が有効になっている場合、Azure Filesへのアクセスを許可したユーザーであれば、Azure Filesの提供するエンドポイントを指定し、マウントすることが可能になります。
また、Azure Filesでは大きく2種類のアクセス制御を利用することができます。これにより、オンプレミスのWindowsファイルサーバーで利用したようなユーザー・グループごとのアクセス制御を実現することができます。
- ロールベースのアクセス制御(RBAC):Azure ADのユーザー・グループに対し、リソース毎に設定することのできるアクセス制御です。RBACでは主にAzure Filesへのアクセスを許可するか否かの制御を行うことができます。
- Windows DACL (Discretionary Access Control List)での制御:Azure FilesではWindowsのファイルサーバーと同じように、格納されたディレクトリ・ファイルに対してどのユーザー・グループがアクセスできるかを設定することができます。DACLは主にAzure Files内のディレクトリ・ファイル毎のアクセスを許可するか否かについて制御を行います。
※アクセス制御に関する図
Azure Files - AD DSの連携の仕組み
Azure FilesとAD DSとを連携するには、AD DSの持つID情報をAzure ADと同期し、Azure ADとAD DSに同一のIDを用意する必要があります。Azure ADとAD DSとのID同期にはAzure AD Connect (AADC)を利用します。
Azure FilesとAD DSとのID連携ではKerberosプロトコルを利用します。ドメインに参加しているクライアントがAzure Filesへアクセスすると、その要求はAD DSへと送信され、AD DSでの認証が成功するとKerberosトークンがクライアントへ返されます。Azure FilesはKerberosトークンを見てアクセスを承認し、クライアントからAzure Filesへアクセスすることが可能になります。
構築概要
ここからはAzure FilesとAD DSとの連携した環境を実際に構築します。作業の大まかな流れは以下の通りです。なお、今回は仮想マシンを作成し、ADサーバーを構築するところから開始するため、必要に応じて手順をスキップしていただければと思います。
構築準備作業
- Azure ADへのカスタムドメインの登録
- Azure VMの作成
本構築手順
- AD DS環境の構築
- Azure ADとAD DSとの同期
- クライアントVMのドメイン参加
- Azure Filesの作成
- Azure FIlesのAD DS認証の有効化
- Azure RBACによるAzure Filesへのアクセス権付与
- Windows DACLによるフォルダ・ファイルレベルでのアクセス権付与
- クライアントVMからのAzure Filesマウント
- AADCによる同期の停止
- Azureリソースの削除
注意事項
Azure FilesとAD DSとの連携する環境を用意するには、いくつか前提となる条件があります。これら前提条件を満たしていないまま作業を始めると、後から大きな手戻りが発生することもあるので、注意してください。
Azure ADに関する注意事項
- 利用するAzure ADとAzure Filesとは、同じサブスクリプションに関連づけられている必要があります。一つのサブスクリプションは単一のAzure ADとしか関連付けることができないので、別々のAzure ADを利用してAzure Filesと連携することはできません。
- Azure ADとAD DSとを同期する際、事前にAzure ADにカスタムドメインを登録する必要があります。カスタムドメインにはAD DSで利用するドメインを指定して登録するのに加え、ドメイン名レジストラーに新しいTXTレコードを作成する必要があります。このTXTレコードを作成後に反映されるまで、最大72時間ほどかかる場合があるので、前もって作業を行ったほうが良いです。
AD DSに関する注意事項
- Azure Filesのアクセス制御が有効なIDは、Azure ADとAD DSで同期されたIDのみです。Azure ADとAD DSのそれぞれに対して、異なるアクセス制御の仕組みを適用するため、両方にIDがなければアクセス制御の対象外となります。例えば、Azure VM作成時に指定する管理者アカウントはBuilt-in Administratorであり、これはAADCを利用してもAzure ADには同期されません(その他、AADCで同期されないものはこちらを参照)。
AADCに関する注意事項
AADCはSLD (Single Label Domain)をサポートしません。SLDとは.com、.corp、.net、.orgなどのサフィックスを含まないDNS名を指します。
AADCでAzure ADとの同期を行う際は、Azure ADの全体管理者アカウントが必要になります。Azureの利用開始時に使用できるアカウントであるMicrosoftアカウントではこの操作はできないので、別途ユーザーを作成し、ロールを付与する必要があります。
AADCで設定をする際に同期ドメインの登録を行うのですが、その際既存のアカウントを利用する場合はEnterprise Adminアカウントは利用できません。AADCの同期に利用する新規アカウントの作成を許容できる場合は、特に問題にはなりません。
その他ハードウェア・OS等の制限はこちらのページから。
※参考リンク:
クライアントマシンに関する前提条件
- これは当たり前のことですが、Azure Files - AD DSによるID認証を利用するマシンは、対象のドメインに参加している必要があります。ドメインに参加していない場合は、通常通りストレージアカウントのアクセスキーなどを利用したアクセス方法しか利用できません。
構築手順の紹介
ここから実際の構築手順を紹介します。
構築環境情報
構築した環境情報は以下の通りです。
Terraform version
: v0.12.19provider.azurerm
: v2.13.0
Azure
Region
: Japan East
構築準備作業
1. Azure ADへのカスタムドメインの登録
まずはAzure ADに今回利用するドメインの登録をしておきます。ドメインへのTXTレコード反映が最大72時間ほどかかる場合もあるので、これを最初にやっておきます。
Azureポータルから「Azure AD」を選択し、「Custom domain names」を選択します。「Custom domain names」画面に移動したら、「Add custom domain」を選択し、利用するドメイン名を入力します。
ドメイン登録が完了すると、以下の画面のようにレコード情報が表示されるので、ドメインのレジストラ等で表示されたレコード情報を登録します。
レコードの登録後、画面下の「Verify」を選択します。レコードの登録が反映されている場合はAzure ADでの確認が完了し、登録したドメイン情報を確認すると以下のように表示されます。
ここでの設定は、AADCによるID同期の際に必要となります。レコード登録が反映されるまでの間に、次の作業を行っても問題ありませんが、AADCの作業時にはAzure AD側でドメインが確認できている必要があります。
2. Azure VMの作成
次に今回利用する仮想マシンを用意します。今回はTerraformを利用して3台の仮想マシンを構築しましたが、もちろんAzureポータルから作成しても問題ありません。なお、AADCをADサーバにインストールして利用するのは非推奨となります(公式ドキュメントを参照)。
このステップで作成するリソースは以下の表の通りです。なお、Azure Filesはここでは作成せず、後ほど作成します。
リソース種別 | リソース名 | 用途 |
---|---|---|
リソースグループ | terraform_azure_rg |
作成したAzureリソースを一括で管理するために利用 |
仮想ネットワーク | terraform_vnet |
Azure上の仮想ネットワーク。アドレス空間は10.0.0.0/16 |
サブネット | terraform_subnet |
仮想ネットワーク上に置くサブネット。アドレス範囲は10.0.0.0/24 |
ネットワークセキュリティグループ | terraform_nsg |
ローカルからVMへアクセスするために利用 |
NIC | terraform_windows_nic |
Windowsクライアントに割り当てるNIC |
terraform_ad_nic |
ADに割り当てるNIC | |
terraform_aadc_nic |
AADCに割り当てるNIC | |
パブリックIPアドレス | terraform_windows_pip |
Windowsクライアントに付与するパブリックIPアドレス |
terraform_ad_pip |
ADに付与するパブリックIPアドレス | |
terraform_aadc_pip |
AADCに付与するパブリックIPアドレス | |
仮想マシン | testwindows |
Windowsクライアント |
testad |
ADサーバ | |
testaadc |
AADCサーバ |
作成に利用したTerraformのtfファイルはこちらです。なお、ここでは3台の仮想マシンに別々の管理者アカウントを付与していますが、こちらは3台とも同名のアカウントを指定しても問題ありません。
provider.tf
# provider provider "azurerm" { features {} subscription_id = "<サブスクリプションID>" client_id = "<アプリケーションID>" client_secret = "<パスワード>" tenant_id = "<テナントID>" }
main.tf
# Resource Group resource "azurerm_resource_group" "rg" { name = var.rg_name location = var.location } # virtual network resource "azurerm_virtual_network" "vnet" { name = var.vnet_name address_space = [var.vnet_address_space] location = var.location resource_group_name = var.rg_name depends_on = [azurerm_resource_group.rg] } # subnet resource "azurerm_subnet" "subnet" { name = var.subnet_name resource_group_name = var.rg_name virtual_network_name = var.vnet_name address_prefixes = [var.subnet_address_prefixes] depends_on = [azurerm_virtual_network.vnet] } # nsg resource "azurerm_network_security_group" "nsg" { name = var.nsg_name location = var.location resource_group_name = var.rg_name depends_on = [azurerm_subnet.subnet] security_rule { name = "RDP" priority = 1001 direction = "Inbound" access = "Allow" protocol = "Tcp" source_port_range = "*" destination_port_range = "3389" source_address_prefix = var.allowed_local_address destination_address_prefix = "*" } } # associate nsg to subnet resource "azurerm_subnet_network_security_group_association" "nsg_subnet_association" { subnet_id = azurerm_subnet.subnet.id network_security_group_id = azurerm_network_security_group.nsg.id depends_on = [azurerm_network_security_group.nsg, azurerm_subnet.subnet] } # public_ip resource "azurerm_public_ip" "publicip_windows" { name = var.windows_public_ip_name location = var.location resource_group_name = var.rg_name allocation_method = "Dynamic" depends_on = [azurerm_resource_group.rg] } resource "azurerm_public_ip" "publicip_ad" { name = "terraform_ad_pip" location = var.location resource_group_name = var.rg_name allocation_method = "Dynamic" depends_on = [azurerm_resource_group.rg] } resource "azurerm_public_ip" "publicip_aadc" { name = "terraform_aadc_pip" location = var.location resource_group_name = var.rg_name allocation_method = "Dynamic" depends_on = [azurerm_resource_group.rg] } # nic resource "azurerm_network_interface" "nic-windows" { name = var.windows_nic_name location = var.location resource_group_name = var.rg_name depends_on = [azurerm_public_ip.publicip_windows] ip_configuration { name = var.windows_nic_ipconfig_name subnet_id = azurerm_subnet.subnet.id private_ip_address_allocation = "Dynamic" public_ip_address_id = azurerm_public_ip.publicip_windows.id } } resource "azurerm_network_interface" "nic-ad" { name = "terraform_ad_nic" location = var.location resource_group_name = var.rg_name depends_on = [azurerm_public_ip.publicip_ad] ip_configuration { name = "terraform_ad_nic_ipconfig" subnet_id = azurerm_subnet.subnet.id private_ip_address_allocation = "Dynamic" public_ip_address_id = azurerm_public_ip.publicip_ad.id } } resource "azurerm_network_interface" "nic-aadc" { name = "terraform_aadc_nic" location = var.location resource_group_name = var.rg_name depends_on = [azurerm_public_ip.publicip_aadc] ip_configuration { name = "terraform_aadc_nic_ipconfig" subnet_id = azurerm_subnet.subnet.id private_ip_address_allocation = "Dynamic" public_ip_address_id = azurerm_public_ip.publicip_aadc.id } } resource "azurerm_windows_virtual_machine" "windows" { name = var.windows_vm_name resource_group_name = var.rg_name location = var.location size = var.windows_vm_size admin_username = var.windows_admin_user_name admin_password = var.windows_admin_password network_interface_ids = [azurerm_network_interface.nic-windows.id] os_disk { caching = "ReadWrite" storage_account_type = "Standard_LRS" } source_image_reference { publisher = "MicrosoftWindowsServer" offer = "WindowsServer" sku = "2016-Datacenter" version = "latest" } } resource "azurerm_windows_virtual_machine" "ad" { name = "testad" resource_group_name = var.rg_name location = var.location size = var.ad_vm_size admin_username = var.ad_admin_user_name admin_password = var.ad_admin_password network_interface_ids = [azurerm_network_interface.nic-ad.id] os_disk { caching = "ReadWrite" storage_account_type = "Standard_LRS" } source_image_reference { publisher = "MicrosoftWindowsServer" offer = "WindowsServer" sku = "2016-Datacenter" version = "latest" } } resource "azurerm_windows_virtual_machine" "aadc" { name = "testaadc" resource_group_name = var.rg_name location = var.location size = var.aadc_vm_size admin_username = var.aadc_admin_user_name admin_password = var.aadc_admin_password network_interface_ids = [azurerm_network_interface.nic-aadc.id] os_disk { caching = "ReadWrite" storage_account_type = "Standard_LRS" } source_image_reference { publisher = "MicrosoftWindowsServer" offer = "WindowsServer" sku = "2016-Datacenter" version = "latest" } } # output value data "azurerm_public_ip" "publicip_windows" { name = azurerm_public_ip.publicip_windows.name resource_group_name = azurerm_windows_virtual_machine.windows.resource_group_name } data "azurerm_public_ip" "publicip_ad" { name = azurerm_public_ip.publicip_ad.name resource_group_name = azurerm_windows_virtual_machine.ad.resource_group_name } data "azurerm_public_ip" "publicip_aadc" { name = azurerm_public_ip.publicip_aadc.name resource_group_name = azurerm_windows_virtual_machine.aadc.resource_group_name } output "ip_addr_windows" { value = data.azurerm_public_ip.publicip_windows.ip_address } output "ip_addr_ad" { value = data.azurerm_public_ip.publicip_ad.ip_address } output "ip_addr_aadc" { value = data.azurerm_public_ip.publicip_aadc.ip_address }
variables.tf
# common variable "location" { default = "japaneast" } # resource group variable "rg_name" { default = "terraform_azure_rg" } # virtual network variable "vnet_name" { default = "terraform_vnet" } variable "vnet_address_space" { default = "10.0.0.0/16" } # subnet variable "subnet_name" { default = "terraform_subnet" } variable "subnet_address_prefixes" { default = "10.0.0.0/24" } # NSG variable "nsg_name" { default = "terraform_sg" } variable "allowed_local_address" { default = "<仮想マシンにアクセスするローカルのIPアドレスを指定>" } # public ip variable "windows_public_ip_name" { default = "terraform_windows_pip" } # nic variable "windows_nic_name" { default = "terraform_windows_nic" } variable "windows_nic_ipconfig_name" { default = "terraform_windows_nic_ipconfig" } # VM variable "windows_vm_name" { default = "testwindows" } variable "windows_vm_size" { default = "Standard_D2s_v3" } variable "windows_admin_user_name" { default = "testadm01" } variable "windows_admin_password" { default = "<ログインパスワードを指定>" } variable "ad_vm_size" { default = "Standard_D2s_v3" } variable "ad_admin_user_name" { default = "testadm02" } variable "ad_admin_password" { default = "<ログインパスワードを指定>" } variable "aadc_vm_size" { default = "Standard_D2s_v3" } variable "aadc_admin_user_name" { default = "testadm03" } variable "aadc_admin_password" { default = "<ログインパスワードを指定>" }
※構築環境模式図
上記tfファイルを利用してリソースを作成します。リソースの作成が完了すると、各VMに付与されたパブリックIPアドレスが表示されるので、そのIPを指定してRDPでログインします。
# 初期化 C:\azure-terraform\azurefiles_ad\vm>terraform init # バリデーション確認 C:\azure-terraform\azurefiles_ad\vm>terraform validate # 作成予定のリソースを確認 C:\azure-terraform\azurefiles_ad\vm>terraform plan (中略) Plan: 14 to add, 0 to change, 0 to destroy. # リソースの作成 C:\azure-terraform\azurefiles_ad\vm>terraform apply (中略) Plan: 0 to add, 0 to change, 14 to destroy. Do you really want to destroy all resources? Terraform will destroy all your managed infrastructure, as shown above. There is no undo. Only 'yes' will be accepted to confirm. Enter a value: yes # yesと入力してEnterキーを実行 (中略) Apply complete! Resources: 14 added, 0 changed, 0 destroyed. Outputs: ip_addr_aadc = 20.37.115.29 ip_addr_ad = 20.37.115.48 ip_addr_windows = 20.37.115.50
本構築手順
1. AD DS環境の構築
AD DSのインストール
まずAD DS環境の構築を行います。ここでは作成した仮想マシンのうちtestad
にログインして作業を行います。なお、今回は英語表記のまま作業を行いましたが、必要に応じて日本語化作業を行ってください。
※参考リンク:
ADの構築は、Server Managerから「Add roles and features」を選択します。「Server Roles」で「Active Directory Domain Services」を選択し、インストールを行います。それ以外の設定はデフォルトで行っています。
ドメインコントローラーへの昇格
続いてドメインコントローラーへの昇格を行います。今回は新規構築のため、新しいフォレストを導入するよう選択し、利用するドメインを入力します。
ドメイン指定後はデフォルトの設定値のままドメインコントローラーへの昇格を行い、マシンの再起動を行います。
マシンの再起動が完了したら、ここでテスト用ユーザーとOUを作成します。Azure FilesでAD DSの認証を有効化する際、AD DSのOUを指定し、対象のOUに含まれるユーザーを認証可能とするため、あらかじめ用意しておく必要があります。
今回は以下の2ユーザーと1OUを用意しました。
- User:
testuser01
、testuer02
- OU:
StorageAccountOU
2つのユーザーはStorageAccountOU
へ移動し、Azure Filesへアクセスできるようにしておきます。
参照先DNSの変更
ADの構築は完了しましたが、他のマシンがドメインに参加できるよう、ADサーバーをDNS参照先とするよう設定する必要があります。DNS参照先を変更するには、Azureポータルから設定変更を行います。
Azure VMのDNS参照先は、VMが所属する仮想ネットワーク、もしくはNICの設定によって決まります。デフォルトではAzureの既定のDNSサーバーを参照するよう設定していますので、これをADサーバーへと変更します。
今回は仮想ネットワークのDNS参照先を変更しました。仮想ネットワークのDNS参照先を変更することで、所属するすべてのVMの参照先を変更することが可能になります。変更後はVMを再起動することで設定が反映されるので、各VMの再起動も行います。
※参考リンク:
2. Azure ADとAD DSとの同期
続いてAzure ADとAD DSのID同期を行うため、AADCの構築を行います。
まずはtestaadc
にRDPでログインをし、ドメイン参加を行います。
続いてAADCのインストールを行います。AADCはMicrosoftのこちらのページからダウンロードをし、msiファイルを実行することでインストールされます。
インストールが完了するとAADCが起動し、以下のような画面が表示されます。
ライセンスとプライバシーに同意し次の画面に進むと、簡易インストールであるExpress Settingを利用するか尋ねられます。今回はカスタム設定を利用するため、「Customize」を選択します。
カスタム設定では、まずAADCを動作するのに必要なコンポーネントのインストールを開始します。必要なコンポーネントのうち、既にインストール済みのものがある場合は、そちらを利用することもできます。
次にサインインの形式を選択します。ここではデフォルトのパスワードハッシュ同期を選択しました(サインインオプションの詳細はこちらから)。
続いて同期するAzure ADを選択します。Azure ADに作成したユーザーのうち、全体管理者の権限を持つユーザーを指定して、Azure ADと接続します。
続いて同期するADのドメインを登録します。「FOREST」には所属するドメイン名が表示されるはずですが、この時点ではまだ利用できる状態ではなく、明示的にドメインを追加する必要があります。ドメインを追加するため「Add Directory」を選択します。
ドメインの登録画面では、新しいユーザーを作成するか、既存のユーザーを利用するかを選択します。今回は新しいユーザーの作成を選択し、Enterprise Admin権限を持つユーザー(ここではドメイン管理者アカウント)のID/PW情報を入力します。
登録が完了すると、以下の画面のように登録したドメインが表示されるので、次へ進みます。
次にAzure ADにサインインするため、Azure AD側でのドメイン登録状況が表示されます。ここで「Verified」と表示されている場合は、Azure ADとAD DSとのドメインが一致していることが確認できているため、次に進んでも問題ありません。
Azure AD側で指定したドメインが登録されていない、あるいは確認が済んでいない場合は「Not Added」「Not Verified」と表示されます。この場合は「構築準備作業:1. Azure ADへのカスタムドメインの登録」の手順に戻り、ドメインの登録・確認が必要になります。Azure AD側で「Verified」でない状態でも、以降の作業を進めること自体は可能ですが、この段階でドメインの登録等を済ませておいたほうが手戻りは発生しにくいと思います。
続いてドメイン・OUによる同期IDのフィルタリングを設定する画面になります。今回は全てのドメイン・OUを同期しますが、必要に応じて同期するドメイン等を選択してください。
続いて、AD DS内のユーザーと、Azure AD内ユーザーの識別方法を選択します。
まず、AD DS内でユーザーをどのように識別しているかを選択します。今回はフォレスト内で一意のアカウントのみが存在するため、デフォルトで選択されているUser are represented only once across all directories
を選択します。複数のフォレスト間で同じアカウントが存在する場合は、それらを識別する要素を選択する必要があります(各選択肢の内容はこちらを参照)。
次にAzure AD内での識別方法を選択します。ここではSourceAnchorという、Azure ADとAD DS間で同期したユーザーが同一であることを確認するために使う属性について、Azure ADに管理を任せるか、Azure ADに既存のポリシーを指定するかを選択します。ここではAzure ADにSourceAnchorの管理を任せるため、Let Azure manage the source anchor
を選択します。
※参考ドキュメント:
続いて同期するユーザー・デバイスの選択を行います。今回は全てのユーザーとデバイスを同期するよう選択します。
続いてオプションの選択です。今回は特に指定せず次に進みます。
なおここでは3つのオプションが選択可能となっています。各オプションを有効にした場合、それぞれ以下のような機能を提供します。その他オプションについてはこちらから内容を確認することができます。
Azure AD app and attribute filtering
: 同期される属性のセットをカスタマイズすることができます。Password writeback
: Azure ADでパスワードを変更した場合、その変更はAD DS側にそれが反映されます(詳細はこちらから)。Directory extension attribute sync
: 指定した属性をAzure ADに同期することができます。
最後にインストールの開始画面が表示されます。ここではAADCの設定が完了したら同期を開始するか、設定のみを行い同期は改めて手動で行うかを選択できます。
同期が完了すると、以下のような画面が表示されますので、AADCの設定・同期は終了です。
同期が完了してからしばらく待つと、Azure AD側でもユーザーを確認することができます。なお「Sync_・・・」で始まるアカウントは、AADCが同期を行うために新規に作成されるユーザーです。
3. クライアントVMのドメイン参加
つぎにクライアントVMをドメインに参加させます。testwindows
VMに対してRDPログインを行い、ドメインに参加します。合わせてADで新規に作成したユーザーアカウント(ここではtestuser01
testuser02
)でログインできるかを確認しておきましょう。RDPでログインする前に、testwindows
でリモートアクセスを有効にする必要があります。VM作成時点ではネットワークレベルの認証が有効になっているため、アクセスを許可するユーザーを追加するか、NLAを無効化します(NLA無効化は非推奨)。
※参考リンク:
4. Azure Filesの作成
ここまででAzure ADとAD DSのID同期が完了しましたので、続いてAzure Filesを作成します。
Azure Filesの作成には、先ほどAzureリソースを作成した時と同様にTerraformを利用しますが、Azureポータルから作成しても問題ありません。
リソース種別 | リソース名 | 用途 |
---|---|---|
ストレージアカウント | ランダムに生成される文字列 |
Azure Storage全般を利用するのに必要 |
Azure Files (Fileshare) | terraformfs |
マネージドファイル共有サービスとして利用 |
今回利用したtfファイルは以下の通りです。Azure Filesを作成するには、まずストレージアカウントを用意する必要がありますが、ストレージアカウントの名称はグローバルに一意なものを指定する必要があります。そのため、ここではランダムな文字列を生成し、それをストレージアカウント名として指定しています。
main.tf
# storage accdount ID resource "random_id" "randomId" { keepers = { # Generate a new ID only when a new resource group is defined resource_group = var.rg_name } byte_length = 8 } # storage account resource "azurerm_storage_account" "sa" { name = "diag${random_id.randomId.hex}" resource_group_name = var.rg_name location = var.location account_tier = "Standard" account_replication_type = "LRS" //depends_on = [azurerm_resource_group.rg] } # file share resource "azurerm_storage_share" "fileshare" { name = var.fileshare_name storage_account_name = azurerm_storage_account.sa.name quota = var.fileshare_quota }
variables.tf
# common variable "location" { default = "japaneast" } # resource group variable "rg_name" { default = "terraform_azure_rg" } # file share variable "fileshare_name" { default = "terraformfs" } variable "fileshare_quota" { default = 50 }
上記tfファイルを利用してリソースを作成します。
# 初期化 C:\azure-terraform\azurefiles_ad\files>terraform init # バリデーション確認 C:\azure-terraform\azurefiles_ad\files>terraform validate # 作成予定リソースの確認 C:\azure-terraform\azurefiles_ad\files>terraform plan (中略) Plan: 3 to add, 0 to change, 0 to destroy. # リソース作成 C:\azure-terraform\azurefiles_ad\files>terraform apply (中略) Plan: 3 to add, 0 to change, 0 to destroy. Do you want to perform these actions? Terraform will perform the actions described above. Only 'yes' will be accepted to approve. Enter a value: yes # yesと入力してEnterキーを実行 (中略) Apply complete! Resources: 3 added, 0 changed, 0 destroyed.
5. Azure FIlesのAD DS認証の有効化
Azure Filesを作成したので、次にAD DS認証の有効化を行います。AD DS認証を有効にするには、AzFilesHybrid
というPowershellモジュールを利用し、ストレージアカウントをAD DSに登録する必要があります。登録に必要なコマンドを実行する際にドメインとOUを指定し、対象のドメイン・OUによる認証を有効化します。
ここではストレージアカウントにAD DSを登録するために用意されたスクリプトを利用して作業を行います。こちらのページには、登録スクリプトを実行するうえでの前提条件があります。検証時には特に問題となるポイントはありませんが、念のためご確認ください。
まずはtestad
VMにtestadm02
アカウントでログインし、PowerShellを開きます。次に、仮想マシン、またはローカル端末からAzFileHybridモジュールをダウンロードします。
モジュールをダウンロードしたのち、ファイルを解凍すると、以下の3つのファイルが確認できると思います。
AzFilesHybrid.psd1
AzFilesHybrid.psm1
CopyToPSPath.ps1
解凍後、以下の通りコマンドを実行します。
# AzFileHybridを実行可能にするため、実行ポリシーを変更する PS C:\windows\system32> Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope CurrentUser # 解凍したファイルから”CopyToPSPath.ps1”を実行する。実行時のパスは適宜変更 PS C:\windows\system32> .\CopyToPSPath.ps1 # AzFileHybridのインポート PS C:\windows\system32> Import-Module -Name AzFilesHybrid This module requires Azure PowerShell ("Az" module) 2.8.0+ and Az.Storage 2.0.0+. This can be installed now if you are running as an administrator. [Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"): #Yを入力してEnterキーを実行 # Azureと接続する。接続時はストレージアカウント所有者、もしくは共同作成者のRBACロールが付与されたアカウントを指定 PS C:\windows\system32> Connect-AzAccount Account SubscriptionName TenantId Environment ------- ---------------- -------- ----------- <アカウント名> 従量課金制 <テナントID> AzureCloud # 変数の指定 PS C:\windows\system32> $SubscriptionId = "<サブスクリプションID>" PS C:\windows\system32> $ResourceGroupName = "terraform_azure_rg" PS C:\windows\system32> $StorageAccountName = "diag8194a1fdaf499471" # 利用するサブスクリプションを指定 PS C:\windows\system32> Select-AzSubscription -SubscriptionId $SubscriptionId Name Account SubscriptionName Environment TenantId ---- ------- ---------------- ----------- -------- 従量課金制 (<サブスクリプションID>) <アカウント名> 従量課金制 AzureCloud <テナントID> # ストレージアカウントにAD DSを登録 PS C:\windows\system32> Join-AzStorageAccountForAuth -ResourceGroupName $ResourceGroupName -Name $StorageAccountName -OrganizationalUnitName "StorageAccountOU" StorageAccountName ResourceGroupName PrimaryLocation SkuName Kind AccessTier CreationTime ProvisioningState ------------------ ----------------- --------------- ------- ---- ---------- ------------ -------- diag8194a1fdaf499471 terraform_azure_rg japaneast Standard_LRS StorageV2 Hot 6/17/2020 2:00:20 AM Succe...
Connect-AzAccount
を実行すると、以下の画像のようにアクセス情報を入力する画面が表示されるので、ストレージアカウント所有者、もしくは共同作成者のRBACロールが付与されたアカウントを指定してログインします。
上記コマンド完了後、登録が完了したかを確認します。
PS C:\windows\system32> Debug-AzStorageAccountAuth -StorageAccountName $StorageAccountName -ResourceGroupName $ResourceGroupName -Verbose (中略) VERBOSE: CheckStorageAccountDomainJoined - SUCCESS VERBOSE: Summary of checks: CheckADObjectPasswordIsCorrect Passed CheckADObject Passed CheckDomainJoined Passed CheckPort445Connectivity Passed CheckSidHasAadUser Failed★ CheckGetKerberosTicket Passed CheckStorageAccountDomainJoined Passed CheckAadUserHasSid Skipped PS C:\windows\system32>
ここでCheckSidHasAadUser
がFailedとなっていますが、これはコマンド実行時、Azure ADに登録されていないtestadm02
というアカウントを使用しているためです。その他チェック項目はパスしているので、AD DS情報の登録は完了しております。
※参考リンク:
6. Azure RBACによるAzure Filesへのアクセス権付与
続いてAzure FilesにアクセスするIDに対して、Azure RBACを利用してアクセス権を付与します。Azure Filesにアクセスするには、次の3種類の組み込みロールを利用することができます。
Storage File Data SMB Share Contributor
:Azure Filesへの読み取り・書き込み、削除アクセスを許可します。Storage File Data SMB Share Elevated Contributor
:Azure FilesのWindows DACLの読み取り・書き込み・削除・変更を許可します。Storage File Data SMB Share Reader
:Azure Filesへの読み取りアクセスを許可します。
Azure Filesへのアクセス権を付与するには、Azureポータルから「Storage Account」→「Access Control(IAM)」へ移動し、「Add Role Assignment」を選択します。
対象のロールとそれを適用するユーザー・グループを選択します。「Assign access to」はデフォルトで選択されるAzure AD user, group, or service principal
を選択します。
ユーザーごとに適切なロールを付与します。今回はtestuser01
にStorage File Data SMB Share Contributor
、testuser02
にStorage File Data SMB Share Reader
を割り当てます。
※参考リンク:
7. Windows DACLによるフォルダ・ファイルレベルでのアクセス権付与
続いてAzure Filesに対してWindows DACLのアクセス制御を行います。Windows DACLのアクセス制御を行う方法は、Windowsエクスプローラーから行う方法とicacls
コマンドを利用する方法とがあります。今回はエクスプローラーから行う方法を紹介します。
まずADサーバーからAzure Filesをマウントします。マウントの際はストレージアカウントキーを利用するので、事前にキー情報を確認しておきます。
キー情報を確認したら、ADサーバー上でコマンドプロンプトを起動し、以下のようにnet use
コマンドを実行します。コマンド実行時のオプションの指定は、以下の通りです。
net use <ドライブレター>: \\<Storage Account名>.file.core.windows.net\<Azure Files名> /user:Azure\<Storage Account名> <Storage Accountキー>
今回は各オプションについて、以下のように指定しました。
ドライブレター
:ZStorage Account名
:diag8194a1fdaf499471Azure Files名
:terraformfs
C:\Users\testadm02>net use Z: \\diag8194a1fdaf499471.file.core.windows.net\terraformfs /user:Azure\diag8194a1fdaf499471 <Storage Accountキー> The command completed successfully. C:\Users\testadm02>
Azure Filesのマウントが成功したので、WindowsエクスプローラーからWindows DACLを設定します。設定の方法は通常のWindowsサーバー上で行うものと同じく、制御するファイル・フォルダからプロパティを選択し、「Security」タブから権限を操作します。
「Add」を選択し、アクセス権を追加するユーザーを入力します。
今回はtestuser01
に読み取り・書き込み権限を付与します。
なお、Azure Filesを作成した時点では、デフォルトで以下のようなアクセス許可がされています。
- BUILTIN\Administrators:(OI)(CI)(F)
- NT AUTHORITY\SYSTEM:(OI)(CI)(F)
- BUILTIN\Users:(RX)
- BUILTIN\Users:(OI)(CI)(IO)(GR,GE)
- NT authority \authenticated Users:(OI)(CI)(M)
- NT AUTHORITY\SYSTEM:(F)
- CREATOR OWNER:(OI)(CI)(IO)(F)
※参考リンク:
上記のうちauthenticated Users
が許可されているため、デフォルトでは同期した認証ID全てに対してアクセスが許可されます。そのため、今回は上記デフォルトの設定からauthenticated Users
を削除し、testuser01
のみに読み取り・書き込み権限を付与しました。
設定変更後は以下のようなアクセス権となっています。
C:\Users\testadm02>icacls Z:\ Z:\ CREATOR OWNER:(OI)(CI)(IO)(F) NT AUTHORITY\SYSTEM:(OI)(CI)(F) BUILTIN\Administrators:(OI)(CI)(F) <ドメイン>\testuser01:(OI)(CI)(RX)★ Successfully processed 1 files; Failed processing 0 files C:\Users\testadm02>
ここまででAzure Filesに必要な設定が完了します。また、後程testuser01
でのアクセス権を確認するため、testadm02
アカウントでいくつかテスト用フォルダ・ファイルを作成しておきます。
※参考リンク:
8. クライアントVMからのAzure Filesマウント
最後にWindowsクライアントからAzure Filesをマウントします。マウント時にはnet use
コマンドを利用しますが、先ほどとは違いストレージアカウントキー情報などは含みません。
まずWindowsクライアントにtestuser01
アカウントでログインをし、コマンドプロンプトを起動します。起動後、以下のようにコマンドを実行します。
# コマンド体系 # net use <ドライブレター>: \\<Storage Account名>.file.core.windows.net\<Azure Files名> C:\Users\testuser01>net use Z: \\diag8194a1fdaf499471.file.core.windows.net\terraformfs The command completed successfully. C:\Users\testuser01>
マウントが完了したのでアクセスをしてみます。
事前にtestadm02
アカウントで作成しておいたファイルも読み取ることができます。
またファイルを作成できることも確認できます。
次にtestuser02
でAzure Filesにアクセスします。testuser02
はAzure RBACによりAzure Filesをマウントすることは可能ですが、Windows DACLによるアクセス権は付与されていないので、以下のようにアクセスをすることができません。
なお、terraformfs
内にあるファイルにアクセス制御を設定することで、testuser01
から対象のファイルにアクセスした際は、以下のようにエラーメッセージが表示されることも確認できています。
ここまでで、Azure FilesとAD DSとを連携し、ID認証を用いてAzure Filesをマウントできること、Windows DACLによるアクセス制御ができることが確認できました。
※参考リンク:
9. AADCによる同期の停止
前項まででAzure FilesとAD DSの連携は確認できました。一通り検証が完了した後は、作成したリソースの削除を行います。
AADC同期の無効化
まずはAADCでの同期を無効化し、AADCのアンインストールを行います。同期を無効にするにはMSOnline
モジュールを利用してAzureと接続し、Set-MsolDirSyncEnabled
を利用して同期の無効化を行います。
MSOnline
モジュールを導入するには、NuGet
のインストールを行う必要があります。NuGetは2020年4月以降は、ダウンロード・インストールはTLS1.2のみ利用可能となっている一方、Windows Server 2016 PowerShellはデフォルトではTLS1.0のみ利用可能となっています。これを解決するため、ここではPowerShellGet
モジュールを2.2.4以上にすることでTLS1.2を強制的に利用するよう変更しています。
# バージョン情報 PS C:\Users\testadm02> $PSVersionTable Name Value ---- ----- PSVersion 5.1.14393.3471 PSEdition Desktop PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...} BuildVersion 10.0.14393.3471 CLRVersion 4.0.30319.42000 WSManStackVersion 3.0 PSRemotingProtocolVersion 2.3 SerializationVersion 1.1.0.1 PS C:\Users\testadm02> # PowerShellGetモジュールの更新 PS C:\Users\testadm02> [Net.ServicePointManager]::SecurityProtocol Ssl3, Tls PS C:\Users\testadm02> [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 PS C:\Users\testadm02> Install-Module PowerShellGet -RequiredVersion 2.2.4 -SkipPublisherCheck NuGet provider is required to continue PowerShellGet requires NuGet provider version '2.8.5.201' or newer to interact with NuGet-based repositories. The NuGet provider must be available in 'C:\Program Files\PackageManagement\ProviderAssemblies' or 'C:\Users\testadm02\AppData\Local\PackageManagement\ProviderAssemblies'. You can also install the NuGet provider by running 'Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force'. Do you want PowerShellGet to install and import the NuGet provider now? [Y] Yes [N] No [S] Suspend [?] Help (default is "Y"): # Enterキーを実行 Untrusted repository You are installing the modules from an untrusted repository. If you trust this repository, change its InstallationPolicy value by running the Set-PSRepository cmdlet. Are you sure you want to install the modules from 'PSGallery'? [Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "N"): Y # Yを入力しEnterキーを実行 PS C:\Users\testadm02> # MSOnlineモジュールのインストール PS C:\Users\testadm02> Install-Module MSOnline Untrusted repository You are installing the modules from an untrusted repository. If you trust this repository, change its InstallationPolicy value by running the Set-PSRepository cmdlet. Are you sure you want to install the modules from 'PSGallery'? [Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "N"): Y # Yを入力しEnterキーを実行 PS C:\Users\testadm02> # Azureに接続 PS C:\Users\testadm02> $credential = Get-Credential cmdlet Get-Credential at command pipeline position 1 Supply values for the following parameters: Credential PS C:\Users\testadm02> Connect-MsolService -Credential $credential PS C:\Users\testadm02> # ドメインの確認 PS C:\Users\testadm02> Get-MsolDomain Name Status Authentication ---- ------ -------------- <既定のドメイン> Verified Managed <追加ドメイン> Verified Managed <既定のドメインメールアドレス> Verified Managed PS C:\Users\testadm02> # AADC同期の無効化 PS C:\Users\testadm02> Set-MsolDirSyncEnabled -EnableDirSync $false Confirm Continue with this operation? [Y] Yes [N] No [S] Suspend [?] Help (default is "Y"): # Enterキーを実行 PS C:\Users\testadm02> # 確認 PS C:\Users\testadm02> (Get-MSOLCompanyInformation).DirectorySynchronizationEnabled False PS C:\Users\testadm02>
AADCの同期が無効化されたのは、Azureポータルからも確認できます。
※参考ドキュメント:
焦げlog - Windows PowerShell から NuGet プロバイダーがインストールできなくなった原因と対処方法について
Classmethod - [PowerShell] PowerShell GalleryがTLS 1.2を強制する様になりました
AADCのアンインストール
AADCの同期を無効化したので、AADCのアンインストールを行います。
コントロールパネルからプログラムのアンインストールを開き、「Microsoft Azure AD Connect」を右クリックし、「Uninstall」を選択します。
AADCのアンインストール画面が表示されるので、「Remove」を選択します。この時、AADCをインストールした際に一緒にインストールされたコンポーネントも、合わせてアンインストールするかを選択することができます。
アンインストール開始からしばらくすると、以下のような画面が表示され、アンインストールが完了します。
プログラム画面に戻ると、AADCや周辺コンポーネントがアンインストールされていることが確認できます。
10. Azureリソースの削除
Azure Filesの削除
最後に作成したAzureリソースの削除を行います。Terraformで作成をした場合はterraform destroy
コマンドを実行すれば削除されます。Azureポータルから作成した場合は、リソースグループの削除を行えば、リソースグループ内のすべてのリソースが削除されるので、そちらのほうが楽かと思います。
まずはAzure Files・ストレージアカウントを削除します。
C:\azure-terraform\azurefiles_ad\files>terraform destroy (中略) Plan: 0 to add, 0 to change, 3 to destroy. Do you really want to destroy all resources? Terraform will destroy all your managed infrastructure, as shown above. There is no undo. Only 'yes' will be accepted to confirm. Enter a value: yes # yesと入力してEnterキーを実行 (中略) Destroy complete! Resources: 3 destroyed.
Azure AD登録ドメインの削除
続いてVMの削除を行いますが、その前にAzure ADに登録していたドメインを削除しておきます。
削除するにはいくつか条件を満たす必要があります。ここでは指定ドメインに紐づくユーザーをすべて削除する必要がある、と表示されています。
該当のユーザーを削除します。今回はtestuser01
testuser02
に加え、AADCで同期をした際に自動的に作成されたユーザーも合わせて削除します。
ユーザー削除後はカスタムドメインの削除が可能となりますので、削除します。合わせて、利用したドメインレジストラーの設定から、TXTレコードの削除もしておきましょう。
仮想マシンの削除
最後に仮想マシンを削除して完了です。
# terraform destroy C:\azure-terraform\azurefiles_ad\vm>terraform destroy (中略) Plan: 0 to add, 0 to change, 14 to destroy. Do you really want to destroy all resources? Terraform will destroy all your managed infrastructure, as shown above. There is no undo. Only 'yes' will be accepted to confirm. Enter a value: yes # yesと入力してEnterキーを実行 (中略) Destroy complete! Resources: 14 destroyed.
Azure FilesとAD DSの連携でできること・できないこと
前項まででAzure FilesとAD DSが連携され、ID認証ベースでのアクセス制御を行うことが確認できました。一方、これまでのWindowsファイルサーバーではアクセス制御だけでなく、様々な機能を利用することができました。ここからは、既存のWindowsファイルサーバーと比較し、Azure Filesで利用できる機能について見ていきます。
クォータ制御
WindowsファイルサーバーではFile Server Resource Managerを利用したクォータの制御を行い、ファイルサーバー内の各フォルダでどれだけの容量を利用してよいか、上限を設定することができました。しかし、Azure FilesはFile Server Resource Managerを経由したクォータの設定はできません。
一方、クォータを制限していた理由の一つに、ファイルサーバー上に大量のファイルを配置し、ディスク容量を超えてしまうことを防ぐことがあるかと思います。Azure Filesの場合はフォルダの利用上限をいつでも拡張することが可能なため、対応が可能となります。
シャドウコピーによる世代管理
Windowsではボリュームシャドウコピー(VSS)を利用することでストレージ上のデータのバックアップを取得することができます。ファイルサーバー上のファイルを誤って削除したとき、VSSを有効にしていれば、ファイルサーバー上からの復旧が可能となります。
一方、Azure Filesはネットワークドライブをマウントする形で利用しますが、VSSはネットワークドライブに適用することができません。そのため、Azure FilesでVSS機能を利用することはできません。その代わり、Azure FIlesはAzure BackupやSnapshotに対応しており、バックアップデータからファイル単位での復旧が可能となります。
※2020.7.19追記:
Azure Backupを利用する場合、Azureポータル、またはマウントしたWindows OSからのファイル復旧を行うことができます。これにより、従来のVSSと同じような操作感でファイル復旧を実行することが可能です。
Azure Backupの利用方法についてはこちらの記事で説明をしております。
※参考ドキュメント:
また、Azure FilesにはSoft Deleteという機能が利用できます。これはAzure Filesを削除した際に一定期間データを保持し、期限内であれば削除したAzure Filesを復旧することのできる機能です。
Azureポータルから設定をする場合は、「Soft delete」という項目を選択し、本機能を有効にします。またバックアップデータの所持期間も指定します。なお保持期間は1~365日の間で設定できます。
なお、Soft Delete機能は本記事執筆時点ではプレビューの機能となります。
※参考ドキュメント:
アクセスログ
Windowsファイルサーバーを利用している場合、共有フォルダのアクセスログを記録することで、どのユーザーがファイルにアクセスしたかを記録することが可能でした。一方Azure Filesは、現時点ではWindows OSで利用するようなアクセスログを取得することはできません。
監視
Windowsファイルサーバーのパフォーマンスや容量などを監視する際は、Zabbixなど別の監視サーバーを用意したりサービスを利用することが多いかと思います。Azure Filesの場合、Azure Monitorと連携しており、作成時点から監視サービスを利用することができます。
Azure Monitor for Storageは、Azureストレージの容量やパフォーマンス、可用性などをモニターします。一方、Azure MonitorではAzure Filesにアクセスしたユーザーの情報などは確認することができないため、アクセスログの代わりとなるような機能ではありません。
モニターを有効にするには、ストレージアカウントのページから有効化する必要があります。
有効化をすると、以下の画面のようにAzure Filesの監視が開始されます。
※参考リンク:
最後に
本記事ではAzure FilesとAD DSを連携してID認証を利用する方法、そしてAzure Filesで現状実現できることについて紹介しました。
既存のWindowsファイルサーバーとAzure Filesを比較した場合、これまで通りには利用できないいくつかの制限事項があることを記載しました。Azure Filesの利用に関する制限事項を許容できる場合、Azure Filesを利用することで、ファイルサーバーの管理・運用コストを削減することや、データの高可用性を担保することが可能です。一方で従来通りWindowsファイルサーバーとその機能を利用したい場合は、Azure上に仮想マシンを作成し、Windowsファイルサーバーを作成する必要があります。ただしその場合、仮想マシンやディスクの冗長性、データの可用性については利用者が設計をする必要があります。
どちらもメリット・デメリットがあり、またどちらの方法を採用するかはシステムの要件によって決まりますので、構築するファイルサーバーに求められる機能を検討したうえで選択していただければと思います。