【Azure】Linux VMのSSHサーバ(sshd)のホストキー(公開鍵)を安全に確認するには:Tech TIPS
SSHで初めてのサーバに接続しようとすると、「ホストキー」の指紋(フィンガープリント)の確認が求められる。Azureの仮想マシン(VM)上のLinuxを対象として、安全にホストキーを確認する一連の手順を説明する。
対象:Azure Virtual Machine(仮想マシン)、Linux、Bicep
SSHでいままで接続したことのないホスト(サーバ)に接続しようとすると、以下のようなメッセージが表示される。
これは、「ホストキー(ホスト鍵)」と呼ばれるSSHサーバ(sshd)の公開鍵から算出された指紋(フィンガープリント、fingerprint)をユーザーに確認するための問い合わせメッセージだ。意図したサーバに正しく接続しようとしているかどうかをユーザーが確認させるための仕組みである。
言うまでもなく、表示された指紋と実際のsshdの指紋が一致することを確認すべきだ。しかし、SSH接続後ならともかく、接続前に指紋を確認するのは何かと面倒だ。そのため、ここで確認せずに「yes」と答えてしまい、以後も確認しないことが意外と多いのではないだろうか?
そこで本Tech TIPSでは、Azureの仮想マシン(VM)にインストールしたLinuxで、安全にsshdの(指紋の元である)ホストキーを取得してSSHクライアントに登録し、SSHも安全に接続できるようにする一連の手順を説明する。SSHクライアントの対象は、Windows 10/11標準のOpenSSHクライアントとする。またsshdの対象は、主な最新LinuxディストリビューションでパッケージからインストールできるOpenSSHサーバとする。
■執筆時の各種ツール/APIのバージョン
- Azure CLI: Ver. 2.50.0
- Bicep CLI: Ver. 0.19.5
- Bicepでのデプロイ時のAPIバージョン: 2022-11-01(仮想マシン生成)、2023-02-01(ネットワーク系リソース生成)
手順その1――Linux VMでホストキー読み出しコマンドを実行する
●Linuxでsshdの全ホストキーを出力(表示)するには
Linux上のsshdの場合、そのホストキーは通常、「/etc/ssh」ディレクトリに「ssh_host_<署名アルゴリズム略称>_key.pub」に格納されている。全ホストキーを一括出力するには、bashで以下のコマンドラインを実行すればよい(以下ではこれを「ホストキー読み出しコマンド」とする)。
find /etc/ssh -type f -name 'ssh_host_*_key.pub' -exec cat '{}' \;
この時点では、まだSSHで安全に接続できない状態なので、このコマンドをSSH以外の方法でリモートから安全に実行し、その出力を得る必要がある。ここでは、Azureが提供する機能を利用した2種類のリモートコマンド実行方法を紹介する(どちらか一方を実施すればよい)。
●作成済みのVMに対してホストキー読み出しコマンドを実行する
すでにデプロイ済みのVMが対象なら、「Azure CLI」と「マネージド実行コマンド」を利用して、ホストキー読み出しコマンドを実行するとよいだろう。
az vm run-command create -g <VMのリソースグループ名> --vm-name <VM名> --run-command-name GetSshdHostPubKeys --script "find /etc/ssh -type f -name 'ssh_host_*_key.pub' -exec cat '{}' \;"
「GetSshdHostPubKeys」は、このホストキー読み出しコマンドに付ける名前。
※Microsoftのレファレンス: az vm run-command create
ただし、上記のコマンドを実行しただけではホストキーは得られない。このコマンドの実行結果を取得するためのコマンドを別途実行する必要がある(手順2で説明する)。
●VMのデプロイ時にホストキー読み出しコマンドを実行する
VMをこれからデプロイするなら、同時にホストキー読み出しコマンドを実行することも可能だ。それには、以下のように「Microsoft.Compute virtualMachines/runCommands」というコマンド実行のためのリソースをVMのリソーステンプレートに追記する。
param location string = resourceGroup().location
<……中略……>
// リソース生成: 仮想マシン
resource vm 'Microsoft.Compute/virtualMachines@2022-11-01' = {
<VMリソースの記述>
}
// sshdのホストキーを出力するためのコマンドライン
var cmdLineGetSshdHostPubKeys = 'find /etc/ssh -type f -name \'ssh_host_*_key.pub\' -exec cat \'{}\' \\;'
// 末尾の「\」は2つ並べる
// リソース生成: sshdのホストキーを出力するためのコマンド実行
resource runCmdGetSshdHostPubKeys 'Microsoft.Compute/virtualMachines/runCommands@2022-11-01' = {
parent: vm // コマンドを実行する仮想マシンのリソース
name: 'GetSshdHostPubKeys' // このコマンドに付ける名前
location: location
properties: {
source: {
script: cmdLineGetSshdHostPubKeys
}
}
}
VMやネットワークなどの設定は省いているので、必要に応じて追加/変更してほしい。Tech TIPS「【Azure】Linux VMのSSHの公開鍵認証をデプロイ時に有効化する方法」が参考になるだろう。
※Microsoftのレファレンス: Microsoft.Compute virtualMachines/runCommands
手順その2――手順1の実行結果を表示する
ここまでの手順でホストキー読み出しコマンドを実行したら、以下のAzure CLIのコマンドラインでその実行結果を取得する。
az vm run-command show -g <VMのリソースグループ名> --vm-name <VMのリソース名> --run-command-name GetSshdHostPubKeys --instance-view -o tsv --query instanceView.output
「GetSshdHostPubKeys」は、前述のホストキー読み出しコマンドに付けた名前。
※Microsoftのレファレンス: az vm run-command show
ホストキー読み出しコマンドが正しく実行できていたら、以下の画面のように「<署名アルゴリズム略称> <公開鍵> ……」という行がホストキーの数だけ表示されるはずだ。
●ホストキーが1つも表示されなかった場合は?
ホストキーが1つも表示されなかった場合、ホストキー読み出しコマンドの実行に失敗して、エラーが生じていることが考えられる。その場合、以下のAzure CLIのコマンドラインを実行して、詳細を確認してみよう。
az vm run-command show -g <VMのリソースグループ名> --vm-name <VMのリソース名> --run-command-name GetSshdHostPubKeys --instance-view -o jsonc
コマンド実行に失敗した場合、出力されるJSONの[instanceView]−[executionState]キーの値が「Failed」になっているはずだ。また、コマンドがまだ実行中なら、これは「Pending」となっていることがある。指定したコマンドラインが間違っていないか見直してみよう。
手順その3――SSHクライアントにホストキーを登録する
ホストキーが正しく取得できたら、ホスト名を加えつつ、SSHクライアントの「known_hosts」ファイルに追記する。Windows 10/11標準のOpenSSHクライアントの場合、このファイルは「%userprofile%\.ssh」にある。
■操作手順
- エクスプローラのアドレスバーに「%userprofile%.ssh」と入力して開く
- known_hostsをコピー&ペーストしてバックアップを作成
- known_hostsを右クリックしてコンテキストメニューを開く
- [プログラムから開く]をクリックし、表示されるアプリ一覧から「メモ帳」を選択する。他のテキストエディタで開いてもよい
- メモ帳で「known_hosts」ファイルの末尾に、読み出したホストキーの一覧をコピー&ペースト
- 追加したホストキーの行頭に、接続先のホスト名(FQDN)またはIPアドレスを挿入して、半角スペースで区切る
known_hostsで、追加したホストキーより上(前)に同じホスト名/IPアドレスから始まる行があったら、その行は削除する。
AzureのVMでパブリックIPアドレスを割り当てている場合、そのIPアドレスやホスト名は以下のAzure CLIのコマンドラインで取得できる。
az network public-ip show -g <VMのリソースグループ名> -n <パブリックIPアドレスのリソース名> --query "{ HostName:dnsSettings.fqdn, IPAddress:ipAddress }"
※Microsoftのレファレンス: az network public-ip show、--queryオプション(JMESPath クエリ)
パブリックIPアドレスを生成する際、そのホスト名をDNSに登録していないと、上記の「HostName」は取得できないので注意してほしい。
ホストキー登録後にSSHクライアントからLinux VMに接続してみる
known_hostsファイルの修正が完了したら、SSHクライアントから接続してみよう。OpenSSHの場合は、次のようなコマンドラインを実行する。公開鍵認証の場合は「 -i <秘密鍵を収めたファイル>」を追加すること。
ssh <ユーザー名>@<VMのホスト名(FQDN)>
すると、ホストキーの問い合わせなしに、パスワードまたはパスフレーズの入力が求められる。指示どおりに入力するとログインに成功するはずだ。
■関連リンク
- Azure CLI で Azure Resource Manager (ARM) のデプロイ テンプレートを使用する方法(Microsoft Learn)
- 仮想マシンのリソースのレファレンス(Microsoft Learn)
- 仮想マシンでコマンドを実行するためのリソースのレファレンス(Microsoft Learn)
- マネージド実行コマンドを使用して Linux VM でスクリプトを実行する(Microsoft Learn)
Copyright© Digital Advantage Corp. All Rights Reserved.