検索
連載

【Azure】Linux VMのSSHの公開鍵認証をデプロイ時に有効化する方法Tech TIPS

LinuxにSSHでログインする際、パスワードではなく公開鍵で認証するのが一般的だ。では、AzureでLinuxの仮想マシンをデプロイする場合、最初からSSHの公開鍵認証を有効化しつつパスワード認証を禁止する具体的な方法は?

PC用表示 関連情報
Share
Tweet
LINE
Hatena
「Tech TIPS」のインデックス

連載目次

Azure Linux VMにSSHで接続する際 パスワードではなく公開鍵で認証するには?(デプロイ時に自動設定)

対象:Azure Virtual Machine(仮想マシン)、Linux、Bicep


 LinuxにSSHでリモートからログインする際、認証にパスワードではなく公開鍵を利用するのが一般的になっている。特にインターネットから接続可能なサーバなどでは、パスワード認証は禁止して、より安全に運用できる公開鍵認証を有効化したいところだ。

 本Tech TIPSでは、AzureでLinuxベースの仮想マシン(Virtual Machine、VM)をデプロイする際、最初から公開鍵認証を有効化しつつ、パスワード認証を禁止する方法を紹介する。デプロイにはBicepを用いる。また、すでに秘密鍵/公開鍵のペアが存在することを前提としている。

■執筆時の各種ツール/APIのバージョン

  • Azure CLI: Ver. 2.50.0
  • Bicep CLI: Ver. 0.19.5
  • Bicepでのデプロイ時のAPIバージョン: 2022-11-01(仮想マシン生成)、2023-02-01(ネットワーク系リソース生成)

SSHで公開鍵認証のみ有効にしつつLinux VMをデプロイするには

 AzureではLinuxの仮想マシンをデプロイする際、SSHでログインするためのユーザー名とともに、その公開鍵を指定できる。具体的には、仮想マシンのリソースを生成するところで、[properties]−[osProfile]−[linuxConfiguration]−[ssh]−[publicKeys]に、公開鍵とその保存先のパスを記載すればよい。

 またパスワード認証を無効化するなら、[linuxConfiguration]に「disablePasswordAuthentication: true」を加える。

param location string = resourceGroup().location
param vmName string // 仮想マシンの名前
param adminUsername string // 管理アカウントのユーザー名
param adminPublicKey string = loadTextContent('id_rsa.pub') // RSA署名の公開鍵
// デフォルトでは、このBicepファイルと同じ場所にある「id_rsa.pub」に保存されている公開鍵が用いられる
// loadTextContent()では変数でファイル名を指定できないので注意

// リソース生成: 仮想マシン
resource vm 'Microsoft.Compute/virtualMachines@2022-11-01' = {
  name: vmName
  location: location
  properties: {
    osProfile: {
      computerName: vmName
      adminUsername: adminUsername
      linuxConfiguration: { // Linux特有の設定
        disablePasswordAuthentication: true // SSHでのパスワード認証を禁止
        ssh: {
          publicKeys: [
            {
              path: '/home/${adminUsername}/.ssh/authorized_keys' // 仮想マシン内での公開鍵の保存先
              keyData: adminPublicKey // 公開鍵そのもの
            }
          ]
        }
      }
    }
  }
}

// デプロイ後、確認のためにパラメータやプロパティを出力
output resouceType string = vm.type
output computerName string = vm.properties.osProfile.computerName
output adminUsername string = vm.properties.osProfile.adminUsername
output adminSSHPublicKey string = vm.properties.osProfile.linuxConfiguration.ssh.publicKeys[0].keyData

【Bicep】Linux VMのデプロイ時にSSH公開鍵認証を有効化する
仮想マシンのサイズ(SKU)やOSイメージ、ストレージ、ネットワーク、タグなどの設定は省いているので、必要に応じて追加/変更してほしい。
※Microsoftのレファレンス: Microsoft.Compute virtualMachines

 ネットワークセキュリティグループについては、最低限、SSHの受信を許可するためのセキュリティルール(受信ポートの規則)を追加する必要がある(もっとも、これは公開鍵認証に限らず、パスワード認証でも必要だ)。

// リソース生成: ネットワークセキュリティグループ
resource networkSecurityGroup 'Microsoft.Network/networkSecurityGroups@2023-02-01' = {
  name: 'nsg-${vmName}'
  location: location
  properties: {
    securityRules: [
      {
        name: 'allow-ssh'
        properties: {
          description: 'Allow the SSH Connection'
          protocol: 'TCP'
          sourcePortRange: '*'
          destinationPortRange: '22' // SSHのデフォルトの着信ポート番号
          destinationAddressPrefix: '*'
          access: 'Allow' // 許可
          priority: 1000
          direction: 'Inbound' // 内向き
          sourceAddressPrefixes: []
        }
      }
    ]
  }
}

【Bicep】SSHの受信を許可するためのネットワークセキュリティグループを生成する
※Microsoftのレファレンス: Microsoft.Network networkSecurityGroups

 またインターネット経由でLinux VMに接続するなら、パブリックIPアドレスも必要だ。

// ↓ホスト名を指定。デフォルトは「<仮想マシン名>-<ユニークな英数字>
param hostName string = toLower('${vmName}-${uniqueString(resourceGroup().id)}')
@allowed([
  'Basic' // 動的IPアドレスが必要ならこちらを選択
  'Standard' // IPアドレスは固定のみ
])
param pipSKU string = 'Basic'
@allowed([
  'Dynamic' // 動的IPアドレス
  'Static' // 固定IPアドレス
])
param pipAllocationMethod string = pipSKU == 'Standard' ? 'Static' : 'Dynamic'
param pipIdleTimeoutInMinutes int // アイドル時のタイムアウト秒数を指定

// リソース生成: パブリックIPアドレス
resource publicIPAddress 'Microsoft.Network/publicIPAddresses@2023-02-01' = {
  name: 'pip-${vmName}'
  location: location
  sku: {
    name: pipSKU
  }
  properties: {
    publicIPAllocationMethod: pipAllocationMethod
    publicIPAddressVersion: 'IPv4'
    dnsSettings: {
      domainNameLabel: hostName // FQDNは「<ホスト名>.<Azureのドメイン>」になる
    }
    idleTimeoutInMinutes: pipIdleTimeoutInMinutes
  }
}

// SSHクライアントのコマンドラインを出力
output sshCommand string = 'ssh ${adminUsername}@${publicIPAddress.properties.dnsSettings.fqdn} -i id_rsa'

【Bicep】インターネット経由でSSHに接続するためのパブリックIPアドレスを生成する
※Microsoftのレファレンス: Microsoft.Network publicIPAddresses

 その他、ネットワークインタフェースや仮想ネットワークなどのリソース生成については割愛するので、環境に合わせて適宜追加していただきたい。

 さて、このようにしてデプロイすると、指定のユーザー名と公開鍵でのみログイン可能な状態でLinux VMが起動する。

Linux VMをデプロイしたときの出力
Linux VMをデプロイしたときの出力

 上記スクリーンショットにある「sshCommand」は、OpenSSHクライアントで接続するためのコマンドラインを表している。前述したパブリックIPアドレスの生成時にホスト名を指定しておくと、このようにLinux VMの接続先のFQDNを確認できる。

デプロイしたLinux VMにSSHで接続するには

 デプロイが完了したら、SSHクライアントから接続してみよう。OpenSSHの場合は、次のようなコマンドラインを実行する。

ssh <指定したユーザー名>@<デプロイしたVMのホスト名(FQDN)> -i <秘密鍵を収めたファイル>



 すると、秘密鍵に設定したパスフレーズの入力が求められる。指示どおりに入力するとログインに成功するはずだ。

デプロイしたLinux VMに公開鍵認証で接続したところ
デプロイしたLinux VMに公開鍵認証で接続したところ
SSHでの初回の接続時に求められるマシンの公開鍵の確認については割愛している。

 一方、前述のコマンドラインから「-i <秘密鍵を収めたファイル>」を省き、パスワード認証で接続しようとすると、以下のように失敗するはずだ。

デプロイしたLinux VMにパスワード認証で接続しようとして失敗したところ
デプロイしたLinux VMにパスワード認証で接続しようとして失敗したところ

デプロイ時に指定できる公開鍵の署名アルゴリズムはRSAのみ!?

 AzureのLinux仮想マシンの場合、デプロイ時に指定できるSSHの公開鍵の署名アルゴリズムは「2048bit以上のRSA」に限られている。実際、Ed25519で署名した公開鍵を指定してデプロイすると、「The value of parameter linuxConfiguration.ssh.publicKeys.keyData is invalid.」というエラーが生じて、仮想マシンの生成に失敗してしまった。

 もっとも、生成後のLinux VMでEd25519による鍵ペアに切り替えることは可能だ。例えば、Ed25519による公開鍵を「~/.ssh/authorized_keys」に追記すると、そのペアの秘密鍵をSSHクライアントに指定してログインできるようになる。

 ここでAzureの「Microsoft.Compute virtualMachines/runCommands」というコマンド実行のためのリソースを活用すると、仮想マシンのデプロイと一緒に公開鍵の追記を実行できる。具体的には、前述の各リソースの記述に以下のrunComamndsリソースを追加すればよい。

// Ed25519署名の公開鍵
param adminEd25519PublicKey string = loadTextContent('id_ed25519.pub')
// デフォルトでは、このBicepファイルと同じ場所にある「id_ed25519.pub」に保存されている公開鍵が用いられる
// loadTextContent()では変数でファイル名を指定できないので注意

// Ed25519署名の公開鍵をauthorized_keysに追記するためのコマンドライン
var cmdLineAppendEd25519Key = 'echo \'${adminEd25519PublicKey}\' >> /home/${adminUsername}/.ssh/authorized_keys'

// リソース生成: 公開鍵を追記するためのコマンド実行
resource vmAppendEd25519Key 'Microsoft.Compute/virtualMachines/runCommands@2022-11-01' = {
  parent: vm // コマンドを実行する仮想マシンのリソース
  name: 'Append-Ed25519-Key'
  location: location
  properties: {
    source: {
      script: cmdLineAppendEd25519Key
    }
  }
}

// 実行したコマンドラインを出力
output runCommands string = runCmdAppendEd25519Key.properties.source.script

【Bicep】Ed25519署名の公開鍵をauthorized_keysに追記するためのrunCommandsリソース
※Microsoftのレファレンス: Microsoft.Compute virtualMachines/runCommands

Linux VMのデプロイ時に自動でEd25519署名の公開鍵をauthorized_keysに追記したところ
Linux VMのデプロイ時に自動でEd25519署名の公開鍵をauthorized_keysに追記したところ

 この方法だと、仮想マシンの生成時に指定したRSA署名の鍵をSSHで利用することなく、最初からEd25519署名の鍵でログインできるようになる。

「Tech TIPS」のインデックス

Tech TIPS

Copyright© Digital Advantage Corp. All Rights Reserved.

ページトップに戻る