基礎からのネットワーク&サーバ構築　まとめ



# 参考

[Amazon Web Services 基礎からのネットワーク&サーバー構築](http://www.amazon.co.jp/Amazon-Web-Services-基礎からのネットワーク-サーバー構築/dp/4822262960/ref=sr_1_1?ie=UTF8&qid=1448979621&sr=8-1&keywords=amazon+web+services+ネットワーク '紫本')


# 概要

参考図書は、AWSを借りてWordPressのブログを作成するという例を用いて、

* ネットワークの基本
* Linuxの操作
* 仮想サーバーの構築
* アプリケーションの設定

という多岐にわたる内容を押さえられる、とてもお得な本。
本記事はその内容を自分なりに復習しやすいようにまとめたものです。


# 目標

* 単語の意味を理解して覚える
* ネットワークの原理を理解し、それにまつわるLinuxコマンドを覚える


# 項目

1. IPアドレス
2. VPC領域とサブネット
3. 仮想サーバー
4. SSH
5. ポート番号
6. ファイアウォール
7. WEBサーバーソフトのインストール
8. ドメイン
9. HTTP
10. プライベートサブネット
11. NATサーバー
12. アプリケーションのインストール
13. TCP/IP


# 内容

## 1. IPアドレス

IPアドレスはネットワーク上で互いに重複しない唯一無二の番号で「住所」に相当する。

### パブリックIPアドレス

インターネットに接続するために使う。
自由に設定することはできず、ICANNという団体が一括管理している。

EC2を作成した場合、基本的にパブリックIPアドレスは固定ではなく変化する。
Elastic IPで設定することで、外部からアクセスできるIPアドレスを作成でき、これは主にELBに付与することが多い。

### プライベートIPアドレス

以下の範囲のIPアドレスは、インターネット上でパブリックIPアドレスとしては使われない。

|IPアドレス範囲|
|:---|
|10.0.0.0 ~ 10.255.255.255|
|172.16.0.0 ~ 172.31.255.255|
|192.168.0.0 ~ 192.168.255.255|

社内LANを構築するときなどに使う。
自由に設定することができ、値も固定である。

### IPアドレスの表記法

ネットワークを構築する際は、使用するIPアドレスの範囲を定める。
その時にIPアドレスは「2のn乗個(nビット単位)で区切る」という決まりがある。

例えば「192.168.1.0 ~ 192.168.1.255」は「192.168.1.0/24」と表記するが、これは「192.168.1」までの24ビット分までは固定で、最後の8ビット分だけ割り当てられる。

このようなIPアドレスの範囲は、ネットワーク部とホスト部というように分けられる。

* ネットワーク部 ... 同じネットワーク内では同じ値(上記の例だと「192.168.1」の24ビット分の数字)
* ホスト部 ... 割り当てたいサーバーやネットワーク機器に対する連番(上記の例だと最後の部分で0~255の8ビット分の数字)

この例では24ビットで区切っているが、16ビットで区切ったりしてもよい。
「192.168.0.0/16」というような書き方をCIDR表記という。


## 2. VPC領域とサブネット

### VPC領域

VPCは「Virtual Private Cloud」のことで、仮想上に構成するネットワーク領域。
「10.0.0.0/16」のように適当な区間のIPアドレスを割り当て、ひとまとまりのサービスのために大きな粒度で作成する。

例えば、

* Production環境のVPC
* Staging環境のVPC
* 社内システムのVPC

といった粒度で作成する。

### サブネット

VPCに割り当たれたらCIDRブロックを、さらに細分化して作成したCIDRブロックを「サブネット」という。

例えば、

* パブリックサブネット ... インターネットと通信するCIDRブロック
* プライベートサブネット ... インターネットとは通信しないCIDRブロック

といった粒度で作成する。

ロードバランサで負荷分散するためにサーバーを複数用意するときにも、別々のアベイラビリティゾーンに別々のサブネットを作る。

### サブネットの設定

サブネットでは、以下の項目を設定する。

* CIDRブロック
* インターネットゲートウェイ ... 自分のネットワークとインターネット回線を接続
* ルートテーブル ... 他のネットワークにデータを流すための設定

ルーターというソフトウェアが、ルートテーブルとインターネットゲートウェイの間にいて、外部のネットワークと接続する。

### インターネット回線とルーティング

インターネットで使われるTCP/IPプロトコルでは、データを「パケット」という単位でやりとりする。
パケットの中には「宛先IPアドレス」が含まれており、ネットワーク機器である「ルーター」がこの宛先IPアドレスを見ながら次々と他のルーターへパケットを転送し、最終目的地までパケットを到達させる。

そのためルーターには、以下の内容を含んだルートテーブルを定義する。

* 宛先アドレス
* 流すべきネットワークの入り口となるルーター

例えば「10.0.1.0/24」というCIDRブロックを持つサブネットでは、以下のようなルートテーブルにする。

|宛先IPアドレス|ターゲット|説明|
|:---|:---|:---|
|10.0.0.0/16|local|同じVPC内なら内部を探す|
|0.0.0.0/0|インターネットゲートウェイ|それ以外なら外部を探す|


## 3. 仮想サーバー

### EC2の設定

作成したサブネットの中に、仮想サーバーを構築する。
AWSでは、EC2(Elastic Compute Cloud)という仮想サーバーがあるので、これを利用する。

以下の項目を設定する。

* リージョン
* AMI ... OSがインストールされて初期アカウントの設定までが済んだもの
    + 例. Amazon Linux AMI ... AWSがサポートするLinuxのイメージ
    + Linuxの場合でもUbuntu、Debian、CentOSなど複数種類がある
* インスタンスタイプ ... 仮想マシンのスペック
    + CPUとメモリを元にスペックを選べる
    + ストレージは後述するEBSで別途選ぶ
    + マイクロインスタンス ... もっとも安価なインスタンス
    + 参考. [インスタンスの種類](https://aws.amazon.com/jp/ec2/instance-types/)
* サブネット
    + VPC内のどのサブネットに配置するかを決める
* パブリックIPアドレス
    + ELB経由でアクセスする場合は設定しなくても良い
* プライベートIPアドレス
* ストレージ
    + EC2本体に付けられる仮想ハードディスク(EBS/Elasting Block Store)
    + インスタンスタイプとは別に選べる
    + Amazon Linux AMIでは8Gバイトがデフォルト
* インスタンスの名前
* セキュリティグループ
    + アクセス権などの設定(後述)
* キーペアの作成
    + SSHの項でまとめる


## 4. SSH

SSH（Secret SHell）は仮想サーバーにアクセスすることができるプロトコル。
Macの場合、標準のターミナルからSSHクライアントを起動することができる。

### キーペア

EC2インスタンスを作成するときに、キーペアを作成し`my-key.pem`というファイルがダウンロードする。
（なお、これを紛失するとインスタンスにログインできなくなるので注意。）

SSHは秘密鍵と公開鍵によって接続する方法であり、この`my-key.pem`は秘密鍵に相当する。

### 接続

接続するときは以下のコマンドで接続する。

```bash
$ ssh -i my-key.pem ec2-user@54.199.208.105
```

* `-i` ... 秘密鍵のパスを指定するオプション
* `my-key.pem` ... ダウンロードした秘密鍵
* `ec2-user@54.199.208.105` ... 接続するユーザー名とIPアドレス

接続に成功すると、リモートからEC2インスタンスにログインして、各種コマンドを実行できる。


## 5. ポート番号

### EGPとIGP

インターネットは無数のルーターで接続されており、ルーター同士はルートテーブルの情報をやりとりし、必要に応じて内容を更新する。
そのための代表的な方法がEGPとIGPである。

* EGP ... 大きなネットワークでネットワークを管理する「AS番号」を使ってやりとりに使われる
* IGP ... EGP内部のルーター同士でのやりとりに使われる

なおEGPやIGPはルーティング情報プロトコルの総称である。

### ポート番号

ポートは、TCP/IPで通信するサーバーなどの機器にある「他のコンピュータと、データを送受信するための出入り口」のことで、0から65535まである。
ポートによって、1つのIPアドレスに対して、複数のアプリケーションが同時に通信できる。
（ポートにはTCPとUDPがある。）

### ポート番号の確認

どのポート番号でどのプログラムが待ち受けているのかを確認するには`lsof`コマンドを使えば良い。

```bash
# sshログインしたインスタンスで実行
$ sudo lsof -i -n -p
```

### ウェルノウンポート

ウェルノウンポート番号は代表的なアプリケーションが使うポート番号のことで、あらかじめ番号が定められている。

|プロトコル名|番号|用途例|
|:---|:---|:---|
|SSH|22|仮想サーバーに接続する|
|SMTP|25|電子メールを転送する|
|HTTP|80|WEB上で通信する|
|HTTPS|443|セキュリティの高いHTTP|
|MySQL|3306|代表的なデータベース|


## 6. ファイアウォール

ファイアウォールとは、「通して良いデータだけを通しそれ以外を遮断する機能」の総称。

### パケットフィルタリング

最も簡単な構造のファイアウォールで、流れるパケットを見て通過の可否を決める仕組み。
パケットにはIPアドレスのほか、ポート番号も含まれるため、これらの情報から通過の可否を決める。

例えばMySQLはポート3306番で待ち受けているが、データベースにアクセスできるようにするのは好ましくないので、ポート番号3306番のパケットを除外するように構成する。
逆にsshdはポート22番なので、これは除外しないようにする。

### セキュリティグループ

AWSのインスタンスでは「セキュリティグループ」でパケットフィルタリングを設定できて、デフォルトでは、

* ポート22に対して、すべての通信（0.0.0.0/0）を許可する

という設定だけがなされている。
デフォルトの設定ではWebサーバーソフトをインストールしても阻まれて通信できないので、必要に応じてセキュリティグループの構成も変更していく。

セキュリティグループの設定は以下の記事が参考になる。
http://qiita.com/kenjiszk/items/b1c0bfb75a2c44253cd6


## 7. Apacheのインストール

Apacheは世界で最も多く利用されているWebサーバーソフト。

### Apacheのインストールから実行まで

Apacheをインストールするには、SSHでインスタンスにログインして、以下のコマンドを実行する。

```bash
$ sudo yum -y install httpd
```

ここで、httpdはApacheを構成する実行ファイル名。

```bash
$ sudo service httpd start
```

```bash
$ sudo chkconfig httpd on
```

### 実行中プロセスの確認

`ps`コマンドは実行中のプロセスを確認するLinuxコマンド。

```bash
$ ps -ax
```

以下のようにすると`httpd`を含む行だけを出力できる。

```bash
$ ps -ax | grep httpd
```

プロセスを削除するときは`kill`コマンドを使う。

### ファイアウォールの設定

ポート80番（HTTPのウェルノウンポート）がファイアウォールにブロックされているため、Apacheをインストールしてプロセスを起動しても、そのままではWEBブラウザからアクセスできない。
そのためポート80番を開けるよう、ファイアウォールを設定する。

### 参考

Railsを動かすためのWebサーバーには、Nginx+Unicornが選択されることが多い。

* [Railsで使えるWebサーバーの一覧](http://simosan.minibird.jp/wordpress/rails/railsで利用可能なwebサーバのパフォーマンスその環境/)
* [ローカル環境でNginxとUnicornを動作させる方法](http://qiita.com/itosho/items/e0c2290f8079e740030b)
* [NginxとUnicornの違い](http://fujiike.hateblo.jp/entry/2015/08/20/170751)

実際のアプリケーションの運用を行うときには、メモリやCPUの使用状況といったリソース監視が必要になる。

* [起動中のApacheのリソースを見る方法](http://www.very-cute.net/wp/web-access-memory/)


## 8. ドメイン

### ドメイン

ドメインとは、

* 覚えにくいIPアドレスに、名前をつける（ドメイン名）
* ピリオドで区切られ階層がある（`www.example.co.jp`）
* ドメイン名はIPアドレスと同様にICANNが管理している
* 名前解決（ドメイン名から対応するIPアドレスを引き出すこと）を行う
* DNS（Domain Name System）が名前解決に使われる仕組み

といったもの。

ドメインを利用するために、DNSの設定を行う必要がある。
Amazon VPCには名前解決をするオプション機能がある（詳細略）。

### nslookコマンド

```bash
$ nslookup www.nikkeibp.co.jp

Server:		10.0.0.2
Address:	10.0.0.2#53

Non-authoritative answer:
Name:		www.nikkeibp.co.jp
Address:	202.214.174.229
```


## 9. HTTP

### HTTPリクエストとレスポンス

リクエストは以下の項目が必要。

|項目|例|
|:---|:---|
|リクエストライン|GET/HTTP/1.1|
|ヘッダー|Host:exmaple.com|
|ボディ(オプション)|...|

レスポンスには以下の項目が含まれる。

|項目|例|
|:---|:---|
|ステータスライン|HTTP/1.1 200 OK|
|ヘッダー|Content-Type: text/html ...|
|ボディ(オプション)|<!DOCTYPE html...|

### HTTPメソッド

GET/POST/PUT/DELETEの4つで、CRUD(Create, Read, Update, Delete)に対応している。

### HTTPステータスコード

|コード|意味|
|:---|:---|
|1xx|処理中|
|2xx|成功|
|3xx|リダイレクト|
|4xx|クライアントエラー|
|5xx|サーバーエラー|

### リクエストヘッダーの例

|種類|用途|
|:---|:---|
|HTTPヘッダー|要求を送ろうとするホスト名|
|User-Agentヘッダー|ブラウザの種別|
|Cookieヘッダー|以前Set-Cookieヘッダーで送信されたデータ|

### レスポンスヘッダーの例

|種類|用途|
|:---|:---|
|Content-Typeヘッダー|ボディ部のコンテンツの種類(HTMLなど)|
|Dateヘッダー|コンテンツの日付|
|Set-cookieヘッダー|Cookieを設定する|

### Telnet

HTTPプロトコルで通信するためのコマンド。

```bash
$ telnet aws.amazon.com 80

GET / HTTP/1.1
HOST: aws.amazon.com
```


## 10. プライベートサブネット

インターネットと隔離したサブネット。

### プライベートサブネットの設定

サブネットを作成して以下の項目を設定する。

* アベイラビリティゾーン
* ルートテーブル ... インターネットに接続しないのでデフォルトで良い

次にサブネットの中にインスタンスを作成し以下の項目を設定する。

* IPアドレス ... パブリックIPのチェックを外す
* セキュリティグループ ... MySQLを使うのでポート3306は通す

パブリックサブネットと設定がぜんぜん違う。

### pingコマンド

`ping`はサーバー間での疎通を確認するコマンドで「ICMP（Internet Control Message Protocol）」というプロトコルを利用する。
デフォルトのセキュリティグループではICMPは許可されていないため、インバウンドのファイアウォールの設定でICMPを追加する。

まずはローカルからパブリックサブネットにログインする。

```bash
$ ssh -i my-key.pem ec2-user@public_dns_name 
```

Webサーバー上でDBサーバー（IPアドレス: 10.0.2.10）に疎通を確認。

```bash
$ ping 10.0.2.10

64 bytes from 10.0.2.10: icmp_seq=1 ttl=64 time=1.07 ms
```

### 踏み台サーバー

インターネットから直接接続できないプライベートサブネットに接続するときに経由するサーバー。

DBサーバーに接続するための秘密鍵のファイルを、「SCP（Secure Copy）」というプロトコルを用いて転送する。

```bash
$ scp -i my-key.pem my-key.pem ec2-user@ec2-user@public_dns_name
```

次にWebサーバーにログインし、秘密鍵ファイルのパーミッションを自分しか読めないように変更する。

```bash
$ chmod 400 my-key.pem
```

この状態で以下のコマンドでDBサーバーにログインできる。

```bach
$ ssh -i my-key.pem ec2-user@10.0.2.10
```


## 11. NATサーバー

### NATサーバー

ネットワークアドレス変換(Nwtwork Address Translation)サーバー。
MySQLなどをインストールするために、「プライベートサブネット => インターネット」の向きの通信だけを許可するためのサーバー。

### NATサーバーの構築

NATサーバーのセキュリティグループは以下のように構成する。

* インバウンド

yumコマンドで利用するHTTPとHTTPSに加えて、菅利用のSSHを通す。

|送信元|プロトコル|ポート番号|コメント|
|:---|:---|:---|:---|
|10.0.2.0/24|TCP|80|プライベートサブネットからのインバウンドHTTPトラフィック|
|10.0.2.0/24|TCP|443|プライベートサブネットからのインバウンドHTTPSトラフィック|
|10.0.1.10|TCP|22|Webサーバーを踏み台にしたSSHアクセス|

* アウトバウンド

インバウンドの通信をインターネットへ転送する。

|送信元|プロトコル|ポート番号|コメント|
|:---|:---|:---|:---|
|0.0.0.0/0|TCP|80|インターネットへのアウトバンドHTTPアクセス|
|0.0.0.0/0|TCP|443|インターネットへのアウトバンドHTTPSアクセス|

あとは他のサーバーと同様に、

* AMI
* インスタンスタイプ
* ネットワーク
* ストレージ
* サーバー名
* セキュリティグループ

を設定すれば良い。

### curlコマンド

Amazon Linuxにはデフォルトで`telnet`コマンドがインストールされていないので、代わりに`curl`コマンドを使う。

```bash
$ curl www.nikkeibp.co.jp
```


## 12. アプリケーションのインストール

### MySQLのインストール

DBサーバー上で実行。

```bash
$ sudo yum -y install mysql-server # インストール

$ sudo service mysqld start # mysqlサーバーの起動

$ mysqladmin -u root password # ログイン
New password: 設定したいパスワードを入力
Confirm new password: 同じものを入力

$ mysql -r root -p # ログイン
Enter password: 設定したパスワードを入力
以下ローカルでのMySQLの操作と同様
```


## 13. TCP/IP

### 通信の復習

#### IPアドレス

* ネットワーク上の通信先を一意に特定するもので、ICANNという団体が管理している
* パブリックIPアドレスとプライベートIPアドレスがある
* ルーターがパケットを次々と転送する
* ルーティング情報はEGPやIGPを使って交換する

#### ポート番号

* 1つのIPアドレスで同時に複数のアプリケーションが通信できる
* よく使われるサービスは利用するポート番号が決まっている（ウェルノウンポート）

#### DNS

* IPアドレスは覚えにくいため、ブラウザからのアクセスはドメイン名を使う
* ドメイン名とIPアドレスを相互変換することを名前解決という
* 名前解決にはDNSサーバーを用いる

#### HTTP

* WebサーバーとWebブラウザはHTTPを用いてデータのやり取りをする

### TCP/IPモデル

上位の階層は下位の界層が何でもよく、下位の階層は上位の階層の内容は分からなくてもよい。

|層|役割|代表的なプロトコル|
|:---|:---|:---|
|アプリケーション層|ソフトウエア同士の通信|HTTP SSH DNS SMTP|
|トランスポート層|データのやりとりの順番の制御、エラーの訂正|TCP UDP|
|インターネット層|ルーティング（IPアドレスの割り当て）|IP ICMP ARP|
|インタフェース層|ネットワーク上で接続された機器同士の通信|Ethernet PPP|

ドメイン名の例だと、

1. 名前解決リクエストの作成（アプリケーション層; DNS）
2. UDPでカプセル化（トランスポート層; UDP）
3. IPでカプセル化（インターネット層; IP）
4. Ethernetでカプセル化（インターフェース層; Ethernet）

となっている。

Ethernetで通信するパソコン、サーバー、各種ネットワーク機器などのホストには、「MACアドレス」という唯一無二の番号が振られる。
ARP（Address Resolution Protocol）がホストのMACアドレスとIPアドレスの対応を結びつける。

### UDPとTCP

TCP/IPで通信する場合、アプリケーションのデータの転送には「UDP」と「TCP」の2通りの通信方法がある。

UDPには以下の特徴がある。

* 状態を持たない「ステートレスプロトコル」
* 送りっぱなしのプロトコル
* 相手がパケットを受け取ったかどうかを確認する手段はない
* やり取りが単純な分だけ、高速に送れる（動画など）

TCPには以下の特徴がある。

* 双方向の通信が可能
* 自分と通信相手の間に仮想的な通信経路である「コネクション」を確立する
* 3ウェイハンドシェークというやりとりを行う
* ACK（受領の合図）とシーケンス番号が大事