Windows10ホストでのVisualStudioCodeリモート開発

## はじめに

この記事は、macをクライアント、Windows 10をホストとして、Visual Studio CodeでのSSHリモート開発環境を構築する手順を記録、共有するためのものです。

Visual Studio Codeでのリモート開発に関するドキュメントは多くありますが、ほとんどがLinuxをホストとするものです。Windows 10をホストとするものが見当たりませんでしたので、つまづいたポイントとあわせてセットアップの手順を解説します。

### この記事で想定する環境

-   ホスト : Windows 10 Home 19041.985
-   クライアント : macOS 11.3.1
-   Visual Studio Code : 1.56.2

この記事ではWindowsをホスト、macをクライアントと呼びます。

-   手元にホスト、クライアント両方のPCが存在し、直接操作できる
-   それぞれのPCの管理者アカウントを操作できる
-   ホスト側の接続アカウントには管理者権限がある

また、以上の条件でリモート開発環境をセットアップします。それぞれのPCの操作権限がないと、この記事の手順を再現できない場合があります。ご了承ください。

### 目次

作業の手順は以下のようになります。

-   ホストにOpenSSHサーバーをインストールする
-   クライアントにSSH接続環境を作る
-   ホストのOpenSSHサーバーを設定する
-   Visual Studio Codeのリモート開発プラグインを導入する

### 公式ドキュメント

[Visual Studio Code : Remote Development using SSH](https://code.visualstudio.com/docs/remote/ssh)

この記事は公式ドキュメントを元にしています。もしこの記事と公式ドキュメントに食い違いがある場合、正しい内容は公式ドキュメントです。ご了承ください。

## ホストにOpenSSHサーバーをインストールする

まず、ホストにSSH接続できる環境を整えます。

### サービスのインストール

Windows 10にはMicrosoft公式のOpenSSHサーバーがあります。まずはこれをインストールします。

公式ドキュメント : [Microsoft Build : OpenSSH をインストールする](https://docs.microsoft.com/ja-jp/windows-server/administration/openssh/openssh_install_firstuse)

OpenSSHサーバーのインストールには、2つの方法があります。

-   PowerShellからのコマンドライン操作
-   設定パネルからの操作

この記事では設定パネルからの操作を解説します。

_❗設定パネルからオプション機能をインストールするには、管理者アカウントが必要です。一般アカウントではオプション機能一覧が表示されません。ご注意ください。_

[設定]を開き、[アプリ]→[アプリと機能]の順に選んで、[オプション機能]を選択します。

![](https://www.evernote.com/l/AAn-xaQKH2RP-pARyeNqroXy7Z5idaBGYlgB/image.png?=v1)

[機能の追加]を選びます。

![](https://www.evernote.com/l/AAllxuYrfMFICZLU58GvkKC1-Ts97Cm-BbcB/image.png)

[openssh]と検索して表示される[OpenSSHサーバー]を追加します。

![](https://www.evernote.com/l/AAlPKUQJz31EoIP5OLWai6xIGJ_l47FYIAoB/image.png)

### サービスの起動

OpenSSHサーバーをインストールしたら、PowerShellを管理者権限で立ち上げます。以下のコマンドでOpenSSHサーバーが立ち上がります。

```powershell
Start-Service sshd
```

#### IPアドレスのメモ

ホストのIPアドレスを確認します。

```powershell
ipconfig
```

このコマンドで表示されるIPv4アドレスが、テスト接続に必要です。メモを取っておいてください。

### テスト接続

ここまでで、ホストにはパスワード認証方式のSSHサーバーが立ち上がりました。サーバーが正常に稼働しているか、クライアントから接続テストします。

クライアントのターミナルを立ち上げ、以下のコマンドを実行します

```shell
ssh <ホストのユーザー名>@<IPアドレス>
```

あるホストにはじめて接続する場合、そのホストを信頼するかという警告が表示されます。yesをタイプして処理を続けます。

```shell
The authenticity of host 'servername (192.168.*.*)' can't be established.
ECDSA key fingerprint is SHA256:(<a large string>).
Are you sure you want to continue connecting (yes/no)?
```

_❗いままで接続したことがあるホストで、上記の警告が表示された場合、信頼できない別のホストに誘導されている可能性があります。noをタイプして処理を中断してください。_

次にパスワード入力を求められます。ここにWindowsユーザーのログインパスワードを入力します。クライアントのパスワードではありませんのでご注意ください。

```powershell
ユーザー名@IPアドレス C:\Users\username>
```

PowerShellが表示されれば接続成功です。
`exit`コマンドでSSH接続を終了します。

## クライアントにSSH接続環境を作る

ホストにSSHサーバーが立ち上がりました。しかしこのサーバーはパスワード認証で動いています。接続テストができたらより安全な公開鍵認証に切り替えます。

クライアントで公開鍵/秘密鍵ペアを生成する手順は以下の記事をご参照ください。

[デザイナーでもわかるrsync : 導入](https://qiita.com/masato_makino/items/23835169428ee3015c59#%E5%B0%8E%E5%85%A5)

この記事の[サーバーに公開鍵を登録する](https://qiita.com/masato_makino/items/23835169428ee3015c59#%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%81%AB%E5%85%AC%E9%96%8B%E9%8D%B5%E3%82%92%E7%99%BB%E9%8C%B2%E3%81%99%E3%82%8B)の手順までを実行してください。ここでコピーした公開鍵を、次の手順でホストに登録します。

## ホストのOpenSSHサーバーを設定する

OpenSSHサーバーの設定を変更し、公開鍵認証に対応します。

### ssh-config

Windows版のOpenSSHサーバーは、次の場所に設定ファイルを保存しています。

    C:\ProgramData\ssh\sshd_config

拡張子はありませんが、このファイルはプレーンテキストです。お好みのエディターで編集してください。

```ssh
# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented.  Uncommented options override the
# default value.

# OpenSSH に同梱されているデフォルトの sshd_config のオプションに使われている戦略は、
# 可能な限りオプションをそのデフォルト値で指定し、コメントを残すというものです。
# コメントされていないオプションはデフォルトの値を上書きします。
```

ssh_configファイルは冒頭に書かれている通り、デフォルト値を列挙しつつ#でコメントアウトされています。設定を変更する場合は#を削除し、設定値を書き換えます。

公開鍵認証をONにします。

```diff
- #PubkeyAuthentication no
+ PubkeyAuthentication yes
```

パスワード認証を禁止します。

```diff
- #PasswordAuthentication yes
+ PasswordAuthentication no
```

管理者グループ設定をコメントアウトします。

この記事では、ユーザーに個別の公開鍵ファイルを設定するためこの項目をコメントアウトします。皆様の公開鍵ファイルの管理方針に合わせて設定を検討してください。

```diff
- Match Group administrators
-        AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys
+ #Match Group administrators
+ #       AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys
```

ssh_configの編集が完了したら、OpenSSHサーバーを再起動します。

```powershell
Restart-Service sshd
```

これで公開鍵認証がONになりました。この状態で、パスワードを入力してSSH接続すると失敗するかテストしてください。接続に失敗すれば、パスワード認証がOFFになっています。

### authorized_keys

ホストのユーザーアカウントに、認証済み鍵ファイルを作成します。

まずはauthorized_keysファイルを指定の位置に作成します。

    C:\Users\<ユーザー名>\.ssh\authorized_keys

このファイルに、クライアントで作成した公開鍵ファイル`id_rsa.pub`の内容をペーストします。これで鍵交換が完了です。クライアントのターミナルで、以下のコマンドを実行してください。

```shell
ssh <ホストのユーザー名>@<IPアドレス>
```

パスワードを聞かれずに接続できれば設定成功です。

### Windows Defenderファイアウォール

OpenSSHサーバーは、インストール後に22番ポートを開放します。セキュリティ強化のため、Windows Defenderファイアウォールで特定のIPアドレス以外からホストへの接続を禁止します。

コントロールパネルを開き、Windows Defenderファイアウォールを検索します。

![](https://www.evernote.com/l/AAm9cUfQ5bNCK51KVqV7wuKezdqED6DBgcAB/image.png)

ファイアウォールの規則一覧が表示されますので、OpenSSHの受信規則をダブルクリックで開きます。

![](https://www.evernote.com/l/AAnbIA2WkEBCW4h5AZVRKT1UKbcbe3ARNd4B/image.png)

[スコープ]→[リモートIPアドレス]→[追加…]をクリックします。

![](https://www.evernote.com/l/AAn4dh4S95BJsYP1ZbEXr7-K7514Ph9vE1IB/image.png)

LAN内のIPアドレスを指定します。

![](https://www.evernote.com/l/AAmSADYuPZdFc5MRUCofTeKLHN30hZu9p8UB/image.png)

これで接続可能なクライアントのIPアドレスが絞り込めます。テストとして、クライアントのIPアドレスを範囲外にしてください。接続に失敗すれば、ファイアウォールが正常に動作しています。

## クライアントの~/.ssh/configファイルを整備する

クライアントの接続設定を、configファイルにまとめると再接続が簡単になります。
こちらの記事を参考に、クライアントで`~/.ssh/config`ファイルを作成、編集してください。

[デザイナーでもわかるrsync ~/.ssh/configファイルの作成と編集](https://qiita.com/masato_makino/items/23835169428ee3015c59#sshconfig%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E4%BD%9C%E6%88%90%E3%81%A8%E7%B7%A8%E9%9B%86)

この記事の設定に合わせると、configファイルは以下のようになります。

```ssh
Host *
 AddKeysToAgent yes
 UseKeychain yes
 IdentityFile ~/.ssh/id_rsa

Host [任意の名前]
 HostName   [ホストのIPアドレス]
 User       [ユーザー名]
```

これでクライアントから

```shell
ssh 任意の名前
```

というコマンドだけでホストに接続できます。

## Visual Studio Codeのリモート開発プラグインを導入する

ここまでの手順で、ホストへのSSH接続が確立しました。最後に、Visual Studio Codeにプラグインを導入して、リモート開発環境を整えます。

### プラグインのダウンロード

[marketplace.visualstudio.com : Remote Development](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack)

こちらのページから、Microsoft公式のリモート開発プラグインをインストールします。

### リモートホストの選択

インストールすると、Visual Studio Codeのアクティビティバーにリモートホスト一覧メニューが追加されます。

![](https://www.evernote.com/l/AAkknILGiSJOdaMgx3grCV-U5EZQs-KRJ2wB/image.png)

この一覧には、`~/.ssh/config`ファイルに登録されたホストが表示されます。今回対象とするホストの末尾「ウィンドウに+」のアイコンをクリックすると接続が始まります。初回接続時にはホストに`VS Code Server`というソフトをインストールしますので、少し時間がかかります。

![](https://www.evernote.com/l/AAlbPIyZzrpHMqtNYgzKu7cV3R5u0q5kexwB/image.png)

新しいウィンドウが表示され、画面左下に`SSH:任意の名前`と表示されたら接続成功です。
「フォルダーを開く…」メニューから、ホスト側のディレクトリを指定して開発を始めます。

## トラブルシューティング

### `Permission denied (publickey,keyboard-interactive)`

SSH接続時にこのエラーが発生する場合、ホスト上の設定ファイルパーミッションが不適切です。OpenSSHサーバーは設定ファイルが攻撃によって上書きされる危険性を考え、ログインするユーザーが設定ファイルを上書きできる場合接続をキャンセルします。

この記事の場合、手動で作成した`authorized_keys`のパーミッションが広すぎるかもしれません。authorized_keysは、SYSTEMアカウントが読み込めれば動作します。公式のWikiを参照して、適切なファイルパーミッションを設定してください。

[Security protection of various files in Win32 OpenSSH](https://github.com/PowerShell/Win32-OpenSSH/wiki/Security-protection-of-various-files-in-Win32-OpenSSH#authorized_keys)

具体的な手順としては、以下のコマンドで継承したパーミッションの削除と、SYSTEMへのパーミッションを追加します。

```powershell
PS C:\> icacls .\users\<ユーザー名>\.ssh\authorized_keys /inheritance:r
PS C:\> icacls .\users\<ユーザー名>\.ssh\authorized_keys /grant SYSTEM:`(F`)
```

このコマンドを実行して、パーミッションを再確認します。

```powershell
PS C:\> icacls .\users\<ユーザー名>\.ssh\authorized_keys
```

SYSTEMユーザー以外のパーミッションが削除されていれば成功です。

参考記事 : [Windows10公式のopensshサーバーを起動して、macからsshで接続するまで](https://qiita.com/hatobeam75/items/825ee10a5261835e814b#%E3%83%8F%E3%83%9E%E3%81%A3%E3%81%9F%E3%81%A8%E3%81%93%E3%82%8D%E9%8D%B5%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E6%A8%A9%E9%99%90%E3%81%BE%E3%82%8F%E3%82%8A)

### `Setting up SSH Host <ホスト名>: (details) Initializing VS Code Server`

SSHでWindowsホストにリモートログインする場合、接続先ユーザーに管理者権限がないと処理が中断します。

![](https://www.evernote.com/l/AAlCn7AdZNtHvp1fkhxD9vt6Spj7AmQsT_AB/image.png)

これは既知の問題で、まだ解決策はありません。接続先ユーザーを管理者にすることで問題を回避できます。

[Can't connect to non-admin Windows account (Get-CimInstance PermissionDenied) #2648](https://github.com/microsoft/vscode-remote-release/issues/2648)

以上、ありがとうございました。