図解で、クラウドのWindowsサーバーにSSH接続する(RDP over SSH)!


クラウドの Windowsサーバーに直接SSH接続する!

[Windows Server 2019]からOpenSSHが標準インストールされるようになったので、踏み台サーバーのOSをWindowsで用意することを検証した。今回も直観的にわかりやすくするため図解付きにて。

シナリオ(利用シーン)

パブリッククラウドでアプリケーションを実行する。アプリケーションのOS要件がWindows Serverであり、リモートデスクトップ接続(以降RDP接続と略す)が必要。保守対象のWindowsサーバーが複数あるので、Windowsの踏み台サーバーを経由してRDP接続する。今までなら踏み台サーバーを2台用意して、Linuxの踏み台サーバーでSSH接続した後、Windowsの踏み台サーバーへRDPをポートフォワードしてリモートデスクトップ接続していた。

今まで

これから

手順1.踏み台サーバー(Windows)のOpenSSHを設定する

最初の設定だけはインターネットから直接RDP接続するため、最初のセキュリティグループ設定はあらゆるコンピュータからアクセス可能な「TCP3389 ソース(アクセス元)0.0.0.0/0」でありリスクあるので手早く設定する。まず、AWSやIBMCloudで[Windows Server 2019]をデプロイした後、AdministratorでログインしてPowerShellを使ってOpenSSH機能を有効にする。

Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

▼インストール済みプログラムを確認。SSHサーバーがインストールされていない。
PS C:\Users\Administrator>  Get-WindowsCapability -Online | ? Name -like 'OpenSSH*'

Name  : OpenSSH.Client~~~~0.0.1.0
State : Installed

Name  : OpenSSH.Server~~~~0.0.1.0
State : NotPresent           ←インストールされていない

▼OpenSSHサーバーをインストールする。
PS C:\Users\Administrator>  Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0

Path          :
Online        : True
RestartNeeded : False

▼再確認(今度はSSHサーバーがインストールされた)。
PS C:\Users\Administrator>  Get-WindowsCapability -Online | ? Name -like 'OpenSSH*'

Name  : OpenSSH.Client~~~~0.0.1.0
State : Installed

Name  : OpenSSH.Server~~~~0.0.1.0
State : Installed

▼ sshdサービス起動
PS C:\Users\Administrator> Start-Service -Name "sshd" 

▼ スタートアップを [自動] に設定
PS C:\Users\Administrator> Set-Service -Name "sshd" -StartupType Automatic 

▼ 再起動時にSSHがスタートすることを確認
PS C:\Users\Administrator> Get-Service -Name "sshd" | Select-Object * 

Name                : sshd
RequiredServices    : {}
CanPauseAndContinue : False
CanShutdown         : False
CanStop             : True
DisplayName         : OpenSSH SSH Server
DependentServices   : {}
MachineName         : .
ServiceName         : sshd
ServicesDependedOn  : {}
ServiceHandle       : SafeServiceHandle
Status              : Running
ServiceType         : Win32OwnProcess
StartType           : Automatic       ←自動スタートになってること
Site                :
Container           :

手順2.Windows踏み台サーバーにSSH公開鍵を登録する

Windowsにログインする保守ユーザアカウントを設定して保守ユーザでログインする(この例ではwinuserが保守ユーザID)。

▼PowerShellを起動してユーザディレクトリに".ssh"ディレクトリを作る。
PS C:\Users\winuser\ mkdir .ssh
PS C:\Users\winuser\ cd .ssh

▼メモ帳を起動してOpenSSH形式の公開鍵(ssh-rsaで始まる鍵)を保存する。
PS C:\Users\winuser\ notepad authorized_keys

 …メモ帳で作業(割愛)…

▼検査
PS C:\Users\winuser\ type authorized_keys
ssh-rsa AAAAB3**************KkqqQ== rsakey

SSHコンフィグファイルを修正する。ファイル名は[c:\programdata\ssh\sshd_config]。

PS C:\Users\winuser\ notepad c:\programdata\ssh\sshd_config

公開鍵での認証をyesとする。パスワード認証はnoとする。ユーザ毎の鍵設定をしたいのでアドミニストレータの鍵保存場所を検査しないようにする。

#PubkeyAuthentication yes     ← # を外す

# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2
# but this is overridden so installations will only check .ssh/authorized_keys
# ↓ 複数のユーザ、複数の鍵を指定するときはスペースで区切る。
#AuthorizedKeysFile c:\Users\winuser\.ssh\authorized_keys c:\Users\winuser2\.ssh\authorized_keys
AuthorizedKeysFile  c:\Users\winuser\.ssh\authorized_keys

#PasswordAuthentication yes       ← # を外して、noに変更する。
PasswordAuthentication no     ← noにするとパスワード認証が無効になり、公開鍵認証になる。

#Match Group administrators       ← # を付けて無効にする
#       AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys     ← # を付けて無効にする

SSHDサービスを再起動する。

PS C:\Users\winuser\ Restart-Service sshd

手順3.保守用PCでsshクライアントのPuttyを設定する。

Puttyに新しい接続セッションとして(1)と(2)の2つを追加する。意味は、最初に保守用PCからLinux踏み台サーバーへのSSH接続ルート(1)を確立して、次に保守用PCからSSH接続ルート(1)を経由してWindows踏み台サーバーへのSSH接続ルート(2)を確立するもの。

▼下図を参考にPuttyを2つ設定する。
・[セッション]-[ホスト名]には、"OSユーザ名@IPアドレス"を入力。両方ともポートはSSHの[22]。
・[セッション]-[セッション一覧]の、接続ルート(1)のセッション名は、接続ルート(2)で使います。
・[接続]-[プロキシ]は、接続ルート(1)はデフォルトのまま、接続ルート(2)は、"plink -load <セッション(1)名> nc %host %port"を入力する。

▼接続ルート(2)が正しく動作することを検査する。
接続ルート(2)のセッション名を選んで[開く]ボタンを押して、Windows踏み台サーバーにログインできたら成功。

SSHで接続しているがコマンドシェルはDOSになる。

手順4.Puttyのポートフォワードを設定する。

続いて、RDP接続をSSH接続トンネルで転送するためのポートフォワーディングを設定する。SSH接続ルート(2)をトンネルとして使うので、設定するのは(2)側のみ。
・[接続]-[SSH]-[トンネル]の、[源ポート]は自由なポート番号(例えば43389)を記入、[送り先]にはWindows踏み台サーバーのパブリックIPアドレスとRDPポート番号(例えば3.3.3.3:3389)を記入して[追加]ボタンを押す。源ポート番号に下図では33389を設定しているが、RDPの3389と重ならないポート番号なら何でもよい。

手順5.Windows踏み台サーバーにリモートデスクトップ接続する。

保守用PCのリモートデスクトップを起動したらコンピュータ名には自分のPCを意味する"localhost"を指定する(この例ではlocalhost:43389)。ユーザ名にはWindows踏み台サーバーの保守用ユーザIDを指定する。リモートデスクトップ接続を実行する際、自分のPCに43389ポートでRDP接続しようとしたらPuttyがWindows踏み台サーバーの3.3.3.3:3389へ転送してくれる。パスワードを聞いてきたら成功。

セキュリティのポイント

WindowsサーバーOSへのログインはユーザIDとパスワード、初期状態ではユーザIDがAdministratorであるため、パスワードだけ見つけられればログイン出来てしまう。実際にパブリッククラウドにデプロイされたWindows仮想サーバーがウィルスに感染させられた事例を見ているので、ポート3389をソース0.0.0.0/0にしたまま保守するのは危険、というか攻撃されるのを待っているようなもの。本書で紹介した方法ならば、(1)ソースIPアドレスを自分のLinux踏み台サーバーに限定し、(2)SSH秘密鍵を持っているユーザをSSH公開鍵で照合し、(3)ユーザIDとパスワードで認証する多段防御が実現する。なお、Windows踏み台サーバーから自分自身のWindows踏み台サーバーへRDP接続する時のセキュリティグループに登録するソースIPアドレスはAWSとAzureで異なるので注意。

つまづきポイント

sshが怪しい

Windows踏み台サーバーの公開鍵やコンフィグを変更したらsshdサービスを再起動する。タスクマネージャーはAdministrator権限で実行する必要あり。

ファイアウォールが怪しい

リモートデスクトップ接続がずーーーっと待ちの時は、ファイアウォールの設定が間違っているのかも。

AWSの場合

AWSの場合、Windows踏み台サーバーに対するセキュリティグループは、外部からのSSH接続はパブリックIPアドレスでソースを指定するが、RDP接続のポートフォワードは自分自身のプライベートIPアドレスで指定するので要注意。
from 1.1.1.1 to 3.3.3.3 OpenSSH(22)
from 2.2.2.2 to 2.2.2.2 RDP(3389)

Azureの場合

Azureの場合は、仮想ネットワークインターフェース(ENI)からのRDP接続になるらしく、RDP接続のポートフォワードも自分自身のパブリックIPアドレスで指定するので要注意。
from 1.1.1.1 to 3.3.3.3 OpenSSH(22)
from 3.3.3.3 to 2.2.2.2 RDP(3389)

IBM Cloudの場合

IBM Cloudの場合は、浮動IP(eth0)にセキュリティグループを割り当てている場合が最もシンプルで、外部からのSSH接続だけでよい(RDPの許可は不要)。
from 1.1.1.1 to 3.3.3.3 OpenSSH(22)

ポートフォワードされているか怪しい

本当にRDPポートが転送されているのかな~、と不安な時は自分の保守用PCでポート43389や33389がリッスン(待ち状態)になっているか、DOSの[netstat -a]コマンドで検査する。

C:\Users\Ichiro>netstat -a

アクティブな接続

プロトコル  ローカル アドレス      外部アドレス           状態
TCP         0.0.0.0:80             Ichiro-PC:0            LISTENING
TCP         0.0.0.0:135            Ichiro-PC:0            LISTENING
TCP         [::]:80                Ichiro-PC:0            LISTENING
TCP         [::]:135               Ichiro-PC:0            LISTENING
TCP         [::1]:33389            Ichiro-PC:0            LISTENING
TCP         [::1]:33389            Ichiro-PC:0            LISTENING
TCP         [::1]:33389            Ichiro-PC:50942        ESTABLISHED
TCP         [::1]:50942            Ichiro-PC:33389        ESTABLISHED

Puttyでエラー[SSH2_MSG_UNIMPLEMENTED]の時

PuttyでSSH接続するときの鍵交換アルゴリズムを強固な[Diffie-Hellman group 14]を一番上に変更する[Up]ボタンで入れ替える。

最後に

インターネット(ソース0.0.0.0/0)からのRDP接続(TCP 3389)を拒否していることを確認すること。

以上。