以前に試した
ですが、PowerShell Core 6.0が正式リリースされ当時の内容では正しく動作しなくなっていたので改めてやり直しました。
PowerShell Remoting over SSHとは
従来のPowerShell Remoting Protocol(PSRP)では通信の下回りにHTTP/HTTPSを使いますが、PowerShell Remoting over SSH
では名前の通りSSHを使った通信を行います。
基本的な仕組みとしては、
クライアント側はpowershell(.exe)がリモートセッション生成時にssh(.exe)を呼び出し、powershell(.exe)→ssh(.exe)のプロセス間通信を経由してサーバーへの通信を行う。
サーバー側はSSHdのサブシステムにPowerShellを登録。
クライアントからの接続があった場合はsshd(.exe)→powershell(.exe)とリモートシェルが実行される。
となっています。
PowerShell Remoting over SSHを試す
手順はGitHubで公開されているのでこの手順をベースに行います。
https://github.com/PowerShell/PowerShell/tree/master/demos/SSHRemotinggithub.com
【2018/05/20更新】
いつのまにかGitHubの手順が削除されてしまいました... (#6628)
手順は一致しないかもしれませんが、Docsのこちらの手順が参考になりますので代わりにご覧ください。
もしくは削除直前のこちらのバージョンをご確認ください。
試験環境
試験環境はVirtualBox上でWindows Server 2012 R2とCentOS 7.4.1708を使い双方向で通信させてみます。
他のOSでも細かい部分に違いはあるでしょうが基本的には同じ流れになると思います。
その他細かい条件は以下。
項目 | Windows Server 2012 R2 | CentOS 7.4.1708 |
---|---|---|
基本設定 | インストール直後の状態+最新のWindows Updateを実施 | bento/centos7.4のBoxにyum updateを実施 |
IP | 192.168.33.210 | 192.168.33.209 |
ユーザー | vagrant, administrator | vagrant, root |
Windows → CentOSへの通信(パスワード認証)
CentOS側の設定
CentOSにPowerShell Coreをインストールして、sshd_config
の設定を変更します。
パスワード認証、鍵認証の可否については試験環境のデフォルト設定のままとしました。
# CentOS PowerShell for Linuxのインストール curl https://packages.microsoft.com/config/rhel/7/prod.repo | sudo tee /etc/yum.repos.d/microsoft.repo sudo yum install -y powershell # /etc/ssh/sshd_config の設定 # '# override default of no subsystems'のコメント行の下に設定を追加 # ※位置指定をかなり決め打ちにしているので注意 sudo sed -i.orig -e "/# override default of no subsystems/a Subsystem powershell /usr/bin/pwsh -sshs -NoLogo -NoProfile" /etc/ssh/sshd_config # sshdの再起動 sudo systemctl restart sshd.service
Windows側の設定
標準でインストールされているPowerShell 4.0ではPowerShell Remoting over SSHできませんので、こちらにもPowerShell Coreをインストールします。
前回と比べてGitHubへの接続にTLS 1.2が必須となったため、Windows PowerShell側の設定を若干変更する必要があります。
# Windows PowerShell 4.0 # GitHubへ接続するためにTLS 1.2を有効化 [Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [System.Net.SecurityProtocolType]::Tls12 # PowerShell Coreのインストール Invoke-WebRequest -Uri "https://github.com/PowerShell/PowerShell/releases/download/v6.0.1/PowerShell-6.0.1-win-x64.msi" -OutFile "PowerShell-6.0.1-win-x64.msi" Start-Process -FilePath msiexec.exe -ArgumentList @("/i", "$($pwd.Path)\PowerShell-6.0.1-win-x64.msi", "/passive") -Wait -PassThru
次にSSHをインストールします。 Zipの解凍をしたいので先ほどインストールたPowerShell Coreから以下の手順でインストールします。
# PowerShell Core 6.0.1 # ssh.exeのインストール Invoke-WebRequest -Uri "https://github.com/PowerShell/Win32-OpenSSH/releases/download/v7.6.0.0p1-Beta/OpenSSH-Win64.zip" -OutFile "OpenSSH-Win64.zip" Expand-Archive -Path ".\OpenSSH-Win64.zip" -DestinationPath "C:\" [Environment]::SetEnvironmentVariable('PATH', [Environment]::GetEnvironmentVariable('PATH') + ';C:\OpenSSH-Win64', 'Machine')
インストール先はC:\OpenSSH-Win64
としましたが、こちらについては必要に応じて変更しても構いません。
また、PowerShell Remoting over SSHではssh.exeに対してPATHが通っていること(正確にはssh.exeだけでコマンド呼び出しができること)が必須であるためPATHは必ず通す様にしてください。
テスト接続
ここから実際に試してみます。
まずはNew-PSSession
でPSセッションを作成します。
-HostName
(-ComputerName
ではない)、-UserName
パラメーターを指定するとPowerShell Remoting over SSHで通信することになります。
# PowerShell Core $Session = New-PSSession -HostName 192.168.33.209 -UserName vagrant
実行すると以下の様にssh.exe
を使ってサーバーに接続する際のあれやこれやを聞かれるので適切な情報を入力していきます。
入力後、エラーが出なければ成功です。
$Session
の中身を確認すると以下の様になり、名前がSSHになっていることがわかります。
このセッションがssh.exe
と紐づいています。
この$session
を使いEnter-PSSession
してリモート接続します。
# PowerShell Core Enter-PSSession -Session $Session
実行結果は以下の様になり、無事CentOSにリモート接続できました。
リモートからClear-Host
が使えないのは相変わらずでした...
TERM環境変数を適当に設定してみましたが、Clear-Host
してもエスケープシーケンスが表示されるだけなのでOSが対応しないとダメそうな雰囲気を感じます。
(Windows10やWindows Server 2016だと上手くいくやも?)
最後にRemove-PSSession
してセッション情報を削除すると紐づいていたssh.exe
も終了します。
# PowerShell Core Remove-PSSession -Session $Session # 個別に消すのが面倒なら以下で一気に消しても良い Get-PSSession | Remove-PSSession
Windows → CentOSへの通信(鍵認証)
鍵認証で通信する場合、基本的にSSHの鍵認証の方法と同一です。
先ずはWindows側でssh-keygen.exe
で鍵を作ります。
鍵の種類やパスフレーズの有無は適当にしてください。
以下の実行例ではRSA2 4096Byte、パスフレーズ有りにしています。
# Windows PowerShell 4.0 / PowerShell Core どちらでも可 # 作成する鍵の設定は適当に cd C:\OpenSSH-Win64\ .\ssh-keygen.exe -t rsa -b 4096
あとは作った公開鍵(id_rsa.pub
)をCentOS側に転送し~/.ssh/authorized_keys
に追加するだけです。
以下の例では/vagrant/id_rsa.pub
に鍵を転送しています。
# CentOS bash # ユーザーはvagrantユーザー cat /vagrant/id_rsa.pub >> ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys
これで鍵認証の準備は完了です。
鍵認証で接続する場合はNew-PSSession
の-KeyFilePath
パラメーターを使用します。
実行例は以下
# PowerShell Core $Session = New-PSSession -HostName 192.168.33.209 -UserName vagrant -KeyFilePath ~\.ssh\id_rsa
セッションが生成された後はパスワード認証の場合と同様です。
CentOS → Windowsへの通信(パスワード認証)
最後に、CentOSをクライアント、Windowsをサーバーにした場合の接続を試します。
前回同様パスワード認証のみとします。
まずはWindows上でsshdを動作させます。 基本的にはGitHub上のインストール手順に従うだけなので問題ないかと思います。
# Windows PowerShell 4.0 cd C:\OpenSSH-Win64\ # sshdのインストール .\install-sshd.ps1 # Firewall設定 New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22 # サービス起動 Start-Service sshd
sshd_config
の設定はCentOSの場合と同様でサブシステムにPowerShell(Coreの方)を登録します。
なお、sshd_config
はC:\ProgramData\ssh\sshd_config
を修正してください。(これはVer.1.0.0.0-betaからの変更になります)
追加例 )
# C:\ProgramData\ssh\sshd_config # override default of no subsystems の欄に追記 Subsystem sftp sftp-server.exe Subsystem powershell c:/program files/powershell/6.0.1/pwsh.exe -sshs -NoLogo -NoProfile
あとパスワード認証も許可しておきます。
# コメント解除 PasswordAuthentication yes
サービスを再起動して設定を反映させます。
Restart-Service sshd
これで準備は完了です。
CentOSからWindowsへ接続してみます。
# CentOS PowerShell Core $Session = New-PSSession -HostName 192.168.33.210 -UserName administrator
セッション情報はこんな感じになります。
Enter-PSSession
でWindowsへ接続できます。
# CentOS PowerShell Core Enter-PSSession -Session $Session
前回同様にPowerShell Core→PowerShell 4.0(Desktop)とネストしてPowerShellを対話的に実行できないままで、powershell.exe -Command {ほげ}
の様にコマンド実行であればネストして実行可能でした。