Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Web ターミナル (SSH / Telnet)

wpg の画面から、試験対象の機器に SSH / Telnet で接続できます。パケットを送りながら対向機器のカウンタやログを確認するときに、Tera Term などの端末ソフトや踏み台サーバを別に用意する必要がありません。接続は wpg サーバから張るので、作業用 PC から機器に直接届かないラボ (CML2、EVE-NG、閉域の実機ラボ) でも使えます。設計の背景は ADR-0011 にあります。

有効にする

Web ターミナルは既定で無効です。wpg.toml に [terminal] セクションを書き、サーバを再起動します。

[terminal]
enabled = true                                 # Web ターミナル (SSH / Telnet)
allowed_targets = ["10.0.0.0/8", "*.lab.example", "console-srv:2001"]
record_sessions = true                         # <data_dir>/terminal-logs にセッションログを残す
idle_timeout_secs = 1800                       # 無操作で切断するまでの秒数 (0 = 切断しない)
max_sessions = 8                               # 全ユーザ合計の同時セッション数
キー既定値内容
enabledfalseWeb ターミナルを有効にする
allowed_targets[]接続を許可する宛先。空の場合はすべて許可
record_sessionstrueセッションログを許可する (false でサーバ側のログを無効化)
idle_timeout_secs1800入出力が途絶えてから切断するまでの秒数。0 で無効
max_sessions8同時に開けるセッション数

環境変数でも指定できます (例: WPG_TERMINAL__ENABLED=true、WPG_TERMINAL__ALLOWED_TARGETS='["10.0.0.0/8"]')。設定は wpg config validate で確認できます。allowed_targets を空のまま、ループバック以外のアドレスで待ち受けると警告が出ます。

allowed_targets の書き方

書き方意味
r1、r1.lab.exampleそのホスト名 (大文字小文字は区別しない)。ポートは問わない
r1:22そのホスト名の 22 番ポートだけ
*.lab.examplelab.example のサブドメインすべて
192.0.2.10、192.0.2.10:2001その IP アドレス (とポート)
[2001:db8::1]:830IPv6 アドレスとポート
10.0.0.0/8、2001:db8::/32アドレス範囲 (CIDR)

ホスト名の規則は利用者が入力した名前と照合します。アドレスと CIDR の規則は、名前解決した結果のアドレスと照合し、許可されたアドレスにだけ接続します。照合したアドレスにそのまま接続するので、DNS を後から書き換えて許可範囲を迂回することはできません。

使い方

サイドバーの ターミナル (ショートカット g c) を開きます。

  1. 接続フォームでプロトコル (SSH / Telnet)、ホスト、ポート (省略時は 22 / 23)、SSH のユーザ名を入力します。
  2. SSH の認証方式を選びます。
    • パスワード: 入力したパスワードで認証します。空欄にすると、サーバのプロンプト (keyboard-interactive やパスワード入力) をダイアログで表示します。ネットワーク機器でよくある keyboard-interactive の「Password:」プロンプトには、入力したパスワードで自動的に応答します。
    • 秘密鍵: OpenSSH 形式、PEM、PuTTY の .ppk を貼り付けるか、ファイルから読み込みます。パスフレーズ付きの鍵にも対応します。
  3. 接続 を押すと新しいタブが開きます。複数のタブを同時に開け、他の画面に移動してもセッションは維持されます。

プロファイルを保存 で、プロトコル、ホスト、ポート、ユーザ名、認証方式、ログ設定をブラウザ (localStorage) に保存できます。パスワード、秘密鍵、パスフレーズは保存しません。

初めて接続する SSH ホスト

初めての SSH ホストでは、ホスト鍵のアルゴリズムと SHA-256 フィンガープリント (SHA256:...) を表示します。正しい値と一致することを確かめてから接続してください。正しい値は、たとえば次の方法で得られます。

  • 対象ホスト上で ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub を実行する。

  • 信頼できる経路の端末で ssh-keyscan -p 22 ホスト | ssh-keygen -lf - を実行する。

  • ネットワーク機器では、機器が表示する公開鍵 (Cisco IOS の show crypto key mypubkey rsa など) を OpenSSH 形式にして ssh-keygen -lf に渡す。機器によっては MD5 や 16 進表記で表示するため、形式をそろえて比較します。

  • 信頼して保存: 鍵をサーバの <data_dir>/terminal/known_hosts (OpenSSH の known_hosts 形式) に保存して接続します。次回からは確認なしで接続します。

  • 今回のみ接続: 保存せずに接続します。作り直すことの多いラボ機器に向きます。

  • キャンセル: 接続しません。

保存済みの鍵と異なる鍵が提示されると、中間者攻撃の可能性があるため接続を拒否し、提示された鍵と保存済みの鍵を表示します。機器の交換や鍵の再生成など心当たりがある場合は、画面下の 既知のホスト から該当ホストの鍵を削除し、再接続して新しい鍵を確認します。ssh-keyscan で取得した行を known_hosts に追記しておくこともできます。

踏み台を経由する (ProxyJump)

接続フォームの 踏み台 (ProxyJump) で 踏み台を追加 を押し、経由する SSH サーバを近い順に入力します (最大 4 台)。OpenSSH の ssh -J ops@bastion,ops@inner admin@r1 と同じ動きで、手で ssh を打たずに 1 回で奥の機器につながります。

ブラウザ ── wpg サーバ ──SSH── 踏み台 1 ──SSH── 踏み台 2 ──SSH / Telnet── 機器
  • wpg サーバは踏み台 1 にだけ直接接続します。踏み台 2 と機器へは、手前の踏み台に開いた direct-tcpip チャネル (OpenSSH の -W / ProxyJump と同じ仕組み) を通ります。踏み台側の sshd で AllowTcpForwarding が有効である必要があります。
  • 各段のホスト鍵は、直接接続と同じように初回に確認ダイアログが出ます。ダイアログとログインプロンプトには、どの段のホストかが表示されます。
  • 各段のログインは、パスワードか秘密鍵を段ごとに指定します。パスワードを空にすると、その段でプロンプトを表示します。秘密鍵とパスワードはプロファイルに保存しません (踏み台のホスト、ポート、ユーザ名は保存します)。
  • 最終的な宛先は SSH でも Telnet でも構いません。踏み台の奥にあるコンソールサーバの Telnet ポートにも、そのまま接続できます。
  • 失敗した場合、どの踏み台で起きたかがエラーに表示されます (例: 「踏み台 10.0.0.1:22 で発生」)。
  • 監査ログとステータス (GET /api/terminal/status) には経由した踏み台 (via) が記録されます。

許可リストとの関係: allowed_targets は、踏み台を含むすべての段に適用されます。1 段目の踏み台は wpg サーバで名前解決して照合します。2 段目以降と最終的な宛先は踏み台側で名前解決されるため、ホスト名ならホスト名のエントリ (r1.lab、*.lab.example)、IP アドレスならアドレスや CIDR のエントリで照合します。名前で指定した宛先は CIDR のエントリでは許可されません。

Telnet

Telnet では、サーバから要求されたときだけオプションを交渉します (ECHO、SGA、NAWS によるウィンドウサイズ通知、端末タイプ XTERM-256COLOR、BINARY)。wpg からは交渉を始めないので、ターミナルサーバの生 TCP ポート (CML2 や EVE-NG のコンソール) にも余計なバイトを送りません。Enter は NVT の規則どおり CR NUL として送ります。

コピーと貼り付け

操作方法
コピー範囲を選択 (既定で自動コピー)、Ctrl+Shift+C、Ctrl+Insert
貼り付け右クリック / 中クリック、Ctrl+Shift+V、Shift+Insert、Ctrl+V
検索ツールバーの検索欄 (Enter で次、Shift+Enter で前)

複数行を貼り付けるときは、行数と内容を表示して確認します (設定で無効にできます)。行ごとの待ち時間 を設定すると、1 行ごとに指定ミリ秒待って送ります。入力バッファが小さい機器のコンソールに設定を流し込むときに使います。ファイル送信 はテキストファイルの内容を同じ確認のあとに送ります。

ブラウザのクリップボード API は HTTPS か localhost でしか使えません。HTTP で別ホストから使う場合、右クリックでの貼り付けはできないので Ctrl+V か Shift+Insert を使ってください (コピーは動作します)。

文字サイズ、スクロールバック行数、自動コピー、右クリック貼り付け、貼り付け確認、行ごとの待ち時間は ターミナル設定 で変更でき、ブラウザに保存されます。

セッションログ

record_sessions = true の場合、接続時に「サーバにセッションログを記録する」を選ぶと (既定でオン)、接続先から受信した内容を <data_dir>/terminal-logs/ に記録します。ファイル名は 20261027-101500_ssh_r1.lab_22_ab12cd34.log の形式 (UTC 時刻、プロトコル、ホスト、ポート、セッション ID) です。

  • 記録するのは接続先からの出力だけで、キー入力は記録しません (エコーされない入力、たとえばパスワードは残りません)。
  • 既定でエスケープシーケンスを取り除いたプレーンテキストで記録します (Tera Term の「プレーンテキスト」相当)。取り除かない場合は cat で色付きのまま再生できます。
  • ツールバーの ログ開始 / ログ停止 で途中から記録したり止めたりできます。再開すると新しいファイルになります。
  • 1 ファイルは 256 MiB で記録を止めます (セッションは続きます)。
  • セッションログ の一覧からダウンロード、削除できます。記録中のログは削除できません。
  • ログは自動では削除されません。保持期間は運用で管理してください (ファイルは所有者のみ読み書きできる権限 0600 で作成します)。

サーバにログを残さない場合でも、バッファを保存 でブラウザ上のスクロールバックをテキストファイルとして保存できます。

セキュリティ

Web ターミナルを有効にすると、wpg サーバは試験ネットワークへの踏み台になります。次の点に注意してください。

  • 接続先を絞る: allowed_targets に試験対象のアドレス範囲だけを書きます。空のままにすると、wpg にログインできる全員が、サーバから届く任意のホスト (管理ネットワークや社内のサーバを含む) に接続できます。
  • HTTPS を使う: パスワードや秘密鍵はブラウザから wpg サーバへ送られます。localhost 以外で使う場合は wpg serve --tls か証明書を設定し、HTTPS で接続してください (認証と TLS)。
  • パスワードは保存しない: wpg はパスワード、秘密鍵、パスフレーズをディスクに保存しません。接続処理の間だけメモリに置きます。ブラウザのタブは再接続のために入力内容をメモリに保持しますが、タブを閉じると消えます。
  • 監査ログ: セッションの開始・終了・拒否を wpg::audit ターゲットで記録します (wpg のユーザ、クライアントのアドレス、接続先、ログイン名、終了理由、送受信バイト数、ログファイル名)。RUST_LOG=wpg::audit=info で監査イベントだけを出力できます。ホスト鍵の保存・削除、ログの削除も記録します。
  • 権限: ログインしているユーザだけが使えます。WebSocket は同一オリジンからの接続だけを受け付けます (server.base_url を設定したリバースプロキシ経由を含む)。viewer ロール (P1) のユーザは使えません。
  • 無操作タイムアウトと同時セッション数: 放置されたセッションは idle_timeout_secs で切断します。max_sessions で同時セッション数を制限します。
  • 古い暗号方式: 古いネットワーク機器と接続できるよう、SHA-1 の鍵交換や CBC 暗号も最下位の優先度で提示します。相手がより安全な方式を持たない場合にだけ使われます。

リバースプロキシ

リバースプロキシの後ろに置く場合は、/api/ws と同様に /api/terminal/ws の WebSocket アップグレードも転送してください。nginx の例:

location /api/terminal/ws {
    proxy_pass http://127.0.0.1:8080;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
    proxy_read_timeout 3600s;
}

proxy_read_timeout は idle_timeout_secs より長くしてください。

API

メソッドパス内容
GET/api/terminal/status設定 (有効 / 無効、許可リスト) と実行中のセッション
GET/api/terminal/wsセッションの WebSocket (無効時は 403 terminal_disabled)
GET/api/terminal/logsセッションログの一覧
GET / DELETE/api/terminal/logs/{name}ログのダウンロード / 削除
GET/api/terminal/known-hosts保存済みのホスト鍵
DELETE/api/terminal/known-hosts/{host}/{port}ホスト鍵の削除

WebSocket では最初に {"type":"connect","protocol":"ssh","host":"r1","username":"admin","password":"...","cols":120,"rows":40} を送ります。サーバは state、host_key、auth_prompt、connected、record、error、closed を JSON で、端末の出力をバイナリフレームで返します。キー入力はバイナリフレーム (または {"type":"input","data":"..."}) で送ります。詳細は API リファレンス の TerminalClientMessage / TerminalServerMessage を参照してください。

トラブルシュート

表示原因と対処
「このホストはサーバの接続許可リストにありません」allowed_targets に宛先を追加し、サーバを再起動します
「ホスト鍵が変わっています」機器の鍵が変わりました。正当な変更なら 既知のホスト から古い鍵を削除します
「SSH エラー: No common … algorithm」機器と共通の暗号方式がありません。機器側で新しい方式 (aes-ctr、ecdh、ed25519 など) を有効にしてください
「ログインに失敗しました」ユーザ名、パスワード、鍵を確認します。鍵認証が無効な機器もあります
踏み台で「接続できませんでした」(踏み台 … で発生)踏み台から宛先に届かないか、踏み台の sshd で AllowTcpForwarding no になっています
右クリックで貼り付けできないHTTP で別ホストから使っています。Ctrl+V / Shift+Insert を使うか、HTTPS にします
表示が崩れるウィンドウサイズを変えると機器に通知されます。Telnet で NAWS に対応しない機器では terminal length 0 などで調整してください