[Windows] SSHメモ

環境:
- Windows10
- コマンドプロンプト


# SSH時のパスワードの入力を省略する

おおまかな流れ

- 移動前のサーバーで秘密鍵・公開鍵のペアを作成し，移動先のサーバーに公開鍵を登録
    - 移動先のサーバーのパスワードの代わりに，秘密鍵作成時に指定したパスフレーズで認証
    - (何かしらのパスワードを要求されるという意味では)変わらない
- パスフレーズを毎回聞かれるのを避けるためにパスフレーズをssh-agentに登録
    - ssh-agentの登録状況はシェルが再起動する度にリセットされる
        - e.g. PuTTYのduplicate sessionでも
    - 結局毎回ssh-addをする羽目に
- ssh-agentの登録情報を保持するためにkeychain導入

## 公開鍵認証によるログイン

### 移動元サーバーでの準備

#### 公開鍵の作成

```bash
$ ssh-keygen
```

何も入力しないと，id_rsa，id_rsa.pubという2つのファイルが生成される．
ここで決めるパスフレーズを今後使って認証することになる．

- id_rsaが秘密鍵（他には公開しない）
- id_rsa.pubが公開鍵（他と共有する）

**.pubがついている方**を移動後サーバーに登録しておくことで，公開鍵認証ができるようになる．

#### ~/.ssh/configでの設定

ssh時の設定を管理する~/.ssh/configを以下の通り編集．

```bash
Host ${ホスト名}
    HostName ${IPアドレス}
    User ${ユーザー名}
    IdentityFile ~/.ssh/id_rsa # 上の行程で作成した秘密鍵ファイルのパス
```

これで

```bash
$ ssh ${ホスト名}
```

をしたときに秘密鍵のパスが指定されるようになる（`ssh ~~`とコマンドラインで打って指定する方法もある）．

### 移動先サーバーでの準備

~/.ssh/authorized_keysに移動元サーバーの公開鍵id_rsa.pubを追加
これで移動前サーバーの秘密鍵と移動先サーバーの公開鍵を照合して認証するようになる．

### ここまでで出来るようになること

移動先サーバーのパスワードではなく，id_rsaの生成時に指定したパスフレーズを使って認証するようになる．
**しかし，何かしらのパスワードが求められるという意味では手間は変わらない．**






## ssh-agentを使ったパスフレーズの記憶 (keychainを導入する場合スキップ可)

この問題を回避するために，ssh-agentに（秘密鍵認証に使う）パスフレーズを記憶させる．

```bash
$ eval `ssh-agent`
$ ssh-add ~/.ssh/id_rsa
```

[Qiita@evakichi: SSH で毎回パスフレーズを入れるのが面倒だと思ったときには]
(https://qiita.com/evakichi/items/abb6dde9df78f049b913)

しかし，ssh-agentの登録情報はシェルの再起動ごとにリセットされる．
例えば，PuTTYでSSH接続してssh-addをする→duplicate sessionで新しいウインドウを開いてもその情報を使えず，再度ssh-addする必要がある．



### keychainの導入

[情報系学生の備忘録: パスフレーズ入力回数を劇的に減らしてくれる「keychain」]
(http://note-for-cs.seesaa.net/article/400265433.html)
が詳しい．しかし，インストール方法やURLが変更されているので注意．

最新の情報・ソースは，
[GitHub: keychain](https://github.com/funtoo/keychain)
[Keychain公式Wiki](https://www.funtoo.org/Keychain) (上記ページからリンク)

#### インストール方法

- 上記のGitHubからダウンロード
- その中のkeychainにパスを通す (ビルドする必要もない)
    - 例えば~/local/bin/keychainにリンク，~/local/binを$PATHに
    - GitHubに書かれている"Please apply your patches to keychain.sh, not the generated keychain script"はkeychain開発者向け?
- 上記公式Wikiの通り，.bash_profileに以下を追記

```bash:.bash_profile
eval `keychain --eval --agents ssh id_rsa`
```

これで起動する度に「ssh-agentを立ち上げてssh-addでパスフレーズを入力して…」という手間から解放される！



























# X11 Forwardingの設定

やるべきことは2つ:
- 転送されてきた画面を受けるDISPLAYを設定
- SSHの設定でX11 Forwardingを許可
    - これは飛ばしても`ssh -Y ${ホスト名}`で出来るが，.ssh/configに設定を残しておくと`-Y`が不要に

本記事では**Xming**を使用

## DISPLAYの設定

以下でOK．cmd再起動してもDISPLAYの再設定は不要だった．

```bash
set DISPLAY=localhost:0.0
```

[stackoverflow: Why does X-forwarding using ssh.exe work in cmd.exe but not Powershell?]
(https://superuser.com/questions/1498938/why-does-x-forwarding-using-ssh-exe-work-in-cmd-exe-but-not-powershell)
上ページの質問者のコマンド参照．回答はPowershell用．

**これで出来ること**

- `ssh -Y ${ホスト名}`で接続したサーバーで何か動かすと (e.g. Pythonで図を描画) Xming上で見られるようになる
- `ssh -X ${ホスト名}`はダメだった．`-Y`の省略も不可．

[Qiita@tama14142356: windows標準ssh(openssh)だけを用いてLinuxサーバから画面をX転送する。]
(https://qiita.com/tama14142356/items/be7b93fcce8978173ffd)
この記事はPowershell用．


## .ssh/configの設定で`-Y`オプションを省略

以下の3行を加えると`ssh ${ホスト名}`でX転送可能に．

```ssh
ForwardX11Trusted yes
ForwardX11 yes
XAuthLocation /usr/pkg/bin/xauth
```

[[comp] ssh -Y を ~/.ssh/ssh_config に設定](http://www.ki.nu/~makoto/diary/2010/05/05/1.html)