Cloudflare Browser Isolation を日常的に Dogfooding するための設定

# Cloudflare Browser Isolation とは

https://www.cloudflare.com/ja-jp/zero-trust/products/browser-isolation/

>高パフォーマンスのリモートブラウザ分離（RBI）
Cloudflare Browser Isolation はすべてのコードを当社のグローバルネットワークのエッジで実行し、ランサムウェア、フィッシング、ブラウザのゼロデイ脆弱性からユーザーを隔離します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101361/268c853e-7823-1c75-0af7-cb94b7b02760.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101361/3300a09a-09e9-b8d6-6b18-4a138ed43fdb.png)

https://blog.cloudflare.com/ja-jp/cloudflare-and-remote-browser-isolation/

>通常のクラウドベースのRBIシステム（下記の青い破線のボックス①） では、個々のリモートブラウザ②はクラウドで削除可能なコンテナインスタンスとして実行されます。通常ユーザー1人につき1つのインスタンスです。リモートブラウザは、特定のプロトコルとデータフォーマット③を使って、Webページのレンダリングされたコンテンツをユーザーのエンドポイントデバイス④に送信します。キーストローク、マウスコマンド、スクロールコマンドなどのユーザーの動作は、セキュアな暗号化チャンネルを介して分離サービスに送り返されます。その後で、リモートブラウザによって処理され、リモートブラウザのWebページへの変更はエンドポイントデバイスに送り返されます。

>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101361/7221ad5f-ced0-306f-4a20-6fd472c969e2.png)

>リモートChromiumブラウザのSkia描画コマンド①をインターセプト（傍受）してからトークン化して圧縮し、そして暗号化してワイヤ②を介して、ユーザーエンドポイントデスクトップまたはモバイル端末でローカルに実行するHTML5準拠のWebブラウザ③（Chrome、Firefox、Safariなど）へと送信します。NVRにキャプチャされたSkia APIコマンドは事前にラスタ化されています。つまり非常にコンパクトだという意味です。

>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101361/ec5b4c0c-2c8a-f974-79fd-a8e3ec0944e0.png)

# Cloudflare Browser Isolation を利用する方法

以下の 5 つの方法があります

- [Gateway with WARP](https://developers.cloudflare.com/cloudflare-one/policies/gateway/initial-setup/http/)
- [Clientless Web Isolation | Cloudflare Zero Trust docs](https://developers.cloudflare.com/cloudflare-one/policies/browser-isolation/setup/clientless-browser-isolation/)
- [Non-identity on-ramps | Cloudflare Zero Trust docs](https://developers.cloudflare.com/cloudflare-one/policies/browser-isolation/setup/non-identity/)
    - [Connect to Cloudflare Gateway with Magic WAN](https://developers.cloudflare.com/magic-wan/zero-trust/cloudflare-gateway/)
    - [Proxy endpoints | Cloudflare Zero Trust docs](https://developers.cloudflare.com/cloudflare-one/connections/connect-devices/agentless/pac-files/)
- [Isolate self-hosted application | Cloudflare Zero Trust docs](https://developers.cloudflare.com/cloudflare-one/policies/access/isolate-application/)

```mermaid:
%%{init: {'themeCSS': 'img {width: 48px; height:48px;}'}}%%
graph BT

subgraph DC [Data Center]
subgraph Conn [Connector Server]
cfd[<img src='https://cf-icons.pages.dev/Cloudflared.svg'/><br>cloudflared]
end
Intra["<img src='https://cf-icons.pages.dev/server-database.svg'><br>Intra Server"]
Conn --> Intra
end

WARP["<img src='https://cf-icons.pages.dev/warp-client.svg' width='48' height='48'/><br>WARP Client"]
Browser[<img src='https://cf-icons.pages.dev/internet-browser.svg' width='48' height='48'/><br>Local Browser]
Router[<img src='https://cf-icons.pages.dev/router.svg' width='48' height='48'><br>Router]
OS[<img src='https://cf-icons.pages.dev/device-laptop.svg' width='48' height='48'><br>Proxy Setting]

subgraph Cloudflare
GW[<img src='https://cf-icons.pages.dev/gateway.svg' width='48' height='48'/><br>Gateway Policies]
Iso{Isolate?}
RBI[<img src='https://cf-icons.pages.dev/browser-rendering.svg' width='48' height='48'/><br>Remote Browsers]
subgraph less [Clientless Web Isolation]
URL["`hxxps[:]//TEAM_NAME.cloudflareaccess.com/browser/URL`"]
end
Access[<img src='https://cf-icons.pages.dev/cloudflare-access.svg' width='48' height='48'/><br>Access]
subgraph Noid [Non-identity on-ramp]
MWAN[<img src='https://cf-icons.pages.dev/magic-wan.svg' width='48' height='48'/><br>Magic WAN]
PE[<img src='https://cf-icons.pages.dev/cloudflare-zero-trust.svg' width='48' height='48'/><br>Proxy Endpoint]
end
end

Inter[<img src='https://cf-icons.pages.dev/cloud-internet.svg' width='48' height='48'/><br>Internet]
Web[<img src='https://cf-icons.pages.dev/applications.svg' width='48' height='48'/><br>Website]
IdP[<img src='https://cf-icons.pages.dev/security-fingerprint-privacy.svg' width='48' height='48'/><br>IdP]

WARP ---> Access
WARP ---> GW 
GW --> Iso --> RBI --> |Isolation|GW
GW --> Inter
GW --> cfd
Inter --> Web
Browser ---> URL & Access
URL & Access <--> |Auth|IdP
URL --> RBI
Access --> Iso
Router ----> |IPsec|MWAN ---> GW
OS ----> |Src IP allowlist|PE --> GW
```

# 日常的に Dogfooding するための設定
以下のようなイメージで、Google 検索でリストされる URL を Clientless Web Isolation のプレフィックスをつけてリライトします。

```mermaid
graph LR

subgraph Google [Google 検索ページ]
URL --> |ReWrite|URL2["`hxxps[:]//TEAM_NAME.cloudflareaccess.com/browser/URL`"]
end

URL2 ~~~ Click --> |Click|URL2
Click ~~~ URL2

Click:::hidden

classDef hidden display: none;
```

## Clientless Web Isolation 設定
以下のドキュメントに従って設定します。

https://developers.cloudflare.com/cloudflare-one/policies/browser-isolation/setup/clientless-browser-isolation/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101361/83b84a4e-ef78-c05f-5dbd-fd9af40905fa.png)

## Chrome 拡張 ReWrite インストール設定
以下の Chrome 拡張をインストールします。

https://chromewebstore.google.com/detail/rewrite/hfcabmeacpcbomdjcoipnnddiofbgokj

`TEAM_NAME` に合わせて以下のようなリライトルールを設定します。

```
"match": ["http://", "https://"], 
"substitute": "https://TEAM_NAME.cloudflareaccess.com/browser/https://", 
"url": ["www.google.com/*"];
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101361/c272c65a-de93-da63-b16c-d703008aa54f.png)

# 動作確認
上記の設定を適用すると、以下のように Clientless Web Isolation のリンクに書き換わります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101361/522ef73a-a1c9-61cb-e4d4-c1192a5cdf2d.png)

クリックすると、連携済みの IdP を経由して認証が求められます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101361/36d494cf-56ed-9341-97c0-d0b78eafbee0.png)

その後、リモートブラウザ分離（RBI）によってブラウジングがおこなわれていることが確認できます。

ここでは、リモートブラウザのブラウジング結果が [`canvas` 要素](https://developer.mozilla.org/ja/docs/Web/HTML/Element/canvas) を使って、ローカルブラウザに表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101361/6cdee5d6-76a5-05a5-7f46-df233aceb6d6.png)

# 参考：ユースケース
例えば、以下のようなユースケースにも対応できます。

- ローカル クリップボードのコンテンツをリモート Web ページにコンテンツを貼り付けたい
- リモート Web ページのコンテンツをローカル クリップボードにコピーするのを禁止したい

この場合、以下のような分離設定によって、実現できます。

- `コピー（リモートからクライアントへ）` ＞ `許可しない`
- `貼り付け（クライアントからリモートへ）` ＞ `許可`

https://developers.cloudflare.com/cloudflare-one/policies/browser-isolation/isolation-policies/#policy-settings

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101361/fed33b22-0e6d-4ba0-8370-3230f7672818.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101361/9e8d59c0-f742-4a4d-8089-e52e90eeea61.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101361/9586b100-2096-4466-bc8d-eba952dfc338.png)

# 参考：ユーザアクションログ
上記ポリシーを設定した場合、以下のようなユーザアクションログが確認できます。

Logpush によってログデータを取り込み、SIEM で監視・分析することも運用として想定できます。

```json:user-action.log
[
  {
    "AccountID": "xxx",
    "Decision": "allow",
    "DomainName": "www.yahoo.co.jp",
    "Timestamp": "2025-02-18T17:24:27Z",
    "Type": "paste",
    "UserID": "zzz"
  },
  {
    "AccountID": "xxx",
    "Decision": "block",
    "DomainName": "www.yahoo.co.jp",
    "Timestamp": "2025-02-18T17:24:36Z",
    "Type": "copy",
    "UserID": "zzz"
  }
]
```

# まとめ

製品を提案する立場上、日頃から使用感に慣れて、説明できるようにしておく必要があると思い、今回の発想に至りました。

Dogfooding によって、バグ等があれば、適時社内で製品担当者へのフィードバックを挙げられます。

もちろんデモ用途にも便利かなと思います。