MultipassのVMインスタンスにSSH接続し、VSCodeでファイルを編集する

# 目次

**SSH接続の準備**
1. SSHの公開鍵と秘密鍵を生成する
1. VMインスタンスのauthorized_keysに公開鍵を追記する
1. VMインスタンスのIPアドレスを調べる
1. sshコマンドで接続する

**VSCodeでmultipass内のファイルを編集**
1. VSCodeにRemote-SSHを入れる
1. ~/.ssh/confingに設定を書く
1. サイドバーのリモートエクスプローラーから接続する


# はじめに

:::note warn

この記事内に出てくる`#`から始まる文字は、全てコメントです。
正確にいうと、**コメントのつもりで書いた文**です。

実際にはコメントにならなくてもコメントなので、
そのつもりで読んでください。

:::

はじめまして、nanasi-1と申します。

この記事は、

* MultipassのVMインスタンスにSSHで接続し、
* VSCodeからそのVMインスタンスのファイルを編集する

という内容になってます。

私自身があまりこういうことに詳しくないのと、Qiita記事を書き慣れていないため、
だいぶ拙い文章になっていると思いますが、最後まで目を通していただけたら幸いです。


## 環境、前提条件

**環境**
* OS ... MacOS Sonoma 14.1
* Multipass ... 
    * multipass   1.11.1+mac
    * multipassd  1.11.1+mac
* Visual Studio Code ... 1.83.1
* ターミナル ... iTerm2 3.4.21
* SSH ... OpenSSH_9.4p1, LibreSSL 3.3.6


**前提条件**

* multipassのセットアップが完了している
* VSCodeの拡張機能を入れることができる(後半のみ)


## 参考文献

* [Multipassの仮想マシンにssh接続する](https://virment.com/how-to-ssh-to-multipass-vm/) - note
* [Multipassで作成した仮想マシンにsshで接続する](https://note.com/inagy/n/ndee177461a6e) - virtualiment


# VMインスタンスにSSH接続する

ここでは、`ssh`コマンドによって、multipassのVMインスタンスのコンソールに入れるようにします。
SSH接続がすでにできる場合は、[VSCodeでファイルを編集する](#-VSCodeでファイルを編集する)まで読み飛ばしてください。

## 0. VMインスタンスを立ち上げる

なんでもいいので作ってください(雑)
とりあえず`multipass launch 22.04 --name 好きな名前`でやれば間違いないです。

...と言おうと思ってたのですが、思った以上Qiita内にMultipassの記事がなかったため、起動するコマンドを書いておきます。


### 0-1 名前を決める

好きな名前で構いませんが、多分半角英数字と-と_のみを使った方がいいです。
ここで決めた名前がVMインスタンスの名前になります。

私は今回、なぜか`crontab`という名前にしました。
もともとcrontabの実験用だったからな...


### 0-2 起動する

以下のコマンドを入力してください。
```shell:これからVMインスタンスになるホストOS
multipass launch 22.04 --name さっき決めた名前
multipass shell さっき決めた名前
```
これでVMインスタンスの中に入れたと思います。

VMインスタンスから抜ける時は`exit`コマンドが使えます。

起動しているVMインスタンスにホストOSから入るには、上に書いたコマンドのうち2行目のほうを入力してください。

### 0-3 ２つのターミナルを用意(任意)

* VMインスタンスに入っているコンソール
* ホストOSに入っているコンソール

の二つを用意してください。
同時に2つが見れる状態ならなんでもいいです。

こうすると作業効率が上がります。たぶん。


## 1. 公開鍵と秘密鍵を生成する

ホスト側に以下のコマンドを入力します。
```shell:ホストOS
ssh-keygen
```

すると、
```shell:ホストOS
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/ユーザー名/.ssh/id_rsa): 
```
のように表示されるため、好きな場所を入力してください。

この時、`/Users/ユーザー名/.ssh/ここに好きな名前`という感じで入力すると、
~/.sshの中にファイルが入ります。
ちなみに私はなぜか`namae`にしました。

そしたら、
```shell:ホストOS
Enter passphrase (empty for no passphrase): 
```
のように聞かれるため、パスフレーズを決めてください。
あとこのパスフレーズは覚えておいてください。

めんどくさければパスフレーズなしでもいいと思います(雑)
なしの場合は何も入力せずにEnterを押してください。
ちなみに私は今回なしでやってます。~~まあたぶん平気でしょ個人用だし~~

入力したら
```console:ホストOS
Enter same passphrase again: 
```
と言われるので、もう一度パスフレーズを入力してください。

そしたらなんかずらーっと表示されます。
```console:ホストOS
Your identification has been saved in namae
Your public key has been saved in namae.pub
The key fingerprint is:
SHA256:ここ鍵かな？ ユーザー名(たぶん)@なんかの名前.local
The key's randomart image is:
+---[RSA 3072]----+
|     oB%+*o      |
|      +o* .      |
|       o+=o      |
|      o BBo. .   |
|       BS.o.o o  |
|      + E. = + . |
|       .  + * =  |
|         . o * +o|
|          .   o +|
+----[SHA256]-----+
```
~~↑これって載っけて大丈夫なんかな？~~

一応しっかり鍵ファイルが生成されているかどうか確認します。
```shell:ホストOS
ls ~/.ssh
```
.ssh以外の場所に保存した方は、上の`~/.ssh`の部分は保存した場所に読み替えてください。
また、今後出てくる`~/.ssh/鍵ファイル`みたいなところも読み替えてください。
ただし`~/.ssh/config`は別です。

このコマンドを実行すると、
```shell:ホストOS
config                  namae
known_hosts             namae.pub
known_hosts.old　　#<=これ何？　
```
みたいに表示されると思います。

名前を指定しなかった方はファイル名がが`id_rsa`みたいになっていると思います。
生成した鍵ファイルがあれば成功です。


## 2. VMインスタンスに公開鍵を追記する

まずは、先ほど作った鍵のうち、公開鍵の中身をコピーします。
```sh:ホストOS
cat ~/.ssh/namae.pub
```
ここの`~/.ssh/namae.pub`は自分が作った公開鍵ファイルに置き換えてください。
また、**最後に`.pub`と入っているファイルを使う**ので、そこだけ気をつけてください。

これを入力すると、`ssh-rsa`みたいな文字から始まる文字列が出力されます。
この文字列を**全てコピー**してください。

これができたら、VMインスタンス側のターミナルに以下を入力します。
```shell:VMインスタンス
echo "ここにコピーした公開鍵" >> ~/.ssh/authorized_keys
```

注意点として、

* 公開鍵の前後は`""`で囲む
* 公開鍵は`>>`で追記する

ことがあげられます。

ちなみに、追記できればなんでもいいので、Vim等を使って編集しても大丈夫です。

一応追記できたかどうか確認します。
```shell:VMインスタンス
cat ~/.ssh/authorized_keys
```
下の方に、`自分のユーザー名@コンピューター名.local`という文字があれば成功です。
これがない場合は、正しく公開鍵をコピーできていないか、追記する際のコマンドが間違っていると思われます。


## 3. VMインスタンスのIPアドレスを調べる

ホスト側に以下のコマンドを入力してください。
```shell:ホストOS
multipass info crontab
```
crontabは自分が作ったVMインスタンスの名前に置き換えてください。

すると、下のように表示されると思います。
```console:ホストOS
Name:           crontab
State:          Running
IPv4:           192.168.68.3
Release:        Ubuntu 22.04.3 LTS
Image hash:     eafa7742ce5f (Ubuntu 22.04 LTS)
CPU(s):         1
Load:           0.02 0.01 0.00
Disk usage:     1.4GiB out of 4.7GiB
Memory usage:   143.1MiB out of 962.3MiB
Mounts:         --
```
この中の、IPv4の項目をメモしておいてください。


## 4. SSH接続する

そしたら、いよいよSSHで接続してみます。
ホストに以下のコマンドを入力してください。

```shell:ホストOS
#ssh メモしたIPアドレス -i 秘密鍵のありか -l ubuntu(ログインするユーザー)
ssh 192.168.68.3 -i ~/.ssh/namae -l ubuntu
```

注意点として、

* `-l ubuntu` を入れないと`Permission denied (publickey)`と出て失敗する
* `-i ~/.ssh/namae`では、最後に`.pub`とついていない**秘密鍵ファイルを使う**
* ちなみに`-p 22`を入れても大丈夫

があげられます。

そしたら下のように聞かれます。
```console:ホストOS
The authenticity of host '192.168.68.3 (192.168.68.3)' can't be established.
ED25519 key fingerprint is SHA256:KNKo+x1TUQcBi/he8krkq5G1ABqJ+YUE30NWQqWogtY.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])?
```
このように表示されたら、yesと入力してEnterを押してください。

接続が成功したら、以下のように出力されると思います。
```console:さっきまでホストOSだったやつ
Welcome to Ubuntu 22.04.3 LTS (GNU/Linux 5.15.0-87-generic aarch64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Wed Nov  1 10:41:23 JST 2023

  System load:             0.0
  Usage of /:              30.0% of 4.68GB
  Memory usage:            17%
  Swap usage:              0%
  Processes:               87
  Users logged in:         1
  IPv4 address for enp0s1: 192.168.68.3
  IPv6 address for enp0s1: fdee:4789:2219:b110:5054:ff:feb7:d25d


Expanded Security Maintenance for Applications is not enabled.

0 updates can be applied immediately.

Enable ESM Apps to receive additional future security updates.
See https://ubuntu.com/esm or run: sudo pro status


Last login: Wed Nov  1 10:41:31 2023 from 192.168.68.1
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

ubuntu@crontab:~$ # ここが緑になってる
```

これが出たら成功です。お疲れ様でした。
`exit`でVMインスタンスから抜けてください。

この後はVSCodeでVMインスタンスのファイルを編集する方法になってます。
そのため、VSCodeを使っていない方や、別にそんなこと興味ないって人はここまでで大丈夫です。


# VSCodeでファイルを編集する

:::note warn
VMインスタンスにSSH接続ができることが前提条件になってます。
:::


## 1. Remote-SSHを入れる

このRemote-SSHは、VSCodeからSSH接続ができるみたいな拡張機能です。(多分)
以下のリンクから入れてください(雑)

https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh

確かセッティングとかいらなかったと思います。


## 2. configに設定を書く

VSCodeで`~/.ssh/config`を開きます。

Finderやエクスプローラーから開いてもいいですが、
サイドバーからリモートエクスプローラーを選択して、SSHをホバーしたら出てくる
:gear:設定アイコンをクリックして一番上の選択肢を押すと、configファイルが開けます。

![ssh-setting.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588083/33073155-a9c4-4dfb-2974-815c2416b3c5.png)

開けたら、以下の設定を追記します。

```ssh:~/.ssh/config
Host crontab # 好きな名前、これを接続に使う
  HostName 192.168.68.3 # 先ほど控えた、VMインスタンスのIPアドレス
  Port 22
  IdentityFile ~/.ssh/namae # 秘密鍵ファイルのありか
  User ubuntu # ログインするユーザー、わからなかったらubuntuでok
```

追記が完了したら、一応上の設定を使ってSSH接続してみます。
ホストに以下のコマンドを入力してください。

```shell:ホストOS
ssh さっき設定した名前 # この記事の場合はcrontab
```

先ほどのように接続できたら確認はokです。
`exit`でVMインスタンスから抜けてください。

## 3. サイドバーから接続する

ここまで来たらあと一歩です。
サイドバーからリモートエクスプローラーを開き、
SSHの中にある、先ほど設定した名前の右の:arrow_right:をクリックしてください。

![arrow_right.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588083/bdd3459a-ab33-3499-2453-a6d23c50fb94.png)

そしたら接続が始まります。
この時、鍵を生成する時に入力したパスフレーズを聞かれる(何も入力しなかった場合は聞かれない)ので、入力してください。

少し待ったら接続が完了すると思います。
左下が**SSH:さっきの名前**のような表示になったら、接続は成功です。

接続できたら、サイドバーのエクスプローラーから「フォルダを開く」をクリックしてください。
そして、編集したいフォルダのパス(`home/ubuntu`が多いかな？)を入力します。

エクスプローラーになんかいろんなフォルダとファイルが表示されたら成功です。

これでもうVSCodeからファイルを編集できます。
お疲れ様でした。

## 再接続したいとき

一度`multipass stop`で止めたVMインスタンスは、再度`multipass start`で起動したらIPアドレスが変わってしまいます。(時間経過したらかも)

この状態で接続しようとすると、タイムアウトというエラーが出ます。

この状態から再接続したければ、`~/.ssh/config`に書いたIPアドレスを変更してください。
`multipass info VMインスタンス名`を使ってIPアドレスを調べられます。

```ssh:~/.ssh/config
Host crontab
  HostName 192.168.70.2 # ここを変える(変えた)
  Port 22
  IdentityFile ~/.ssh/namae
  User ubuntu
```

これだけで再度接続できるようになります。意外と簡単。


# 終わりに

ここまで読んでいただきありがとうございます。
記事書くのって結構大変ですね...

実は記事書きながら手元のVMインスタンスのSSH接続設定やってました。
SSHむずい...

これから先、この記事の内容が少しでも役に立てば幸いです。