Oracle Cloudが永遠に無料らしいので開発環境を作ってみたかった (ネットワーク編)

前回でDBサーバも無事に作成できたので、ここからはそのDBサーバにアクセスできるようなAPサーバを構築することを目指します。
その前段階として、まずはDBサーバと疎通可能なネットワーク環境を構築します。

1. [準備編](https://qiita.com/mokkan/items/cc1b6b3ca04c105e807a)
2. [DBサーバ編](https://qiita.com/mokkan/items/0dea4a2f35ed4d28e167)
3. ネットワーク編 <- いまここ
4. [APサーバ編](https://qiita.com/mokkan/items/875b666de20ab96b4b2e)

ネットワーク環境はほぼほぼ自動構築に任せることも出来るのですが、実際には作成するAPサーバにも何かしらのサーバソフトウェアをインストールして外部からのアクセスを待ち受けることが想定できるため、ある程度手動でカスタマイズができるように、ネットワークの構成も理解しつつ進めることを目的とします。

※とはいえ自動構築に任せても基本的に問題ないのでここは無視してAPサーバ編に進んでいただいても問題ありません
自動構築の内容については下記のドキュメントを参照ください。
https://docs.oracle.com/cd/E97706_01/Content/GSG/Tasks/creatingnetwork.htm#two

## ネットワーク構成(ざっくり)
最初にOCIのネットワーク構成についてざっくりと説明します。
登場人物は多いですがあまり難しいことはないので、とりあえずふわっと全体像をつかんでもらえればと思います。

まずはVCN(Virtual Cloud Network)というものを用意します。
これは、クラウド上に作成する自分専用のネットワークです。このVCNの上にネットワーク環境を構築していきます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512576/e69becf3-9f23-3f4d-e7f7-ecc79d8dc4ca.png" width="50%">

次はSubnetを作成します。
これは、VCNの上に作成するより小さな区画のようなものだと思ってください。このSubnetの単位でいろいろとネットワークを制御していきます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512576/f99ef2b6-cda7-025b-f6d5-d5aa9b62eca3.png" width="50%">

ここで今後の解説をわかりやすくするために、仮想マシンも1つ作成しておきます。
OCI上に作成する仮想マシンはVNICと呼ばれる仮想のネットワークインターフェースを持ち、そのVNICでVCNに接続します。また、VNICは必ずいずれかのSubnetに所属し、そのSubnetの設定が適用されます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512576/ee96d1ee-2484-cf67-f18d-70fa13a63e9c.png" width="50%">

基本的な構成は出揃ったので、ここからより詳細なネットワークの構築を行っていきます。

まずはInternet Gatewayを作成します。
これは文字通りVCNからインターネットに出ていくための出入口になります。VCNは内部で閉じたネットワークなので、これが無いと外部との通信が出来なくなります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512576/297070d9-ac21-e888-6ae4-154892b86502.png" width="50%">

次はRoute Tableです。
これはSubnet内のルーティングを決定します。(～のIPアドレスはどこどこにルーティングする的なやつです)
Internet Gatewayを作成するだけでは外部との通信は不可能で、ちゃんと内部の通信がそのゲートウェイに向かうように設定する必要があります。このRoute Tableでそのための設定を実施します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512576/86667c26-8707-4487-71e4-d57c94dffd0d.png" width="50%">

最後はSecurity Listです。
これは、Subnet内のVNICについて一括でFirewallを設定します。(～の通信を許可するとか許可しないとかの設定です)
注意する点としては、Subnet内部の通信がデフォルトで許可されているというようなことはなく、内部の通信も明示的に許可するルールを書く必要があるということです。
(オンプレミスのネットワークの感覚で行くと高確率ではまるポイントだと思っています)

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512576/758943e7-b9dd-46d8-5050-aa75a359b74c.png" width="50%">

ざっくりとした構成の説明は以上です。
これを踏まえて、それぞれについてもう少し細かく見ていきつつ構築していきたいと思います。

## ネットワーク構築
では実際にネットワークを構築していきたいと思います。
ネットワークに関する事前知識が無い状態でもそれなりに理解できることを目指したいので、ちょくちょくOCIに拠らないネットワーク用語の解説も挟んでいきたいと思います。

### VCN
まず最初にVCN(Virtual Cloud Network)を作ります。
これはOCI上に作る仮想のプライベートネットワークです。プライベートネットワークというのは、インターネットに公開されていない、その内部で閉じているネットワークだというイメージを持っていただければ問題ないです。

#### 設定する項目
##### NAME
作成するVCNの名前です。わかりやすい名前をつけましょう！

##### CREATE VIRTUAL CLOUD NETWORK ONLY
「CREATE VIRTUAL CLOUD NETWORK ONLY」にチェックします。
「PLUS RELATED RESOURCES」のほうにチェックするといろいろ自動で作って貰えますが、今回はネットワーク構成の理解も目的にしているので手動で構築していきます。

##### CIDR BLOCK
VCNのCIDRを決定します。
指定できる範囲は/16から/30までで、プライベートIPアドレスの範囲から設定することが推奨されています。(`10.0.0.0/8`, `172.16.0.0/12`, and `192.168.0.0/16`)

###### CIDRって？
ネットワーク用語の解説です。知ってるよーという方は読み飛ばして下さい。

CIDR(さいだー)というのはIPアドレスの範囲を示しています。
と言っても、`192.168.0.0/16`のような書き方を見ただけではどこが範囲なのかわからない気がするので、まずはIPアドレスの構成から順を追って説明します。

前提として、IPアドレスは8桁の2進数が4つ並んだ状態で記述されます。
例えば、`192.168.0.0`であれば、`11000000.10101000.00000000.00000000`となります。
これに対して`192.168.0.0/16`というCIDRが示す範囲は、2進数で記述したIPアドレスの先頭16桁(`/`の後ろの数字分の桁数)を固定した範囲になります。
具体的に示すと、`11000000.10101000.00000000.00000000`から`11000000.10101000.11111111.11111111`までの範囲となり、これを10進数に戻すと、`192.168.0.0`から`192.168.255.255`が、`192.168.0.0/16`の示す範囲ということになります。

今回の例では、VCNを`172.16.0.0/20`で作成しました。
これは`10101100.00010000.00000000.00000000`から`10101100.00010000.00001111.11111111`の範囲、すなわち、`172.16.0.0`から`172.16.15.255`を示しています。

ここで指定した範囲が、作成したVCN内で使用可能なIPアドレスの範囲となります。

###### プライベートIPアドレスとパブリックIPアドレス
引き続きネットワーク用語の解説です。知ってるよーという方は読み飛ばして下さい。

まずはパブリックIPアドレスについて説明します。
パブリックIPは基本的にインターネットのどこからでもアクセスできるアドレスで、インターネット全体の中で一意に識別されます。

通常のインターネットアクセスでは、URL(例えば`qiita.com`のような)に直接アクセスしているように感じるかもしれませんが、実はその裏では名前解決という仕組みによってURLがパブリックIPアドレスに変換され、最終的にはそのパブリックIPアドレスにアクセスしています。
(グローバルIPアドレスという呼び方のほうが一般的かもしれませんが、ここではOCI上の呼び方で統一します)

対してプライベートIPアドレスですが、これはインターネット上ではなく、社内ネットワーク等の閉じたネットワーク内で使われるIPアドレスになります。これに関しては以下のアドレス帯をプライベートIPアドレスとするように決められています。
`10.0.0.0/8`、`172.16.0.0/12`、`192.168.0.0/16`

ここで押さえておいて欲しいことは、IPアドレスにはインターネットの中で使えるパブリックIPアドレスというものと、自分のプライベートネットワークの中でだけ使えるプライベートIPアドレスというものがあって、今回作成するVCNについても、プライベートIPの範囲からCIDRを指定することが推奨されているという点です。

パブリックIPの範囲を指定してVCNを作成することも可能なのですが、その場合はそのパブリックIPの範囲にはVCN内部からアクセスできなくなってしまいます。(VCN内部の通信が優先されます)

##### DNS RESOLUTION
では、VCNの作成に戻ります。
このDNS RESOLUTIONの項目を有効にすると、作成したVCNの内部で名前解決できるようになります。特別な理由がなければ有効にしておくことを推奨します。

名前解決というのは、前項でも少し触れましたが`qiita.com`のようなURLをIPアドレスに変換する仕組みになります。このDNS RESOLUTIONを有効にすると、VCN内部のプライベートIPアドレスに対して、VCN内部で名前解決ができるようになります。
(具体例は次の項で説明します)

##### DNS LABEL
この項目ではVCN内部で名前解決するための、VCNのドメイン名を決定します。
ここで値を入力すると、その下のDNS DOMAIN NAMEの項目が自動入力されると思います。

一応、具体的に設定されるドメイン名の詳細についても触れておきます。
まずはOCI上のネットワークの構成ですが、現在作成しているVCNに加えて、VCNの上にSubnetというものを作成し、そのSubnetに接続する形でVMを作成します。
その際に、作成したVMのドメイン名は以下の形式になります。

`<hostname>.<subnet DNS label>.<VCN DNS label>.oraclevcn.com`

詳細はSubnetやVMを作成する際に説明しようと思いますが、

1. vm01というhostnameのマシンが存在して
1. そのマシンがsubnet01というDNS LABELのSubnetに接続していて
1. そのSubnetがvcn01というDNS LABELのVCNの上に作られていた場合

vm01のマシンのドメイン名は`vm01.subnet01.vcn01.oraclevcn.com`となります。

この設定により、vm01にアクセスする際には、直接プライベートIPアドレスを指定する以外にも、`vm01.subnet01.vcn01.oraclevcn.com`のドメイン名を指定してアクセスすることが可能になります。

例: 仮にvm01のプライベートIPアドレスが`172.16.0.2`の場合は、VCN内部からのアクセスであれば、下記のどちらのコマンドでもちゃんと応答が返ってきます。

```
$ ping 172.16.0.2
$ ping vm01.subnet01.vcn01.oraclevcn.com
```

VCNの作成については以上になります。

![02-7.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512576/e7d70b81-a1da-cc94-5102-927ab9981f3c.png)

### VCNと同時に作成されるリソースたち
VCNを作成すると同時に作成されるリソースが全部で3つあります。
これらはCREATE VIRTUAL CLOUD NETWORK ONLYの設定に依らずに必ず生成され、`Default ～ for <VCN名>`といったような名前を持っています。

* DHCP Options
* Route Tables
* Security Lists

これらはSubnetに設定して使用するので説明は後に回しますが、一応気には留めておいて貰えればと思います。

### Subnet
ではVCNの作成が完了したので、次はSubnetを作成していきます。
VCNの詳細画面の下にCreate Subnetのボタンがあると思うので、そのままクリックしましょう。

#### 設定する項目
##### NAME
作成するSubnetの名前です。わかりやすい名前をつけましょう！

##### SUBNET TYPE
推奨されている通り、REGIONALを選択しましょう。

AVAILABILITY DOMAIN(AD)について補足します。
東京リージョンには1つのADしか存在しないためイメージしにくいですが、Ashburn等のリージョンでは1つのリージョン内に3つのADが存在し、それぞれ物理的に別のデータセンターに分かれていることが保証されています。

東京リージョンでは現状この2つの選択肢に差がありませんが、REGIONALを選択した場合はリージョン全体で使用可能なSubnetとなり、AVAILABILITY DOMAIN-SPECIFICを選択した場合は、指定したAVAILABILITY DOMAINの中でのみ使用可能なSubnetが作成されます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512576/ffbfe7cf-2b41-dc6e-5f26-bd1e72c785f6.png" width="70%">

##### CIDR BLOCK
SubnetのCIDRを設定します。
SubnetはVCN上に作成するので、VCNのCIDRの範囲に含まれるものでなければ設定不可能です。

##### ROUTE TABLE
Subnet内で使用するRoute Tableを指定します。
Route Tableの説明は別途行いますが、VCNを作成するとデフォルトで1つ作成されているはずなので、ここではそのRoute Tableを選択しておきます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512576/6e4c3d08-d25e-b6b3-4423-a136318b83f9.png" width="70%">

##### SUBNET ACCESS
PUBLIC SUBNETを選択します。

これは、Subnet内部でパブリックIPを使用可能にするか否かの設定になります。
VCNの項でも解説しましたが、パブリックIPはインターネットからアクセス可能なアドレスです。
ここでPRIVATE SUBNETを選択すると、内部ではプライベートIPしか使用できなくなります。

VM作成時にパブリックIPを付与できないと外部から接続するのが困難になってしまうので、特別な理由がなければPUBLIC SUBNETを推奨します。

##### DNS RESOLUTION
VCNと同様にSubnetのドメイン名を決定します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512576/861be4ec-4f96-dd58-f177-d79715bb4fe5.png" width="70%">

##### DHCP OPTIONS
Route Tableと同様にVCNを作成するとデフォルトで1つ作成されているはずなので、ここではそのDHCP Optionsを選択しておきます。

##### Security Lists
Security Listも同様に1つ作成されているのでひとまず選択しておきます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512576/75b97e87-726d-9316-424d-c28fb1c49b89.png" width="70%">

これでSubnetの作成も完了です。
この後は、インターネットに出ていくためのゲートウェイを作成した後、
デフォルト状態で割り当てた、Route Table、DHCP Options、Security Listの各リソースについて見ていきます。

![02-12.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512576/544dfd5b-d20b-e181-5a6d-e3fed0b8647b.png)

### Internet Gateway
Internet Gatewayを作成します。
VCNの詳細画面に戻ってResourcesからInternet Gatewayを選択後、Create Internet Gatewayをクリックします。

入力項目はNAMEだけなのでわかりやすい名前をつけましょう！

Internet Gatewayは、外部からの通信がVCNの中に入ってきたり、VCN内からの通信が外部に出て行ったりするための出入口になります。

### Route Table
次はRoute Tableの設定に進みます。
ここでは新規作成ではなく、デフォルトで作成されているRoute Tableを選択し、Add Route Rulesをクリックします。

![02-13.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512576/054e9a90-ed6d-115a-a12a-41e6d1371f24.png)

#### Route Ruleについて
Route Ruleでは、Route Tableを適用したSubnet内の通信が、どのようにルーティングされるかについての設定を行います。

前提として、VCN内部の通信についてはルーティングを定義せずとも自動的に宛先に送信されます。ここで定義するのはVCNの外部への通信の宛先をどこにするかということです。

今回は、すべての通信をInternet Gatewayにルーティングして、そのままインターネットに出ていく設定にします。すべてのIPアドレスを対象にするので、Destinationは`0.0.0.0/0`、Targetに前項で作成したInternet Gatewayを設定してください。

![02-14.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512576/417b4ec3-4993-d36a-1d59-551f4b245abc.png)

参考情報として、Autonomous DatabaseへのアクセスをInternetに出したくない場合は、Service Gatewayを使用してOCIの内部のネットワークを使用してアクセスする方法もあります。
https://docs.oracle.com/cd/E97706_01/Content/Network/Tasks/servicegateway.htm#AccesstoOracleServicesServiceGateway

### DHCP Options
DHCP Optionsについては変更の必要はありません。

DHCP Optionsでは、Subnet内に接続されたマシンに対して自動的に投入される設定について定義します。定義できるのは名前解決に関する設定で、デフォルトの状態でVCN内の名前解決とインターネット上の名前解決が可能な状態になっています。
独自のDNSサーバを使用したい場合には設定を変更します。

### Security List
最後にSecurity Listを見ていきます。
これについてもデフォルトで作成されたものを選択します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512576/1ebbfee9-c185-3b0d-7a6a-350299e59f92.png" width="70%">

#### Security Rule(Ingress RuleとEgress Rule)
Ingress/Egress Ruleでは、Subnetに接続しているマシン(の仮想NIC)についてのファイアウォールを設定します。

実際にデフォルトで設定されている内容を見ながら解説したいと思います。
まずはIngress Ruleです。これはどのような入力を許可するかということについて定義しています。

![02-16.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512576/03ddf664-2a76-d995-978d-65da0146a5c0.png)

次にEgress Ruleも見ておきます。これはどのような出力を許可するかということについて定義しています。

![02-17.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512576/8ade1233-6c57-ac1d-472e-bf783d2c4634.png)

今回はAPサーバ構築が目的なので、通信はTCPに絞って解説します。

ネットワークに詳しい人はおそらく直感的に設定して問題ないので読み飛ばしてください。注意点としては、デフォルト設定だとpingも拒否されることと、Stateful/Statelessの設定についてぐらいだと思います。
Statefulルールに関しては下記のドキュメントをご参照いただければと思います。
https://docs.oracle.com/cd/E97706_01/Content/Network/Concepts/securityrules.htm#stateful

##### TCPについて
ここで前提知識として、TCPというプロトコルについてとてもざっくり説明します。

まず大前提として、インターネット上ではIPアドレスで宛先を指定して通信を行うことができます。これはインターネットプロトコル(IP)というプロトコルによるものです。
ではTCPとは何をするプロトコルなのかということですが、そのインターネットプロトコルの上で動作する、通信相手とのコネクションやエラー発生時の再送等、よりリッチな機能を備えたプロトコルです。

今回の設定で重要なTCPの機能はポートという機能です。
TCPの通信ではポート番号というものを指定することができ、これにより同じマシンに届いた通信でもポート番号によって別々のアプリケーションに振り分けることができます。具体例としては、22番ポートに届いたらそれはSSHで、443ポートに届いたらそれはHTTPSの通信といったような形です。
(上の例はデフォルト設定の例で、待ち受けポートは変更することが可能です)

そしてこれから設定するファイアウォールでは、どのポートの通信を許可してどのポートの通信を遮断するかといったような設定を実施していきます。

とりあえずこれぐらいのざっくりした認識を持っていただければ問題ないと思います。

##### Ingress Ruleの設定
Ingress Ruleは、どのような入力を許可するかの設定です。逆に言えば、ここで許可していない入力は基本的にすべて遮断されます。

では、各設定項目について説明します。
ここではデフォルト状態から特に変更を加えないため、1番上の列に設定されている値を見ながらそれぞれの意味について解説していきます。

###### Stateless
これをNoにすると、「このルールで許可した通信に対する返信」が自動的に許可されます。(Egressで許可する必要なし)
あくまで「返信」が自動的に許可されるのみなので、内部から通信を開始する場合はちゃんとEgressにルールを定義する必要があります。

基本的にNoにしておいたほうが設定が楽になるので、理由がなければNoにすることを推奨します。

###### Source
送信元のIPアドレスの範囲を指定します。`0.0.0.0/0`はすべてのIPアドレスを示すCIDRなので、送信元に制限がないことを示しています。

##### IP Protocol
通信プロトコルを指定します。TCPという値は通信プロトコルがTCPであることを示しています。

##### Source Port Range
送信元のポートの範囲を指定します。特に理由がなければallのままにしておきます。

##### Destination Port Range
受信を許可するポートの範囲を指定します。
22番ポートを閉じてしまうとSSHで接続できなくなってしまうので許可しておきます。

セキュリティ上の理由等でSSHのポートを変更した場合は、ここで変更後のポートを許可する必要があります。また、APサーバを立てて80や443や8080等で待ち受ける必要が出てきた場合は、適宜ルールを追加します。

Ingress Ruleの設定値は以上です。

##### Egress Ruleの設定
Egress RuleについてもほぼほぼIngress Ruleと同じです。
IngressではSourceのIPアドレス範囲を指定して送信元を制限していましたが、Egress Ruleでは、DestinationのIPアドレス範囲を指定して宛先を制限します。

デフォルトの設定では、宛先のIPは制限されておらず、またTCPのみでなくAll Protocolsで通信が許可されています。
(要するに何の制限もかかっていません)

今回作成した環境の内部からは、外部のインターネットに自由にアクセスできることを想定しているので、この状態から特に変更する必要はありません。また、作成したAutonomous Databaseにはインターネット上からアクセスするので、この設定によりDBとも疎通できることになります。

長くなりましたが、これでネットワーク環境の構築も完了です。

次は[APサーバ編](https://qiita.com/mokkan/items/875b666de20ab96b4b2e)として、ここで作成したネットワークに仮想マシンを接続し、実際にDBにアクセスしてみたいと思います。