mcpField
C
cloudflare-zero-trust

cloudflare-zero-trust

github.com/bagelholeセキュリティ1.2k329 回インストール23 週間前に更新
リポジトリ

cloudflare-zero-trust について

cloudflare-zero-trust は Cloudflare Zero Trust の設定スキルです。トンネル、ID ポリシー、デバイスチェック、DNS フィルタリングで、内部サービスとリモートアクセスを保護します。

主な機能

  1. 01Tunnel による内部サービスの公開
  2. 02ID ベースのアプリケーションアクセス設定
  3. 03デバイスポスチャチェックの適用
  4. 04Gateway DNS フィルタリングの設定
  5. 05WARP によるトラフィックのルーティング

活用シーン

  1. 01内部アプリへの VPN アクセスの置き換え
  2. 02SSH または RDP のリモートアクセス保護
  3. 03DNS による悪意あるドメインの遮断

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/bagelhole/devops-security-agent-skills --skill cloudflare-zero-trust

インストール後、Claude Code で/cloudflare-zero-trustを入力して読み込まれたか確認します。

詳細

Cloudflare Zero Trust

CloudflareのZero Trustプラットフォーム(Access、Tunnel、Gateway、WARP)を使用して、VPNなしで内部サービスへのアクセスを保護します。

使用する場面

  • 内部Webアプリケーション、SSH、RDPへのアクセスをVPNから置き換える場合。
  • 内部ツール(ダッシュボード、管理パネル)に対して、ID認識型のアクセスポリシーを適用する場合。
  • オンプレミスまたはプライベートネットワークのサービスを、リモートチームに安全に公開する場合。
  • DNSトラフィックをフィルタリングして、マルウェア、フィッシング、シャドーITをブロックする場合。
  • デバイスの状態チェック(管理対象デバイス、OSバージョン、ディスク暗号化)を適用する場合。

前提条件

  • Zero TrustプランのCloudflareアカウント(無料プランは最大50ユーザーに対応)。
  • Cloudflare上のドメイン(Accessアプリケーションのホスト名用)。
  • IDプロバイダーの設定(Google Workspace、Okta、Azure AD/Entra ID、GitHub)。
  • 内部サービスをホストするサーバーにcloudflared CLIをインストールしていること。
# Install cloudflared
# macOS
brew install cloudflared

# Debian/Ubuntu
curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/cloudflared.list
sudo apt update && sudo apt install -y cloudflared

# Docker
docker pull cloudflare/cloudflared:latest

Cloudflare Tunnelのセットアップ

Tunnelは、インフラストラクチャからCloudflareのエッジへの暗号化されたアウトバウンド接続を作成し、インバウンドポートを開放する必要をなくします。

Tunnelの作成と設定
# Authenticate with Cloudflare
cloudflared tunnel login

# Create a named tunnel
cloudflared tunnel create internal-apps

# This creates credentials at ~/.cloudflared/<TUNNEL_ID>.json

# List tunnels
cloudflared tunnel list

# Route DNS to the tunnel (creates a CNAME record)
cloudflared tunnel route dns internal-apps grafana.example.com
cloudflared tunnel route dns internal-apps wiki.example.com
cloudflared tunnel route dns internal-apps ssh.example.com
Tunnel設定ファイル
# ~/.cloudflared/config.yml
tunnel: <TUNNEL_ID>
credentials-file: /home/deploy/.cloudflared/<TUNNEL_ID>.json

ingress:
  # Grafana dashboard
  - hostname: grafana.example.com
    service: http://localhost:3000

  # Internal wiki
  - hostname: wiki.example.com
    service: http://localhost:8080
    originRequest:
      noTLSVerify: true

  # SSH access via browser
  - hostname: ssh.example.com
    service: ssh://localhost:22

  # Private network access (CIDR routing)
  - hostname: internal.example.com
    service: http://10.0.0.0/24

  # Catch-all — required as the last rule
  - service: http_status:404
Tunnelの実行
# Run in foreground (for testing)
cloudflared tunnel run internal-apps

# Install as a systemd service
sudo cloudflared service install
sudo systemctl enable cloudflared
sudo systemctl start cloudflared

# Or run via Docker
docker run -d --name cloudflared \
  --restart unless-stopped \
  -v /home/deploy/.cloudflared:/etc/cloudflared \
  cloudflare/cloudflared:latest \
  tunnel run internal-apps
Tunnelを使用したDocker Compose
# docker-compose.yml
version: "3.8"
services:
  cloudflared:
    image: cloudflare/cloudflared:latest
    restart: unless-stopped
    command: tunnel run
    environment:
      - TUNNEL_TOKEN=${TUNNEL_TOKEN}
    networks:
      - internal

  grafana:
    image: grafana/grafana:latest
    networks:
      - internal

  wiki:
    image: requarks/wiki:2
    networks:
      - internal

networks:
  internal:
    driver: bridge

アクセスポリシー

アクセスポリシーは、Cloudflareの背後にあるアプリケーションにアクセスできるユーザーを制御します。

Accessアプリケーションの作成
# Via API — create a self-hosted application
curl -X POST "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/access/apps" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Grafana",
    "domain": "grafana.example.com",
    "type": "self_hosted",
    "session_duration": "12h",
    "auto_redirect_to_identity": true,
    "allowed_idps": ["<IDP_UUID>"]
  }'
ポリシーの種類と例
# Allow policy — members of the engineering group
curl -X POST "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/access/apps/<APP_ID>/policies" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Engineering Team",
    "decision": "allow",
    "include": [
      { "group": { "id": "<GROUP_UUID>" } }
    ],
    "require": [
      { "login_method": { "id": "<MFA_METHOD_UUID>" } }
    ]
  }'
一般的なポリシーパターン
パターンIncludeルールRequireルール
全従業員メールドメイン@company.com-
エンジニアリング部門のみAccess Group "Engineering"MFA
契約社員(期間限定)メールリストデバイスの状態
CI/CDの自動化サービストークン-
外部パートナー特定のメールアドレス国の確認
自動化用サービストークン
# Create a service token for CI/CD
curl -X POST "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/access/service_tokens" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "github-actions-deploy"}'

# Response includes Client ID and Client Secret
# Use in CI with headers:
# CF-Access-Client-Id: <CLIENT_ID>
# CF-Access-Client-Secret: <CLIENT_SECRET>
# Use service token in CI/CD
curl -H "CF-Access-Client-Id: $CF_CLIENT_ID" \
     -H "CF-Access-Client-Secret: $CF_CLIENT_SECRET" \
     https://grafana.example.com/api/health

デバイスの状態チェック

アクセスを許可する前に、エンドポイント要件を適用します。

状態チェックの設定(ダッシュボード)
  1. Settings > WARP Client > Device postureに移動します。
  2. チェック項目を追加します。
    • ディスク暗号化:FileVault(macOS)またはBitLocker(Windows)を必須にします。
    • OSバージョン:macOS 14.0以降、またはWindows 11を必須にします。
    • ファイアウォール:ホストファイアウォールが有効であることを確認します。
    • Crowdstrike/SentinelOne:EDRエージェントが実行中であることを確認します。
  3. AccessポリシーのRequireルールで状態チェックを参照します。

Gateway DNSフィルタリング

DNSレベルで悪意のあるドメインをブロックし、適切な利用ポリシーを適用します。

DNSロケーション
# Configure DNS endpoints for offices or networks
# Dashboard: Gateway > DNS Locations > Add a location
# Assign the Gateway DNS IPs to your network's DNS resolver:
# IPv4: 172.64.36.1, 172.64.36.2
# IPv6: 2606:4700:4700::1111
# DoH: https://<UNIQUE_ID>.cloudflare-gateway.com/dns-query
DNSポリシー
# Create a DNS policy to block malware and phishing
curl -X POST "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/gateway/rules" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Block Security Threats",
    "enabled": true,
    "action": "block",
    "traffic": "any(dns.security_category[*] in {80 83 131 134 151 153})",
    "filters": ["dns"]
  }'
一般的なDNSポリシールール
ルール名トラフィック式アクション
マルウェアをブロックany(dns.security_category[*] in {80 83})ブロック
フィッシングをブロックany(dns.security_category[*] in {131 134})ブロック
ソーシャルメディアをブロックany(dns.content_category[*] in {75})ブロック
例外を許可dns.fqdn == "allowed.example.com"許可

WARPクライアントのデプロイ

Cloudflare WARPクライアントをデプロイして、Gateway経由でトラフィックをルーティングします。

# MDM deployment — macOS configuration profile
# Use Cloudflare's managed deployment:
# Dashboard: Settings > WARP Client > Device enrollment

# Manual enrollment
# 1. Install WARP client from https://1.1.1.1
# 2. Click gear icon > Account > Login with Cloudflare Zero Trust
# 3. Enter your team name (from Settings > General)

# Verify WARP is connected
curl https://connectivity.cloudflare.com/cdn-cgi/trace
# Look for: warp=on
WARPのスプリットトンネル
# Configure split tunnels to exclude certain traffic from WARP
# Dashboard: Settings > WARP Client > Device settings > Split Tunnels

# Exclude mode (default): WARP handles everything except listed IPs
# Include mode: WARP only handles listed IPs/domains

# Common exclusions:
# - Local network: 192.168.0.0/16, 10.0.0.0/8
# - Video conferencing: zoom.us, *.teams.microsoft.com
# - Printer subnets

SSHとブラウザーベースのターミナル

# In cloudflared config.yml — expose SSH via browser rendering
ingress:
  - hostname: ssh.example.com
    service: ssh://localhost:22
# Users access ssh.example.com in their browser
# Cloudflare renders an in-browser terminal after Access authentication

# Or use cloudflared on the client side for native SSH
cloudflared access ssh --hostname ssh.example.com

# Add to SSH config for seamless access
# ~/.ssh/config
# Host ssh.example.com
#   ProxyCommand /usr/local/bin/cloudflared access ssh --hostname %h

トラブルシューティング

症状原因対処方法
ダッシュボードでトンネルが ERR と表示されるcloudflared が実行されていない、または設定にエラーがあるsystemctl status cloudflared を確認し、設定 YAML を検証します
正しい ID なのにアクセスすると 403 が返されるポリシーの順序、または require ルールがないポリシーは上から順に評価されます。Allow が Block より上にあることを確認します
WARP に「Unable to connect」と表示されるチーム名が間違っている、または登録が無効になっているSettings > General でチーム名を確認し、登録権限を確認します
サービストークン認証に失敗するトークンの有効期限切れ、またはヘッダーが間違っているトークンを再生成し、CF-Access-Client-Id と CF-Access-Client-Secret の両方を使用します
DNS フィルタリングでブロックされないクライアントが Gateway DNS リゾルバーを使用していないDNS が 172.64.36.1 に設定されていることを確認し、WARP が接続されていることを確認します
トンネルのレイテンシーが急増するトンネルが過負荷のホストで実行されているcloudflared のリソース使用量を監視し、専用インフラで実行します
「No healthy origins」エラーバックエンドサービスが停止している設定された ingress ポートでサービスを確認し、cloudflared のログを確認します

関連スキル

コメント