Windows に何もインストールせずに SSH を使う

Tera Term などをインストールせずに SSH を使う方法をご紹介します。

ちょっとむずかしめに言うと Windows 10 バージョン 1803 以降に導入されている Win32-OpenSSH をクライアントとして使う方法です。


## この方法の利点

- サード パーティーのアプリを導入する際のリスクが減る
    - 私の環境で Google で Tera Term を検索すると公式は 8 番目、PuTTY を検索すると公式は 2 番目に表示されるため、誤って怪しいアプリをインストールしてしまう可能性がある
- Unix と同じ ssh コマンドなので、覚えたことをほかの OS でも活用できる
- Windows Terminal を使うか、PowerShell の履歴を使えばユーザー名や接続先の IP は一度だけ入力すればいい
- Tera Term と違いウィンドウ サイズを自由に変えられるので、Windows キー + 矢印 で簡単に 1/4 サイズの画面を作れる
- 鍵で認証するならばパスワードを覚える必要がない
- ssh-agent を使えばサーバーからサーバーへの SSH 接続も簡単 (ただし危険)
- 深刻な脆弱性が見つかった場合には Windows Update で更新されることを期待できる


## この方法の欠点

- 画面の表示が乱れて、同じ行が 2 回表示されることがある (慣れたらあまり困らない)
- Tera Term や PuTTY のようなログを保存する機能はない


## (Windows Terminal ではない場合) デフォルト設定の変更

以降では PowerShell を使います。また、サーバーは UTF-8 を使っており、パスワードで接続できる想定です。

Windows 11 など、Windows Terminal で PowerShell を使う場合には不要なようですが、コード ページが Shift-JIS (932) になっていると、ssh などを実行した瞬間に UTF-8 (65001) に切り替わり、そこまでは良いのですが、なぜか日本語が表示できないフォントになってしまうようです。

以下の手順で、PowerShell を起動したときから UTF-8 でＭＳ ゴシックを使うように設定できます。

1. PowerShell のショートカット (スタート ボタン > Windows PowerShell > Windows PowerShell > その他 > ファイルの場所を開く) を右クリックしてプロパティ(R) を開く
1. ショートカット タブでリンク先の末尾に ` -NoExit -Command "chcp 65001"` を追加する (先頭のスペースに注意)
1. フォント タブで、ＭＳ ゴシックにする

画面の背景色は黒がおすすめです。


## 素朴な使い方 (初回接続時)

### 悪意ある利用者がネットワークにいない確信がある場合

PowerShell を開き、以下のコマンドを実行します。

```
ssh <ユーザー名>@<サーバーのアドレス>
```

初めて接続するときには以下のように聞かれますので、yes と入力して Enter を押してください。

```
The authenticity of host '<ホスト名> (<IP アドレス>)' can't be established.
ECDSA key fingerprint is SHA256:ETZj0xIezigdI/+OosTSaTJYFX3dIoz2kLNV7C9i+24.
Are you sure you want to continue connecting (yes/no/[fingerprint])?
```

パスワードを入力して接続してください。

### 悪意ある利用者がネットワークにいるかもしれない場合

信頼できる接続方法 (サーバーに物理的にディスプレイとキーボードを接続するなど) で以下のコマンドを実行し、表示された ASCII アート (randomart) や fingerprint を控えます。

```terminal
$ ssh-keyscan localhost | ssh-keygen -lv -f -
```

次にローカルで PowerShell を開き、次のコマンドを実行します。

```
ssh -o VisualHostKey=yes <ユーザー名>@<サーバーのアドレス>
```

以下のように聞かれます。

```
The authenticity of host '<ホスト名> (<IP アドレス>)' can't be established.
ECDSA key fingerprint is SHA256:ETZj0xIezigdI/+OosTSaTJYFX3dIoz2kLNV7C9i+24.
+---[ECDSA 256]---+
|    o.o+X*..     |
|     =BX**= .    |
|    o.+B=+ .     |
|   . ......      |
|  .     S  .     |
|.+ .   oo . .    |
|= * . ...o .     |
| * . .  . E      |
|  .      +o      |
+----[SHA256]-----+
Are you sure you want to continue connecting (yes/no/[fingerprint])?
```

"Are you sure you want to continue connecting (yes/no/[fingerprint])?" と表示された際に、randomart がサーバーと一致していることを確認して yes を入力するか、控えた fingerprint を入力すればパスワードの入力に進みます。

パスワードを入力して接続してください。


## おすすめの使い方 (初回接続時)

パスワードを毎回入力するのは大変なので、パスフレーズなしの秘密鍵を使って認証する方法がおすすめです。

PowerShell を使用してください。

### 1. ssh-keygen を実行してキー ペアを作成する

以下のように、すべてデフォルトで作成します。パスフレーズも空です。秘密鍵にアクセスできるほかの人 (IT 部門の管理者など) もサーバーにアクセスできてしまう点にはご注意ください (パスフレーズを設定しても時間稼ぎができる程度です)。

```
PS C:\Users\hanohrs> ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (C:\Users\hanohrs/.ssh/id_rsa):
Created directory 'C:\Users\hanohrs/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in C:\Users\hanohrs/.ssh/id_rsa.
Your public key has been saved in C:\Users\hanohrs/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:hMMyJFAbUnEB2/pR2YwI4ipdwllF7rx+6+GJ7zOj7YU hanohrs@DESKTOP-VUPHBLR
The key's randomart image is:
+---[RSA 3072]----+
|++Oo=+o          |
|.+ % + *         |
| .* * O +        |
|.. + * o         |
|o o . o S        |
|.  . . . .       |
|    . . E .      |
|     . +=+       |
|      +BX=       |
+----[SHA256]-----+
```

### 2. OpenSSH Authentication Agent (ssh-agent) サービスを開始する

ファイル名を指定して実行で services.msc を実行するなどしてサービスを開き、OpenSSH Authentication Agent を見つけます。

ダブルクリックして、スタートアップの種類(E) を「自動 (遅延開始)」にして、「適用(A)」してください。これにより、リブート後も自動で起動するようになります。

今はサービスが停止した状態なので「開始(S)」を押してサービスを開始してください。

### 3. ssh-add で ssh-agent に秘密鍵を登録する

引数なしで ssh-add を実行してください。以下のようになります。

```
PS C:\Users\hanohrs> ssh-add
Identity added: C:\Users\hanohrs/.ssh/id_rsa (hanohrs@DESKTOP-VUPHBLR)
```

`ssh-add -l` で登録済みの鍵を確認できます。

### 4. (複数ある場合はサーバーごとに) 公開鍵をサーバーにコピーする

ssh-copy-id が使えないので、以下のようにして公開鍵をコピーします。<ユーザー名>、<サーバーのアドレス> は正しい値に置き換えてください。

```
Get-Content ~/.ssh/id_rsa.pub | ssh -o VisualHostKey=yes <ユーザー名>@<サーバーのアドレス> "umask 077; test -d .ssh || mkdir .ssh; cat >> .ssh/authorized_keys"
```

このコマンドにより初回接続が行われます。素朴な使い方と同様に fingerprint の確認とパスワードの入力が必要です。


## 通常の使用時

単に以下のようにして接続します。

```
ssh <ユーザー名>@<サーバーのアドレス>
```

<ユーザー名>@<サーバーのアドレス> を毎回入力すると面倒なので、PowerShell の履歴機能を使って ↑ キーや Ctrl+R での検索から呼び出して使用してください。

### Windows Terminal のプロファイルとして登録する

設定の下のほうの「＋　新しいプロファイルを追加します」をクリックし、コマンドラインに上記コマンドを指定することで SSH 用のプロファイルを作成できます。

### ssh-agent を使用する場合

-A オプションを指定して接続します。

```
ssh -A <ユーザー名>@<サーバーのアドレス>
```

-A オプションにより、ssh で接続した先で ssh や scp を使う際に、踏み台から先のサーバーにもローカルに登録済みの鍵で自動的に認証されるようになります。

ただし、[-A オプションのドキュメント](https://man.openbsd.org/ssh#A)にある通り、注意してご利用ください。サーバーが攻撃を受けている可能性があるなど、管理者権限で悪いことをされるかもしれない場合には -A は使わないでください。

サーバーの .ssh ディレクトリーに秘密鍵を置く方法と比べると、ちょっとだけ悪用されにくい代わりに、悪用された場合にはローカルの ssh-agent で好き放題されてしまうようです。


## 画面の表示が乱れたら

ログイン直後に起きやすい事象で、以下のように何行かが 2 回繰り返して表示されることがあります。less でファイルを表示した際に起きやすいです。Ctrl+L を押す、ウィンドウのサイズを変更するなどして再描画させると解消します。

![duplicate_lines.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/782342/f9ac5552-8c94-8bc2-6494-cc728f01f887.png)


## Terrapin Attack への対応について

最近 Terrapin Attack という脆弱性が話題になり、Tera Term などの最新版では対策されています。Win32-OpenSSH も最新版では対策済みですが、Windows Update での更新の基準には達していないと判断されているため、手動で更新する必要があります。

手動での更新ができない環境では、設定ファイルを書き換えて問題を緩和することが可能です。


## 参考

https://blog.shibata.tech/entry/2018/05/14/201319

https://dev.classmethod.jp/articles/tips-for-openssh-client-on-windows-environment/

https://qiita.com/s4i/items/75c19c9feb10b54c1ce9

https://serverfault.com/questions/224810/is-there-an-equivalent-to-ssh-copy-id-for-windows

https://qiita.com/angel_p_57/items/19eda15576b3dceb7608

https://qiita.com/aki3061/items/99f1cce099c64d66861f

https://learn.microsoft.com/en-us/windows/terminal/tutorials/ssh