Cloudflare のセキュリティ ルールでアクセス元を制限する


やりたかった事

OCI 上にデプロイした Redmine に対して、IP アドレス制限を設けたかった。
OCI の NSG やセキュリティ ルールを使えば実現できるんだけど、せっかく Cloudflare でドメイン名も購入しているので、そのドメインを使って Redmine にアクセスする。

Proxied の DNS 使うので、「Cloudflare のエッジ → OCI の LoadBalancer → Redmine (Container Instance)」という通信経路になる。

LoadBalancer 挟んでいるのは、Public IP を固定にしたかったから。

やった事

HTTPS で通信するためにオリジン証明書作成して OCI の LoadBalancer に割り当てる

Cloudflare の [SSL/TLS - オリジン サーバー] のページにて証明書を作成。
キーのタイプは RSA、ホスト名には Redmine のホスト名を指定。
公開証明書と秘密鍵が作成されるので、それぞれを origin.crt、origin.key としてローカルに保存。

あとは OCI の LoadBalancer に証明書を登録する。
自分は、下記のようなコマンドを叩いた。

oci --profile <プロファイル名> --region ap-tokyo-1 lb certificate create `
  --load-balancer-id <LoadBalancer の OCID> `
  --certificate-name redmine-origin-2026 `
  --public-certificate-file "origin.crt" `
  --private-key-file "origin.key" `
  --wait-for-state SUCCEEDED

その後、LoadBalancer に HTTPS リスナーを作成。
作成の際に、上記で登録した証明書を割り当てる。
結果こんな感じ。 alt text

その後は OCI 側のネットワーク セキュリティ ルールをゴニョゴニョ変更。
Cloudflare からの通信のみ許可するように変更した。
Cloudflare の IP アドレスリストはこちら。

登録するのがめんどくさいので、Codex にお願いして登録してもらった。
予め OCI CLI を使えるようにしているので、こういうところは便利。

Cloudflare DNS に A レコード追加

個人用のドメインを予め購入しているので、そのドメインに対して A レコードを追加。
A レコードには OCI LoadBalancer のパブリック IP を指定し、Proxied にする。
これで単なる名前解決じゃなくて、Cloudflare のエッジを経由して OCI LoadBalancer へ通信するようになる。

alt text

あとは、Cloudflare の SSL/TLS の設定を。
暗号化モードを “フル (厳格)” に設定したり、[SSL/TLS - エッジ証明書] のページにて “常に HTTPS を使用” を有効にしたり。

alt text

alt text

Cloudflare 側のセキュリティ ルールの設定

[セキュリティ - セキュリティ ルール] のページにてカスタム ルールを作成。
ルール名を適当に指定して、下記のようなルールを。

<受信リクエストが一致する場合...>
ホスト名 : 次と等しい : <Redmine のホスト名>
AND
送信元の IP アドレス : リストに含まれない : <通信を許可する IP リスト>

<実施するアクション>
ブロック

alt text

こんな感じでセキュリティ ルールを作ると、IP アドレス リストに登録していない IP からの通信をブロック可能。

<正常系 : 許可している IP アドレスからの通信>
アクセス出来る。 alt text

<例外系 : 許可していない IP アドレスからの通信>
アクセス出来ない。 alt text

menu