Kasm WorkspacesをUbuntuにインストール:オープンソースのBrowser IsolationとDesktop-as-a-Serviceの構築

Virtualization tutorial - IT technology blog
Virtualization tutorial - IT technology blog

直面した課題:リモートワークチームのためのBrowser Isolation

去年の年初に、チームでかなり痛い思いをしたインシデントがあった。あるデベロッパーが個人のパソコンでメールの添付ファイルを開いたところ、マシンがキーロガーに感染し、VPNの認証情報が漏洩してしまった。彼のせいではない——自宅で作業していて、家のパソコンで社内システムにアクセスしていただけだ。

課題は、従業員の個人端末が安全かどうかを気にせずに、社内システムへアクセスさせる方法だった。そこでBrowser Isolationの解決策を探し始めた——ブラウザをユーザーのマシンから完全に隔離した独立した環境で実行する仕組みだ。

分析:なぜ従来のソリューションでは不十分なのか

Kasmにたどり着く前に、いくつかの方向性を試した:

  • Windows ServerへのRDP:ライセンス費用がかかり、管理が複雑で、各ユーザーが個別セッションを必要とするためRAM消費が膨大。
  • エンタープライズVDI(Citrix、VMware Horizon):ライセンスコストが非常に高く、セットアップに数週間かかり、20人規模のチームにはオーバースペック。
  • Guacamole + KVM:Proxmoxのホームラボでしばらくこの組み合わせを使っていた。技術的には問題ないが、セッション管理やVMのライフサイクル管理が非常に手動で——新しい環境が必要なたびに手作業でVMを作成しなければならなかった。

共通の問題:安くて速く、ブラウザやデスクトップ環境を数秒でオンデマンドにスピンアップできるソリューションがなかった。

利用可能なソリューション

Option 1:Apache Guacamole + VMプール

GuacamoleはRDP/VNC/SSH向けのHTML5ゲートウェイだ。VMプールと組み合わせれば解決できなくもないが、セッション管理やVMのライフサイクル管理が非常に手動で——新しい環境が必要なたびに手作業でVMを作成しなければならなかった。試してみたが、2週間で断念した。

Option 2:Neko (m1k1o/neko)

NekoはDockerで動くブラウザで、WebRTC経由でストリーミングする。インターフェースが美しく、レイテンシも低いが、コンテナあたり1ユーザーしかサポートせず、管理ポータルがない。

Option 3:Kasm Workspaces(Community Edition)

これが現在本番環境で使っているソリューションだ。KasmはDockerコンテナ内でブラウザ、デスクトップ、さらにはフルLinuxデスクトップを実行し、HTTPS/WebSocket経由でストリーミングする。Community Editionは無料で、最大5つの同時セッションをサポートする。

最良の方法:UbuntuへのKasm Workspacesインストール

KasmはProxmox VEのホームラボ内のVM上で動かしている——本番環境に上げる前にすべてをテストするプレイグラウンドだ。このVMのスペック:Ubuntu 22.04、4 vCPU、8GB RAM、50GBディスク。Kasmの最小要件は2 CPUと4GB RAMだ。

ステップ1:システムの準備

# システムをアップデート
sudo apt update && sudo apt upgrade -y

# 必要なパッケージをインストール
sudo apt install -y curl wget gnupg2

# スワップを無効化(Kasmはスワップが苦手)
sudo swapoff -a
sudo sed -i '/swap/d' /etc/fstab

ステップ2:Kasmのダウンロードとインストール

# インストーラーをダウンロード(kasm.ioで最新バージョンを確認)
cd /tmp
wget https://kasm-static-content.s3.amazonaws.com/kasm_release_1.16.0.a12b22.tar.gz

# 解凍
tar -xf kasm_release_*.tar.gz

# インストーラーを実行(--accept-eulaで確認プロンプトをスキップ)
sudo bash kasm_release/install.sh --accept-eula

インストールはネットワーク速度に応じて5〜10分かかる——KasmはDockerイメージを大量にプルしてくる。完了すると、ターミナルに以下のような情報が表示される:

Kasm UI Login Credentials
-----------------------------
Username: [email protected]
Password: XXXXXXXXXXXXXX

Kasm UI is available at https://<YOUR_IP>

このパスワードはすぐにコピーしておくこと——表示されるのは一度だけだ。

ステップ3:アクセスと初期設定

ブラウザを開いて https://<IP_SERVER> にアクセスする。自己署名SSLの警告が表示される場合があるが、「詳細設定」→「続行」をクリックする。[email protected]と先ほどコピーしたパスワードでログインする。

Admin → Workspaces に移動すると、デフォルトのワークスペーステンプレート一覧が表示される:Chrome、Firefox、Ubuntu Desktop、VS Code…それぞれが個別のDockerイメージだ。

ステップ4:ユーザーの追加と権限設定

# KasmにはユーザーをAPIで自動作成するためのREST APIもある
# API経由でユーザーを作成する例:
curl -k -X POST https://localhost/api/public/register_user \
  -H 'Content-Type: application/json' \
  -d '{
    "api_key": "YOUR_API_KEY",
    "api_key_secret": "YOUR_API_SECRET",
    "target_user": {
      "username": "[email protected]",
      "first_name": "Dev",
      "last_name": "User",
      "password": "SecurePass123!",
      "locked": false,
      "disabled": false
    }
  }'

APIキーは Admin → API Configurations から取得する。小さなチームならUIから手動でユーザーを作成しても構わない。

ステップ5:カスタムワークスペースの設定

よく使うのは、いくつかのセキュリティ設定を施したChromeワークスペースの作成だ——コンテナからホストへのクリップボードを無効化し、マイクやカメラを制限する:

Admin → Workspaces → Add Workspace に移動する:

  • Workspace Type:Container
  • Docker Imagekasmweb/chrome:1.16.0
  • Cores:2
  • Memory (MB):2048
  • GPU Count:0

セッション間でユーザーのブックマークや設定を保持したい場合、Persistent Profile Path の設定が重要だ:

/mnt/kasm_profiles/{username}/chrome

ステップ6:Nginxでのリバースプロキシ設定

Kasmはデフォルトでポート443でHTTPSを自己管理して動作する。独自ドメインを使いたい場合はリバースプロキシが必要だ。ProxmoxのVM上にNginxを立てて使っている:

server {
    listen 443 ssl;
    server_name kasm.yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/kasm.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/kasm.yourdomain.com/privkey.pem;

    location / {
        proxy_pass https://KASM_SERVER_IP;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # WebSocketサポート — 重要、これがないとストリーミングが動作しない
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        proxy_read_timeout 1800;
        proxy_send_timeout 1800;
    }
}

ステップ7:動作確認とモニタリング

# Kasmサービスの動作確認
sudo /opt/kasm/bin/stop
sudo /opt/kasm/bin/start

# ログを確認
sudo docker logs kasm_proxy
sudo docker logs kasm_api
sudo docker logs kasm_manager

# 実行中のコンテナを確認
sudo docker ps | grep kasm

実際の運用から得た注意点

ホームラボでKasmを数ヶ月運用してから本番環境に移行した経験から、いくつかの点を学んだ:

  • RAMが主なボトルネック:Chromeセッション1つあたり約1.5〜2GB RAMを消費する。8GB RAMで快適に使えるのは最大4〜5の同時セッションだ。
  • 永続プロファイルは定期的なクリーンアップが必要:ユーザーがファイルをダウンロードするとプロファイルディレクトリがすぐに膨れ上がる。リテンションポリシーの設定を推奨する。
  • Community Editionは5同時セッションに制限:小規模チームには十分だ。それ以上必要な場合は有料プランへのアップグレードか、マルチノードクラスターの自前構築(かなり複雑)が必要になる。
  • WebRTCとUDP:ファイアウォールが厳しい場合、ストリームがWebSocketにフォールバックすることがある——遅くはなるが動作はする。最高のパフォーマンスを求めるならUDP 4902を開放すること。

KasmとGuacamole——どちらを選ぶべきか?

この質問はよく受ける。チームが主に既存サーバーへのSSH/RDPを必要とするならGuacamoleの方がシンプルで軽量だ。しかし本当のBrowser Isolation——ブラウザがコンテナ内で完全に動作し、ユーザーのマシンに一切触れない——が必要なら、Kasmの方がはるかに適した選択肢だ。

現在は両方を使っている:GuacamoleはSSHジャンプホスト用、KasmはBrowser Isolationと、メインマシンに影響を与えずに何かをテストしたいときの一時的なデスクトップ環境用だ。

Share: