たいちの何か

趣味を中心に車・クラウド・サーバーなどの話を勝手気ままに書いています

Azure - サービスプリンシパルを使ってPoweshellスクリプトでAzureに自動ログインする その2

会社のPMP(Project Management Professional)の研修の準備と、研修でバタバタしてBlog更新ができませんでした(言い訳)
さて、今日は実際に証明書を使ってサービスプリンシパルを作成し、Azureに自動ログインしてみたいと思います。
自動ログインを実現する方法には、大きく2通りありますが、今回はよりセキュアな方法ということで 証明書 を使った方法を試そうと思います。

以前の記事はこちらから
edge.hateblo.jp

目次

Powershellを用意する

今回はAzureADに自動ログインさせるために、Azure Resouce Manager用のPowershellモジュール(以下AzureRM)が必要になります。
AzureRMのインストールは以下のリンクを参照してください。

docs.microsoft.com

証明書の確認

今回は証明書を新たに用意するのが面倒だったので、既存の証明書を使用するので、証明書の場所を確認します!*1

Powershellを実行するコンピューターでMMCを起動し、証明書(コンピューター)を開きます。ここに幾つか証明書があるので、今回は、証明書の個人ストアにある一番下のクライアント証明書を使ってサービスプリンシパルを作ってみようと思います。 *2

証明書を使ってサービスプリンシパルを作成する

  • まずPowershellを起動し、AzureRMモジュールを読み込みます。
Import-module Azurerm
  • 読み込みが完了したら、以下のコマンドを実行し、AzureADにログインをします。  
** #AzureADにログインする(ポップアップがでます) **
Login-AzureRmAccount
  • ローカルコンピューターの証明書ストアから、<<証明書のSubject名を入れる>>にマッチする証明書を抽出し変数に代入します。
$cert =  $Thumbprint = (Get-ChildItem cert:LocalMachine\My\ | Where-Object {$_.Subject -match "<<証明書のSubject名を入れる>>" })  
  • 取得した証明書情報のフォーマットを変換します。
$keyValue = [System.Convert]::ToBase64String($cert.GetRawCertData())  
  • AzureADにサービスプリンシパルを作成する。-DisplayNameには任意の名称をつけます。この時、CertValueオプションとEnddate/Startdateオプションを使い証明書情報をAzureに送信します。
$sp = New-AzureRMADServicePrincipal -DisplayName "Powerhsell_Auto_logon" -CertValue $keyValue -EndDate $cert.NotAfter -StartDate  cert.NotBefore  
  • 最後にアサインメントをして完了です
New-AzureRmRoleAssignment -RoleDefinitionName Contributor -ServicePrincipalName $sp.ApplicationId
  • Azureポータルを確認すると、Powershell_Auto_logonというサービスプリンシパルが作成されていることが確認できました。    f:id:taitioooo:20170902232614p:plain

Powershellを使って自動ログインを試す

次にPowershellを使ってAzureVMの一覧を取得してみようと思います。
サービスプリンシパルがきちんと作成できていれば、パスワードを聞かれることなくAzureVMの一覧が入手できるはずですが、そう簡単にはイカないようです。
自動ログインしてコマンドを実行するには、証明書情報をAzureに教えて上げる必要があります。
そのおまじないが以下の構文です。

注意:今回コンピューター証明書を使ってサービスプリンシパルを作っているので、powershellは管理者として実行させてください

$Thumbprint = (Get-ChildItem cert:\CurrentUser\My\ | Where-Object {$_.Subject -match "<<サービスプリンシパル作成時に使った証明書のSubject名を入れる>>" }).Thumbprint
Login-AzureRmAccount -ServicePrincipal -CertificateThumbprint $Thumbprint -ApplicationId "<<作成したサービスプリンシパルのアプリケーションIDを入れる>>" -TenantId "AzureポータルのテナントIDを入れる"

上記コマンド実行後に Get-AzurermVM を実行するとAzure上の仮想マシン一覧を取得できます。 パスワードの入力画面はありませんでしたね。

最後に

いかがでしょうか。この方法を使うことで、Powershell内部にパスワードやアカウント情報を記載しなくて良いので、人の異動などにも影響されず、もしスクリプトが盗まれた場合でも、証明書も一緒に盗まれない限り、他の場所からのログインもできません。
PowershellでAzureを管理したいと考えている皆さん、一度試してみてはいかがでしょうか。

次回は何をするの?

次回は、Office365に同様の方法でログインする方法を紹介したいと思います。 (Office365の自動ログイン方法をググってみたら、証明書を使った方法が全くヒットしなかったため。殆どの記事はパスワードを埋め込む方式でした…)

*1:本来はサービスプリンシパル用の証明書を内部CAから発行するほうがよいですが、今回はテストなので…

*2:証明書(ユーザー)でも大丈夫ですが、Powershellの実行アカウントを気にする必要があるので、今回はコンピューターを使いました。

Azure - テナント制御を使ってOffice365の個人利用を禁止する その1

企業でパプリッククラウドを使う際に問題の一つ。個人のアカウントでサービスにログインできてしまう問題を解決する方法についてまとめてみました。

目次

何が問題なの?

企業がOffice365などのパブリッククラウドサービスを導入した場合、社員は自分のPCなどからOffice365などにサインインしてメールなどを利用します。
例えばメールを利用する場合であれば、Outlookクライアントを使ったり、Outlook Web appを使ったり、スマートフォンで使ってアクセスしています。それらの方法の裏側ではOffice365のExchange onlineへの接続が行われています。

これまでもOffice365へのログインのセキュリティを高めるべく、企業はADFSなどのフェデレーション機能を使って、様々な対策を行ってきています。

上記の対応により、自社が許可した場所や端末からのみアクセスが許可されるようになったのですが、これのどこに問題があるのでしょうか。

それは、 自社内から個人のアカウントでもOffice365にログインできてしまう ということです。
*1

これは、Office365と言うサービスが一つのプラットフォーム上に企業のアカウントも個人のアカウントも一緒に管理していることが原因です。Office365側としては、アカウントとパスワードが正しければログインさせない理由はないので、ログインできてしまうというわけです。
Office365では、この企業や個人の契約単位をテナントと表現します。

ではどうするか?
そこで登場するのが、Azure ADの新機能*2である “テナント制御” です。

テナント制御すると何がいいの

テナント制御を実装することで、自社内から自社のテナント(契約)にのみログインさせることが可能となります。つまり、個人のアカウントに一切アクセスできなくなるということです。
この機能を実装することで企業は、クラウド利用の完全コントロールに大きく近づくことが可能となります。

f:id:taitioooo:20170825214502p:plain 引用:https://blogs.technet.microsoft.com/office365-tech-japan/2017/02/06/tenant-restrictions/

どうやってテナント制御するの

テナント制御の実態はHTTPヘッダーに記載された以下の2つの情報です。

Restrict-Access-To-Tenants: テナント名
Restrict-Access-Context: テナントID

上記の2つのヘッダー情報は、プロキシサーバーで挿入します。*3
通常、クラウドサービスへのアクセスはhttpsプロトコルとなりますので、SSLインターセプトが可能なプロキシサーバーが必要となってきます。
このあたりは、セキュリティを意識している企業であれば導入済みのはずなので、あまり敷居は高くなさそうですね。イメージとしてはこんな感じです。(即席で作ったので雑な絵ですいません…)

f:id:taitioooo:20170825222353p:plain

また、ヘッダーを挿入する パケット・ URL は以下の 3 つのみで大丈夫なようなのでプロキシ サーバーの負荷も軽減できそうです。

login.microsoftonline.com
login.windows.net
login.microsoft.com

上の図を見ると分かる人もいたかもしれませんが、この方法の良いところはHttpパケットに対して処理をしているという点です。つまり、Windows, Linux, Andoroid, iOSなど全ての端末に対応できるということです。
たった2つのヘッダーで数千台の端末を制御できる。それも 追加費用無し で。

ちなみに、この方法Office365だけでなくGoogle Appsなど他のSaaSアプリケーションでも使える方法なのです。

support.google.com

ちなみにOffice365でテナント制御を行うには以下の条件をクリアする必要があります。

  • SSL インターセプトが行え、指定した URL に対して HTTP ヘッダーを挿入できるプロキシ サーバーがあること (サーバー証明書の実装含む)
  • Office 365 テナント及び クライアント ソフトウェアで、Modern Authentication (先進認証/ADAL) が有効になっていること
  • すべてのクライアントが本プロキシ サーバー経由で Office 365 に接続されること

注意点はある?

はいあります。httpプロトコルを使わないで認証を行うもの(例えばOutlookSkypeのレガシー認証)は、テナント制御の管理外となってしまいます。*4
これらの製品を制御するためには、Modern Authentication (先進認証/ADAL) に対応したOffice製品が必要です。各OSの先進認証対応状況は下図の通りのようです。

f:id:taitioooo:20170825224344p:plain
引用:https://blogs.office.com/en-us/2015/11/19/updated-office-365-modern-authentication-public-preview/

これを見ると、殆ど全てのOSで先進認証対応となっているようです。
WindowsだけでなくiOS, AndoroidのOfficeクライアントでも先進認証が有効になっているのは凄いですね。
Windows Phoneの対応が遅れいるところは、Microsoftの戦略が如実にあらわれていて少し笑ってしまいました。

いかがでしょうか。テナント制御、結構使えそうではないですか?
次回は、テナント制御が本当に動くか、検証をしてみたいと思います。

関連ページ

Azure - Cloud App DiscoveryでPCがアクセスしたクラウドサービスを検出する その1 - たいちの何か
Azure - Cloud App DiscoveryでPCがアクセスしたクラウドサービスを検出する その2 - たいちの何か

*1:シングルサインオンを実装していても同じです

*2:2017年2月リリース

*3:ブラウザでもプラグインがあれば挿入可能ですが管理性の面からプロキシサーバ一択となると思います

*4:プロキシを経由しないので当たり前ですね

Azure - Cloud App DiscoveryでPCがアクセスしたクラウドサービスを検出する その2

前回Cloud App DiscoveryをPCをにセットアップしてログを見てみましたが、その後1週間ほどログを収集して見たので、その結果をまとめます。

前回の記事 edge.hateblo.jp

目次

なんのログを収集したの?

FacebookやOnedriveなどインターネット上のSNSやストレージサービスなどへのアクセスログを収集しました。
Cloud App Discoveryのデータ収集範囲は、全てのクラウドアプリケーション としました。
全てのクラウドアプリケーションといってもAzureが対応しているものに限られますが、今日時点で1465個のクラウドアプリを認識できるようです。
代表的なものには、[twitter] [Facebook] [youtube]などがありました。
f:id:taitioooo:20170822233556p:plain

どうやってログを収集するの?

ログを収集したいPCやサーバーにAgentをインストールするだけです。
インストール時の設定は必要ありませんが、AgentをAzureポータルから入手する時に設定が必要になります。

具体的には、以下の3点です。
下記項目を決めた後に、Agentのダウンロードが可能になります。

  • ログの収集ポリシー
  • Deep Inspection (HTTPS通信もログ収集の対象とするか)
  • Agentの自動アップデートを行うか
ログ収集ポリシー 説明
No notification or consent required Web traffic monitoring will begin immediately and without notifying user.(ユーザへ通知せずにログ収集を開始する。)
Require notification Upon logon, the user will be notified that web traffic is monitored. The agent will only start collecting web traffic after the user acknowledges the notification.(ログオン後、ユーザにトラフィックが監視されていることを通知し、ユーザが認識した後にログ収集を開始する。)
Require user consent Upon logon, the user will be asked to approve data collection. The agent will only start collecting web traffic if the user selects ‘Approve’.(ログイン後、データ収集についてユーザが承認した場合のみ、ログ収集を開始する。)

f:id:taitioooo:20170822234916p:plain

私は以下の設定でAgentをダウンロードしました。 Deep Inspectionについては、昨今Google検索やYahoo検索を始め、多くのサービスでHttps通信を強制している状況を鑑みるとHTTPSの通信も監視して降りたほうが良いと考え、設定をONにしました。

設定
ログ収集ポリシー No notification or consent required
Deep Inspection ON
Autoupdate ON

収集結果

思った以上の情報が取得できました。
サービスはもとより、誰が、いつ、どこに、どの程度のデータを送受信したかまで詳細に表示されています。

f:id:taitioooo:20170822233436p:plain

これって結構すごいことなんじゃないかと思います。
Agentを入れるだけで、インターネットに接続されたPCから自動でAzure ADにログが送信され、自動で解析までしてくれる。
管理者が行うことは、Azure ADプレミアムを契約し、AgentをPCに配布/インストールするだけです。

Cloud App DiscveryはAzure ADプレミアムを契約すると、利用することができます。
多くのユーザはADFSなどの機能を使うためにAADプレミアムを契約している人も多いかと思います。 実はAADプレミアムにはいろんな機能がついているのですが、そのうち1−2個しか使っていないのが現状ではないでしょうか。

azure.microsoft.com  

一人あたり数百円/月でも1000人いれば数十万円/月のコストになり、なんとなく割高感を感じている人も多いかと思います。
そういう人こそAzure ADプレミアムの使っていない機能に目を向けて見てはいかがでしょうか。
役に立つ機能が、すでに利用可能な状態となっていますよ。

Azure - サービスプリンシパルを使ってPoweshellスクリプトでAzureに自動ログインする その1

定常化された作業はスクリプトなどで自動化し省力化することは多々あるかと思います。
もちろんAzureも例に漏れず、自動化することで省力化できる部分はたくさんありますが、多くの人が悩まされていないでしょうか? Azureへのログオン処理 に。

ベタな方法だと、以下のコマンドで都度認証情報を入力するという感じですが、これでは自動化の効果も半減してしまいます。

Add-AzureRMAccount
Add-AzureAccount

今日は、Azureの仕組みを使ってPowershellスクリプトの自動ログインの方法を考えてみたいと思います。  

目次

自動ログオンをするには?

下記リンクにサービスプリンシパルを使って自動ログオンする方法が詳しく載っているのですが、意外と難解なところが多いのでこの記事では簡単にまとめてみようと思います。

docs.microsoft.com

リソースへのアクセスを必要とするアプリやスクリプトがある場合は、アプリの ID を設定し、アプリを独自の資格情報で認証できます。 この ID は、サービス プリンシパルと呼ばれます。 このアプローチを使用すると、以下のことを実行できます。
 ・ユーザー自身のアクセス許可とは異なるアクセス許可を、アプリケーション ID に割り当てることができます。 通常、こうしたアクセス許可は、アプリが行う必要があることに制限されます。
 ・無人スクリプトを実行するときに、証明書を使用して認証できます。

そもそもサービスプリンシパルってなに?

サービスプリンシパルを初めて聞いて、「あれでしょ?」って思った人がいたらすごいと思います。自分も最初、なにこれ?美味しいの?って思いました。

Azureにおけるサービスプリンシパルとは、 Azureのリソースにアクセスするアプリケーションが利用する専用のID を指します。
じゃぁ、アプリケーションがAzureにアクセスするときはサービスプリンシパルが絶対必要なの?という疑問も湧きますが、必須ではありません。
AzureADに設定されたユーザーアカウントを使ってもOKです。

しかし、サービスプリンシパルを使わないと様々な不都合が出てきてしまいます。一例を上げると…

不都合 正しい形
使用しているアカウントの権限でアプリケーションがログイン/操作をしてしまう アカウント乗っ取りなどのインシデントに備えて、必要最低限の権限のみ与えるべき
ユーザが退職などでいなくなったときに、アプリケーションが動かなくなる アプリケーションが利用するアカウントは常に利用可能な状態にする
アプリケーションのログインも、ユーザ本人によるログインも同じユーザ名で記録される 用途や人に応じてログインユーザ名を変える。(セキュリティインシデントが起きた時にログを追跡できなくなる恐れがある)
本来不要な対話型ログオンの仕組みがスクリプトに提供されてしまう アプリケーションは非対話型のログインとする

これらの不都合を解消し、よりセキュアにアプリケーションを稼働させるためのIDが サービスプリンシパル という仕組みです。よりわかりやすい説明がSlideshareにあったのでリンクを張っておきます。

www.slideshare.net

ちなみにAzureポータル上でサービスプリンシパルを確認したい場合は、Azure ADの以下パスにアクセスします。
[Azure Active Directory] - [アプリの登録]

f:id:taitioooo:20170815225241p:plain

サービスプリンシパルの作成方法は?

サービスプリンシパルの作成の方法は大きく分けて[パスワード方式]と[証明書方式]の2種類があります。
さらに[証明書方式]は[自己署名証明書]と[証明機関から発行された証明書]の2通りあります。
個人用途であれば、パスワードや自己署名証明書が使いやすいのではないでしょうか。 Enterprise用途の場合は、セキュリティを考慮すると、証明書方式のどちらかが良いと思います。

方法 必要なもの メリット デメリット
パスワード パスワード文字列 手軽に設定できる Powershellにパスワードか、パスワードのハッシュをセットする必要がある
自己署名証明書 自己署名証明書(いわゆるオレオレ証明書 少し手間はかかるが、パスワードをスクリプト内に書かなくて良い 自己署名なので、信頼性が担保されずアクセス時に警告が出る場合もある
証明機関から発行された証明書 3rdParty発行の証明書 第3者によって信頼された証明書を使うため信頼性が保たれる 取得にお金がかかる場合は殆ど

ここまででサービスプリンシパルの役割は理解できたでしょうか。
次回は実際にサービスプリンシパルを作成し、Powershellで自動ログオンする方法を紹介したいと思います。

Azure - Powershellモジュールのインストールとアップグレード (補足版)

前回Azure用のPowershellモジュールのバージョンアップの記事を書きましたが、よくよく調べてみると色々なことがわかったので、追加の記事を書くことにしました。

edge.hateblo.jp

追加でわかったこと

  1. AzureのPowershellには「Azure」と「AzureRM」の2種類が存在すること
  2. AzureのPowershellモジュールのインストールや更新には PowershelGet が使えること

1.についてはAzureクラシックポータルとAzureリソースマネージャーの違いを理解する必要があるみたいなので、後日まとめるとして、今日は PowershellGet についてまとめてみたいと思います。

目次

PowershellGetって何者?

PowershellGetとは、Powershell Galleryで公開されているPowershellモジュールをコマンドで取得できる仕組みです。 LINUXでいうとApt-getなどに相当する機能に近いと思います。
下記のリンク先を見ると、今ではPowershellコマンドだけではなく、DSC(Desired State Configuration)*1のリソースまで公開しているようですね。

PowerShell Gallery | Home

The PowerShell Gallery is the central repository for PowerShell content.
You can find new PowerShell commands or Desired State Configuration (DSC) resources in the Gallery.

PowershellGetが使えるかどうかは、以下のコマンドを実行します。

Get-Module PowerShellGet -list | Select-Object Name,Version,Path

結果にPowershellGetの情報が表示されたらPowershellGetは利用可能です。
もし何も表示されない場合は、Powershel v5の導入が必要になります。

PowershellGetを使うには?

PowershellGetは Powershell v5 の新機能となるため、手元のWindowsによっては、Windows Management Framework 5.0を導入しPowershell v5へアップグレードする必要があります。

Windowsのエディション PowershellGetの利用可否
Windows10 / Windows Server 2016以降 初期状態で利用可能
Windows 8/8.1 Windows Management Framework 5.0 の導入が必要
Windows7 Windows Management Framework 5.0の導入が必要

[Windows Management Framework 5.0をダウンロードする]
https://www.microsoft.com/en-us/download/details.aspx?id=50395

Powershellのバージョンを5にしたくないなどの理由がある場合は、PackageManagementモジュールを導入することでPowershellGetを使うことができるようですが、今はプレビュー版しかないようです。*2

PacageManagementモジュールをダウンロードする
Download PackageManagement PowerShell Modules Preview - March 2016 from Official Microsoft Download Center

PowershellGetの使い方

PowershellGetが使えるようになれば、後は簡単です。
Powershellを管理者として実行し、以下のコマンドを入力することでAzureもしくはAzureRMモジュールを導入することができます。

Install-Module Azure  
Install-Module AzureRM  

ちなみに上記コマンドにある"Azure “はクラシックデプロイモデルのPowershellモジュールであり、 "AzureRM"はResourceManagement版のモジュールだそうです。
この辺りの違いは、AzureAPIの世代に左右されるようなのでもう少し勉強したら紹介したいと思います。
*3

以上でPowershellGetの導入と、Azure甩Powershellモジュールの導入は終わりです。

関連ページ

Azure - Powershellを使ってAzureに接続してみる - 準備編 - たいちの何か Azure - Powershellを使ってAzureに接続してみる - 接続編 - たいちの何か Azure - Powershellのバージョン確認方法とアップデート - たいちの何か

*1:Powershell版ChefやPuppetです

*2:正式版を見つけられませんでした。

*3:ざっと調べましたが、内容が多岐にわたり理解が追いついていません。

Copyright © 2014 - taitioooo. All Rights Reserved.