fbpx

Cloudflareで始める:Cloudflare Tunnelを使ったwebサーバ公開

はじめに

Cloudflareという会社の名前を聞いたことがある人でも、CloudflareはCDN屋さんやDDoS対策屋さん、WAF屋さん、あるいはDNS屋さんだと思っている思っている人は多いのではないでしょうか。

この(勝手に始めた)「Cloudflareで始める」シリーズでは、クラウド事業者としてのCloudflareの知られざる実力を暴いていきたいと思います!

Cloudflareがどのような会社か、他社と比較してどうなのか等は特に述べません。

注意事項

サービス内容やコストなどは執筆時点の情報になります。最新の情報と相違無いか確認しつつ活用してください。

今回の題材

「はじめに」で大見得を切りましたが、今回は自宅サーバの定番でありCloudflareの基本中の基本であるwebサーバの公開を取り扱います。

自宅で簡単にお試しできる、ぐらいの構成から始めていこうという魂胆です。

とはいえ、普通にルータのポート開放してIPアドレスをDNSサーバに登録して、IPアドレス非公開化のためにproxy設定して...みたいな使い方は多く紹介されていると思うので、Cloudflare Tunnelを利用する構成をご紹介します。

Cloudflare Tunnelを採用する利点としては

  • ルータのポート開放不要
    • 手間の削減だけでなく、ルータの操作ができない場合にも有効
  • Webサーバ、ルータのIPアドレス変更に強い
    • ルータにwebサーバのIPアドレスを覚えさせる必要がない
    • CloudflareのDNSサーバにルータのグローバルIPアドレスを覚えさせる必要がない
  • 設定をTerraformで行える・管理できる
    • (最初のCloudflareのアカウント登録やwebサイト登録はご容赦ください...)

があります。

欠点としては

  • 接続元IPアドレスによる制限がwebサーバ側でかけられない
    • IPのレイヤではlocalhostからの通信に見える為
    • HTTP以後のレイヤであればCf-Connecting-Ipヘッダを読み込み、処理分岐させる事で対処可能
  • webサーバへの一回のアップロード容量が絞られる可能性

があります。

具体的にどのような経路を辿ってユーザがwebサービスを利用するかはこちらの公式ドキュメントを参照してください。

https://developers.cloudflare.com/cloudflare-one/connections/connect-network

検証

折角なのでCloudflare側の設定はTerraformを使って設定を試みます。

(webサーバ側の設定は手動で行います)

前提

  • Cloudflareにアカウントを作成済み
  • example.comなど、自分のDNSドメイン名を取得している
  • Cloudflareアカウントにwebサイトを登録済み
    • 「Webサイト」と言うと警戒されますが、DNSドメイン名とCloudflareアカウントの紐付けです
  • クレジットカード、PayPalなどCloudflareで有効な支払い方法が用意できる
    • 用途
      • Cloudflare Zero Trustの利用登録
        • 課金が発生しない構成でも支払い情報の登録が必要な場合があります
      • (Optional) Cloudflareで自分のDNSドメイン名を取得する際に利用
  • Cloudflare Tunnelで利用するドメイン、IPアドレス、ポートへのアクセスが可能

検証環境

  • 設定PC
    • Terraform v1.9.5
  • webサーバ
    • Nginx公式dockerイメージ(1.27.1-alpine3.20-slim)を設定を変えずにデプロイ済
      • デプロイコマンド
        • docker run --rm -it -p 80:80 nginx:1.27.1-alpine3.20-slim

設定手順

Cloudflare Zero Trustの登録

  • Cloudflareアカウントにログインし、Zero TrustをクリックしてZero Trustの管理メニューに移動します。
  • このタイミングで支払い情報の登録やZero Trustのプラン選択を迫られるので、画面の指示に従って登録を進める

CloudflareのAPIキー設定

  • 必要な権限:英語版

TerraformでCloudflare Tunnelを設定

Terraformで設定を行っていきます。

  • webサイト編集画面でアカウントIDを控えておく
  • terraformファイルを作成し、適切なパラメータを設定しておく
locals {
  cloudflare_account_id = "****"        # 自前のアカウントのアカウントIDに置き換えてください
  cloudflare_zone_name  = "example.com" # 自前のアカウントのドメイン名に置き換えてください
  subdomain             = "nginx"       # webサーバに設定したいサブドメインに置き換えてください
  fqdn                  = "${local.subdomain}.${local.cloudflare_zone_name}"
}

variable "cloudflare_token" {
  description = "Cloudflare API token created at https://dash.cloudflare.com/profile/api-tokens"
  type        = string
  sensitive   = true
}

terraform {
  required_providers {
    cloudflare = {
      source  = "cloudflare/cloudflare"
      version = "4.40.0"
    }
    random = {
      source = "hashicorp/random"
    }
  }
  required_version = ">= 0.13"
}

# Providers
provider "cloudflare" {
  api_token = var.cloudflare_token
}

provider "random" {
}

resource "random_password" "tunnel_secret" {
  length = 64
}

# Creates a example tunnel.
resource "cloudflare_zero_trust_tunnel_cloudflared" "example_tunnel" {
  account_id = local.cloudflare_account_id
  name       = "Example tunnel"
  secret     = base64sha256(random_password.tunnel_secret.result)
}

resource "cloudflare_zero_trust_tunnel_cloudflared_config" "example_config" {
  account_id = local.cloudflare_account_id
  tunnel_id  = cloudflare_zero_trust_tunnel_cloudflared.example_tunnel.id
  config {
    warp_routing {
      enabled = true
    }
    ingress_rule {
      hostname = local.fqdn
      service  = "http://localhost:80"
    }
    ingress_rule {
      service = "http_status:404"
    }
  }
}

data "cloudflare_zone" "example" {
  name = local.cloudflare_zone_name
}

resource "cloudflare_record" "example" {
  zone_id = data.cloudflare_zone.example.zone_id
  name    = local.subdomain
  content = "${cloudflare_zero_trust_tunnel_cloudflared.example_tunnel.id}.cfargotunnel.com"
  type    = "CNAME"
  proxied = true
}
  • Terraformのvariableを指定するファイルを作成しておく
    1. 例としてexample.tfvarsという名前で作成
cloudflare_token = "****" # 自前のトークンに置き換える
  • Terraformを実行し、Cloudflare TunnelとDNSレコードの設定を行う
    1. terraform init
    2. terraform plan -var-file example.tfvars
    3. terraform apply -var-file example.tfvars

webサーバにcloudflaredを導入しCloudflare Tunnelに接続する

webサーバにcloudflaredというCloudflare Tunnelに接続するためのクライアントを導入し、設定する。

  • Cloudflare Zero Trustのwebページに移動する
  • Tunnelsメニューから作成したトンネルのConfigure画面に移動する
  • Configure画面の下方にChoose your environmentメニューがあるので、webサーバの環境を選択する
  • 同じ画面にInstall and run a connectorメニューがあるので、curlから始まるコマンドをコピーしてwebサーバで実行してcloudflaredをインストール、セットアップする
    • ドラッグで選択してコピーではなく、枠をクリックするだけでコピーできる

動作確認

シンプルにwebブラウザから「TerraformでCloudflare Tunnelを設定」で指定したFQDNに接続するだけです!

(スマホのモバイル回線などで接続するとローカルネットワーク経由の可能性を除外できます)

HTTPsでの終端もやってくれていますね!

おわりに

今回は自宅サーバの定番でありCloudflareの基本中の基本であるwebサーバの公開をCloudflare Tunnelを通すという変化球の構成で行ってみました!

まだまだCloudflareの真価は発揮できていませんが、第一歩としては程よい難易度だったのではないでしょうか。

脚注

米国およびその他の管轄区域において、Cloudflare、Cloudflareのロゴ、Cloudflare Workersは、Cloudflare, Inc.の商標および/または登録商標です。

Author

色々やらせてもらっている系エンジニア。
Arch Linuxユーザー。

菅野 洋信の記事一覧

新規CTA