OCI 2台のバックエンドサーバにロードバランシングさせてみる（ネットワーク・セキュリティ・グループ利用）

# はじめに
OCIでFLB (フレキシブルロードバランサ)の後ろに2台バックエンドサーバを配置し、http(80)でブラウザからアクセスしてみる。
各バックエンドサーバでは、必要となるApacheのインストールやOS上のファイアウォールの設定、ブラウザアクセス時に返却する静的ファイルの作成も行ってみる。

少し余談だが、よくある構成として、パブリックサブネットにFLBを配置し、プライベートサブネットにバックエンドサーバを配置する構成があるが、今回はパブリックサブネットにFLBおよびバックエンドサーバを配置し、バックエンドサーバにはインターネットから直接アクセスできないようにセキュリティルールを構成している。

# ゴール

ここでは、以下のようなOCI上の構成を構築する。
VM1とVM2に対して、ランダムにロードバランシングされることを確認する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588872/6e6a9cbf-f425-3f75-89a2-17ba77938f73.png)



# VCN作成
### ウィザード利用して作成
「ナビゲーション・メニュー」→「ネットワーキング」→「仮想クラウド・ネットワーク」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588872/f84cedad-f6ec-583b-89d5-3a395153d0c8.png)

「VCNウィザードの起動」をクリック。
「インターネット接続性を持つVCNの作成」を選択し、「VCNウィザードの起動」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588872/e8eae47a-9f56-1ba2-6657-cbab1ab2cb69.png)

以下のようなVCNを構築する。
- VCN名：VCN-WAF　※任意
- コンパートメント：(ご自身のコンパートメント)
- VCN CIDRブロック：10.0.0.0/16　※任意のためデフォルトのままでよい
- パブリック・サブネットCIDRブロック：10.0.0.0/24　※任意のためデフォルトのままでよい
- プライベート・サブネットCIDRブロック：10.0.1.0/24　※任意のためデフォルトのままでよい
- DNS解決：チェック　※任意のためデフォルトのままでよい

 「次」をクリック。



 確認および作成にて、「作成」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588872/c420a10e-65ea-d72b-eb53-5922ba928ff8.png)


各リソースが順に作成され、作成完了したら、仮想クラウド・ネットワークの表示をクリック。
以下のようになっていれば作成完了。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588872/91c18c1d-cdc0-7280-7e06-35c851082f1a.png)

 
# コンピュート・インスタンス作成
### コンピュート・インスタンスを２つ作成
「ナビゲーション・メニュー」→「コンピュート」→「インスタンス」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588872/81074ebd-b5e3-31e3-5e7e-808dc8d31fea.png)

「インスタンスの作成」をクリックして、パブリックサブネットにコンピュートを2台作成する。

 - 1台目
    - インスタンス名：VM1
    - イメージ：Oracle Linux 8
    - Shape：VM.Standard.E4.Flex (1 core OCPU, 4 GB memory)
    - VCN：先ほど作成したVCN-WAF
    - サブネット：先ほど作成したパブリックサブネットVCN-WAF(リージョナル)
    - パブリックIPv4アドレス：パブリックIPv4アドレスの自動割当て
    - SSHキーの追加：「キー・ペアを自動で生成」、「公開キー・ファイル(.pub)のアップロード」、「公開キーの貼付け」いずれの方法でも問題なし

「作成」をクリック。

 - 2台目
    - インスタンス名：VM2
    - イメージ：Oracle Linux 8
    - Shape：VM.Standard.E4.Flex (1 core OCPU, 4 GB memory)
    - VCN：先ほど作成したVCN-WAF
    - サブネット：先ほど作成したパブリックサブネットVCN-WAF(リージョナル)
    - パブリックIPv4アドレス：パブリックIPv4アドレスの自動割当て
    - SSHキーの追加：「キー・ペアを自動で生成」、「公開キー・ファイル(.pub)のアップロード」、「公開キーの貼付け」いずれの方法でも問題なし

「作成」をクリック。

状態が実行中となったら作成完了。



### コンピュート・インスタンスにログイン
OCI コンソール・ヘッダーの右側にある「開発者ツール」アイコンをクリックし、「Cloud Shell」を起動する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588872/90e8eb3d-9b97-50ba-724b-322a065b1b38.png)


起動後、まずはVM1のコンピュート・インスタンスに対して、sshでログインする（以下のコマンド参考）。
~~~bash:
$ ssh -i [private_key_file] opc@ [public-ip-address of VM1]
~~~

なお、事前にインスタンスに関連付けた秘密キー private_key_file を Cloud Shell へアップロードが必要だが、
~~~bash:
chmod 400 [private_key_file]
~~~
で権限を変更した上でsshコマンド実行する流れになる（644とかだとログインできない）。


ssh -i コマンドを実行すると、
~~~bash:
Are you sure you want to continue connecting (yes/no)? 
~~~
と聞かれるため、yesと入力し実行する。
プロンプトが以下のように変われば、これでVM1のコンピュート・インスタンスにログインできた状態になる。

~~~bash:
[opc@vm1 ~]$
~~~

### Apacheインストール

Apache のインストールする。完了するとComplete! と出力された。
~~~bash:
$ sudo yum -y install httpd

Ksplice for Oracle Linux 8 (x86_64)                                                                                                                                                       53 MB/s | 5.1 MB     00:00    
MySQL 8.0 for Oracle Linux 8 (x86_64)                                                                                                                                                     44 MB/s | 3.6 MB     00:00    
MySQL 8.0 Tools Community for Oracle Linux 8 (x86_64)                                                                                                                                     12 MB/s | 634 kB     00:00    
MySQL 8.0 Connectors Community for Oracle Linux 8 (x86_64)  

・
・
・
Installed:
  apr-1.6.3-12.el8.x86_64                                                 apr-util-1.6.1-9.el8.x86_64                                        apr-util-bdb-1.6.1-9.el8.x86_64                                             
  apr-util-openssl-1.6.1-9.el8.x86_64                                     httpd-2.4.37-62.0.1.module+el8.9.0+90011+2f9c6a23.x86_64           httpd-filesystem-2.4.37-62.0.1.module+el8.9.0+90011+2f9c6a23.noarch         
  httpd-tools-2.4.37-62.0.1.module+el8.9.0+90011+2f9c6a23.x86_64          mod_http2-1.15.7-8.module+el8.9.0+90011+2f9c6a23.3.x86_64          oracle-logos-httpd-84.5-1.0.2.el8.noarch                                    

Complete!
~~~

Apache を有効にして、Apache 再起動する。
~~~bash:
$ sudo systemctl enable httpd
Created symlink /etc/systemd/system/multi-user.target.wants/httpd.service → /usr/lib/systemd/system/httpd.service.

$ sudo systemctl restart httpd
$ 
~~~

 Apache 再起動完了。

のちほどブラウザからアクセスしたときに分かりやすくするために、index ファイル(静的ファイル)を作成しておく。

~~~bash:
$ sudo bash -c 'echo You are visiting Web Server 1 >> /var/www/html/index.html'

$ cat /var/www/html/index.html
You are visiting Web Server 1
~~~

### OS上のファイアウォール設定
ポート80 の通信を許可するファイアウォール・ルールを作成し、リロードする。
~~~bash:
$ sudo firewall-cmd --list-all　　　# 現在の状況確認
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens3
  sources: 
  services: dhcpv6-client ssh
  ports: 
  protocols: 
  forward: no
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 

$ sudo firewall-cmd --permanent --add-port=80/tcp　　　# ポート80 の通信を許可するルール追加(恒久的に反映)
success

$ sudo firewall-cmd --reload 　　　# 恒久反映の時にはリロードが必要
success

$ sudo firewall-cmd --list-all　　　# 変更後の状況確認
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens3
  sources: 
  services: dhcpv6-client ssh
  ports: 80/tcp　　　　　　　　　　<----------ルールが追加されていることが確認できる
  protocols: 
  forward: no
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 
$ 
~~~


続いて、VM2にsshログインし、ApacheインストールおよびOS上のファイアウォール設定を行う。
ここでは繰り返しになるため、省略する。


# FLB作成
### ネットワーク・セキュリティ・グループ作成
作成したVCNにネットワーク・セキュリティ・グループを新規作成する。
このNSGは後続で作成するロードバランサのセキュリティルールを制御するために利用する。

「ナビゲーション・メニュー」→「ネットワーキング」→「仮想クラウド・ネットワーク」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588872/f84cedad-f6ec-583b-89d5-3a395153d0c8.png)

VCNのリストから、「VCN-WAF」をクリックする。
左側のナビゲーション・ペインの「リソース」の下の「ネットワーク・セキュリティ・グループ」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588872/c69fb177-ff9b-4a26-50e6-f56802767df7.png)

「ネットワーク・セキュリティ・グループの作成」をクリックし、以下の内容で作成する。
- 基本情報
    - 名前：FLB-NSG　※任意
    - コンパートメント：(ご自身のコンパートメント)
- セキュリティ・ルール
    - ステートレス：チェックしない
    - 方向：イングレス
    - ソースタイプ：CIDR
    - ソースCIDR：念のため、インターネット経由でFLBにアクセスする際のグローバルIP
    - IPプロトコル：TCP
    - ソースポート：ALL
    - 宛先ポート：80
    - 説明：任意 

<!--  "エグレスルールは無くてもできるので書かないことにした"
- セキュリティ・ルール
    - ステートレス：チェックしない
    - 方向：エグレス
    - ソースタイプ：CIDR
    - ソースCIDR：0.0.0.0/0
    - IPプロトコル：TCP
    - ソースポート：ALL
    - 宛先ポート：ALL
    - 説明：任意 
「作成」をクリックする。
-->

### <参考> ネットワーク・セキュリティ・グループおよびセキュリティ・リスト
セキュリティルールを制御する方法として、セキュリティ・リストを利用する方法もあるが、サブネット単位のセキュリティ制御となり、インスタンスとFLBとでそれぞれサブネットを分けて配置し、それぞれのセキュリティ・リストで制御するのがよりセキュアだと思われる。
一方でNSGはVNIC単位での制御になるため、同一サブネットに配置されていても、VNICごとに細かくセキュリティ制御することができる。

| 制御方式 | 適用範囲 | ルール定義数|設定数|
|-----------|------------|------------|-----|
| ネットワーク・セキュリティ・グループ| VNIC|120| 1VNICに5つ |
| セキュリティ・リスト| サブネット|200| 1サブネットに5つ|

2023.12時点

どちらのやり方でも良いが、今回はNSGを利用している。

### FLB作成
パブリックロードバランサを作成し、作成済のインスタンスをバックエンドサーバーに追加する。
「ナビゲーション・メニュー」→「ネットワーキング」→「ロード・バランサ」の下の「ロード・バランサ」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588872/b74a0240-61b9-3b53-fcec-4dbe3db50b11.png)

「ロード・バランサの作成」をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588872/5e62542a-b096-a85a-a3c6-bfe721006a89.png)
それぞれ以下のように設定する。
- 「詳細の追加」セクション：
    - ロード・バランサ名：任意
    - 可動性タイプの選択：パブリック
    - パブリックIP アドレスの割当て：エフェメラルIP アドレス
    - シェイプ：フレキシブル・シェイプ
    - 最小帯域幅の選択：10 Mbps
    - 仮想クラウド・ネットワーク：VCN-WAF
    - サブネット：作成したパブリックサブネットVCN-WAF(リージョナル)
    - ネットワーク・セキュリティ・グループを使用してトラフィックを制御：チェックする
    - ネットワーク・セキュリティ・グループ：作成したFLB-NSG

- 「バックエンドの選択」セクション：
    - ロード・バランシング・ポリシーの指定：重み付けラウンド・ロビン
    - バックエンドの追加より、作成したコンピュート・インスタンス(VM1、VM2)を追加する
    - ヘルス・チェック・ポリシーの指定
        - プロトコル：HTTP
        - ポート：80
        - URL パス(URI)：/

- 「リスナーの構成」セクション：
    - リスナー名：任意
    - リスナーが処理するトラフィックのタイプの指定: HTTP
    - リスナーがイングレス・トラフィックをモニターするポートを指定します: 80

- 「ロギングの管理」セクション：
    - エラー・ログ：無効　※任意
    - アクセス・ログ：無効　※任意

「送信」をクリック。


### FLB経由でインターネットからアクセスできるか確認
ロード・バランサがアクティブになったら、パブリックIP アドレスをコピーしておき、
ブラウザを開き、以下URLのように入力する。
~~~bash:
http://[Public IP of FLB]
~~~
複数回実行し、VM1とVM2のそれぞれのindex.html のテキストが表示されることおよびFLBでロードバランシングされること含めて確認する。

実際にアクセスしてみると、現状は以下のように出力される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588872/2e4ff1b1-cf04-6c18-cf43-51a071e325c8.png)



# まとめ
OCIでフレキシブルロードバランサの後ろに2台バックエンドサーバを配置し、http(80)でブラウザからアクセスしてみた。
各バックエンドサーバで、ApacheのインストールやOS上のファイアウォールの設定、ブラウザアクセス時に返却する静的ファイルの作成も行った。
VM1とVM2に対して、ランダムにロードバランシングされることを確認ができた。

また以下についても記述した。
- [ネットワーク・セキュリティ・グループおよびセキュリティ・リスト](#-参考-ネットワーク・セキュリティ・グループおよびセキュリティ・リスト)


# 今後
ここで構成した環境に対してOCI WAFポリシーを適用することでインターネットアクセスに対するセキュリティ強化を図ってみたいと思う。
- [OCI WAFポリシーでセキュリティ強化してみる](https://qiita.com/ramtan0522/items/aa4f55d5b13655c6c024)