今回はCode Engine上のアプリにIP制限をかけ、特定の利用者へのみアプリ公開する方法を試してみたいと思います
IBM Cloud Code Engineのアプリはパブリックとプライベート、そしてプロジェクトと3タイプでアプリの公開範囲の設定ができますが、より細かな制御をするために今回はCloud Internet Service(CIS)と組み合わせてみます
事前準備
- 独自ドメイン
私はIBM Cloudでドメインを購入しました
https://cloud.ibm.com/classic/services/domains - CA証明書(中間証明書を含むfullchain)とプライベートキー
私はLet's Encryptでワイルドカードの証明書を発行しました
参考にしたqiita:https://qiita.com/F_clef/items/136d81223c030904523c
※自己証明書, CISのオリジン証明書は利用できません
設定の流れ
- Code Engineでアプリをデプロイ
- Code EngineでDomain Mappingを設定
- CISでドメインを登録
- CISでDNSレコードの登録
- CISでIPファイアウォールの設定
- 最終確認
1. Code Engineでアプリをデプロイ
まずは簡単なアプリをCode Engineにデプロイします
今回はサンプルアプリのコンテナイメージ ( icr.io/codeengine/helloworld ) をそのまま使っていきます
動作検証をスムーズにするため、1インスタンスだけで稼働し続けるようにしています
また課金を抑えるためにリソースは最低限のものを選択しました
デプロイが完了したので、実際にアプリにアクセスして稼働チェックしておきます
アプリのURLは、「アプリケーションのテスト」ボタンから取得できます
Hello Worldが表示され、アプリが稼働していることが確認できたので、次にすすみます
2. Code EngineでDomain Mappingを設定
次に、CIS経由でアクセスできるように、カスタム・ドメイン・マッピングを設定します
「ドメイン・マッピング」 の画面にて、 「作成」 をクリックします
「ドメイン・マッピングの作成」 ダイアログが表示されるので必要事項を入力します
- TLSシークレット
- 選択 or 作成:
- 作成:初めての登録、証明書がワイルドカードではない場合
- 選択:ワイルドカード証明書を利用している場合ですでに登録している場合は作成済みのSecretを選択する(同じワイルドカード証明書は同じリージョンに1つしか登録できないようです。別プロジェクトであっても同じリージョンでは利用できません)
- Certificate chain: 中間証明書を含むfullchainのCA証明書の内容
(let's encryptの場合はfullchain.pemの内容) - Private key: プライベートキーの内容
(let's encryptの場合はprivkey.pemの内容)
- 選択 or 作成:
- ドメイン名とターゲット・アプリケーション
- カスタム・ドメイン・ネーム: アプリ公開に利用したいURL(私はmyapp.handson-lab.comと指定)
- ターゲット・アプリケーション: ターゲットのCode Engineアプリを選択
- CNAME ターゲット:DNSの設定に使うのでコピーしておきます
状況が「デプロイ中」から「準備完了」になったらOKです
数分で完了するはずなので、かなり待ってもデプロイ中から進まない場合は登録している証明書の内容や鍵の確認をしてみてください
またワイルドカード証明書を利用している人は、同じプロジェクトで同じワイルドカード証明書を登録済みの状況で新たにTLS Secretを作成してしまっていないかや、同じリージョンの別プロジェクトですでにワイルドカード証明書を使っていないかチェックしてみてください
3. CISでドメインを登録
CISのインスタンス作成や、ドメインの登録の部分はこちらのQiitaをご参照ください
IBM Cloud CISの動作確認(1) -初期導入編- - Qiita
4. CISでDNSレコードの登録
Code Engineのドメイン・マッピングにて提供されたCNAME ターゲットを使ってDNS登録していきます
CISにて「信頼性」から「DNS」を選び、「DNSレコード」の「追加」をクリックします
「レコードの追加」ダイアログにて必要事項を入力します
- タイプ:CNAME
- 名前:Code Engineのカスタム・ドメインにて設定したドメイン名
(私の場合はmyapp.handson-lab.com) - 別名のドメイン名:Code Engineのカスタム・ドメイン設定時に表示されたCNAME ターゲット
(私の場合はcustom.z6qoi5aro6g.jp-tok.codeengine.appdomain.cloud)
無事にレコードが登録されました
この後IPファイアウォールを利用するので、プロキシーをONにしておきます
nslookupで確認し、以下のようなCISの宛先が返ってくることを確認します
# proxy-onでの期待結果
❯ nslookup myapp.handson-lab.com
Server: 2404:1a8:7f01:b::3
Address: 2404:1a8:7f01:b::3#53
Non-authoritative answer:
Name: myapp.handson-lab.com
Address: 172.67.31.110
Name: myapp.handson-lab.com
Address: 104.22.62.198
Name: myapp.handson-lab.com
Address: 104.22.63.198
# proxy-offだと以下のような結果が返ってきてしまいます
❯ nslookup myapp.handson-lab.com
Server: 2404:1a8:7f01:b::3
Address: 2404:1a8:7f01:b::3#53
Non-authoritative answer:
myapp.handson-lab.com canonical name = custom.z6qoi5aro6g.jp-tok.codeengine.appdomain.cloud.
custom.z6qoi5aro6g.jp-tok.codeengine.appdomain.cloud canonical name = s01.jp-tok.codeengine.appdomain.cloud.
s01.jp-tok.codeengine.appdomain.cloud canonical name = 163f4bf89dd14529ab332f76dd35b0eb.pacloudflare.com.
Name: 163f4bf89dd14529ab332f76dd35b0eb.pacloudflare.com
Address: 172.65.200.138
5. CISでIPファイアウォールの設定
それでは最後に、特定のIPからのみアクセスできるようにIPファイアウォールの設定をしていきます
今回はドメイン・ロックダウン機能をつかっていきます
各機能の違いはこちらを参考にしました IBM Cloud Internet Services (CIS) IP Firewallについて - Qiita
「ドメイン・ロックダウン・ルールの作成」ダイアログにて必要事項を入力します
- ルール名: わかりやすい名前
- URL:ファイアウォールを設定したいURL
- IPアドレスと範囲:許可したいIPアドレス(IPv4とIPv6両方書きます)
レコードが追加され、有効がONになっていることを確認します
これですべての設定が完了です!
6. 最終確認
最後にIP制御ができているかチェックしてみます
左側が、私のLocal環境からのアクセスで許可されたIPからのアクセスです
右側が、リモートデスクトップで接続している別拠点にあるRemote環境で、許可されていないIPからのアクセスです。
期待通り、許可していないIPからのアクセスは「Access denied」とブロックされました
補足-Code Engineの提供のパブリックエンドポイントは残す?残さない?
残しておくと、仮にパブリックのURLが知られた場合にダイレクトでアクセスされてしまうので、プライベートなどに変更することをおすすめします
パブリックのエンドポイントを無効化しました
左:インターネットからCode Engineが提供していたFQDNにアクセスすることができなくなりました
右:カスタムドメインマッピングで設定したドメインを使ってインターネットからアクセスできます
補足-2つ目以降のアプリでのカスタムドメインの設定方法
もう一つ、Helloworldアプリもカスタムドメインで公開してみます
手順はほぼ同じですが、ワイルドカード証明書を利用している場合はドメイン・マッピングの作成のTLSシークレットの部分だけ変わります
前回同様、「ドメイン・マッピング」の画面から作成をクリックします
ワイルドカードの証明書の場合はすでにTLS Secretが登録済みなので「TLSシークレット」は作成ではなく、選択を選びます。ワイルドカードではなく、個別に証明書を設定する場合(helloworld.handson-lab.com)はTLSシークレットの作成を選んで登録してください
ドメイン・マッピングの作成が完了後は初回同様に、CISからDNSレコードの追加を行います
CNAMEターゲットはCode Engineプロジェクトごとに割り振られているので、先程と同じCNAMEです
(同じCNAMEにですが、アクセスした際にヘッダー情報に含まれるアクセスURLを元にCode Engine側で適切なアプリにルーティングが行われます)
先程作ったものと並んでDNSレコードが登録できました。
そして最後に、IPファイアウォール設定を更新します
最後に確認のためアクセスします
(nginxのコンテナイメージをそのままデプロイしたので、見慣れたNginxの画面が表示されました)
参考リンク
- Code Engine
- Cloud Internet Service
- [IP ファイアウォール](