Edited at

Windows用の踏み台サーバーにSSH接続する!


Windows Server 用の踏み台サーバーに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で[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)


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

本当に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


最後に

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

以上。