Djangoアプリのサーバーへのデプロイを、マスタリングTCP/IPを元に理解し直す。

# 本記事の目的
DjangoやRailsのチュートリアルで勉強されている方も多いかと思いますが、実際にサーバーにデプロイするとき、以下のようになっていませんか？

- 途中で詰まっても、本質的に理解出来ていないので、エラーを元に処置のみを調べて、その場しのぎの対応しかできない。
- エラーが出ない不具合(サーバーにデプロイが完了しているはずなのに、アクセスしてもレスポンスが帰ってこないし、サーバーのログにも何も出ない)にぶつかったときに、不具合の目星がつけれず、とにかく時間を浪費
- デプロイまでなんとかこぎつけたが、これが正攻法なのかわからない。叩いているコマンドや設定が黒魔術にしか見えない。

私はお恥ずかしながら、なっていました...

本記事では、筆者のこのような苦い経験を解決するために、デプロイ作業それぞれが何をおこなっているのかをネットワークの知識を元に理解し直すことを目的とします。

この記事が皆さんの役にたてば嬉しいです。

# 本記事の流れ
本記事は以下のような流れで説明します。

1. ネットワーク周りの知識や単語に関する説明
a. プロトコルについて
d. ネットワークの基本用語の説明

2. デプロイ作業を上述の知識で理解し直す。


# 本記事で解説するデプロイ作業
[この記事](https://qiita.com/moto2g/items/e6454a51d61570948171)に紹介されているデプロイ作業の中から、以下について説明します。
1. AWSのポートを開く
2. ElasticIPの取得と設定
2. Djangoの設定とNginxの設定
2. DNSの設定

# ネットワーク周りの知識
ここからはマスタリングTCP/IP入門編に掲載されている内容に従っています。
## プロトコルについて
大前提として、通信を行う際には定められた共通のルールで通信を行う必要がある。
この共通のルールをプロトコルといいます。

人間に置き換えると、誰かと会話するときに、自分は日本語しかしゃべれないのに、英語で喋りかけられたら、当然会話は成立しないですよね？
会話に使用する言語がプロトコルに相当していると言えます。

後で出てくるTCPというのもコンピューターが通信するためのプロトコルの一種で、データちゃんと相手まで正確にわたったことを保証してくれるコネクション型のプロトコルです。

## ネットワークの基本用語の整理

### IPアドレス
OSI参照モデルでの、ネットワーク層に相当するIPで使われるアドレスです。
人間世界で例えると、住所だと思っていただければ良いです。
ネットワークの世界が日本だとすると、IPアドレスはまさしく住所に対応しています。
はがきや荷物を郵送する際には、住所が必要なのと一緒で、通信の際にも情報を問い合せる先のコンピューターのアドレスが必要となります。

例えば、`172.217.161.35`というIPアドレスをWebブラウザのアドレスバーに打ち込むとGoogle.comの検索エンジンの画面が表示されます。

IPアドレスだと、よく目にするのはIPv4とIPv6だと思います。

#### IPv4アドレス
先程もご紹介した、10進数で`0~255.0~255.0~255.0~255`の数字です。
この0~255というのは、8bit、つまり2進数で8桁の数字という意味です。それらが4つ合わさって出来ているので、32bitの数字となります。

`.`は人が認識しやすいように置かれた記号で意味はありません。

このIPアドレスは現実世界の場所にも対応していて、IPアドレスを見るだけで、大まかな場所を知ることが出来ます。
例えば[このサイト](https://rakko.tools/tools/11)に先程のGoogleのIPアドレス(172.217.161.35)を打ち込むとアメリカの場所がわかります。
ただ、この場所というのは、接続時の最寄りのルーターの場所なので、サーバーのある場所を直接表しているわけではないようです。([参考](https://ut-vessel.com/ip%E3%82%A2%E3%83%88%E3%82%99%E3%83%AC%E3%82%B9%E3%81%A6%E3%82%99%E5%80%8B%E4%BA%BA%E6%83%85%E5%A0%B1%E3%81%AE%E7%89%B9%E5%AE%9A%E3%81%AF%E3%81%A8%E3%82%99%E3%81%93%E3%81%BE%E3%81%A6%E3%82%99%E3%81%A6/#:~:text=IP%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E3%81%8B%E3%82%89%E5%BE%97%E3%82%89%E3%82%8C%E3%82%8B,%E5%8C%BA%E7%94%BA%E6%9D%91%E5%8D%98%E4%BD%8D%E3%81%BE%E3%81%A7%E3%81%A7%E3%81%99%E3%80%82))
#### IPv6アドレス
IPｖ４アドレスでは、2の32乗=42億9496万7296個のユニークなアドレスが作成可能ですが、現代のネットワークの普及により、それだけではIPアドレスの数が足りなくなってしまう恐れがありました。

そのため、IPv6では、128bit長のアドレスを使用します。
現状どんどん、移行が進んでいるそうです。

### DNS(名前解決)
先程は`172.217.161.35`というIPアドレスでgoogle.comにアクセスしましたが、普段、私達が生活をしていて、このような数字を打つことはほとんど無いと思います。
数字が並んでいるだけだと、そのページがどんなページかわかりませんし、打ち間違いも多発しそうです。

そこで、`google.com`という`ドメイン`にアクセスしたときに、それを`IPアドレス`に変換してくれる仕組みがDNS(名前解決)です。

### ポート
IPアドレスが分かっても、たどり着けるのはそのコンピュータまでで、その中のどのプログラムに情報を伝えれば良いのかがわかりません。
そこでポートを使用します。
#### wellknownポート
wellknownポートは0~1023までの用途がデフォルトで決まっているものです。例えば、22番ポートであればSSHの通信に使用されることが多いですし、80番ポートはHTTP通信に使用されることが多いです。
もちろん、使用するポート番号を変更することも出来ます。
#### それ以外のポート
1024以降のポートは任意のプログラムが使用できます(すでに他プログラムに使用されていなければ)。
例えば、Djangoで開発サーバーを起動するときに以下のコマンドを打つと思うのですが、これは8000番ポートでDjangoを起動していることになります。

```
python manage.py runserver　8000
```

####　証明書
証明書は認証局が発行する証明書のことで、通信データの暗号化に使用されます。
例えば、大事なパスワードをWebサイトに送る際に、そのパスワードの平文がそのまま誰でも覗ける通信回線上に流れてしまうのは問題ですよね。それらの情報は第三者からは見れないように暗号化されて通信します。しかし、暗号化されていると、Webアプリケーション自体もその暗号を複合できないと困ります。

そこで、公開鍵暗号と共通鍵暗号が用いられます。
公開鍵暗号を用いた通信では、公開鍵と秘密鍵の2つを使用します。
まず最初にブラウザからデータを送る際には、この公開鍵を使用して、データを暗号化します(つまりデータに鍵を掛けるということ)。
公開鍵によって暗号化されたデータは秘密鍵でしか復号(データに掛かっている鍵を解除)することが出来ません。こうすることで安全な通信を行うことが出来ます。

しかし、公開鍵暗号は処理時間が長いため、共通鍵暗号も使用して処理をはやめます。共通鍵暗号ではデータに鍵を掛けるのにも、鍵を解除するのにも同じ共通鍵を使用します。共通鍵による暗号化復号は、公開鍵暗号のそれに比べると高速です。
しかし、共通鍵を`他の人に知られずに`データの送信者と受信者に知らせる必要があります。

そこで、この２つを組み合わせることで安全な通信を確立しています。
これらの通信を行うために必要なものが証明書です。

詳細は以下のページがわかりやすかったです。
https://www.idcf.jp/rentalserver/aossl/basic/ssl-what/

## Djangoのデプロイ作業を上の知識で理解する。

### AWSのポートを開く
これはEC2というAWS上のサーバー(コンピューター)にアクセスするためのステップです。これにより、外部からデプロイされたアプリケーションにアクセスすることができるようになります。

###　ElasticIPの取得と設定
ElasticIPはAWSのサービスで、EC2インスタンスに固定のIPアドレスを紐付けることができるサービスです。
これを設定しないと、EC2インスタンスを起動するたびに、IPアドレスが変更になるため、外部から通信することが出来ません。

### Djangoの設定とNginxの設定
ここでは`settings.py`の`ALLOWED_HOSTS`の配列の値を上記で設定した、IPアドレスとドメイン名にしています。この項目はDjango1.5から追加された項目でHTTPヘッダインジェクション攻撃を防ぐことが出来ます。

(参考：https://office54.net/python/django/settings-allowed-hosts)

また、Nginxの設定では、起動する本番用サーバーにドメイン名を設定しています。
Nginxについての説明は以下がわかりやすかったです。

https://www.kagoya.jp/howto/it-glossary/web/nginx/

### DNSの設定
取得したドメインとElasticIPで固定したIPアドレスを実際に紐付ける作業を行っています。この作業を行うことで、取得したドメインに対してリクエストを送ることで、デプロイするサーバーにリクエストを送ることが可能になります。


以上になります。

マスタリングTCP/IPではOSI参照モデルの説明や普段我々が使用しているSSH,HTTPといった通信プロトコルの下位レイヤであるTCPやさらにその下のIPについて説明されており、非常に勉強になったのですが、この記事で説明することが出来ずに残念です(まだ自分でもちゃんと理解できていない)

この記事が少しでも参考になれば幸いです。