しばたテックブログ

気分で書いている技術ブログです。

Windows 10で利用可能なSSHサーバー、クライアントまとめ

Windows 10ではSSHサーバー、クライアントの機能が使える様になっているのですが、バージョンによって色々違いがあり自分でも混乱してきたのでわかる範囲でまとめました。
必要があれば随時更新します。

Microsoft SSH Server

Windows 10 Anniversary Update(1607)より、開発者機能の一部としてMicrosoft独自のSSHサーバーが利用可能になっています。
サーバーのみの提供でクライアント機能はありません。

この機能の実体は次の2つのサービスになります。*1

  • SSH Server Broker
  • SSH Server Proxy

機能に関する細かい話はこちらの記事を見ると良いでしょう。

こちらの記事では「Server Broker版SSH」と呼ばれ、具体的な用途についても触れられていませんが、Win32-OpenSSHのこちらのIssueにこのSSHサーバーについての質問があり、そこで中の人であるJoeyさんがこう答えています。

github.com

The "Microsoft SSH Server" is installed when you enable developer mode but is unrelated to the Windows Subsystem for Linux. As @jdunn0 said, it's used for the very specific scenario of deploying and testing UWP apps. You can read more about the server and scenario here: https://msdn.microsoft.com/en-us/windows/uwp/get-started/enable-your-device-for-development#ssh

コメントによるとこのサーバは「Microsoft SSH Server」と呼称され、特定のUWPアプリケーションのテスト(Device discovery系の機能っぽい)に使うためのものだそうです。

機能の詳細については、

msdn.microsoft.com

を見ると良いでしょう。

組み込みWin32-OpenSSH

Windows 10 Fall Creators Update(1709)よりMicrosoftによるOpenSSHのポートであるWin32-OpenSSHがOSに組み込まれました。

こちらはMicrosoft SSH Serverと異なりサーバー、クライアント両方の機能が提供されています。

Windows 10 Fall Creators Update(1709)

Fall Creators Updateの時点ではOpenSSHの機能はベータ版です。

GUIからだと「設定→アプリと機能→オプション機能の追加」で機能を追加できます。

f:id:stknohg:20180514172902p:plain

またコマンドではGet-WindowsCapabilityで機能がインストールされているか確認でき、Add-WindowsCapabilityで機能をインストールすることができます。

機能の確認

# 要管理者権限
Get-WindowsCapability -Online | ? { $_.Name -like 'OpenSSH*' }

結果

PS C:\> Get-WindowsCapability -Online | ? { $_.Name -like 'OpenSSH*' }


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

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

機能のインストール

# 要管理者権限
# OpenSSHクライアントをインストール
Add-WindowsCapability -Online -Name 'OpenSSH.Client~~~~0.0.1.0'

# OpenSSHサーバーをインストール
Add-WindowsCapability -Online -Name 'OpenSSH.Server~~~~0.0.1.0'

インストールされたOpenSSHはC:\Windows\System32\OpenSSH配下にあり、バージョンはv0.0.18*2になります。

# バージョン確認 (Ver.7.5とコマンドからはバージョンが上手く確認できない...)
PS C:\> ssh -V
OpenSSH_7.5p1, without OpenSSL

サーバー機能は以下のサービスとしてインストールされます。

  • ssh-agent : C:\Windows\System32\OpenSSH\ssh-agent.exe
  • sshd : C:\Windows\System32\openssh\sshd.exe

ちなみにベータ版のためssh-keygenなどの初期設定をしないとsshdサービスが動作しません。
設定方法の詳細は以下のPowerShell Teamのブログにありますので参考にしてください。

blogs.msdn.microsoft.com

なお、このバージョンではsshd_configsshd.exeと同じディレクトリに置く必要があります。

Windows 10 Spring Creators Update(1803)

Spring Creators UpdateでOpenSSHの機能は正式版となり、デフォルトでOpenSSHクライアントが導入済みの状態になっています。
すなわち、何もせずともはじめからssh.exeが使えるということです。

f:id:stknohg:20180514192602p:plain

# 要管理者権限
# SSHクライアントは最初からインストール済み
PS C:\> Get-WindowsCapability -Online | ? { $_.Name -like 'OpenSSH*' }


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

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

ちなみに現時点でインストールされているバージョンは、v7.6.0.0p1-Betaです。

PS C:\> ssh -V
OpenSSH_for_Windows_7.6p1, LibreSSL 2.6.4

サーバー機能に関してはFall Creators Updateと同様にAdd-WindowsCapabilityでインストールする必要があります。

# 要管理者権限

# OpenSSHサーバーをインストール
Add-WindowsCapability -Online -Name 'OpenSSH.Server~~~~0.0.1.0'

実体のサービスはFall Creators Updateの時から変わりませんが、こちらは正式版とあってサービスの表示名がきちんとした形になっています。

  • ssh-agent(OpenSSH Authentication Agent) : C:\Windows\System32\OpenSSH\ssh-agent.exe
  • sshd(OpenSSH SSH Server) : C:\Windows\System32\OpenSSH\sshd.exe

また、Spring Creators Updateでは、機能のインストール後にいきなりsshdサービスを起動して構いません。
初期処理を自動で行いC:\ProgramData\ssh\sshd_configなどの各種設定ファイルを作成します。*3

このバージョンではC:\ProgramData\ssh\sshd_configを設定する必要があります。

【2018/10/08追記】Windows 10 October 2018 Update(1809)

特に目新しい機能追加は無く、インストールされているバージョンがv7.7.2.0p1-Betaに更新されただけの様です。

PS C:\> ssh -V
OpenSSH_for_Windows_7.7p1, LibreSSL 2.6.5

【2019/05/22追記】Windows 10 May 2019 Update (1903)

Windows 10 October 2018 Updateから更新されずバージョンはv7.7.2.0p1-Betaのままでした。

PS C:\> ssh -V
OpenSSH_for_Windows_7.7p1, LibreSSL 2.6.5

【補足】Win32-OpenSSHの開発方針について

最後に補足としてWin32-OpenSSHの開発方針の変更について触れておきます。

もともとWin32-OpenSSHの開発は

github.com

で行われていました。
ちょっと事の経緯は把握できていないのですが、今後はopenssh-portableのWindows対応に舵を取り、openssh-portableのWindows対応が完了した時点でWin32-OpenSSHの方を終息させ、openssh-portable本体を主流としていく方針となった様です。

github.com

もとのWin32-OpenSSHはIssueリリース管理のためだけに残されています。
現在のプロジェクトステータスがWin32-OpenSSHのWikiに載っていますので参照してください。

このため今後OpenSSHの情報を追う際は両方のリポジトリを見ておくと良いでしょう。

*1:なお、一度も開発者モードにしていない場合はサービスはありません

*2:ファイルバージョンから確認できます

*3:この挙動はOpenSSH v1.0.0.0-betaからの変更になります。

Windows PowerShellとTLS 1.2

昨今のセキュリティ情勢を受けてトランスポート層の暗号化プロトコルにTLS 1.2を強制するサイトが増えてきています。

身近な例としては、GitHubが今年の2月にHTTPS通信においてTLS 1.2以前のプロトコルを廃止しています。

github.blog

本エントリではWindows PowerShellとPowerShell CoreのHTTPS通信におけるTLSの扱いについて触れていきます。

Windows PowerShellの場合

Windows PowerShellで使用される暗号化プロトコルは[Net.ServicePointManager]::SecurityProtocolプロパティで確認でき、

PS C:\> [Net.ServicePointManager]::SecurityProtocol
Ssl3, Tls

と、デフォルトではSSL3TLS(1.0)が利用可能です。

このためデフォルト設定では最初に例示したGitHubへのアクセスはできません。
GitHubへのアクセスは下図の様にエラーとなってしまいます。

f:id:stknohg:20180430183454p:plain

Windows PowerShellでTLS 1.2通信を許可する

デフォルトではTLS 1.2の通信はできませんが設定により有効にすることができます。

以下の様に先述の[Net.ServicePointManager]::SecurityProtocolプロパティに[Net.SecurityProtocolType]::Tls12を追加してやればOKです。

[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12

実行例)

暗号化プロトコルにTLS 1.2が増えGitHubへのアクセスが可能になっているのが見て取れます。

f:id:stknohg:20180430183505p:plain

この設定はPowerShellセッション全体で有効であり永続化はできません。
ですので常用したい場合はプロファイルにこのコードを仕込んでおけば良いでしょう。

.NET Frameworkの既定値を変える

Windows PowerShellは.NET Framework製であり使用される暗号化プロトコルは.NET Frameworkのそれに従います。

Japan IE Support Team Blogのこちらのエントリにある様にセキュリティアドバイザリを適用するかレジストリを変更することで.NET 4.5以降の設定を変えることができます。

social.msdn.microsoft.com

これにより.NET 4.5で動作するPowerShell 4.0以降であれば、その既定値を変えることができます。

変更例)

# 要管理者権限
New-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\ -Name SchUseStrongCrypto -Value 1

レジストリを変えた後で[Net.ServicePointManager]::SecurityProtocolプロパティの値を確認すると、下図の様にTLS 1.0~TLS 1.2が有効になっていることがわかります。

(Windows PowerShell 5.1 on Windows 10の場合)

f:id:stknohg:20180430183557p:plain

UserVoice

設定変更すればWindows PowerShellでTLS 1.2の通信ができることは確認できましたが、いちいち変更するのは面倒です。
UserVoiceにネイティブサポートする様にリクエストが上がっていますので興味のある方はこちらにVoteすると良いでしょう。

survey
Please feel free to provide feedback or file bugs here.
  • 42 votes
  • 6 comments

Add support for TLS 1.2 (Invoke-WebRequest, Invoke-RestMethod)

Invoke-WebRequest and Invoke-RestMethod commands only support TLS 1.0 protocol. We need to have a native support for newer TLS (1.2) versions for modern web interfaces.

windowsserver.uservoice.com

PowerShell Coreの場合

PowerShell Coreで使用される暗号化プロトコルも[Net.ServicePointManager]::SecurityProtocolプロパティで確認でき、

PS C:\> [Net.ServicePointManager]::SecurityProtocol
SystemDefault

SystemDefaultという設定値になっています。
これはソースを読むとTLS 1.0~TLS 1.2がサポートされていることがわかります。

SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12;

このためPowerShell CoreではデフォルトでTLS 1.2が有効であり追加の設定は必要ありません。

【補足】BetterTlsモジュール

最後に補足としてBetterTlsモジュールを紹介します。

github.com

これはテキサスのMVP元MVP*1であるMark Krausさんが作ったモジュールで、先述のWindows PowerShellでのTLS設定の変更をいくつかのコマンドにして公開したものになります。

基本的には他のモジュールに組み込んで使うことが想定されているのですが単体でも使用できます。

簡単に使い方を説明して本エントリの終わりにしたいと思います。

インストール

# Install-Moduleでインストール
Install-Module BetterTls -Scope CurrentUser

使用例

# 現在の設定を確認
PS C:\> Get-Tls
Ssl3, Tls

# TLS 1.2を有効にする
PS C:\> Enable-Tls -Tls12 -Confirm:$false

# 変更後の設定を確認
PS C:\> Get-Tls
Ssl3, Tls, Tls12

*1:LinkedInに転職して中のひとになったためMVP卒業となったそうです

PowerShell Core 6.0の初期セットアップスクリプトを作りました

blog.shibata.tech

前にPSCoreUpdateというPowerShell Coreのアップデートを自動化するモジュールを作ったとお知らせしました。
このエントリ中で、

なお、このモジュールはあくまで更新のためのツールなので最初にPowerShell Core 6.0をインストールするのは手動で行う必要があります。

と記載し、この点に関しては今も変わってはいないのですが、初回インストールが手動なのはやっぱり面倒だったのでセットアップスクリプトを別に作ってみました。

初回インストールスクリプト

スクリプトはPSCoreUpdate内のこのページで公開しています。

github.com

PowerShell Coreのインストール手順はGitHubDocsで公開されており、基本的はこの手順を各OS・ディストリビューション毎にまとめただけのスクリプトになります。

基本方針として、Windows PowerShellやBashのコンソールにコピペして実行すれば良しなに最新のPowerShell Coreをインストールしてくれるものにしています。
方式としてはChocolateyRVMのインストール手順を参考にしています。*1

スクリプトの中身についてはGitHubで確認してください。
以下に現在のインストール手順を載せておきます。

Windows

前提条件として、Windows PowerShell 4.0以上がインストールされている必要があります。
(これはPowerShell Core 6.0をMSIからインストールするための前提条件です)

コマンドプロンプトから実行する場合

REM Command prompt
powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "[Net.ServicePointManager]::SecurityProtocol=[Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12;iex ((New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/stknohg/PSCoreUpdate/master/FirstTimeInstaller/Install-LatestPowerShell.ps1'))"

PowerShellコンソールから実行する場合

# Windows PowerShell
Set-ExecutionPolicy Bypass -Scope Process -Force; [Net.ServicePointManager]::SecurityProtocol=[Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12; iex ((New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/stknohg/PSCoreUpdate/master/FirstTimeInstaller/Install-LatestPowerShell.ps1'))

macOS

macOS Sierra (10.12)以上が対象です。

# Bash
\curl -s https://raw.githubusercontent.com/stknohg/PSCoreUpdate/master/FirstTimeInstaller/install_latestpowershell_mac.sh | bash -s

Ubuntu

Ubuntu 17.04、16.04、14.04で実行可能です。

# Bash
\curl -s https://raw.githubusercontent.com/stknohg/PSCoreUpdate/master/FirstTimeInstaller/install_latestpowershell_ubuntu.sh | bash -s

RHEL、CentOS、Fedora

以下のディストリビューションで実行可能です。

  • RHEL 7
  • CentOS 7
  • Fedora 26、25
# Bash
\curl -s https://raw.githubusercontent.com/stknohg/PSCoreUpdate/master/FirstTimeInstaller/install_latestpowershell_rhel.sh | bash -s

Debian

Debian 9、8.7+で実行可能です。

# Bash
\wget -q --no-check-certificate https://raw.githubusercontent.com/stknohg/PSCoreUpdate/master/FirstTimeInstaller/install_latestpowershell_debian.sh -O - | bash -s

[Experimental] openSUSE、SLES

以下のディストリビューションで実行可能です。

  • openSUSE 42.1
  • SLES 12
# Bash
\curl -s https://raw.githubusercontent.com/stknohg/PSCoreUpdate/master/FirstTimeInstaller/install_latestpowershell_suse.sh | bash -s

こちらは現在の最新バージョン(6.1.0-preview.1)ではzypperの設定まではうまくいくものの、PowerShellのインストール時に依存関係のエラーが出てしまいインストールが必ず失敗します。
詳細はこのへんを見てください。

このスクリプトを実行した後に手動で

sudo zypper install powershell

を実行し、依存関係のエラーを無視してインストールを続行すればインストールすることができます。
この依存関係のエラーについてはそのうち新しいバージョンで解消されると思います。

*1:手順は参考にしてますが、個人的な信条としてChocolateyが嫌いなのでローカルマシンにChocolateyをインストールしたくないのです...