VSCode (Curosr) の Remote-SSH の実行ユーザーの切り替えと、切り替わらないときの対処法

VSCode (Cursor) には  Remote-SSH というプラグインがある。
これを使うことで VSCode のディレクトリ表示上で、リモートマシンを操作できる。
GUI で操作できたり、ファイル探索や全文検索、ファイルをまたいでの置換なども VSCode を通してできるためとても便利。

:::note warn
パフォーマンスに影響を与える可能性があるため、特に本番環境などの大事な環境では、やろうとしていることの計算量に十分注意すること。

また、非常に小さいインスタンスでなければパフォーマンスに影響を与えることはほとんどないが、ホストに VSCode のためのサーバープロセスも立ち上がる。
:::


# VSCode (Cursor) は起動後に実行ユーザーを切り替えられない
VSCode で Remote-SSH したあとは、なぜかユーザーは切り替えられない。
切り替えるときは、RemoteCommand でユーザーの切替を設定し、再度接続し直さなくてはいけない。

なぜこんな仕様なのか。ターミナルと同じく切り替えられるようにして欲しい。（切り替える方法あれば教えて下さい。）

一方、VSCode 上のターミナル部分は、VSCode そのものとは独立しているので、**ターミナルのユーザーだけ**を切り替えることはできる。

:::note alert
**勘違いしやすいポイント
VSCode 上のターミナルでユーザーを変えても、VSCode そのものが使っているユーザーは変わらない🙀**
VSCode 上のターミナルでユーザーを切り替えて、VSCode そのものが使っているユーザーも切り替わったと勘違いして VSCode でファイル操作してしまうと、実際にはログイン時のユーザーが使われていることになる。意図しないユーザーでファイルを操作すると、アプリケーションが正常に動作しなくなる可能性もあるため、十分注意すること。
:::


# RemoteCommand が効かない

VSCode で SSH するとき `~/.ssh/config` の `RemoteCommand` 属性が効かなくなり、ログイン時のユーザー切り替えができなくなることがある。

具体的には SSH の設定ファイルで `RemoteCommand sudo su some_user` と指定しても、VSCode が使うユーザーをスイッチできなくなる。


## ✅ 解決策

VSCode の設定を以下のようにする。
```js:setting.json
{
    "remote.SSH.useLocalServer": true,
    "remote.SSH.enableRemoteCommand": true,

    // ここに、サーバー名を連ねているとこの設定が優先されてしまい RemoteCommand が効かなくなるのでコメントアウトしておく。
    // 使っていなければ以下まるごと消しても OK
    "remote.SSH.remotePlatform": {
        // "xxxxx-prod-ubuntu": "linux",
        // "yyyyy": "linux",
        "zzzzz": "linux"
    }
}
```

以下のような SSH 設定で選択的に VSCode を実行できるようになる。

```config:~/.ssh/config
Host xxxxx-prod*
    HostName <DOMAIN or IP>
    User cray
    Port 22 # デフォルト 22 なので省略可能
    IdentityFile <PATH>
    RequestTTY yes

# アプリケーションのユーザー（例：ubuntu）で作業をするとき
Host xxxxx-prod-ubuntu
    RemoteCommand sudo su ubuntu

# 個人のユーザー（例：cray）で作業をするとき
Host xxxxx-prod-cray

# root で作業をするとき
Host xxxxx-prod-root
    RemoteCommand sudo su -
```

# 🚫よくある沼パターン


### remote.SSH の設定がないか、属性名が間違っていて効いてない

```js:setting.json
"remote.ssh.useLocalServer": true, // ❗これは誤り
"remote.ssh.enableRemoteCommand": true, // ❗これは誤り
```

正しくは以下である
```js:setting.json
    "remote.SSH.useLocalServer": true,
    "remote.SSH.enableRemoteCommand": true,
```

:::note alert
「SSH」の部分が小文字になっている記事が散見される。これは完全に誤りで、効かない。ただ効かないだけならいいのだが、さらなる問題に発展する。
:::

具体的には、設定がない（間違っている）と接続時に RemotePlatform を登録を促されるプロンプトがでて、それを許可してしまうと `remote.SSH.remotePlatform` が追加される。
そして後述のパターンになりハマる。

### remote.SSH.remotePlatform ディレクティブに設定がある
この設定があると `RemoteCommand=none` になり無視されてしまう

```js:setting.json
{
    "remote.SSH.remotePlatform": {
        "xxxxx-prod-ubuntu": "linux", // ❗これがあるとリモートコマンドが効かなくなる
    }
}
```
### パスワードなしで sudo を実行できるようにする

パスワードが設定されていると、RemoteCommand でパスワードを渡すことは難しい。

sudo コマンドがパスワードを要求しないように設定します。

:::note warn
セキュリティリスクがあるので、グローバルから接続できるようなインスタンスでやみくもに設定しないように。
:::

:::note
IP 許可や AWS SSM （推奨）など別の仕組みで接続を限定しているような場合では適切な設定。
:::

```
sudo visudo
```

以下の行を追加する
```
my_user ALL=(ALL) NOPASSWD:ALL
```

### RequestTTY の設定がない または yes 以外になっている
VSCode そのものの接続確立には影響しないためなくても良いが、ターミナルで ssh するときプロンプトが返ってこなくなる。

```
    RequestTTY yes
```

`true` になっている記事も多いがこれは正式ではなく正しくは `yes`。一応 `true` だが効力を発揮する。

また RequestTTY を `true` にしないとプロンプトの応答が返ってこなくなるだけでだけで、 `sudo` できないわけではない。これも誤解している記事が多い。

https://man.openbsd.org/ssh_config.5#RequestTTY

https://www.computerhope.com/jargon/r/requesttty.htm



# Sources

https://github.com/microsoft/vscode-remote-release/issues/6598

https://github.com/microsoft/vscode-remote-release/issues/6108

https://github.com/microsoft/vscode-remote-release/issues/4388

https://github.com/microsoft/vscode-remote-release/issues/158