ネットワーク知識メモ

## 背景と目的
ネットワーク業務経験がないものの、業務でネットワークを知っておくとシステム全体的な構成を俯瞰しやすくなると考えています。
そこで、ネットワーク知識を独学で吸収するため、内容の備忘メモとしてまとめます。

## 内容
まず、大枠として、ネットワーク関連の知識は以下のサイトが分かりやすいです。参考になりました。

https://www.infraexpert.com/

---


### TCP・IP
#### 通信プロトコル
通信規格が決まっている。プロトコルとしては以下があります。
* アプリケーション層
    * HTTP、SMTP/POP3、DHCP、DNSなど
* トランスポート
    * TCPとUDP
* インターネット層
    * IP、ICMP、ARP
* ネットワークインタフェース層
    * イーサネットや無線LAN(IEEE802.11)、PPP

* 参考URL
https://www.n-study.com/network-architecture/tcp-ip-layer/

#### ARPの仕組み
* ARPの目的：サーバでMACアドレスとIPアドレスの紐づけを行います。
* ARPはサーバ全体に要求し、知りたいMACアドレスのサーバが応答を返す。
* ARPリクエスト（要求）
 ブロードキャストで、IPアドレスを持つノードのMACアドレスを探す。
    ```plantuml
    @startuml1
    title ARPリクエスト
    skinparam linetype ortho
    rectangle "Server0"
    rectangle "ServerA"
    rectangle "ServerB"
    rectangle "ServerC"
    
    Server0-->ServerA
    Server0-->ServerB
    Server0-->ServerC
    }
    @enduml1
    ```

* ARPリプライ（応答）
特定サーバ（MACアドレスを知りたいノード）が応答を返す

    ```plantuml
    @startuml2
    
    title ARPリプライ
    skinparam linetype ortho
    rectangle "Server0"
    rectangle "ServerA"
    rectangle "ServerB"
    rectangle "ServerC"
    
    Server0--ServerA
    Server0<--ServerB
    Server0--ServerC
    @enduml2
    ```
---
* ARPキャッシュ
    * 一定時間情報が保持される。arp -aで確認可能
    * 自身のIP/宛先IP/宛先MACアドレス/種類（dynamicかstaticか）
    * https://www.infraexpert.com/study/tcpip3.html
    * 動的に得られたARP情報は一定時間の後に消える。arp -d で削除可能。
* ルータ側のARPテーブル
    * ｆｆｆ
* ARPパケットのフォーマット
    * イーサネットで動作
    * ARPパケットである
    * イーサネットフレームにヘッダ付加
* 参考URL（ARPとは、RARPとは： https://www.infraexpert.com/study/tcpip2.html）

#### ICMP
* 通信状態を確認することと、エラーを通知する
* pingとtraceroute
* よく使う系のメッセージは障害調査で使うこともある
https://www.infraexpert.com/study/tcpip4.html

| タイプ | コード | 事象                                           | Linuxの対処方法                           | Windowsの対処方法                         |
|--------|--------|------------------------------------------------|------------------------------------------|------------------------------------------|
| 3      | 0      | ネットワークに到達できない                     | ip route show                             | route print                              |
| 3      | 1      | ホストに到達できない                           | ping -c 4 <宛先ホスト>                    | ping -n 4 <宛先ホスト>                   |
| 3      | 2      | プロトコルに到達できない                       | -                                          | -                                        |
| 3      | 3      | ポートに到達できない                           | nc -zv <宛先ホスト> <ポート番号>          | Test-NetConnection -ComputerName <宛先ホスト> -Port <ポート番号> |
| 3      | 4      | フラグメント化が必要だが禁止されている         | -                                          | -                                        |
| 3      | 5      | ソースルートの失敗                             | traceroute <宛先ホスト>                   | tracert <宛先ホスト>                     |
| 4      | 0      | リダイレクト（ネットワーク）                   | -                                          | -                                        |
| 4      | 1      | リダイレクト（ホスト）                         | -                                          | -                                        |
| 11     | 0      | TTL超過                                        | traceroute <宛先ホスト>                   | tracert <宛先ホスト>                     |
| 12     | 0      | パラメータ問題                                 | tcpdump -i <インタフェース名> icmp        | tcpdump -i <インタフェース名> icmp        |
| 13     | 0      | タイムスタンプ要求                             | -                                          | -                                        |
| 14     | 0      | タイムスタンプ応答                             | -                                          | -                                        |
| 17     | 0      | アドレスマスク要求                             | tcpdump -i <インタフェース名> icmp        | tcpdump -i <インタフェース名> icmp        |
| 18     | 0      | アドレスマスク応答                             | -                                          | -                                        |

---
#### 余談（PlantUMLでできるだけきれいなAWS構成図を描く方法）

https://qiita.com/sakai00kou/items/18e389fc85a8af59d9e0

https://plantuml.com/ja-dark/activity-diagram-legacy

---

### ネットワーク全体アーキテクチャ

ネットワークの一般的な要件として、スイッチ、ロードバランサ、ファイヤーウォールがあります。
これらの基本的な役割や、どのように通信制御するかは知っておいた方が良さそうです。




---

#### ファイヤーウォール
* 不正アクセスによるデータの改ざんや情報漏えいなどを防ぎます。
* パケット、httpやftpなどのアプリケーション、サーキットレベルのフィルタリングができます。
* サーキットレベルは送信元IPアドレスの偽装（IPスプーフィング）が防げます。
* タイプは主に3つ。

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

##### アプリケーションレベルゲートウェイ型

##### サーキットレベルゲートウェイ型

##### ファイヤーウォールだけではセキュリティは不十分
* IDS（Intrusion Detection System）
* IPS（Intrusion Prevention System）
* OSやwebサーバの脆弱性を突いた攻撃を防ぐ
* WAF
* SQLインジェクション、クロスサイトスクリプティング、OSコマンドインジェクションなどの偽装リクエストを検知

参考
https://www.ntt.com/business/services/network/internet-connect/ocn-business/bocn/knowledge/archive_09.html#:~:text=ファイアウォール（Fire%20Wall）とは,では必須の機能です%E3%80%82
https://www.rworks.jp/system/system-column/sys-entry/21277/
https://www.infraexpert.com/study/security3.html

---

#### ロードバランサ
* 外部からのトラフィックを適切なノードへ割り振る
* ノードの過負荷防止、SSL暗号化、セッション保持ができる
（特にセッションを維持できると、決済などのクリティカルな通信でメリットあり。途中で別のサーバーに切り替わるのを防ぐ）
* IP、パスベースでのルーティングを指定可能
* 振り分けの方法も選択可能（ラウンドロビンかリーストコネクション）
* DNSラウンドロビンは名前解決で、毎回違うIPアドレスのサーバーを返すようにしているでロードバランサの機能には劣る（負荷分散ではない）
参考：https://www.onamae.com/column/domain/38/
* サーバへの接続
    * ロードバランサは仮想IP:ポートに接続
    * バーチャルサーバに関連付けたリアルサーバ（ 実サーバ ）
    * プールとプールメンバーを登録している
```plantuml
skinparam linetype ortho
circle "client"
rectangle "LoadBalancer" #LightGreen 
rectangle "Pool（SVS）" {
    rectangle "PoolMember(SV1)" #LightBlue 
    rectangle "PoolMember(SV2)" #LightBlue 
    rectangle "PoolMember(SV3)" #LightBlue 
}
"client" -[hidden]d-"LoadBalancer"
"LoadBalancer" -[hidden]d-"PoolMember(SV1)"
"LoadBalancer" -[hidden]d-"PoolMember(SV2)"
"LoadBalancer" -[hidden]d-"PoolMember(SV3)"
"PoolMember(SV1)" -[hidden]r-"PoolMember(SV2)"
"PoolMember(SV2)" -[hidden]r-"PoolMember(SV3)"
"client" =r=> "LoadBalancer"
"LoadBalancer" =r=> "PoolMember(SV1)"
"LoadBalancer" -r-> "PoolMember(SV2)"
"LoadBalancer" -r-> "PoolMember(SV3)"
note right of LoadBalancer
  プール：SVS
  プールメンバー：SV1,SV2,SV3のXXXXポート
end note
note left of LoadBalancer
  バーチャルサーバ：仮想IP:XXXXポート
  ※ポートはプールメンバーと異なるケースもあり（SNAT
end note
```
* 参考：https://www.rworks.jp/system/system-column/sys-entry/16305/
* https://www.infraexpert.com/study/loadbalancer7.html
---

#### スイッチ
* パケット通信を目的のサーバに転送する
* L2SW
   * 宛先MACアドレスを見てパケット転送
* L3SW
   * 宛先IPアドレスを見てパケット転送
* ルータ
   * ネットワーク間を中継する
   * ２つの異なるLAN（Local Area Network）間、WAN（Wide Area Network）間、あるいはLANとISP（Internet Seveice Provider）の間
   * L2SW間を繋ぐ時はルータを挟む


* 参考
https://www.cloudflare.com/ja-jp/learning/network-layer/what-is-a-network-switch/
https://community.fs.com/jp/article/do-you-know-the-differences-between-hubs-switches-and-routers.html
---

##### 3階層型ネットワーク
* コア層、ディストリビューション層、アクセス層で別れる。
* 異なるラック間のサーバ間接続においては、
サーバ→アクセス層→ディストリビューション層（場合によってはコア層）のスイッチにさかのぼって通信する。

```plantuml
@startuml

title 3階層型ネットワークのイメージ
skinparam linetype line 
rectangle "コア層\nSW1"
rectangle "コア層\nSW2"
rectangle "ディストリ\nビューション層\nSW1"
rectangle "ディストリ\nビューション層\nSW2"
rectangle "アクセス層\nSW1"
rectangle "アクセス層\nSW2"
rectangle "アクセス層\nSW3"
rectangle "アクセス層\nSW4"
"アクセス層\nSW1"-[hidden]r--"アクセス層\nSW2"
"アクセス層\nSW2"-[hidden]r--"アクセス層\nSW3"
"アクセス層\nSW3"-[hidden]r--"アクセス層\nSW4"
circle "Server1"
circle "Server2"
circle "Server3"
circle "Server4"

"コア層\nSW1"--"ディストリ\nビューション層\nSW1"
"コア層\nSW1"--"ディストリ\nビューション層\nSW2"
"コア層\nSW2"--"ディストリ\nビューション層\nSW1"
"コア層\nSW2"--"ディストリ\nビューション層\nSW2"
"ディストリ\nビューション層\nSW1"--"アクセス層\nSW1"
"ディストリ\nビューション層\nSW1"--"アクセス層\nSW2"
"ディストリ\nビューション層\nSW1"--"アクセス層\nSW3"
"ディストリ\nビューション層\nSW1"--"アクセス層\nSW4"
"ディストリ\nビューション層\nSW2"--"アクセス層\nSW1"
"ディストリ\nビューション層\nSW2"--"アクセス層\nSW2"
"ディストリ\nビューション層\nSW2"--"アクセス層\nSW3"
"ディストリ\nビューション層\nSW2"--"アクセス層\nSW4"
"アクセス層\nSW1"--"Server1"
"アクセス層\nSW2"--"Server2"
"アクセス層\nSW3"--"Server3"
"アクセス層\nSW4"--"Server4"
@enduml
```

* イメージ図は、コア層、ディストリビューション層、アクセス層、サーバの位置づけである
* <b>接続間は、ロードバランサやファイヤーウォール、サーバが入る場合もあり、性能やセキュリティ要件によって左右される。</b>
---

##### spine-leaf型ネットワーク
* スパインスイッチ：リーフスイッチへの接続をする。スイッチング容量が足りなくなったらスパイン（幹）増設する。
* リーフスイッチ：ポート（サーバを接続するポート）不足になったら、リーフ（枝）を増設する。

```plantuml
@startuml

title spine-leaf型ネットワークのイメージ
skinparam linetype line
rectangle "スパインSW1"
rectangle "スパインSW2"
rectangle "リーフSW1"
rectangle "リーフSW2"
rectangle "リーフSW3"
rectangle "リーフSW4"
circle "Server1"
circle "Server2"
circle "Server3"
circle "Server4"
"リーフSW1"-[hidden]r--"リーフSW2"
"リーフSW2"-[hidden]r--"リーフSW3"
"リーフSW3"-[hidden]r--"リーフSW4"
"Server1"-[hidden]r--"Server2"
"Server2"-[hidden]r--"Server3"
"Server3"-[hidden]r--"Server4"

"スパインSW1"--"リーフSW1"
"スパインSW1"--"リーフSW2"
"スパインSW1"--"リーフSW3"
"スパインSW1"--"リーフSW4"
"スパインSW2"--"リーフSW1"
"スパインSW2"--"リーフSW2"
"スパインSW2"--"リーフSW3"
"スパインSW2"--"リーフSW4"
"リーフSW1"-d-"Server1"
"リーフSW2"-d-"Server2"
"リーフSW3"-d-"Server3"
"リーフSW4"-d-"Server4"
@enduml
```
* <b>接続間は、ロードバランサやファイヤーウォール、サーバが入る場合もあり、性能やセキュリティ要件によって左右される。</b>
* リーフスイッチ同士、スパインスイッチ同士は接続しない
* 3階層型ネットワークと違い、スケーリングが可能で、異なるラック間通信の遅延がない。
* 一方で、障害調査の煩雑さが懸念。

* 参考URL

https://note.com/kenkoishinri/n/ne260aa364e92
    
https://www.kenschool.jp/blog/?p=5329

https://qiita.com/FScom_Japan/items/e7638e7014548725cb04

---