【書きかけ】外出先のノートPCから自宅のUbuntuサーバで捗るコーディングをするための手順まとめ

#要点
趣味や勉強用途の機械学習コーディングはMacbook (Air) ＋ Goole colab or 自宅Ubuntuサーバの2択としている。そこで、外出先のMacbookから、自宅のUbuntuサーバ上でコードを実行するための手順をまとめた。

- ssh接続を設定する
- AppleScriptとiTerm2を利用した接続の自動化
- Jupyter notebookをリモートで使用する
- VS Codeをリモートで使用する
- Wake On Lanを設定する



#環境
自宅サーバ：Ubuntu18.04
外出Macbook：Macbook 2017 OS X Mojave

#ssh接続の設定方法
Ubuntuサーバにopen-sshや公開鍵認証の導入は済んでいる前提。多くのWebサイトに知見がある。それ以外の部分をまとめる。
1．DDNSホスト名の取得
無料ダイナミックDNS(DDNS)サービスの[ieServer](http://ieserver.net/)を利用した。グローバルIPアドレスを[ここらへんのサイト](https://www.cman.jp/network/support/go_access.cgi)でグローバルIPアドレスを調べたあと、対応するホスト名を取得する

2．ルータのポート開放設定
192.168.0.1などでアクセスして設定する。ルータ依存。

| 外部ポート|内部ポート|IPアドレス|プロトコル|
|:--|:--|:--|:--|
|ルータで開放する外部ポート(任意)|サーバのsshdに記載したsshポート|自宅サーバのローカルIPアドレス(192.168.0.~~など)|sshはTCP/Wake On LanはUDP|

3．ssh公開鍵認証設定
多くのWebサイトが手順を公開しているので割愛。RSA鍵を発行して設定したり、サーバ側の/etc/ssh/sshd_configを設定する。サーバ側の設定はssh_configではなく、ssh **d**_configなので注意（ミスりました）。ローカルのMacbookは~/.ssh/configを設定する。
サーバのsshd_configの設定の注意点としてClientAliveIntervalを適切（私の場合は15秒）指定すると、ssh接続が切断されなくなる。また、ssh用のPortはデフォルトでは22番だが、セキュリティのために一般には好きな数字に変更するよう。


```sshdconfig:Ubuntuサーバの　/etc/ssh/sshd_config
ClientAliveInterval 15
Port [sshに使用する任意のポート]
```

4．Macbookの~/.ssh/config設定
Macの場合下記の2つの指定をしておき、
ssh-add -K ~/.ssh/id_rsa
を実施することで、id_rsa認証鍵のパスフレーズの入力を省略できる。

```
AddKeysToAgent yes
UseKeychain yes
```

下記は楽をするための~/.ssh/configの設定。

```ssh:~/.ssh/config
#User settings
AddKeysToAgent yes
UseKeychain yes

#Ubuntu home
Host home
HostName [LAN内で接続する場合のローカルIPアドレス]
Port [サーバのsshdに設定したsshポート]
User [ユーザ名]
IdentityFile ~/.ssh/id_rsa

#Ubuntu outside
Host outing
HostName [DDNSサービスのホスト名]
Port [ルータで開放した外部ポート]
User [ユーザ名]
IdentityFile ~/.ssh/id_rsa

#Ubuntu outside Jupyter
Host jn_outing
HostName [DDNSサービスのホスト名]
Port [ルータで開放した外部ポート]
User [ユーザ名]
GatewayPorts yes
LocalForward 8888 localhost:8888 #ポートフォワーディングによって外部から自宅サーバのjupyter notebookにアクセス可能にしている
IdentityFile ~/.ssh/id_rsa

#Ubuntu home Jupyter
Host jn_home
HostName [LAN内で接続する場合のローカルIPアドレス]
Port [サーバのsshdに設定したsshポート]
User [ユーザ名]
GatewayPorts yes
LocalForward 8888 localhost:8888
IdentityFile ~/.ssh/id_rsa
```


#AppleScriptとiTerm2を利用した接続の自動化
機械学習をしているとCPUやメモリ、GPUの使用状況をモニタリングしたくなる。また、ポートフォワーディングを利用して自宅サーバのJupyter notebookを外出先から使用できるようにしたい。AppleScriptを使用してiTerm2から自動で自宅サーバへの接続とモニタリングを実施する。

下記はiTerm2を開いている状態で新規に4つのPaneを開き、Jupyter notebookサーバの起動とsensors、vmstat、nvidia-smiをモニタリングを実行する。
ssh jn_outingではポートフォワーディング(ポート8888)込の外出先からのssh接続
ssh outingでは通常の外出先からのssh接続

```AppleScript
--for connecting to ubpc outside of the house with new panes
tell application "iTerm"
	activate
	
	tell current window
		tell current session of current tab
			--1st pane
			write text "ssh jn_outing" #ssh configにショートカットを記載している場合はこのようになる。そうでなければsshの記法に従って正確に記載する
			write text "jupyter notebook stop 8888" #念の為既に8888でjupyterが起動していたら一旦終了する。
			write text "jupyter notebook"
			--2nd pane
			tell application "System Events"
				keystroke "d" using {command down, shift down}
			end tell
			delay 1
			write text "ssh outing"
			write text "watch -n2 sensors"
			--3rd pane
			tell application "System Events"
				keystroke "d" using {command down}
			end tell
			delay 1
			write text "ssh outing"
			write text "watch -n2 vmstat"
			--4th pane
			tell application "System Events"
				keystroke "]" using {command down}
				keystroke "d" using {command down}
			end tell
			delay 1
			write text "ssh outing"
			write text "watch -n2 nvidia-smi"
			tell application "System Events"
				keystroke "[" using {command down}
			end tell
		end tell
	end tell
end tell

```

#Jupyter notebookをリモートで使用する
これはWebサイトによって記載が結構異なった。やたらにjupyter_notebook_config.pyをいじってセキュリティを犠牲にしていそうだったので、それが必要ない最も簡単だった方法を記載する。
結論：ポートフォワーディングを指定してsshで接続する。これだけ。
具体的にはMacbookの~/.ssh/configの「これ」と書いた2行を追記するだけ。あとはサーバ上でjupyter notebookを打ち込んでjupyterサーバを起動し、ローカルのMacbookのブラウザ上からhttp://localhost:8888 にアクセスするとサーバのjupyter notebookを動かせる。Ubuntuサーバでのjupyter notebookのportを変更すれば8888以外でも行けるはず。

```~/.ssh/config
Host jn_outing
HostName [DDNSサービスのホスト名]
Port [ルータで開放した外部ポート]
User [ユーザ名]
GatewayPorts yes #これ
LocalForward 8888 localhost:8888 #これ
IdentityFile ~/.ssh/id_rsa
```


#VS Codeをリモートで使用する
これは神がかってる機能が来たもんだ。ポートフォワーディングの設定欄もあるので、jupyter notebookを簡単にリモートすることも可能と思う。→できた。つまり、VS CodeのRemote Developmentを導入しておけば、jupyter notebookも簡単にリモート接続できる。
1．MacbookにVS Codeを導入する。
2．VS Code Remote Developmentを導入する。
ここからインストール[VS CODE Remote Development] (https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack)
3.MacbookでVS CODEを起動して、~/.ssh/configに設定したssh接続設定から選択すると、あら不思議Macbook上のVS CODEがエディタとして機能して、デバッグから実行までサーバのUbuntu環境で実施できる。
4．Jupyter notebookをリモート接続したければ、VS Codeの「Forwarded ports」に8888を指定し、あとはローカルのMacbookでlocalhost:8888にアクセスすればOK。

#Wake On Lanを設定する
brew install wakeonlan


- 自宅の場合：
wakeonlan -i 192.168.0.255 -p 9 [UbuntuサーバのMacアドレス]
- 外出中の場合：
wakeonlan -i [DDNSのホスト名] -p [Wake On Lanのために開放したルータのポート] [UbuntuサーバのMacアドレス]