UPDate. 2019/11/9
2019/11 に開催された Microsoft ignite にてGAされたので記事をアップデートしました。
診断ログで何が確認できるようになったのかを確認しているのが中心です。
更新したのは、以下の通りです。
- ステータスの状況
- 利用料金
- プレビューポータルの記述を削除
- ログ設定と内容(診断ログ)
Azure Bastion とは
ブラウザでAzure Portal から、仮想ネットワークのプライベートIPで仮想マシンに RDPやSSHでアクセスすることができます。仮想マシンにパブリックIPを設定する必要がありません。
ソフトウェアとしては、Apache Guacamole が近いでしょうか。
RDP and SSH directly in Azure portal: You can directly get to the RDP and SSH session directly in the Azure portal using a single click seamless experience.
Azure Bastion - RDP and SSH over SSL - now available for Preview
記事の概要
- Bastion の概要を把握する(リージョン・料金)
- Bastion の設定方法
- Bastion の利用方法(windows: password /Linux: ssh-key)
- Network Security Group による接続制限をしてみる
- 接続状況をポータルで確認する
- 診断ログの設定と内容
- 制限事項の確認・今後、どうなっていてほしいかの整理
はじめる前に
ステータスと利用できるリージョン
- ステータス: General Availability ( 一般公開 )
- リージョン:
- West US / East US / South Central US / West Europe
- West Europe / Australia East / Japan East
料金
- Japan Eastの料金です
- Bastionの実行時間: ¥ 15,833 per month:31日x24時間 ( ¥21.28 per hour )
- アウトバウンドのデータ転送量: ¥13.44 per GB
- 詳細は以下のリンク
https://azure.microsoft.com/en-us/pricing/details/azure-bastion/
評価構成
- 同一仮想ネットワーク内に、bastion を設置するサブネット[AzureBastionSubnet] と ターゲット仮想マシンを配置するサブネットを作成する
- 仮想マシンは、Windows Server 2019 / Ubuntu を配置( id/passのログインとkeyによるログインを試したいため)
- ネットワークセキュリティグループで接続制限を構成
https://docs.microsoft.com/en-us/azure/bastion/bastion-nsg
Bastion を構築する
Azure Portal にログイン
ネットワークの構成
仮想ネットワークを作成するときに注意が必要です。
Bastion 用のサブネット名は固定で AzureBastionSubnet で、セグメントは/27以上である必要があります。
今回は、以下の通り構成
・仮想ネットワーク: vNet-Secure 10.0.0.0/16
・ターゲット仮想マシンの配置用サブネット: vm 10.0.1.0/24
・Bastion 配置用サブネット: AzureBastionSubnet 10.0.2.0/27
Bastion の構成
設定する項目は、リソースグループ、インスタンスの名前・リージョン、仮想ネットワーク、サブネット、パブリックIPアドレス
実際に構成した後に出来上がるもの
仮想マシンスケールセットの仮想マシン2台。
実際にこちらのインスタンスに対してログインや操作は禁止されているため見えるのはここまで。
ログイン先になるサーバの構成(Windows Server / Ubuntu )
- 特に特別な設定は不要です
- Windows Server 2019 と Ubuntu 18.04 LTS を、 VM 用サブネットに配置。グローバルIPは持たせない。Windows Server 2019 は管理者の ID/PASS を Ubuntu は SSH のキーを設定
Bastion 経由でサーバにログインする
共通で注意しておきたいこと
別ブラウザかタブで開くので、ブラウザのポップアップブロックに引っ掛かりました。動かないと思った時はポップアップブロックを疑ってください。
Windows Server に RDP で接続する
- VM のリソースにアクセスする
- メニューの、 Bastion を選択
- Windows Server の Username と Password を入力してログイン
ログインした状態。ブラウザでそのまま RDP 接続ができる。
Ubuntu へキーペアーで SSH アクセスする
- VM のリソースにアクセスする
- ブレードのメニューの、Bastion を選択する
- ログインは、パスワード、 SSH Private Key を書く、 LocalFile の SSH Key ファイルを参照する(結局はブラウザ上に取り込まれます)
- 注意:証明書のパスワードも入力できますが、シークレットになっていないため表示される。これはこんなものか。
ログインした状態。ブラウザで SSH 接続。
Network Security Group による接続制限
接続制限の設定方法
- Bastion はポータル経由でログインしますが、グローバル IP を持つ
- セキュリティを懸念される方は、Network Security Group でインバウンドで443のみに制限することができる
実際の設定
NSG と許可ルールの追加
Subnet との紐づけ
注意事項
どこでまだ何の通信が発生しているかは未確認なので、上記を実施するときはしっかり確認の上実施してください。どこまで絞れるのだろうか。
以下に情報があるがわかりにくい。
https://docs.microsoft.com/en-us/azure/bastion/bastion-nsg
接続状況をポータルで確認する
Sessions のメニューから確認できます。
診断ログ
概要
BastionAuditLogs という診断ログが出力できます。
ログの内容は、基本的にはどういう接続、切断が行われたかという記録になります。
一部ログの内容を紹介すると、処理時刻、処理の名前(connect/disconnect)、接続元情報(resourceId/接続元IP)、接続先情報(targetResourceId/接続先IP/プロトコル(ssh/rdp))、接続に利用したユーザID(接続先サーバのユーザ名)、セッション情報(開始時刻、終了時刻、接続時間(ms))が含まれています。
接続時に何が行われたかという記録は取得できません。
設定方法
診断ログ設定から、ログを出力する先を選択します。
選択肢は、他のサービスと同じで、Blobストレージ、EventHub、Log Analyticsが選択できます。
これらのリソースは事前に作っておいてください。Blobストレージはログ蓄積、EventHubはログをベースとしたイベント処理、Log Analyticsはログの分析とアラートといったところでしょうか。
bastion audit logs schema
以下はサンプルログです。SSHとRDPそれぞれの接続時、切断時のログになります。
{
"time": "2019-11-09T05:00:29.650Z",
"resourceId": "/SUBSCRIPTIONS/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/RESOURCEGROUPS/DEMO_BASTION/PROVIDERS/MICROSOFT.NETWORK/BASTIONHOSTS/DEMO_BASTION",
"operationName": "Microsoft.Network/BastionHost/connect",
"category": "BastionAuditLogs",
"level": "Informational",
"location": "japaneast",
"properties": {
"userName": "sakurai",
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.19018",
"clientIpAddress": "223.135.xxx.xxx",
"clientPort": 52298,
"protocol": "ssh",
"targetResourceId": "/SUBSCRIPTIONS/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/RESOURCEGROUPS/DEMO_BASTION/PROVIDERS/MICROSOFT.COMPUTE/VIRTUALMACHINES/UBUNTU-BASTION",
"subscriptionId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"message": "Successfully Connected.",
"resourceType": "VM",
"targetVMIPAddress": "10.1.1.4",
"tunnelId": "cc93e94c-8a24-47ee-a25b-ae9cb4907b2a"
},
"FluentdIngestTimestamp": "2019-11-09T05:00:29.0000000Z",
"Region": "japaneast",
"CustomerSubscriptionId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
{
"time": "2019-11-09T05:00:40.655Z",
"resourceId": "/SUBSCRIPTIONS/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/RESOURCEGROUPS/DEMO_BASTION/PROVIDERS/MICROSOFT.NETWORK/BASTIONHOSTS/DEMO_BASTION",
"operationName": "Microsoft.Network/BastionHost/disconnect",
"category": "BastionAuditLogs",
"level": "Informational",
"location": "japaneast",
"properties": {
"userName": "sakurai",
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.19018",
"clientIpAddress": "223.135.xxx.xxx",
"clientPort": 52298,
"protocol": "ssh",
"targetResourceId": "/SUBSCRIPTIONS/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/RESOURCEGROUPS/DEMO_BASTION/PROVIDERS/MICROSOFT.COMPUTE/VIRTUALMACHINES/UBUNTU-BASTION",
"subscriptionId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"message": "Successfully Disconnected",
"resourceType": "VM",
"targetVMIPAddress": "10.1.1.4",
"tunnelId": "cc93e94c-8a24-47ee-a25b-ae9cb4907b2a",
"sessionStartTime": "2019-11-09T05:00:29.632Z",
"sessionEndTime": "2019-11-09T05:00:40.655Z",
"duration": 11023
},
"FluentdIngestTimestamp": "2019-11-09T05:00:40.0000000Z",
"Region": "japaneast",
"CustomerSubscriptionId": "723c35fd-fbf9-4394-b543-2c589939374a"
}
{
"time": "2019-11-09T05:07:20.697Z",
"resourceId": "/SUBSCRIPTIONS/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/RESOURCEGROUPS/DEMO_BASTION/PROVIDERS/MICROSOFT.NETWORK/BASTIONHOSTS/DEMO_BASTION",
"operationName": "Microsoft.Network/BastionHost/connect",
"category": "BastionAuditLogs",
"level": "Informational",
"location": "japaneast",
"properties": {
"userName": "sakurai",
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.19018",
"clientIpAddress": "223.135.xxx.xxx",
"clientPort": 52457,
"protocol": "rdp",
"targetResourceId": "/SUBSCRIPTIONS/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/RESOURCEGROUPS/DEMO_BASTION/PROVIDERS/MICROSOFT.COMPUTE/VIRTUALMACHINES/WINSRV-BASTION",
"subscriptionId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"message": "Successfully Connected.",
"resourceType": "VM",
"targetVMIPAddress": "10.1.1.5",
"tunnelId": "bf7bf3d4-8ba6-45bf-8661-a34d2f57c1a2"
},
"FluentdIngestTimestamp": "2019-11-09T05:07:20.0000000Z",
"Region": "japaneast",
"CustomerSubscriptionId": "723c35fd-fbf9-4394-b543-2c589939374a"
}
{
"time": "2019-11-09T05:15:51.402Z",
"resourceId": "/SUBSCRIPTIONS/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/RESOURCEGROUPS/DEMO_BASTION/PROVIDERS/MICROSOFT.NETWORK/BASTIONHOSTS/DEMO_BASTION",
"operationName": "Microsoft.Network/BastionHost/disconnect",
"category": "BastionAuditLogs",
"level": "Informational",
"location": "japaneast",
"properties": {
"userName": "sakurai",
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.19018",
"clientIpAddress": "223.135.xxx.xxx",
"clientPort": 52457,
"protocol": "rdp",
"targetResourceId": "/SUBSCRIPTIONS/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/RESOURCEGROUPS/DEMO_BASTION/PROVIDERS/MICROSOFT.COMPUTE/VIRTUALMACHINES/WINSRV-BASTION",
"subscriptionId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"message": "Successfully Disconnected",
"resourceType": "VM",
"targetVMIPAddress": "10.1.1.5",
"tunnelId": "bf7bf3d4-8ba6-45bf-8661-a34d2f57c1a2",
"sessionStartTime": "2019-11-09T05:07:20.697Z",
"sessionEndTime": "2019-11-09T05:15:51.402Z",
"duration": 510705
},
"FluentdIngestTimestamp": "2019-11-09T05:15:51.0000000Z",
"Region": "japaneast",
"CustomerSubscriptionId": "723c35fd-fbf9-4394-b543-2c589939374a"
}
Field and property descriptions
ログの想定される編集内容になります。
まだ、オンラインに情報がなかったので出てきたログから推測しています。2019/11/9 時点
Field name | Description |
time | The date and time (UTC). |
resourceId | Azure Resource Manager resource ID of bastion host |
operationName | The name of the operation. The value is "Microsoft.Network/BastionHost/connect" or "Microsoft.Network/BastionHost/disconnect" . |
category | Constant value 'BastionAuditLogs' |
level | Constant value 'Informational' |
location | Name of the Azure region where the bastion host that processed the request was located |
properties | Properties of the current session |
userName | User login name for current session |
userAgent | Web Browser userAgent for current session |
clientIpAddress | IP address of client computer for current session |
clientPort | Port number of client computer for current session |
protocol | Protocol name for current session. The value is "ssh" or "rdp" |
targetResourceId | Azure Resource Manager resource ID of target host |
subscriptionId | Subscription entity identifier for current session |
message | The value is "Successfully Connected." or "Successfully Disconnected" |
resourceType | Type name of target host. The value is "VM" |
targetVMIPAddress | IP address of target host for current session |
tunnelId | Session identifier for current session |
sessionStartTime | Start time for current session. This value only set at disconnect. |
sessionEndTime | End time for current session. This value only set at disconnect. |
duration | Number of milliseconds from the moment received login request until the moment received logout or cannot login. |
FluentdIngestTimestamp | Time of collect log data |
Region | Name of the Azure region |
CustomerSubscriptionId | Subscription entity identifier for current session |
現状の注意事項
- どういう単位で構成することが必要なのか?
- Vnet 単位での構成が必要
- VNetPeering をした、同一リージョン、また、他リージョンの別の VNet にある VM に接続しようとしましたが、 Bastion の作成画面に遷移してできなかった
- VNet ごとに設定する必要が現時点ではあります
- Vnet 単位での構成が必要
- ログ
- Bastion なので監査ログが欲しくなる
- 例えば、リモートデスクトップの画面の記録
- 例えば、 SSH で接続したときのコンソールログ
- Bastion なので監査ログが欲しくなる
- 認証(できたらうれしいとふと思ったこと)
- Azure Poral -> Azure AD -> Azure ADDS -> VM と考えると、 Bastion がきれいにつながったら、セキュアで接続が楽な環境を作れるんじゃないかと思いました。
まとめ
- RDP と SSH ともに動きは快適でした
- ログが記録されるようになったので一歩前進です。このログでログイン失敗など拾いたいと思ったのですが直接そのようなことが記録されるわけではないので、検討が必要になります。
duration の時間が非常に短いというのは、RDPのパスワードでは使えるかなと思いましたが、SSHのキーを誤って登録した場合は、再ログインが促されている状態も duration の時間に含まれるのでちょっと難しいなと思いました。 - セキュリティの観点では、パブリック IP を持ちますが、 Azure Portal のログインが前提になっているため、Azure AD や Intune のセキュリティ機能がすべて利用できるし、 VPN や Express Route など通信経路を守るのとは別の解決が図られているのでちゃんと設定すれば安心して利用できる
- 踏み台は、もう少しでなくせる気がしてきた。これがあると cloudshell もなんかうまくつながってくれないかなと