windows標準ssh(openssh)だけを用いてLinuxサーバから画面をX転送する。

## はじめに
~~linux, macやWSL上であればsshのオプションに`-X`を付ければ終了ですが、生のwindows上ではそれができません。~~
また、windowsであってもsshクライアントにTera TermとかPuTTyとかを使えばすぐに設定できることですが、これらの設定法は調べればすぐに出ますので、検索してほしいと思います。
私の考えとしてはwindowsにはせっかく初めからssh接続できるソフトが入っているので、インストールしなくていいソフトはなるべくインストールせず、必要最小限のソフトでsshの設定を行いたいと思ったのがきっかけでこの記事を書きました。

## 環境
<dl>
 <dt> OS </dt>
 <dd> windows10 Pro </dd>
 <dt> ssh接続先OS </dt>
 <dd> Linux(Ubuntu18.04LTS) </dd>
 <dt> sshクライアント </dt>
 <dd> OpenSSH </dd>
 <dt> 必須ソフトウェア </dt>
 <dd> コマンドプロンプト </dd>
 <dd> Windows PowerShell </dd>
 <dd> Xwindow system ソフト(VcXsrv) </dd>
</dl>

## セットアップ

### OpenSSH, コマンドプロンプト, Windows PowerShell
windows10であればデフォルトでインストールされているはずです。その為、セットアップの仕方はわかりませんので、省略します。すいません。

### Xwindow system
X転送されたものを表示するためのソフトウェアには様々な種類がありますが、私はVcXsrvというソフトウェアを用いました。
以下のURLからダウンロードして、インストールできます。
[VcXsrvのダウンロードページ](https://sourceforge.net/projects/vcxsrv/)
より詳しい方法を知りたい場合は以下のURLが参考になります。
[WSL上にXサーバをインストールしてGUIを実現する（VcXsrv編）](https://www.atmarkit.co.jp/ait/articles/1812/06/news040.html)

## 前提
### コマンドラインの先頭文字の表記の意味
<dl>
 <dt> <code> C:\> </code> </dt>
 <dd> コマンドプロンプト上でのコマンド入力 </dd>
 <dt> <code> PS C:\> </code> </dt>
 <dd> windows powershell上でのコマンド入力 </dd>
 <dt> <code> $ </code> </dt>
 <dd> linux環境のターミナルでのコマンド入力 </dd>
</dl>

### 文字の意味
<dl>
 <dt> &lt;windows_username&gt; </dt>
 <dd> windows上でのユーザ名 </dd>
 <dt> &lt;server_usrename&gt; </dt>
 <dd> サーバ上でのユーザ名 </dd>
</dl>

### ssh接続について
目的の接続先にssh接続できる状態であることを前提とします。
この記事で解説することは多段sshができる必要はありませんが、私の試した環境は多段ssh接続するものであるため、それを前提に解説します。
これから解説する設定前の段階で、以下のようにして踏み台サーバ(PC), 目的のサーバ(PC)にアクセスできるものとします。

- 踏み台サーバ(PC)

```
C:\> ssh <server_username>@hoge.jp
```

- 目的のサーバ(PC)

```
C:\> ssh <server_username>@hoge.jp
$ ssh hoge1
```

## X転送するための設定（本題）

1. まずwindows上のファイル`C:\Users\<windows_username>\.ssh\config`を以下のように作成または修正します。
これにより、以下の3点が設定されます。
   - windows上からssh接続するときの指定先が簡略化できる。(&lt;server_username&gt;@hoge.jp -> server)
   - windows上から直接hoge1にアクセスすることができる。
   - X11 forwarding機能を有効にする。

    ```config:config
        Host server
          User <server_username>
          HostName hoge.jp
          ForwardAgent yes
          ForwardX11 yes
          ForwardX11Trusted yes
          ForwardX11Timeout 596h

        Host server1
          HostName hoge1
          User <server_username>
          ProxyCommand ssh.exe server -W %h:%p
          ForwardAgent yes
          ForwardX11 yes
          ForwardX11Trusted yes
          ForwardX11Timeout 596h
          ServerAliveInterval 300
          ServerAliveCountMax 5
    ```

1. 次に環境変数DISPLAYを設定します。
   1. windows powershellを起動して、以下のコマンドを実行します。  

        ```
        PS C:\> [System.Environment]::SetEnvironmentVariable("DISPLAY", "localhost:0.0", "User")
        ```
   
   1. windows powershellを再起動して、設定されているか確認します。

        ```
        PS C:\> $env:DISPLAY
        localhost:0.0
        ```

1. windows上でX window system(VcXsrv)を起動

1. 最後に以下のようにサーバに接続して、何か画面を表示するプログラムを起動して、画面が表示されれば成功です。

```
C:\> ssh server1
$ <何か画面を呼び出すプログラムの実行コマンド>
```

## デモ
hoge1上に以下のただのグラフを表示するコードが存在するとします。
<details><summary>グラフ表示コード(test.py)</summary><div>

```python:test.py
import matplotlib.pyplot as plt

x = [100, 200, 300, 400, 500, 600]
y = [10, 20, 30, 50, 80, 130]

plt.plot(x, y)
plt.show()
```
</div>

この時、x window system(VcXsrv)を起動し、以下のコマンドを実行した時、windows上に以下の画像が表示されます。

```
C:\> ssh server1
$ python test.py
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/516498/a67fda34-4188-2beb-6b03-f8de7d79ed8d.png)


## 終わりに
今回参考にしたのは以下のものです。
もしかすると以下のURLのほうが参考になるかもしれません。
参考URL：
[Windows 10 OpenSSH](https://portal.isee.nagoya-u.ac.jp/stel-it/doku.php?id=public:win10_openssh)
[VSCode Remote Development + SSHトンネルで安全なWebアプリケーション開発](https://qiita.com/miyanaga/items/9680e9a846da2e725b56)
[WSL上にXサーバをインストールしてGUIを実現する（VcXsrv編）](https://www.atmarkit.co.jp/ait/articles/1812/06/news040.html)

## 追記
<dl>
 <dt>2020/9/3時点</dt>
 <dd>configファイルを編集する方法しかwindowsからX転送はできないと思っていた</dd>
 <dt>2020/9/15時点</dt>
 <dd>改めて実験してみたところ、DISPLAYの設定がされていれば、LinuxやMacと同様にして、<code>-X</code>オプションを付けるだけで接続できることが判明。
 </dd>
</dl>

その為、この記事はX転送するときの選択肢の一つとしてみていただければ幸いです。

## 編集履歴
<dl>
 <dt> 2020/9/15 </dt>
 <dd> ・追記の追加 </dd>
 <dt> 2020/11/4 </dt>
 <dd>・編集履歴の追加</dd>
 <dd>・追記の編集</dd>
 <dd> ・ssh.exeを絶対パスで指定すると書いたが、ssh.exeで十分機能することが判明したため、configファイルの訂正
 </dd>
 <dd>・<code>-X</code>オプションが機能することが分かったため、前置き文の取り消し線を追加(9/15の時には訂正し忘れていました。。)
 </dd>
</dl>