VS Code の Remote - SSH 拡張機能:Linux 使い(略)Advent Calendar 2024
はじめに
これは「Linux 使いになりたい人のための Advent Calendar 2024」の記事です。
筆者は、Web エンジニアを志望する人には、セルフホスト Git サービスを稼働させて利用することをオススメしています。もし Git を使ったことがないなら、Git を学ぶときに、セルフホスト Git サービスを稼働させることも視野に含めながら学習するのが効率的だと考えています。
VS Code の Remote - SSH 拡張機能
前回はセルフホスト Git サービスを使うにあたり、OpenSSH を使うことが多いといった説明の流れから、ssh
コマンドの実行を試せる環境を Docker コンテナーを使って用意する方法について紹介しました。
今回は、VS Code Remote - SSH 拡張機能について紹介します。これを使うと、OpenSSH サーバーが動作するリモートマシンに VS Code をリモート接続して開発のための作業をすることができて便利です。
Remote - SSH 拡張機能のインストール
VS Code で Remote - SSH 拡張機能をインストールするには、Quick Open (Ctrl+P) で表示される入力欄へ次のコマンドを貼り付けてから Enter
を入力します。
ext install ms-vscode-remote.remote-ssh
この拡張機能は Remote Development 拡張機能に含まれているので、そちらをインストールしても良いです。その場合は、Quick Open (Ctrl+P) で表示される入力欄へ次のコマンドを貼り付けてから Enter
を入力します。
ext install ms-vscode-remote.vscode-remote-extensionpack
サポートされている環境は次のようになります。
- x86_64 Debian 8+, Ubuntu 16.04+, CentOS / RHEL 7+ Linux.
- ARMv7l (AArch32) Raspbian Stretch/9+ (32-bit).
- ARMv8l (AArch64) Ubuntu 18.04+ (64-bit).
- Windows 10 / Server 2016/2019 (1803+) using the official OpenSSH Server.
- macOS 10.14+ (Mojave) SSH hosts with Remote Login enabled.
なお、Linux については glibc ベースのディストリビューションであれば含まれます。musl libc ベースのものはサポートされていないので注意が必要です。
Remote - SSH 拡張機能の使い方
次の手順で Remote - SSH 拡張機能を使うことができます。
- F1 で表示される入力欄で「Remote-SSH: Open SSH Host」
- 使用するユーザー名とホスト名(または IP アドレス)を
ユーザー名@ホスト名
またはユーザー名@ドメイン名
のフォーマットで入力 - パスフレーズまたはパスワード入力のプロンプトが表示されたら、それを入力
- SSH ログインが成功したら、「File」-「Open Folder」でリモートマシンのフォルダーを開きます。
F1 キーで表示されるコマンドパレットで「Remote-SSH」と入力すると、使用可能なコマンドの一覧が表示されます。
なお、ここで、~/.ssh/config
に Host
のエントリーを登録しておくと、Remote - SSH 拡張機能でそのホストを指定して SSH ログインができるようになります。複雑なオプション指定が必要な SSH ログインについては、この機能を活用しましょう。
拡張機能の管理
リモートマシンでの拡張機能の管理については、注意が必要です。ローカルとリモートで使える拡張機能は異なります。拡張機能は2つのカテゴリーに分類できます。
- UI 用拡張機能。これはローカルホストにインストールされます。
- Workspace 用拡張機能。これはリモートにインストールされます。
リモートにインストールされた拡張機能は、リモートの OS や CPU アーキテクチャで動作するものである必要があります。
Docker を使って試用
Docker を使って Remote - SSH 拡張機能の動作を確認することができます。ただし、前回使ってみた linuxserver/openssh-server
のイメージは Alpine ベースで、これは Remote - SSH 拡張機能が対応していません。ということで、きちんと試すのは結構大変だったりします。
とはいえ、「これぐらいのことはできないとね」というものなのでやってみました。後で説明する openssh-vscode:ubuntu2204
イメージをビルドした後に、OpenSSH サーバーを起動します。
docker compose -f /openssh-vscode/compose.yaml up -d
それから、VS Code の Remote - SSH 拡張機能で openssh-vscode の openssh-server
へ SSH ログインして試用ができます。
作成した環境について簡単に紹介します。詳しい説明はしませんが、簡単なコードしか用意していないので、これを見れば何をしているかは大体わかるはずです。
openssh-vscode ディレクトリー構造
openssh-vscode/
├── README.md ... このファイルと同じ内容
├── build-image/ ... ビルド用
│ ├── Dockerfile
│ ├── compose.yaml
│ ├── entrypoint.sh
│ ├── etc/
│ │ └── apt/
│ │ └── sources.list
│ └── script/
│ ├── add-user.sh
│ ├── install-basic-command.sh
│ ├── install-ext-command.sh
│ └── update-sshd-config.sh
├── compose.yaml ... コンテナー起動用
└── sample/
├── dot.ssh/
│ ├── authorized_keys
│ ├── id_ed25519
│ ├── id_ed25519.pub
│ ├── id_ed25519_pass
│ ├── id_ed25519_pass.pub
│ └── known_hosts
├── ssh_host_keys/
│ ├── ssh_host_ecdsa_key
│ ├── ssh_host_ecdsa_key.pub
│ ├── ssh_host_ed25519_key
│ ├── ssh_host_ed25519_key.pub
│ ├── ssh_host_rsa_key
│ └── ssh_host_rsa_key.pub
└── ssh/
└── config ... この内容を `~/.ssh/config` へ追加します。
openssh-server のエントリー作成
最初に用意する OpenSSH サーバーへの接続用エントリを ~/.ssh/config
へ用意します。これで複雑な OpenSSH サーバーへの接続がホスト名を指定するだけで済むようになります。ここでは先に紹介した openssh-vscode
ディレクトリーは /openssh-vscode
に用意してあるとします。
Host openssh-server
HostName localhost
Port 2222
User vscode
IdentityFile /openssh-vscode/sample/dot.ssh/id_ed25519_pass
このファイルは次のようにして所有者のみが読み書きできるモードにします。
chmod 600 ~/.ssh/config
動作確認用 compose.yaml
動作確認用の openssh-vscode/compose.yaml
は次のとおり。イメージは ubuntu:22.04
ベースのものにしてあります。バインドマウントが多いのですが、ubuntu:22.04
だとホスト用のキーを個別に指定することになって、こうなってしまいました。
name: openssh-vscode
services:
openssh-client:
image: openssh-vscode:ubuntu2204
container_name: openssh-client
hostname: openssh-client
tty: true
user: 1000:1000
entrypoint: /usr/bin/bash
working_dir: /home/vscode
volumes:
- type: bind
source: ./sample/dot.ssh/id_ed25519
target: /home/vscode/.ssh/id_ed25519
read_only: true
- type: bind
source: ./sample/dot.ssh/id_ed25519_pass
target: /home/vscode/.ssh/id_ed25519_pass
read_only: true
- type: bind
source: ./sample/dot.ssh/known_hosts
target: /home/vscode/.ssh/known_hosts
openssh-server:
image: openssh-vscode:ubuntu2204
container_name: openssh-server
hostname: openssh-server
tty: true
ports:
- 127.0.0.1:2222:22
volumes:
- type: bind
source: ./sample/ssh_host_keys/ssh_host_ecdsa_key
target: /etc/ssh/ssh_host_ecdsa_key
read_only: true
- type: bind
source: ./sample/ssh_host_keys/ssh_host_ecdsa_key.pub
target: /etc/ssh/ssh_host_ecdsa_key.pub
read_only: true
- type: bind
source: ./sample/ssh_host_keys/ssh_host_ed25519_key
target: /etc/ssh/ssh_host_ed25519_key
read_only: true
- type: bind
source: ./sample/ssh_host_keys/ssh_host_ed25519_key.pub
target: /etc/ssh/ssh_host_ed25519_key.pub
read_only: true
- type: bind
source: ./sample/ssh_host_keys/ssh_host_rsa_key
target: /etc/ssh/ssh_host_rsa_key
read_only: true
- type: bind
source: ./sample/ssh_host_keys/ssh_host_rsa_key.pub
target: /etc/ssh/ssh_host_rsa_key.pub
read_only: true
- type: bind
source: ./sample/dot.ssh/authorized_keys
target: /home/vscode/.ssh/authorized_keys
read_only: true
openssh-server の方が VS Code をアタッチするコンテナー用です。openssh-client は、ssh コマンドの動作確認用コンテナーのために用意してあるものです。こちらは使わなくても良いです。openssh-server へアクセスできないときに確認用にしてください。こちらからアクセスできる場合はネットワークの問題になります。
鍵については、前回使ったものを流用しています。ただ、前回と違って、authorized_keys
は次のものを用意しました。
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGiL8rnDO1D/SW5p3WnZ+0ctlek2PU1rUoJ9sGXMBF9j user001@openssh-server
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPu5/vlBHnJsuDr2zxDncVPGZ5jjbUUhKeyKOQhkFo0e user001@openssh-server pass
また、known_hosts
も用意しました。
|1|FTkkYo05xCaf1xYoZgSg6zXn3vM=|8MMbIvS6m/iLur1f6DeAubGVuM8= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII4uYsbRjF9zA/NOTA3I4YAd0BpHTBNhXbf6EMmdAkzH
|1|M2uIQypapeZIl8FVZGX3S0LbDF4=|KE+K1hFWo5qZG6UIldS5ylV6boo= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCtW9eyKj9et068MnZIpvUtDZ+34l5bD55Jqahw80EzmNxF45Q+jWM2WoVMDk1aY+cokfDHghNPZ0iaoMzoNftDhz1guJMr53wX1z153z2IohLtnviibgT0dfsTRaUqZ8wg6JbFkcFuNUcNeKbS9sFdC11RY1g5I+0VJOQuISy2NfiaJqRKjJ3IrmmjHUM+4sInt8jt1E9L13y+291fzQNp7MqmkRwA/zD6xHbxk71fYYBr130CVxkoT+h+VEm2J/tL+7ZVQalR6JqAoXZNpVTjF+oaB+QWYxDmPdAwS3KwPae0JUGKXF+/JNyv97TNE4ipUUJOj/iqkUMLpBPlp3dUYf4vfZhHBOzQhU1h+l91r5mjF+eBVdfzgX4TwPhya1dBtHFV+rDhj6qVOK3vEjiVguZXRlJiTNgzuFsxrgXSj0gOmhr79scyCWOMvIgyhHZM5+iFw+yq7F3R/KhBJWx2zxV4gKZY5tGD6gYd7yh74/5Avr2wMnZqkTZhG7ahsJs=
|1|T6Zadz458qmDgfvkPN1Cf16Ak+Y=|3NAwSJNu5eilVBXX7omcrKH6zTU= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHdwMzS0govO4ZCDtMqXhOiuE5uP/GwY2LOejE+6gK+gscgjxcj9U7Iop4XFxoWN2xBEv4f/y77hAZYH5Yf/5b8=
openssh-vscode:ubuntu2204 イメージ作成
openssh-vscode:ubuntu2204
のイメージ作成には、次のファイル openssh-vscode/build-image/compose.yaml
を用意しました。
作成したイメージ名やオプションについて後でわかるようにビルド用に compose.yaml
ファイルを用意する派です。
name: openssh-vscode-build
services:
openssh-vscode-build:
build:
context: .
dockerfile: Dockerfile
image: openssh-vscode:ubuntu2204
container_name: openssh-vscode-build
hostname: openssh-vscode-build
Dockerfile
は次のとおり。インストール関連はスクリプトにしておいて、それを利用する派です。流用がしやすくなります。
FROM ubuntu:22.04
ARG ARGS_TARGET=openssh-vscode
COPY script /usr/local/script
COPY etc/apt/sources.list /etc/apt/sources.list
COPY entrypoint.sh /
# root ユーザーで実行する処理
RUN apt-get update \
&& sh /usr/local/script/install-basic-command.sh \
&& sh /usr/local/script/install-ext-command.sh \
&& apt-get -y autoremove \
&& apt-get -y clean \
&& rm -rf /var/cache/apt /var/lib/apt/lists
# vscode ユーザーを用意し、vscode ユーザーが実行する処理
# vscode だけ sudo 権限ありのユーザーとして用意。ほかは sudo 権限はなし。
RUN SUDO=TRUE USERNAME=vscode bash /usr/local/script/add-user.sh \
&& sudo -u vscode sh -c "mkdir /home/vscode/.ssh" \
&& sudo -u vscode sh -c "chmod 700 /home/vscode/.ssh" \
&& USER=vscode sh /usr/local/script/update-sshd-config.sh \
&& echo "${ARGS_TARGET}: installed"
ENTRYPOINT ["/entrypoint.sh"]
EXPOSE 22
apt は国内のミラーを使うよう、sources.list
を置き換えています。
deb http://ftp.udx.icscoe.jp/Linux/ubuntu/ jammy main restricted
deb http://ftp.udx.icscoe.jp/Linux/ubuntu/ jammy-updates main restricted
deb http://ftp.udx.icscoe.jp/Linux/ubuntu/ jammy universe
deb http://ftp.udx.icscoe.jp/Linux/ubuntu/ jammy-updates universe
deb http://ftp.udx.icscoe.jp/Linux/ubuntu/ jammy multiverse
deb http://ftp.udx.icscoe.jp/Linux/ubuntu/ jammy-updates multiverse
deb http://ftp.udx.icscoe.jp/Linux/ubuntu/ jammy-backports main restricted universe multiverse
deb http://security.ubuntu.com/ubuntu/ jammy-security main restricted
deb http://security.ubuntu.com/ubuntu/ jammy-security universe
deb http://security.ubuntu.com/ubuntu/ jammy-security multiverse
install-basic-command.sh
は次のとおり。
#!/bin/sh
DEBIAN_FRONTEND=noninteractive \
apt-get install -y curl git gpg openssh-server sudo unzip wget zip
install-ext-command.sh
は次のとおり。
#!/bin/sh
DEBIAN_FRONTEND=noninteractive \
apt-get -y install byobu sysstat autossh openssh-client
add-user.sh
は次のとおり。
#!/usr/bin/env bash
if [ "${USERNAME}" = "" ]; then
USERNAME="vscode"
fi
group_name="${USERNAME}"
groupadd "${USERNAME}"
useradd -s /bin/bash --gid "${USERNAME}" -m "${USERNAME}"
if [ "${SUDO}" = "TRUE" ]; then
echo "${USERNAME}" ALL=\(root\) NOPASSWD:ALL > "/etc/sudoers.d/${USERNAME}"
chmod 0440 "/etc/sudoers.d/${USERNAME}"
fi
# Shell customization
user_home="/home/${USERNAME}"
if [ ! -d "${user_home}" ]; then
mkdir -p "${user_home}"
chown "${USERNAME}:${group_name}" "${user_home}"
fi
## Restore user .bashrc / .profile
possible_rc_files=( ".bashrc" ".profile" )
for rc_file in "${possible_rc_files[@]}"; do
if [ -f "/etc/skel/${rc_file}" ]; then
if [ ! -e "${user_home}/${rc_file}" ] || [ ! -s "${user_home}/${rc_file}" ]; then
cp "/etc/skel/${rc_file}" "${user_home}/${rc_file}"
chown "${USERNAME}:${group_name}" "${user_home}/${rc_file}"
fi
fi
done
update-sshd-config.sh
は次のとおり。
#!/bin/sh
apt-get -y install openssh-server
if [ ! -e /root/ws ]; then
mkdir /root/ws/;
fi
cp /etc/ssh/sshd_config /root/ws/sshd_config
cat << EOS | tee -a /etc/ssh/sshd_config
PermitRootLogin no
PasswordAuthentication no
X11Forwarding no
ClientAliveInterval 30
ClientAliveCountMax 3
AllowUsers ${USER}
EOS
sed -i "s/^X11Forwarding yes/#X11Forwarding yes/" /etc/ssh/sshd_config
CMD="diff /etc/ssh/sshd_config /root/ws/sshd_config"
if ${CMD} > /dev/null; then
# 差分がないと失敗
exit 1
else
# 差分があると成功
exit 0
fi
entrypoint.sh
は次のとおり。
#!/bin/sh
if [ ! -e /run/sshd ]; then
mkdir /run/sshd
fi
if [ ! -e /etc/ssh/ssh_host_ed25519_key ]; then
/usr/bin/ssh-keygen -A
fi
exec /usr/sbin/sshd -D -e "$@"
ファイルを用意したら、ビルドします。これで、openssh-vscode:ubuntu2204
イメージが作成できます。
docker compose -f /openssh-vscoder/build-image/compose.yaml build
Discussion