PowerShell Core 6.0の正式リリースに伴い、本エントリの内容を新しいバージョンでやり直しました。
こちらのエントリを参照してください。
PowerShell on Linux(Mac)が公開された際の新機能の一つにSSHによるPSRemoting(PowerShell Remoting over SSH)があります。
本エントリではこの機能を試してみます。
PowerShell Remoting over SSHとは
ドキュメントでの表記がPowerShell Remoting over SSH
、PowerShell Remoting Protocol(PSRP) over SSH
、PSRP over OpenSSH
等と若干揺れているのですが本エントリでは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の仕組みはJobやPowerShell Directと同類でPSRPは(たぶん)使用しておらずWinRMにも依存していません。
このため、あくまでも私見ですが、PSRP over SSHという表記は正確でないと思われます。
このあたりはもう少し時間が経てば公式な情報も増えてくるかと思います。
PowerShell Remoting over SSHを試す
手順はGitHubDocsで公開されているのでこの手順をベースに行います。
https://github.com/PowerShell/PowerShell/tree/master/demos/SSHRemoting
試験環境
試験環境はVirtualBox上でWindows Server 2012 R2とCentOS 7.2.1511を使い双方向で通信させてみます。
これらのOSにした理由は単純に私が使い慣れているだけです。
他のOSでも細かい部分に違いはあるでしょうが基本的には同じ流れになると思います。
その他細かい条件は以下。
項目 | Windows Server 2012 R2 | CentOS 7.2.1511 |
---|---|---|
基本設定 | インストール直後の状態+最新のWindows Updateを実施 | bento/centos7.2のBoxにyum updateを実施 |
IP | 192.168.33.210 | 192.168.33.209 |
ユーザー | vagrant, administrator | vagrant, root |
Windows → CentOSへの通信(パスワード認証)
最初にWindowsをクライアント、CentOSをサーバーにした場合の接続を試します。
CentOSにPowerShellをインストールします。
# CentOS bash # PowerShellのインストール sudo yum install https://github.com/PowerShell/PowerShell/releases/download/v6.0.0-alpha.9/powershell-6.0.0_alpha.91.el7.centos.x86_64.rpm -y
SSHdの設定変更を行います。
/etc/ssh/sshd_config
に次の設定を追加します。
Subsystem powershell powershell -sshs -NoLogo -NoProfile
追加例)
# /etc/ssh/sshd_config # override default of no subsystems Subsystem sftp /usr/libexec/openssh/sftp-server Subsystem powershell powershell -sshs -NoLogo -NoProfile
また、必要に応じてパスワード認証、鍵認証の可否を設定します。
今回は試験環境のデフォルト設定のままとしました。
# Boxのデフォルト設定 PasswordAuthentication yes #RSAAuthentication yes #PubkeyAuthentication yes
設定変更後はSSHdを再起動します。
# CentOS bash sudo systemctl restart sshd.service
これでCentOS側の設定は完了です。
次にWindows側の設定をします。
標準でインストールされているPowerShell 4.0ではPowerShell Remoting over SSHできませんので、こちらにもPowerShell Coreをインストールします。
# Windows PowerShell 4.0 # PowerShell Coreのインストール Invoke-WebRequest -Uri "https://github.com/PowerShell/PowerShell/releases/download/v6.0.0-alpha.9/PowerShell_6.0.0.9-alpha.9-win81-x64.msi" -OutFile "PowerShell_6.0.0.9-alpha.9-win81-x64.msi" Start-Process -FilePath msiexec.exe -ArgumentList @("/i", "$($pwd.Path)\PowerShell_6.0.0.9-alpha.9-win81-x64.msi", "/passive") -Wait -PassThru
次にSSHをインストールします。
Zipの解凍をしたいので先ほどインストールたPowerShell Coreから以下の手順でインストールします。
# Windows PowerShell Core # ssh.exeのインストール Invoke-WebRequest -Uri "https://github.com/PowerShell/Win32-OpenSSH/releases/download/5_30_2016/OpenSSH-Win64.zip" -OutFile "OpenSSH-Win64.zip" Expand-Archive -Path ".\OpenSSH-Win64.zip" -DestinationPath "C:\" [Environment]::SetEnvironmentVariable('PATH', [Environment]::GetEnvironmentVariable('PATH') + ';C:\OpenSSH-Win64')
インストール先はC:\OpenSSH-Win64
としましたが、こちらについては必要に応じて変更しても構いません。
また、PowerShell Remoting over SSHではssh.exe
に対してPATHが通っていること(正確にはssh.exe
だけでコマンド呼び出しができること)が必須であるためPATHは必ず通す様にしてください。
これで準備が整いましたので実際に試してみます。
まずはNew-PSSession
でPSセッションを作成します。
-HostName
(-ComputerName
ではない)、-UserName
パラメーターを指定するとPowerShell Remoting over SSHで通信することになります。
# Windows PowerShell Core $Session = New-PSSession -HostName 192.168.33.209 -UserName vagrant
実行すると以下の様にssh.exe
を使ってサーバーに接続する際のあれやこれやを聞かれるので適切な情報を入力していきます。
# Windows PowerShell Core PS C:\Users\Administrator> $Session = New-PSSession -HostName 192.168.33.209 -UserName vagrant The authenticity of host '192.168.33.209 (192.168.33.209)' can't be established. ECDSA key fingerprint is SHA256:*******************************************. Are you sure you want to continue connecting (yes/no)? Please type 'yes' or 'no': vagrant@192.168.33.209's password:
入力後、エラーが出なければ成功です。
$Session
の中身を確認すると以下の様になり、名前がSSHになっていることがわかります。
このセッションがssh.exe
と紐づいています。
# Windows PowerShell Core PS C:\Users\Administrator> $Session Id Name ComputerName ComputerType State Configuration Name -- ---- ------------ ------------ ----- ------------- 1 SSH1 192.168.33.209 RemoteMachine Opened DefaultShell
この$session
を使いEnter-PSSession
してリモート接続します。
# Windows PowerShell Core Enter-PSSession -Session $Session
実行結果は以下の様になり、CentOSにリモート接続できました。
# Windows PowerShell Core → CentOS PowerShell PS C:\Users\Administrator> Enter-PSSession -Session $Session [192.168.33.209]: PS /home/vagrant> cat /etc/redhat-release CentOS Linux release 7.2.1511 (Core) [192.168.33.209]: PS /home/vagrant>
ちなみに既知の不具合としてリモートだとClear-Host
が使えません。
これはそのうち直ると思います。
# Windows PowerShell Core → CentOS PowerShell # Clear-Hostはエラーになる [192.168.33.209]: PS /home/vagrant> Clear-Host TERM environment variable not set.
とりあえずエラーメッセージの通りに
$env:TERM="vt100"
等とTERM
環境変数を適当に設定しておけば対処は可能です。
最後にRemove-PSSession
してセッション情報を削除すると紐づいていたssh.exe
も終了します。
# Windows PowerShell Core Remove-PSSession -Session $Session # 個別に消すのが面倒なら以下で一気に消しても良い Get-PSSession | Remove-PSSession
Windows → CentOSへの通信(鍵認証)
鍵認証で通信する場合、基本的にSSHの鍵認証の方法と同一です。
先ずはWindows側でssh-keygen.exe
で鍵を作ります。
鍵の種類やパスフレーズの有無は適当にしてください。
以下の実行例ではRSA2 4096Byte、パスフレーズ有りにしています。
# Windows PowerShell 4.0 (Coreでもたぶん良い) PS C:\> cd C:\OpenSSH-Win64\ # ssh-keygen PS C:\OpenSSH-Win64> .\ssh-keygen.exe -t rsa -b 4096 Generating public/private rsa key pair. Enter file in which to save the key (C:\Users\Administrator/.ssh/id_rsa): Enter passphrase (empty for no passphrase): ******** Enter same passphrase again: ******** Your identification has been saved in C:\Users\Administrator/.ssh/id_rsa. Your public key has been saved in C:\Users\Administrator/.ssh/id_rsa.pub. The key fingerprint is: SHA256:******************************************* Administrator@WIN-7JINTK1PS1K The key's randomart image is: +---[RSA 4096]----+ | | | | | | | | | | | | | | | | | | +----[SHA256]-----+
あとは作った公開鍵(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
の-KeyPath
パラメーターを使用します。
実行例は以下
# Windows PowerShell Core # エラーが出なければ成功 PS C:\> $Session = New-PSSession -HostName 192.168.33.209 -UserName vagrant -KeyPath ~\.ssh\id_rsa Enter passphrase for key 'C:\Users\Administrator\.ssh/id_rsa': ******** # セッション情報を確認 PS C:\> $Session Id Name ComputerName ComputerType State Configuration Name -- ---- ------------ ------------ ----- ------------- 1 SSH1 192.168.33.209 RemoteMachine Opened DefaultShell
セッションが生成された後はパスワード認証の場合と同様です。
CentOS → Windowsへの通信(パスワード認証)
最後に、あまり需要があるとは思いませんが、CentOSをクライアント、Windowsをサーバーにした場合の接続を試します。
面倒なのでパスワード認証のみとします。
まずはWindows上でSSHdを動作させます。
基本的にはGitHub上のインストール手順に従うだけなので問題ないかと思います。
# Windows PowerShell 4.0 cd C:\OpenSSH-Win64\ # SSHdのインストール .\install-sshd.ps1 # ホストキーの作成 .\ssh-keygen.exe -A # Firewall設定 New-NetFirewallRule -Protocol TCP -LocalPort 22 -Direction Inbound -Action Allow -DisplayName SSH # 鍵認証周りの設定+再起動 .\install-sshlsa.ps1 Restart-Computer
sshd_config
の設定はCentOSの場合と同様でサブシステムにPowerShell(Coreの方)を登録します。
Subsystem powershell C:/Program Files/PowerShell/6.0.0.9/powershell.exe -sshs -NoLogo -NoProfile
追加例)
# C:\OpenSSH-Win64\sshd_config # override default of no subsystems Subsystem sftp C:/Program Files/OpenSSH/sftp-server.exe Subsystem powershell C:/Program Files/PowerShell/6.0.0.9/powershell.exe -sshs -NoLogo -NoProfile
設定後はサービスを再起動します。
# Windows PowerShell 4.0(Coreでもよい) Restart-Service sshd
これで準備は完了です。
CentOS側からWindowsへ接続してみます。
# CentOS PowerShell PS /home/vagrant> $Session = New-PSSession -HostName 192.168.33.210 -UserName administrator The authenticity of host '192.168.33.210 (192.168.33.210)' can't be established. ECDSA key fingerprint is ***********************************************. Are you sure you want to continue connecting (yes/no)? yes administrator@192.168.33.210's password: ********
セッション情報はこんな感じです。
# CentOS PowerShell PS /home/vagrant> $Session Id Name ComputerName ComputerType State ConfigurationName Availability -- ---- ------------ ------------ ----- ----------------- ------------ 1 SSH1 192.168.33.210 RemoteMachine Opened DefaultShell Available
Enter-PSSession
でWindowsへ接続できます。
# CentOS PowerShell PS /home/vagrant> Enter-PSSession -Session $Session [192.168.33.210]: PS C:\Users\Administrator\Documents>
ここでWindows側でPowerShell Coreが実行されていのですが、現時点ではまだ、PowerShell Core→PowerShell 4.0(Desktop)とネストしてPowerShellを対話的に実行できない様で、実際にやってみるとハングしてしまいます。
ただし、powershell.exe -Command {ほげ}
の様にコマンド実行であればネストして実行可能ですので、以下の例の様にPowerShell Coreにないコマンドレット(Get-NetFirewallRule
)を実行することもできます。
# CentOS PowerShell → Windows PowerShell Core # コマンドの実行結果に日本語があるのでShift-JISを有効に [192.168.33.210]: PS C:\> [System.Text.Encoding]::RegisterProvider([System.Text.CodePagesEncodingProvider]::Instance) [192.168.33.210]: PS C:\> $OutputEncoding = [System.Text.Encoding]::GetEncoding(932) # CentOS PowerShell → Windows PowerShell Core → Windows PowerShell 4.0 [192.168.33.210]: PS C:\> powershell -Command { Get-NetFirewallRule -DisplayName *ssh* } Name : {b467a636-88e4-4478-a408-e43a87356821} ID : {b467a636-88e4-4478-a408-e43a87356821} Group : Platform : {} LSM : False Profile : Any Caption : Description : ElementName : SSH InstanceID : {b467a636-88e4-4478-a408-e43a87356821} CommonName : PolicyKeywords : Enabled : 1 PolicyDecisionStrategy : 2 PolicyRoles : ConditionListType : 3 CreationClassName : MSFT|FW|FirewallRule|{b467a636-88e4-4478-a408-e43a87356821} ExecutionStrategy : 2 Mandatory : PolicyRuleName : Priority : RuleUsage : SequencedActions : 3 SystemCreationClassName : SystemName : Action : 2 Direction : 1 DisplayGroup : DisplayName : SSH EdgeTraversalPolicy : 0 EnforcementStatus : {0} LocalOnlyMapping : False LooseSourceMapping : False Owner : Platforms : {} PolicyStoreSource : PersistentStore PolicyStoreSourceType : 1 PrimaryStatus : 1 Profiles : 0 RuleGroup : Status : 規則は、ストアから正常に解析されました。 StatusCode : 65536 PSComputerName :
最後に
とりあえずこんな感じです。
WindowsからLinuxへのPSRemoting、なかなか胸が熱くなります。
実はWindowsからLinuxへPSRPを使用した接続も可能なのですが、まだバギーな部分が多い様で、このあたりについては別の機会にエントリを書こうと思います。
【2016/09/16追記】
続き書きました。
【2017/08/15追記】
Windows 10 Creators Updateでも使える様になっていたので別エントリを起こしました。