記事一覧 プロジェクト集 検索 このサイトについて
RSS English

Cloudflare Zero TrustでSSHを保護する

Cloudflare Zero TrustでSSHを保護する 背景 サーバにSSHでアクセスするには、通常22番ポートをインターネットに公開する必要がある。しかし公開されたSSHポートは常に攻撃の標的になる。 Cloudflare Zero Trustを使えば、SSHポートを閉じたまま、認証済みのユーザーだけがSSH接続できる環境を構築できる。 Zero Trustとは 従来のセキュリティモデルでは「社内ネットワーク内は信頼する」という前提があった。Zero Trustはこの前提を捨て、全てのアクセスを検証するモデル。 【従来】 インターネット → ファイアウォール → 社内(信頼済み) ※ 一度入れば自由にアクセス可能 【Zero Trust】 インターネット → Cloudflare(認証・認可) → サーバ ※ 毎回アクセスを検証する ※ 認証されていなければ接続不可 仕組み SSHの場合、Cloudflare TunnelとAccess機能を組み合わせる。 開発者のPC └── ssh コマンド └── cloudflared(ProxyCommand) └── Cloudflare(Access認証) └── Tunnel └── サーバのSSHデーモン SSHコマンドを実行すると、cloudflaredがプロキシとして動作 Cloudflare Accessが認証を要求(ブラウザでメール認証) 認証成功後、Tunnel経由でサーバのSSHに接続 サーバ側のSSHポートは閉じたまま 前提条件 Cloudflare Tunnelが設定済みであること(Cloudflare Tunnelの設定方法を参照) ローカルPCにcloudflaredがインストール済みであること 手順 1. Tunnel IngressにSSHを追加 Cloudflare APIでSSHのルーティングを追加する: ...

Cloudflare Tunnelで学術サーバを安全に公開する

Cloudflare Tunnelで学術サーバを安全に公開する 背景 学術研究用のサーバでElasticsearch(全文検索)やCantaloupe(IIIF画像配信)を運用する場合、通常はサーバのポートを外部に公開する必要がある。しかしポートを開放すると、脆弱性を突いた攻撃のリスクが生まれる。 Cloudflare Tunnelを使えば、サーバのインバウンドポートを一切開けずに、サービスを安全に外部公開できる。 Cloudflare Tunnelとは 通常のサーバ公開では、サーバ側がポートを開けて外部からの接続を待ち受ける(インバウンド接続)。Cloudflare Tunnelはこの構造を逆転させる。 【従来】 外部 → (80/443ポート) → サーバ ※ サーバがポートを開けて待ち受ける 【Cloudflare Tunnel】 外部 → Cloudflare → ← サーバ(cloudflared) ※ サーバ側からCloudflareに接続しに行く(アウトバウンド) ※ インバウンドポートは不要 サーバ上で動作するcloudflaredというエージェントが、Cloudflareに対してアウトバウンド接続を維持する。外部からのリクエストはCloudflareが受け取り、このトンネル経由でサーバに転送される。 メリット ポート開放不要: インバウンドポートを全て閉じられる WAF・DDoS防御: Cloudflareが自動で攻撃を吸収 SSL自動化: Let’s Encryptの設定やリバースプロキシ(Traefik等)が不要 無料: Tunnelは無料プランで利用可能 構成 Cloudflare ├── iiif-cf.example.jp → Cantaloupe (8182) └── es-cf.example.jp → Elasticsearch (9200) │ │ Tunnel(暗号化済み) │ サーバ(Docker) ├── cloudflared(Tunnelエージェント) ├── elasticsearch(全文検索) └── cantaloupe(IIIF画像配信) 手順 1. Cloudflareにドメインを登録 Cloudflareのダッシュボードでドメインを追加し、レジストラ(お名前.com等)のネームサーバをCloudflareに変更する。 ...

ネームサーバの仕組み

ネームサーバの仕組み ネームサーバとDNSの違い ほぼ同じ文脈で使われますが、厳密には異なります。 DNS ネームサーバ 何か 仕組み・ルール全体の名前 その仕組みの中で動く実際のサーバ 例えるなら 「電話帳のシステム」 「電話帳を持っている窓口の人」 DNS(Domain Name System) は、ドメイン名からIPアドレスを調べるための仕組み全体を指します。プロトコル、ルール、レコードの形式などを含む概念です。 ネームサーバ は、DNSという仕組みの中で実際に問い合わせに回答するサーバのことです。DNSサーバとも呼ばれますが、同じものです。 「ネームサーバ」=「DNSサーバ」(呼び方が違うだけ) 紛らわしいのは「DNS」が2つの意味で使われること: DNS = 仕組み全体(Domain Name System) DNSサーバ = その仕組みの中で動くサーバ = ネームサーバ DNS = 仕組み全体 ├── ネームサーバ = 問い合わせに答えるサーバ(例: kellen.ns.cloudflare.com) ├── DNSレコード = サーバが持っている対応表(A, CNAME, MX, NS, TXT...) ├── リゾルバ = ユーザー側で問い合わせを行うプログラム └── プロトコル = 問い合わせのルール(UDP 53番ポートなど) 日常的には「DNS変更した」「ネームサーバ変更した」はほぼ同じ意味で使われます。厳密に言い分けるなら: 「ネームサーバを変更した」= 問い合わせ先のサーバを変えた 「DNSレコードを変更した」= 対応表の中身を変えた DNSサーバはどれだけの情報を持っているのか Cloudflareのような大手DNSプロバイダは、全ユーザーのDNSレコードを自社サーバに保持しています。 【CloudflareのDNSサーバ】 ├── example.jp の対応表 ├── someone-else.com の対応表 ├── big-company.io の対応表 └── ... 数千万ドメイン分 これは膨大な数ですが、1つのDNSレコードは数十〜数百バイト程度の小さなデータです。仮に1億レコードあっても数十GB程度で、現代のサーバであれば全てメモリに載る量です。 ...

Elasticsearch → Static JSON / D1 移行検証 — 小規模データなら全文検索エンジンは不要だった

Cloudflare Pages上で動くNext.js製の日本語テキスト検索APIで、Elasticsearchの代替としてCloudflare D1(SQLite)とStatic JSON(インメモリ検索)を実装し、3方式の検索性能を比較しました。 背景 古典日本語テキストの全文検索APIを運用しています。Elasticsearchを外部クラスタとして利用していましたが、以下の理由で代替を検討しました。 外部サービスへの依存を減らしたい Cloudflare Pages内で完結させたい データ量が小さい(約1,800件)ので、全文検索エンジンは過剰かもしれない データ規模 項目 値 レコード数 1,812件 テキスト総量(UTF-8) 約2.5 MB 1レコード平均 約1.4 KB 各レコードは古典日本語テキスト(数行〜十数行)、ページ番号、巻名、IIIFキャンバスURLで構成されています。 3方式の概要 1. Elasticsearch(既存) 外部Elasticsearchクラスタに対して、fetch APIでwildcardクエリを実行する方式です。 { wildcard: { 'original_text_lines.keyword': `*${query}*` } } ngramアナライザーでインデクシングしていますが、実際の検索ではwildcardクエリ(*query*)を使っており、ngramインデックスの恩恵を受けていませんでした。 2. Cloudflare D1(SQLite) Cloudflare D1にデータを格納し、LIKEで部分一致検索する方式です。 SELECT id, page, original_text, vol_str, canvas FROM texts WHERE original_text LIKE '%検索語%' ORDER BY page ASC LIMIT 20 OFFSET 0 集計(ファセット)はSQLのGROUP BYで実現します。 SELECT vol_str, COUNT(*) as doc_count FROM texts WHERE original_text LIKE '%検索語%' GROUP BY vol_str ORDER BY vol_str ASC D1のbatch()APIで検索・カウント・集計の3クエリを同時実行できます。 ...

Vercel ProをHobbyに下げるためにNext.jsアプリをCloudflare Pagesに移行した

Vercel Proプランで60以上のNext.jsプロジェクトを運用していましたが、組織向けアプリをCloudflare Pagesに移行することで、Hobbyプラン(無料)へのダウングレードを実現しました。 背景 Vercel Proの課題 Vercel Hobbyプランは非商用・個人利用のみです。組織のアプリをホストしている場合、Proプラン($20/月〜)を維持する必要があります。 しかし、60以上あるプロジェクトのうち組織向けアプリは2つだけでした。この2つをCloudflareに移せば、残りは個人プロジェクトとしてHobbyプランで運用できます。 移行対象 多言語対応(日本語/英語)の検索アプリ(Next.js + next-intl + Elasticsearch) IIIF画像ビューアアプリ いずれもカスタムドメインで運用中。 Next.js 16の壁 — proxy.tsが未対応 最初にそのままCloudflare Pagesへの移行を試みましたが、ビルドの最終段階でエラーが発生しました。 Node.js middleware is not currently supported. Consider switching to Edge Middleware. Next.js 16では従来の middleware.ts が proxy.ts にリネームされ、Node.jsランタイム固定になりました。@opennextjs/cloudflare v1.18.0時点ではこの新しい proxy.ts に未対応です(opennextjs/opennextjs-cloudflare#962)。 解決策:Next.js 15にダウングレード # package.json "next": "^15.3.1", # 16.x → 15.x "next-intl": "^3.26.5", # 4.x → 3.x(Next.js 15対応版) "eslint-config-next": "^15.3.1", 同時に proxy.ts を middleware.ts にリネームし、エクスポート名も proxy → middleware に変更しました。 Cloudflare Pagesへのデプロイ手順 1. 依存パッケージのインストール npm install --save-dev @opennextjs/cloudflare wrangler 2. 設定ファイルの作成 // open-next.config.ts import { defineCloudflareConfig } from "@opennextjs/cloudflare"; export default defineCloudflareConfig({}); // wrangler.jsonc { "name": "my-app", "pages_build_output_dir": ".open-next/assets", "compatibility_date": "2025-04-01", "compatibility_flags": ["nodejs_compat"] } 3. ビルド npx @opennextjs/cloudflare build 4. Pagesへのデプロイ(ここが最大のポイント) @opennextjs/cloudflare のビルド出力はWorkers向けですが、Pagesにデプロイするには以下の手順が必要です。 ...

AWS AmplifyからCloudflare Pagesへの移行 — Next.js APIサーバーの月額$23→$0化

Next.js製のAPIサーバーをAWS AmplifyからCloudflare Pagesに移行しました。月額約$23(Amplify $15 + WAF $8)のコストが$0になりました。 背景 移行前の構成 フレームワーク: Next.js 15(App Router) ホスティング: AWS Amplify(WEB_COMPUTE / SSR) WAF: Amplifyが自動作成したWebACL バックエンド: 外部のElasticsearchに接続するAPIルート 月額コスト: Amplify $15 + WAF $8 = 約$23/月 無料枠(12ヶ月)が切れた後、1アプリのSSRホスティングとしてはやや割高でした。特にWAFはAmplify作成時に自動的に有効化されており、$5/WebACL/月 + リクエスト課金で$8程度かかっていました。 なぜCloudflare Pagesか 項目 Amplify Vercel Cloudflare Pages SSR対応 有料 個人無料/チーム$20/人 無料 チーム利用 IAM管理 有料 無料 帯域 15GB後従量 100GB/月 無制限 カスタムドメイン CloudFront経由 簡単 CNAME設定で可能 VercelはNext.jsとの相性が最も良いですが、チーム利用は有料($20/ユーザー/月)です。Cloudflare Pagesは無料プランでもチーム・商用利用が可能で、帯域も無制限です。 移行手順 1. @opennextjs/cloudflare のインストール Cloudflare上でNext.jsを動かすために、@opennextjs/cloudflareを使います。 npm install --save-dev @opennextjs/cloudflare wrangler 2. open-next.config.ts の作成 プロジェクトルートに設定ファイルを作成します。 ...