クラウドの 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)を拒否していることを確認すること。
以上。