SSHポートフォワーディングを使ったテレワークによるFPGA開発

[**【この方法にセキュリティの脆弱性の指摘を受けたので次の記事で改善方法を示します】**](https://qiita.com/nahitafu/items/f308d62bfb81d7f3f663)

みなさん、テレワークしていますか？

会社に置いてきた組み込み機器に自宅から書き込みたいときどうしますか？
状況としては、自宅のPCでFPGAのビルドをするけど、機械は会社や学校にあるという場合を想定します。

VPNを張って会社(学校)のPCにリモートデスクトップ接続できればいいのですが、そうではない場合もあるかと思います。
例えば、

- 会社がVPNに対応してくれない
    - 外からの接続を受け付けない
    - NATが超えられない
    - 情報管理部門が許してくれない
- 回線が細くてリモートデスクトップするに耐えられない
- 会社のVPNがすぐ切れる

などを想定してみてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542455/fdc2db92-5fa7-d272-ca74-a5356c1df7b7.png)


**Vivadoを使ってFPGAの書き込みやデバッグだけはしたい！** というのであれば、SSHポートフォワーディングをすると何とかなります。
SSHポートフォワーディングを使うにはグローバルIPを持ったSSHサーバが必要ですが、自宅も会社(学校)もTCPのクライアント側になるので、NATを越えられるし、ファイアーウォールも越えられるからです。つまり、インターネット上にあるSSHが動くサーバを介して、任意の2点間でトンネルを作ることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542455/10ff9405-5ffb-cd42-6ba4-1095f9f0b0c3.png)

# Vivadoのリモート対応

VivadoのJTAGまわりのツールはもともとネットワークに対応していて、概ね次の図のようになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542455/14b35e4c-4f74-7be3-00c7-3e38ab89b29d.png)

実はローカルPCでVivadoを使っていても、内部ではhw_server というプログラムが動いて、TCPの3121で待ち受けています。そして、VivadoやXILINX SDKがFPGAに書き込むときにTCP 3121を通じていろいろなコマンドを与えています。

したがって、hw_server.exeを起動しておけばVivadoは元からリモート接続に対応しているので、遠隔操作ができるのです。

hw_server.exeは、Vivadoをインストールしたフォルダのbinの中にある hw_server.batをダブルクリックすることで起動できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542455/6b075ae0-7dea-cdd9-ccf0-2aa04cbd4e7a.png)

起動するとDOSプロンプトの以下のような画面が開きます。これで待ち受けはOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542455/ad613b70-53e2-1de1-fcf5-bdf2df71df78.png)

# サーバを借りよう！
やるべきことは、グローバルIPアドレスを持ったサーバを借りることです。
AmazonのAWSで、一番安いサーバで十分でしょう。私はUbuntu Linuxの動く最小構成のサーバを借りました。そして、セキュリティグループというのを開き、通したいポートのインバウンドルールを追加します。ログインしてからufwで設定するのではなく、ファイアーウォールの設定はWebのこの画面から行えばよいようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542455/342785d3-abf5-d7a0-f844-aafc8c913735.png)

VivadoのJTAG通信はTCP:3121ですが、同じ番号だと困ることになるので、3121に10000を足して13121番を開けることにしました。sshd_configの設定は特にありません。サーバ上で作業することもありません。

Amazonで借りられるサーバにログインするにはキーペアという証明書が必要で、サーバを作ったときに配布されます。それがないと絶対にログインできないので、かなり安全です。

# 会社と家庭、それぞれの準備
## JTAGサーバ(会社)側の準備
会社の中でhw_serverを起動したPCでTeraTermを起動します。そして設定→SSH転送の設定を開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542455/23e1eb18-cee7-63e7-651e-e6de5035e016.png)

SSHポート転送の設定は、リモートサーバのポートを13121にして、ポートを3121にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542455/5fcbc504-c42b-85fd-5f5f-5494c9f8576c.png)

この設定をして会社のPCからSSHサーバに22番で普通に接続すると、リモートサーバの13121へのアクセスが会社サーバの3121に転送されます。

## 家庭側の作業
Vivadoを起動し、Open Hardware ManagerでConnected toにRemote serverを選び、リモートサーバのIPアドレスを入れます。また、TCPのポート番号は先ほどの13121とします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542455/e2681a2a-7604-de23-11be-7cf71caa989f.png)

これで無事にリモートサーバ経由で接続できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542455/2c7dd859-21fd-3a59-6d5c-0fdd34b73208.png)

## 接続方法のまとめ
- リモートのSSHサーバを立てておく。
- リモートサーバではTCP:13121(任意)を開けておく
- 会社PCでhw_server.batを起動しておく
- 会社PCからリモートサーバにSSH(TCP:22)でつなぐ
- 自宅PCでVivadoを起動し、Remoteの13121につなぐ
- リモートサーバと会社PCのTeraTermの間でトンネルが作られ、会社PCのTCP:3121に転送される
- 自宅PCから会社PCのhw_serverに接続できる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542455/d346ede7-348e-949a-6599-87066a3e2148.png)
というわけです。
繰り返しになりますが、会社からリモートサーバへただのSSHのセッションを張るだけなので、ファイアーウォールもNATも越えられるというわけなのです。

# 性能はどうか
ZYNQ UltraScale+のXCZU2CGに書き込む時間を比べてみました。

- ローカルPCでダイレクト接続・・・2秒
- 会社と自宅でVPNを張った(L2TP)場合・・3~6秒
- TCPポートフォワーディングの場合・・5秒

リモート接続してもそんなに遅くはならないという印象です。AWSがいいバックボーンを持っていると思われ、かなり安定してトンネルできます。
VIOもロジアナも使えるので、テレワークでFPGAを開発するのが少しだけ楽になるかと思います。

[【**この方法にセキュリティの脆弱性の指摘を受けたので次の記事で改善方法を示します**】](https://qiita.com/nahitafu/items/f308d62bfb81d7f3f663)