Azure Automation から SSH を使う


こちらのブログにあるように、Azure Automation には  Orchestrator.SshClient.Cmdlets というモジュールが用意されており、ワークフローから SSH を使ってリモートでのコマンド実行をおこなうことができます。

ここではこのワークフローからの SSH 接続を試してみました。

● 環境について

まず環境としては Azure 上に Linux マシンを一つ用意しました。
これは
UbuntuServer 14.0.4 LTS を使用した標準的なものです。

SSHでの接続テスト用アカウントとして「autouser」というユーザアカウントを作成しております。

ただし、SSHのポートは標準の 22/tcp ではなく 11022/tcp に変更しております。
22/tcp はあちこちからポートスキャンされていて、開けていると頻繁に攻撃を受けます。
そこで、ポート番号をかえておくことでそうした攻撃をある程度避けております。
ポートを変更しているため、ネットワークセキュリティグループの受信規則に、その分の設定を追加しております。

● Azure Automation の準備

Azure Automation を使うためにはまず Automation アカウントを用意する必要があります。

プレビューポータルから左上の「+」ボタンを押し、「管理」にある「Automation Account」を選択、適当な名前を入力し、リソースグループ、サブスクリプション、リージョンを選択、「作成」を押し Automation アカウントを作成します


 

この Automation アカウントには実際に実行される PowerShell のスクリプトを格納する「Runbook」だけではなく、その PowerShell が使用するモジュールや資格情報、大域に参照される変数などの「アセット」や、今後は DSC の構成やノードもまとめて格納されます。同じ Automation アカウントの PowerShell のワークフローは、同じ資格情報や大域の変数を共有します。Automation アカウントを使い回すか、別途用意するかはこうしたアセットの共有の見地から決めるとよいでしょう。

画面を見てみましょう。


 

アセットの「Runbook」をクリックすると、PowerShell によるワークフローの管理画面が表示されます。


 

ここで上にある「Runbook の追加」をクリックし、新たな Runbook を作成しました。

 

Runbook を追加するとスクリプトの入力画面になります。


ここでは、以下のスクリプトを入力しました。

workflow Get-RemoteFileListViaSSH
{
    # linux host name
    $remotehost = Get-AutomationVariable -Name linux-host-dns-name
    # linux host name
    $portnumber = Get-AutomationVariable -Name linux-sshd-port-number 
    #admin credentials to the host    $cred = Get-AutomationPSCredential -Name linux-host-admin

    $result = Invoke-AutomationSshCommand -ComputerName $remotehost -Port $portnumber -Credential $cred -Command {
        ls / ;
    }
    Write-Output $result
}

このスクリプトは冒頭のブログ記事のサンプルとほぼ同じですが、以下3点を変更しています。

  1. 変数名で $host は差し障りがあるので $remotehost に直している
  2. $portnumber SSH の接続ポート名を変数から受け取れるようにしている
  3. 実行するコマンドが echo ではつまらないので、ルートディレクトリの一覧を取得することにした

なお、Invoke-AutomationSshCommand コマンドレットは、以下のパラメータを受け取ります。

パラメータ名

必須?

パイプラインからの入力

内容

-Command <Scriptblock>

必須

不可

リモートホストで実行するコマンド

{}までの間で指定する

-ComputerName <string>

必須

不可

リモートホストのホスト名/IPアドレス

-Credential <PSCredential>

必須

不可

接続に用いるユーザー名とパスワードを含む認証情報

-Port <int>

必須
ではない

不可

リモートホストでのSSHDのポート番号
無指定時は「
22」が使われる

そのほか、-Verbose, -ErrorAction などの一般パラメータが利用可能

 

スクリプトを保存した後、一旦左に戻っていって「アセット」から変数と認証情報を設定します。
ここでは、以下の2つ変数、一つの認証情報をセットしております。

名称

内容

linux-host-dns-name

変数/文字列

リモートホストのホスト名

linux-sshd-port-number

変数/整数

SSHサーバのポート番号。ここでは 11022 を指定

linux-host-admin

認証情報

接続に用いる認証情報
ここでは
autouser と、そのパスワードを指定

● 実行

変数や認証情報の設定が終わったら、さきのスクリプト画面に戻り上のボタンから「テストウィンドウを開く」を押します。「開始」ボタンを押してしばらく待てば、リモートホストのルートディレクトリのファイルの一覧が表示されます。

 

ls コマンドは出力先が端末の場合は1行に複数のファイル名を表示するが、出力先がパイプの場合は、次のコマンドで処理しやすいよう 11ファイル になります。表示を変えたい場合は -c なり -l なりをls コマンドのオプションで指定するとよいでしょう。

 

さて、Invoke-AutomationSshCommand はどんなときに使えるでしょうか?

Azure 上の Linux ならば拡張機能を利用することでデプロイ時にさまざまな処理を行わせたり、DSC Puppet で構成が可能です。なので Azure Automation から SSH で何かを自動実行させるという必要性はそこまで高くはありません。
Invoke-AutomationSshCommand コマンドレットが輝くのはやはり Azure の外、クラウドにない Linux, UNIX サーバや他社のクラウド上の IaaS との連携になるかと思われます。クラウド、オンプレに限らずシステムの自動化を行う際、「どこでそのワークフロー(スクリプト)を実行するか」が盲点になります。せっかくの管理を自動化、省力化しても、スクリプトを実行するホストが止まっていては話になりません。とはいえ、スクリプトを実行するホストを冗長化したり、耐障害性をたかめるのも手間やコストの面からなかなか難しいものがあります。

Azure Automation の場合は Azure というクラウドがその実行をしてくれるので、実行するホストの可用性を考える必要がなくなります。このメリットが Azure の外側にも生かすことができるのは大きな利点と思われます。

● セキュリティに関する考察

Invoke-AutomationSshCommand による ssh 接続ですが、Codeplex でソースも公開されている SSH.NET を使っているようです。これは、Linux 側の sshd でデバッグ出力をさせると分かります。
Renci.SshNet.SshClient.0.0.1 というクライアント名を使っているが、これは SSH.NET のもののためです。


図:sshd
を停止した後、 sshd -d でデバッグ出力を起こして起動することで接続時の情報を得ることができる。

モジュール名が「Orchestrator.SshClient.Cmdlets」のため、一見 SystemCenter Orchestrator SSH 由来かと思われますが、SystemCenter Orchestrator のSSH接続機能は PuTTY ベースのため、どうやらちょっと違うようです。
参考:
https://technet.microsoft.com/en-us/library/hh225041.aspx

さて、SSH.NET はパスワードではなく証明書による認証をサポートしているはずです。
しかし、 Invoke-AutomationSshdCommand コマンドレットのパラメータを見る限りでは証明書による認証を指定できません。 
一般的には、SSHを経由した自動実行でパスワード認証を用いるのはあまり良い手立てではないと考えられております。
参考: http://sonic64.com/2004-11-17.html

 PSCredential を使いパスワードをスクリプトに埋め込む事はないので、その点については一般的な PowerShell スクリプティングと同等に安全です。しかし、SSHのパスワード認証では上記ページで解説されているような authorized_keys を使用したリモートホスト側での実行制限が使用できない点が厄介な点です。

SSHの接続元を限定するなど、ある程度別途セキュリティに関しては考慮を加えた方が良さそうです。


Comments (0)

Skip to main content