Cloudflare Zero TrustでEC2のWebアプリケーションアクセスを制限する

🚀 はじめに

EC2で立てたサーバに対してアクセス制限を付ける方法として手軽なBASIC認証がある。
ただし、BASIC認証ではID/パスワードが漏洩してしまうとアクセス可能となってしまう。
そこで、Cloudflare Zero Trustを使用することで、安全にWebアプリケーションアクセス制御を実現してみる。
今回は、Cloudflare TunnelAccessを組み合わせてEC2上のWebアプリケーションへのHTTP/HTTPSアクセスを制限する方法を試してみる。

✅ Zero Trustアプローチの利点

  • 🚫 パブリックIPの非公開: EC2インスタンスに直接アクセス可能なパブリックIPが不要
  • 🔐 統合認証: 企業のIDプロバイダーとの連携による強固な認証
  • 📊 監査ログ: すべてのWebアクセスが記録される
  • 🌍 場所に依存しないアクセス: どこからでも安全にアクセス可能
  • ⚙️ アクセス制御: URL、メソッド、ユーザーグループなどによる詳細な制御
  • 🛡️ DDoS保護: Cloudflareの強力なDDoS対策を活用

💻 環境

AWS EC2
Cloudflare Zero Trust Account
Cloudflare Tunnel (cloudflared)

📋 前提条件

  • AWS アカウント
  • AWS EC2上で稼働中のWebアプリケーション
  • セキュリティグループの設定(内部通信のみ)
  • Cloudflare DNS管理

⚙️準備

EC2のセットアップ

以下で作成を行う。

項目設定値
名前server
OSAmazonLinux2023 AMI
アーキテクチャ64ビット(Arm)
インスタンスタイプt4g.nano
キーペアserver(新規で作成)
セキュリティグループssh,http,https (自分のIPのみ)
ストレージ8GB (gp3)

Apacheのインストール

# パッケージリストの更新
sudo dnf update -y

# Apacheのインストール
sudo dnf install -y httpd

# Apacheサービスの開始
sudo systemctl start httpd

# 自動起動の設定
sudo systemctl enable httpd

# サービス状態の確認
sudo systemctl status httpd

# 簡単なテストページの作成
sudo tee /var/www/html/index.html << 'EOF'
<!DOCTYPE html>
<html>
<head>
  <title>Test Page</title>
</head>
<body>
  <h1>Apache Test Page</h1>
  <p>Server is running successfully!</p>
</body>
</html>
EOF
ログ
[ec2-user@ip-172-31-42-226 ~]$ sudo dnf update -y
Amazon Linux 2023 Kernel Livepatch repository                               119 kB/s |  15 kB     00:00
Dependencies resolved.
Nothing to do.
Complete!
[ec2-user@ip-172-31-42-226 ~]$ sudo dnf install -y httpd
Last metadata expiration check: 0:00:08 ago on Sun Jun 15 08:52:11 2025.
Dependencies resolved.
============================================================================================================
 Package                      Architecture     Version                           Repository            Size
============================================================================================================
Installing:
 httpd                        aarch64          2.4.62-1.amzn2023                 amazonlinux           48 k
Installing dependencies:
 apr                          aarch64          1.7.5-1.amzn2023.0.4              amazonlinux          126 k
 apr-util                     aarch64          1.6.3-1.amzn2023.0.1              amazonlinux          100 k
 generic-logos-httpd          noarch           18.0.0-12.amzn2023.0.3            amazonlinux           19 k
 httpd-core                   aarch64          2.4.62-1.amzn2023                 amazonlinux          1.4 M
 httpd-filesystem             noarch           2.4.62-1.amzn2023                 amazonlinux           14 k
 httpd-tools                  aarch64          2.4.62-1.amzn2023                 amazonlinux           81 k
 libbrotli                    aarch64          1.0.9-4.amzn2023.0.2              amazonlinux          316 k
 mailcap                      noarch           2.1.49-3.amzn2023.0.3             amazonlinux           33 k
Installing weak dependencies:
 apr-util-openssl             aarch64          1.6.3-1.amzn2023.0.1              amazonlinux           17 k
 mod_http2                    aarch64          2.0.27-1.amzn2023.0.3             amazonlinux          161 k
 mod_lua                      aarch64          2.4.62-1.amzn2023                 amazonlinux           59 k

Transaction Summary
============================================================================================================
Install  12 Packages

Total download size: 2.3 M
Installed size: 27 M
Downloading Packages:
(1/12): apr-util-openssl-1.6.3-1.amzn2023.0.1.aarch64.rpm                   400 kB/s |  17 kB     00:00
(2/12): apr-util-1.6.3-1.amzn2023.0.1.aarch64.rpm                           1.7 MB/s | 100 kB     00:00
(3/12): apr-1.7.5-1.amzn2023.0.4.aarch64.rpm                                1.9 MB/s | 126 kB     00:00
(4/12): generic-logos-httpd-18.0.0-12.amzn2023.0.3.noarch.rpm               807 kB/s |  19 kB     00:00
(5/12): httpd-filesystem-2.4.62-1.amzn2023.noarch.rpm                       557 kB/s |  14 kB     00:00
(6/12): httpd-2.4.62-1.amzn2023.aarch64.rpm                                 1.2 MB/s |  48 kB     00:00
(7/12): httpd-core-2.4.62-1.amzn2023.aarch64.rpm                             26 MB/s | 1.4 MB     00:00
(8/12): mailcap-2.1.49-3.amzn2023.0.3.noarch.rpm                            1.5 MB/s |  33 kB     00:00
(9/12): httpd-tools-2.4.62-1.amzn2023.aarch64.rpm                           1.5 MB/s |  81 kB     00:00
(10/12): libbrotli-1.0.9-4.amzn2023.0.2.aarch64.rpm                         5.0 MB/s | 316 kB     00:00
(11/12): mod_lua-2.4.62-1.amzn2023.aarch64.rpm                              2.3 MB/s |  59 kB     00:00
(12/12): mod_http2-2.0.27-1.amzn2023.0.3.aarch64.rpm                        3.7 MB/s | 161 kB     00:00
------------------------------------------------------------------------------------------------------------
Total                                                                        11 MB/s | 2.3 MB     00:00
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
  Preparing        :                                                                                    1/1
  Installing       : apr-1.7.5-1.amzn2023.0.4.aarch64                                                  1/12
  Installing       : apr-util-openssl-1.6.3-1.amzn2023.0.1.aarch64                                     2/12
  Installing       : apr-util-1.6.3-1.amzn2023.0.1.aarch64                                             3/12
  Installing       : mailcap-2.1.49-3.amzn2023.0.3.noarch                                              4/12
  Installing       : httpd-tools-2.4.62-1.amzn2023.aarch64                                             5/12
  Installing       : libbrotli-1.0.9-4.amzn2023.0.2.aarch64                                            6/12
  Running scriptlet: httpd-filesystem-2.4.62-1.amzn2023.noarch                                         7/12
  Installing       : httpd-filesystem-2.4.62-1.amzn2023.noarch                                         7/12
  Installing       : httpd-core-2.4.62-1.amzn2023.aarch64                                              8/12
  Installing       : mod_http2-2.0.27-1.amzn2023.0.3.aarch64                                           9/12
  Installing       : mod_lua-2.4.62-1.amzn2023.aarch64                                                10/12
  Installing       : generic-logos-httpd-18.0.0-12.amzn2023.0.3.noarch                                11/12
  Installing       : httpd-2.4.62-1.amzn2023.aarch64                                                  12/12
  Running scriptlet: httpd-2.4.62-1.amzn2023.aarch64                                                  12/12
  Verifying        : apr-1.7.5-1.amzn2023.0.4.aarch64                                                  1/12
  Verifying        : apr-util-1.6.3-1.amzn2023.0.1.aarch64                                             2/12
  Verifying        : apr-util-openssl-1.6.3-1.amzn2023.0.1.aarch64                                     3/12
  Verifying        : generic-logos-httpd-18.0.0-12.amzn2023.0.3.noarch                                 4/12
  Verifying        : httpd-2.4.62-1.amzn2023.aarch64                                                   5/12
  Verifying        : httpd-core-2.4.62-1.amzn2023.aarch64                                              6/12
  Verifying        : httpd-filesystem-2.4.62-1.amzn2023.noarch                                         7/12
  Verifying        : httpd-tools-2.4.62-1.amzn2023.aarch64                                             8/12
  Verifying        : libbrotli-1.0.9-4.amzn2023.0.2.aarch64                                            9/12
  Verifying        : mailcap-2.1.49-3.amzn2023.0.3.noarch                                             10/12
  Verifying        : mod_http2-2.0.27-1.amzn2023.0.3.aarch64                                          11/12
  Verifying        : mod_lua-2.4.62-1.amzn2023.aarch64                                                12/12

Installed:
  apr-1.7.5-1.amzn2023.0.4.aarch64                   apr-util-1.6.3-1.amzn2023.0.1.aarch64
  apr-util-openssl-1.6.3-1.amzn2023.0.1.aarch64      generic-logos-httpd-18.0.0-12.amzn2023.0.3.noarch
  httpd-2.4.62-1.amzn2023.aarch64                    httpd-core-2.4.62-1.amzn2023.aarch64
  httpd-filesystem-2.4.62-1.amzn2023.noarch          httpd-tools-2.4.62-1.amzn2023.aarch64
  libbrotli-1.0.9-4.amzn2023.0.2.aarch64             mailcap-2.1.49-3.amzn2023.0.3.noarch
  mod_http2-2.0.27-1.amzn2023.0.3.aarch64            mod_lua-2.4.62-1.amzn2023.aarch64

Complete!
[ec2-user@ip-172-31-42-226 ~]$ sudo systemctl start httpd
[ec2-user@ip-172-31-42-226 ~]$ sudo systemctl enable httpd
Created symlink /etc/systemd/system/multi-user.target.wants/httpd.service → /usr/lib/systemd/system/httpd.service.
[ec2-user@ip-172-31-42-226 ~]$ sudo systemctl status httpd
● httpd.service - The Apache HTTP Server
     Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; preset: disabled)
     Active: active (running) since Sun 2025-06-15 08:52:28 UTC; 6s ago
       Docs: man:httpd.service(8)
   Main PID: 12495 (httpd)
     Status: "Started, listening on: port 80"
      Tasks: 177 (limit: 404)
     Memory: 30.4M
        CPU: 74ms
     CGroup: /system.slice/httpd.service
             ├─12495 /usr/sbin/httpd -DFOREGROUND
             ├─13020 /usr/sbin/httpd -DFOREGROUND
             ├─13022 /usr/sbin/httpd -DFOREGROUND
             ├─13023 /usr/sbin/httpd -DFOREGROUND
             └─13024 /usr/sbin/httpd -DFOREGROUND

Jun 15 08:52:27 ip-172-31-42-226.ap-northeast-1.compute.internal systemd[1]: Starting httpd.service - The A>
Jun 15 08:52:28 ip-172-31-42-226.ap-northeast-1.compute.internal systemd[1]: Started httpd.service - The Ap>
Jun 15 08:52:28 ip-172-31-42-226.ap-northeast-1.compute.internal httpd[12495]: Server configured, listening>
[ec2-user@ip-172-31-42-226 ~]$ sudo tee /var/www/html/index.html << 'EOF'
<!DOCTYPE html>
<html>
<head>
  <title>Test Page</title>
</head>
<body>
  <h1>Apache Test Page</h1>
  <p>Server is running successfully!</p>
</body>
</html>
EOF
<!DOCTYPE html>
<html>
<head>
  <title>Test Page</title>
</head>
<body>
  <h1>Apache Test Page</h1>
  <p>Server is running successfully!</p>
</body>
</html>

アクセス確認

OK!

install-apache-01

🛠️ 設定手順

Cloudflare Zerotrustプランの購入

Zero Trustダッシュボードにアクセス

Cloudflare にアクセスをし「Zero trust」を選択する。

setup-cloudflare-zerotrust-01

チーム名を入力する

一旦、kbushi とした。

setup-cloudflare-zerotrust-02

プランを選択する

今回はお試しということで、Freeプランを選択する。

setup-cloudflare-zerotrust-03

支払いへ進む

内容を確認して、「支払いへ進む」を選択する。

setup-cloudflare-zerotrust-04

※この後のステップで購入まで進める。

Cloudflare Tunnelの作成

Cloudflare Zero Trustダッシュボードへアクセスをする。

トンネルを追加する

  1. 「ネットワーク」→「Tunnels」で「トンネルを追加する」を選択する。 create-cloudflare-tunnel-01
  2. 「選択するCloudflared」を選択する。 create-cloudflare-tunnel-02
  3. トンネル名を入力して、「トンネルを保存」を選択する。 create-cloudflare-tunnel-03

Connectorのセットアップ

表示されたコマンドをコピーし、EC2インスタンスで実行する

# cloudflaredのインストール
# Add cloudflared.repo to /etc/yum.repos.d/ 
curl -fsSl https://pkg.cloudflare.com/cloudflared-ascii.repo | sudo tee /etc/yum.repos.d/cloudflared.repo

#update repo
sudo yum update

# install cloudflared
sudo yum install cloudflared

この後、以下を実行してサービスを起動する。

sudo cloudflared service install [トークン]
create-cloudflare-tunnel-04
ログ
[ec2-user@ip-172-31-42-226 ~]$ curl -fsSl https://pkg.cloudflare.com/cloudflared-ascii.repo | sudo tee /etc/yum.repos.d/cloudflared.repo
[cloudflared-stable]
name=cloudflared-stable
baseurl=https://pkg.cloudflare.com/cloudflared/rpm
enabled=1
type=rpm
gpgcheck=1
gpgkey=https://pkg.cloudflare.com/cloudflare-ascii-pubkey.gpg

[ec2-user@ip-172-31-42-226 ~]$ sudo yum update
cloudflared-stable                                                          1.9 kB/s | 1.6 kB     00:00
Dependencies resolved.
Nothing to do.
Complete!

[ec2-user@ip-172-31-42-226 ~]$ sudo yum install cloudflared
Last metadata expiration check: 0:00:07 ago on Sun Jun 15 09:11:07 2025.
Dependencies resolved.
============================================================================================================
 Package                 Architecture        Version                   Repository                      Size
============================================================================================================
Installing:
 cloudflared             aarch64             2025.6.0-1                cloudflared-stable              18 M

Transaction Summary
============================================================================================================
Install  1 Package

Total download size: 18 M
Installed size: 37 M
Is this ok [y/N]: y
Downloading Packages:
cloudflared-linux-aarch64.rpm                                                21 MB/s |  18 MB     00:00
------------------------------------------------------------------------------------------------------------
Total                                                                        21 MB/s |  18 MB     00:00
cloudflared-stable                                                          2.5 kB/s | 967  B     00:00
Importing GPG key 0x8CACCBF8:
 Userid     : "CloudFlare Software Packaging <[email protected]>"
 Fingerprint: FBA8 C0EE 6361 7C5E ED69 5C43 254B 391D 8CAC CBF8
 From       : https://pkg.cloudflare.com/cloudflare-ascii-pubkey.gpg
Is this ok [y/N]: y
Key imported successfully
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
  Preparing        :                                                                                    1/1
  Installing       : cloudflared-2025.6.0-1.aarch64                                                     1/1
  Running scriptlet: cloudflared-2025.6.0-1.aarch64                                                     1/1
  Verifying        : cloudflared-2025.6.0-1.aarch64                                                     1/1

Installed:
  cloudflared-2025.6.0-1.aarch64

Complete!

[ec2-user@ip-172-31-42-226 ~]$ sudo cloudflared service install [トークン]
2025-06-15T09:11:29Z INF Using Systemd
2025-06-15T09:11:30Z INF Linux service for cloudflared installed successfully

HTTP/HTTPS接続の設定

パブリックホスト名を追加する

「Tunnels」→設定→「パブリックホスト」のタブを選択する。
「パブリックホスト名を追加する」を選択する。

setup-cloudflare-publichost-01

パブリックホスト名の設定

Tunnelの設定で以下を追加する

Public hostname: trust.k-bushi.com
Service: http://localhost

とした。

「保存」を選択する。

setup-cloudflare-publichost-02

アクセス確認

setup-cloudflare-publichost-03 setup-cloudflare-publichost-04

DNS設定の確認

CloudflareのDNS管理画面で、自動的に作成されたCNAMEレコードを確認する:

タイプ名前ターゲットプロキシステータス
CNAMEtrust[UUID]プロキシ済み
setup-cloudflare-publichost-05

Accessポリシーの作成

Web Applicationの作成

  1. 「Access」→「アプリケーション」→「アプリケーションを追加する」を選択する。 cloudflare-accesspolicy-01
  2. セルフホストを選択する。 cloudflare-accesspolicy-02

Access Policyの作成

「ポリシーを追加する」を選択する。
cloudflare-accesspolicy-03

ポリシー名、アクション、セッション時間を入力する。
ルールを追加するにて、以下を設定する。

Include

  • セレクタ: Email
  • 値: [認証画面でアクセス時に認証コードを受け取るメールアドレス]
cloudflare-accesspolicy-04

WebApplicationの作成2

  1. アプリケーション名、セッション時間を設定
  2. パブリックホスト名を追加で今回の対象のドメインを入力する。
  3. Accessポリシーは作成したものを選択する。
    cloudflare-accesspolicy-05
  4. デフォルトで設定する。 cloudflare-accesspolicy-06
  5. デフォルトで「保存」とする。
    cloudflare-accesspolicy-07

アクセステスト

AWS EC2のセキュリティグループにて、http, httpsを許可しているインバウンドグループを外す。

Webアプリケーションへのアクセス

ブラウザで 設定したドメイン にアクセスする。
(今回は https://trust.k-bushi.com となる。)

認証フロー

  1. Cloudflare Access認証画面が表示される。
    access-application-01
  2. メールアドレスを入力する。
  3. 以下のメールが受信できる。
    access-application-02
  4. 認証コードを入力して「Sign in」を選択する。
    access-application-03
  5. 認証成功後、Webアプリケーションが表示される。
    access-application-04

✅ 設定確認チェックリスト

  • EC2 Security Group:

    • Inbound: 必要最小限のポートのみ開放
    • Outbound: 443 (HTTPS) to 0.0.0.0/0 が許可
  • Cloudflare DNS:

    • CNAME レコードが正しく設定
    • Proxy status が有効
  • Tunnel Configuration:

    • Public hostname が正しく設定
    • Service URL が正しい
    • cloudflared サービスが起動中
  • Access Application:

    • Domain が DNS設定と一致
    • Policies が適切に設定

📚 参考

🎯 おわりに

Cloudflare Zero TrustTunnelを組み合わせることで、Cloudflare経由でのアクセス認証ができた。
公開したくないステージング環境、テスト環境などで利用できそうだ。
今後使える手段として覚えておこうと思う。

Hugo で構築されています。
テーマ StackJimmy によって設計されています。