0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ネットワークはなぜつながるのか 自分の言葉で備忘録

Last updated at Posted at 2024-11-14

第1章 Webブラウザがメッセージを作る

ブラウザでURLバーにアドレスを打ってから何が起こるのか

  1. まずはURLの解析が行われる
    http://www.hogehoge.com/fuga

というURLがある
これは

http => プロトコル
www.hogehoge.com => サーバー名
/fuga => パス

という大まかに分けて3つに分類される

プロトコルは通信の方式
サーバー名はどのサーバーか
パスはサーバーの中のどのファイルorディレクトリか
を表す

次にブラウザはHTTPプロトコルを使用することがわかったのでHTTPリクエストを組み立てる

HTTPリクエストは以下の4つからなる

  • リクエストライン
    • メソッド
      • 大まかにわけて以下の2つがある
        • 取得するGET
        • 送信するPOST
    • URI
      • Webサーバーで動作するプログラムのファイル名
    • HTTPバージョン
      • その名の通り
  • メッセージボディ
    • メッセージの内容

そしてサーバーにこのリクエストを送るとサーバーからはレスポンスが返ってくる

  • レスポンスライン
    • HTTPバージョン
      • その名の通り
    • ステータスコード
      • どんな状態かを端的に表す
    • レスポンスフレーズ
      • ステータスコードの内容を表す
  • メッセージボディ
      • メッセージの内容

ちなみに画像などがwebページに100個あったらこれらのリクエストは個別にサーバーに100個送られて個別にレスポンスが返ってくる

HTTPについてはこれでおしまい
つぎはサーバーに対してどうやってデータを送るか
サーバーに対してデータを送るにはIPアドレスというものが必要になる

IPアドレスとはPCの住所のようなもので
172.11.34.11みたいな .が3つつくもの
.で繋がれた数字はすべて0~255の数字になる

アドレスを入力されたブラウザはどうやってhogehoge.comという文字列からこのIPアドレスを取得しているか?

それはDNSサーバーというPCの住所を知っているサーバーに対して「こいつのIPアドレスはなんですか?」と訪ねて、もしそのDNSサーバーが知っていたら「こいつのIPアドレスはXXXX.XXXX.XXXX.XXXXですよ〜」と教えてくれる

これをDNSルックアップという

仕組みはシンプルで以下のような対応表が各DNSサーバーにあってサーバー名が各PCからわたってくるのでそれに対して一致するものがあれば返答してくれる

サーバー名 タイプ クライアントに返答する項目
www.hogehoge.com A 123.234.211.111
www.google.com A 142.251.42.142

ちなみにターミナルで以下のように打つと

nslookup google.com

返ってくる

Non-authoritative answer:
Name:	google.com
Address: 142.251.42.142

そして普通に142.251.42.142をアドレスに打ち込むと普通にgoogleが表示される

余談

  • DNSサーバーに尋ねるにはブラウザからは直接できないらしくてDNSリゾルバというブラウザとは別の仕組みを使用して尋ねる
  • そのDNSリゾルバも実はただ実行するだけのものらしくてプロトコル・スタックという通信するためのものに頼む

DNSサーバーには対応表があってリクエストに一致するものがあれば返されるっていったけどないときはどうするねんってなると思うけどその時はDNSサーバーの中で一番上位の存在のルート・ドメインっていうDNSサーバーに聞くと解決する

こんな感じ
image.png

DNSサーバーは階層構造になっていて

www.hogehoge.com.jpというドメインがあるとして
wwwはhogehogeに属していて
hogehogeはcomに属していて
comはjpに属しているとみる

一番右のやつが一番でかくて左に行くにつれてどんどん規模が小さくなっていく
んで
ルートはcomとかjpとかukとかいうドメインを束ねている
jpはcomとかtokyoとかそういったドメインを束ねている
そのjpの中のcomの中のhogehogeの中にwwwというサーバーの実態がある

それでルートに聞くとまずjpにきいて、jpはcomに聞いてcomはhogehogeに聞いて結局hogehogeが「にwwwという実態がありましたー。こいつのIPアドレスはXXXX.XXXXX.XXXX.XXXXですー」っていう返答を返してくれる

ちなみにこんな感じで聞いていったけど結局どこにもなかったという場合も多々あり、そういうときは DNS_PROBE_FINISHED_NXDOMAIN という返答が返ってくる

実際に
http://fjwlekjfwekl.com/ という適当なURLを打ったらこんな感じの画面になる
image.png

IPアドレスを調べることができたらやっとそのIPアドレスの相手(webサーバー)に対してHTTPリクエストを送ることができるようになる

(ただHTTPリクエストを呼ぶときもDNSのリクエストを送るみたいにプロトコル・スタックというハードウェア寄りの機構を呼ぶことになる)

HTTPリクエストとHTTPレスポンスをブラウザとサーバーの間で行ったり来たりさせるためにはブラウザとサーバーの間でデータの通り道を用意する必要がある

第2章 TCP/IPのデータを電気信号にして送る

第1章でURLを解読し、HTTPリクエストを作り、ドメイン名からIPアドレスを取得するDNSルックアップまでを勉強したが、この章ではその先の動きを勉強する

HTTPリクエストをサーバーに送るため、必要なのはTCPプロトコルを使用してサーバー側と通信のパイプを確立しデータを送受信すること

そのために必要なステップは以下の3つ

  1. ソケットを作成する
  2. サーバーに接続する
  3. データを送受信すること

1. ソケットを作成する

TCPプロトコルは接続のための制御をするプロトコルでブラウザ <=> サーバーの通信ではこちらが主に使用される

ソケットを作成すると通信を制御するための情報として、通信相手のIPアドレスやポート番号、通信の進行状態などの情報が格納されている

2. サーバーに接続する

クライアントから 「IPアドレス、ポート番号、何をしたいか」といった情報を受け取ると接続が確立される

また

「IPアドレス、ポート番号、何をしたいか」
このような送受信の際に使用される情報はTCPヘッダーといい、以下のような種類がある

項目 長さ 詳細
送信元ポート番号 16ビット 送信した側のプログラムのポート番号
宛先ポート番号 16ビット 送信先のプログラムのポート番号
シーケンス番号 32ビット このパケットの先頭位置のデータが送信データの何倍と目に当たるのか伝えるためのもの
ACK番号 32ビット データが何バイト目まで受信側に届いたのか伝えるもの
データオフセット 4ビット ヘッダーの長さを表す
コントロールビット 6ビット 制御用のもの
ウィンドウ 16ビット 受信確認を待たずにまとめて送信可能なデータ量を通知するためにしようする
チェックサム 16ビット 誤りの有無を検査するためのもの

クライアント側のTCPヘッダーのコントロールビットのSYNというビットを1にしてサーバーにパケットを送る

サーバー側がそのTCPヘッダーを受け取り、そこに記録されている宛先ポート番号と同じソケットを探したら、必要な情報を記録し、コントロールビットのSYNとACKを1にしたTCPヘッダーを作り、パケットをクライアントに送り返す。

接続を終了する際は送り返されたクライアントがコントロールビットのACKを1にしてサーバーに送る

3. データの送受信

データが送り返されたときにすぐにデータを送るのではなく、ある程度データが溜まった状態でパケットを送る
なぜならすぐに送ると小さなパケットをたくさん送られてしまい、ネットワークの利用効率が低下してしまうため。

また1つのパケットで送ることができるバイト数は決まっていて、1500バイトとなっている
もしデータが1500バイトを超えると分割して送ることになる

  • UTF-8では半角英数字は1文字1バイトなので1500文字

分割するときにどこが何番目かという情報が必要になるので(=6000バイトあるとして4つに分割されたときに送った順番がないとぐちゃぐちゃになる)TCPヘッダーにあるシーケンス番号という項目にそのパケットが先頭から数えて何バイト目かの値を格納して送ることで受け取り側が順番を知ることができる

受け取り側(サーバー)はそれ以前のデータと合わせて何バイト目までを受け取ったかを計算してTCPヘッダーのACK番号に記載して送信側(クライアント)に知らせます

制御方式について

パケットを1つ送ってACKを待つ(=ピンポン方式)というのはシンプルですが、その時間そのまま待つのは時間がもったいないため、クライアントがACKを待たずにどんどんデータ送信をするウィンドウ制御方式というものがあります

image.png

こんなイメージです
受け取り側は送られたパケットを受信したらとりあえずメモリーにデータを仮置きします
仮置きされたデータの断片をつなぎ合わせて元のデータを復元してアプリケーションに渡します

ただもしクライアントがこのメモリーの許容量を超えてパケットを送ってしまったら溢れてしまいます

そこで受信側はクライアントに対して事前にメモリーのキャパシティを送ることでクライアントは送っても良いバイト数を知り、そのキャパシティまでをデータを送ることができます
このバイト数はTCPヘッダーのウィンドウフィールドに格納されてクライアントが知ることができます
またこの許容量をウィンドウサイズといいます

パケットの基本

サーバーに送られるためにパケットには宛先アドレスからXXX番目のケーブルが使用されるということがわかり、そこから送信される。送信されたあとに中継装置(ルーター)に届き、さらにその次の中継装置に届く
具体的にすると

  1. ルーター(IP担当)が目的地を見定めて次のルーターを示し
  2. ハブ(イーサネット担当)がサブネットの中でパケットを運んで次のルーターに届ける

パケットが荷物だとすると、ルーター(IP)は空港で飛行機が飛んで、ハブ(イーサネット)はバスターミナルで、バスが出発して国の中のどこかに届けられるイメージ
国の中の空港にはバスで移動し、国から国(もしくは遠い国内の空港)へは飛行機で移動する

パケットのイメージ

image.png

ハブのイメージ

image.png

ルーターのイメージ

image.png

TCPからデータを送信することを依頼されたIP担当部分は
MACヘッダーとIPヘッダーとを作ってTCPヘッダーの前にくっつけます

IPヘッダーは以下です(全部ではない)

項目 サイズ 詳細
送信元IPアドレス 32バイト 発信した側のIPアドレス
宛先IPアドレス 32バイト 届ける相手のIPアドレス
ヘッダー長 4バイト IPヘッダーの長さ
ID情報 16バイト ここのパケットを識別する番号。
分割されたパケットはすべて同じ番号になる
生存期限(TTL) 8バイト ネットワークにループができたときに永遠にパケットが回り続けないようにするためのもの。
ルーターを経由するたびに値が-1される
プロトコル番号 8バイト TCP: 06
UDP: 11
ICMP: 01
フラグ 3バイト フラグメンテーションの可否とこのパケットが分割されたかどうかを表す

宛先IPアドレスはTCPから伝わってきたもの(DNSルックアップをして得られたアドレス)で送信元IPアドレスはクライアントのLANアダプタのアドレス
※IPアドレスはコンピュータに対して割り当てられるのではなく、LANアダプタに割り振られる

MACヘッダー

項目 サイズ 詳細
宛先MACアドレス 48バイト パケットを届ける相手のMACアドレス
送信元MACアドレス 48バイト パケットを送信した側のMACアドレス
イーサタイプ 16バイト 0800 IPプロトコル
0806 ARPプロトコル

MACアドレスは個々のLANアダプタのROMに紐付けられた世界に一つだけのアドレス

IPヘッダーを作るときに宛先IPアドレスはDNSルックアップでわかりました
ただ宛先MACアドレスはわかりません
そのときどうするべきか、
ここで使われるのがARPというプロトコルで、イーサネットがサブネット内のつながっている全員にパケットを届けるブロードキャストという仕組みで「XXXXというIPアドレスを持っている人はいませんか?いたらMACアドレスを教えて下さい」というと該当者から「私のMACアドレスはYYYYです」という応答が帰ってきます。
全員にパケットが届けられたのですが、該当しなかった人は返答を何も返さずにパケットを捨てます。
これがイーサネットの基本的な仕組みです。

第3章 ケーブルの先はLAN機器だった

ルーターの基本

ルーターの役目はIPアドレスを元に次のルーターに中継をすることです

パケットがハブから送られてきたとき、IPアドレスで中継先を判断する
このときにルーティングテーブルというサブネットを表すIPアドレスが載っているテーブルを見て、
送られてきたパケットの宛先IPアドレスを見て該当したらパケットをその宛先に中継する
ゲートウェイ欄に登録されているIPアドレスを持つルーターに対してインターフェース欄に登録されているポートからパケットを中継する

前提: 192.168.1.10というサーバー宛に送ったパケット
Aルーターから送られてきたパケットを受け取ったBルーターの動作
まずMACヘッダーは使用しないので捨ててIPヘッダーを見ます
ルーティングテーブルとパケットの宛先IPアドレスを比較します
192.168.1.0/24
192.168.1.0/25
上記のように同じアドレスがあった場合はネットワーク番号のビット数が長いもの(サブネットマスクが25の方)
を優先して選びます
理由としてネットワーク番号が長いということはホスト番号のビット数が少ないということで
割り当て可能な台数が少ないということで、範囲が絞り込まれているからです
逆に一致するものが一つも見つからなかった場合
ネットマスクが0のところにパケットを中継します
これはデフォルトゲートウェイと呼び、インターネットへの入口になります。
そして送信する前にTTLというIPヘッダーのフィールドを-1してから送信します
これによりパケットの中継ループを防ぎます(普通は起きないけど、ルーティングテーブルに中継先が正しく登録されていないときに起こる可能性がある)

第5章 サーバー側のLANには何がある

ファイアウォールについて

サーバーの前に遮るものが何もない状態だと防御力がめちゃめちゃ弱いので対応する必要がある。
その防御のために使用されるのがファイアウォール
ファイアウォールは特定のサーバー上で動く特定のアプリケーションにアクセスするパケットだけを通し、それ以外のパケットを遮断する役割を持っている。そのおかげで外部からのアクセスを許可していないアプリケーションへのパケットの侵入を遮断してくれる。

ファイアウォールの仕組み

アプリケーションにアクセスできるパケットを選り分けるために今はパケットフィルタリングという方法が最も普及している

パケットフィルタリングとは

MACヘッダー、IPヘッダー、TCP or UDPヘッダーなどを見て適切なパケットかを判断すること

IPヘッダーでのフィルタリング

インターネットから流れてくるパケットの場合

IPヘッダーの宛先IPアドレスと送信元IPアドレスを見て、始点と終点を判断する。インターネットから流れてくるパケットは始点を特定できないが、流れの終点はWebサーバーになるのでそこがあっているかを確認して、あっていない場合通さない

webサーバーからインターネットに流れるパケットの場合

始点がちゃんとwebサーバーのアドレスに一致するか確認し、あっていない場合は通さない

TCPヘッダー、UDPヘッダーでのフィルタリング

インターネットから流れてくるパケットの場合

  • 宛先ポート番号を調べてがwebサーバーと一致しているか
  • TCPヘッダーのコントロールビットで判断

webサーバーからインターネットに流れるパケットの場合

  • 送信元ポート番号を調べてがwebサーバーと一致しているか
  • TCPヘッダーのコントロールビットで判断

複数サーバーにリクエストを振り分けてサーバーの負荷の分散をする

サーバーへのアクセスが増えたときにサーバーの処理能力が追いつかなくなることがあります
このときにサーバーのスペックを単純に上げるスケールアップとサーバの台数を増やしてアクセスを振り分けるスケールアウトという方法があります
振り分ける機器はロードバランサーといいます
ロードバランサーのIPアドレスをDNSサーバーに登録することでクライアントのリクエストを直接Webサーバーにするのではなく、ロードバランサーに変えられ、ロードバランサーがそのリクエストをさばくことができます

ラウンドロビン:リクエストをすべてのサーバーに均等に振り分ける方式です。各サーバーで処理するリクエストの数が均等になるため、平均的にはサーバの負荷も均等になります。
リーストコネクション:その時点で一番接続数が少ないサーバーに送信する方式です。
IPハッシュ:同じIPアドレスからのリクエストは、同じ振り分け先サーバーへ振り分けられる方式です。
ノード単位の分散:クライアント(利用者)を1つの単位とし、同じクライアントからのすべてのリクエストを同じ分散対象サーバに振り分ける方式です。

キャッシュサーバーを利用したサーバーの負荷分散

ロードバランサーの他にも負荷分散の方法がありまして、そのうちの一つがキャッシュサーバーになります
キャッシュサーバーはプロキシという仕組みを使用して、webサーバーとクライアントの間に入り、webサーバーから受け取ったデータを保存しておき、そのデータをwebサーバーに代わってクライアントに送り返す機能を持ちます。

例えば計算量に膨大な時間がかかるけど、頻繁に返す値は変わらないようなリクエストがあるとします。
それはwebサーバー的にもクライアント的にもきついです
なのでキャッシュにやってもらいます
キャッシュの仕組みとしてはロードバランサーのように、DNSサーバーにwebサーバーのIPアドレスを登録する代わりにキャッシュサーバーのIPアドレスを登録します。
そしてキャッシュサーバーがクライアントのリクエストを受け取ります
キャッシュサーバーはリクエストを受取り、そのデータが自分のキャッシュに保存されているのか確認します
もし保存されていなければ、webサーバーに対してデータを貰い、そのデータをキャッシュに保存しつつ、クライアントに変えします
次にもし保存されていたら、キャッシュサーバーからwebサーバーに対して前回保存されたん日付を送り、webサーバー側はその日付を確認してもしその日付から変更があればデータを、変更がなければ変更はありませんという内容を送り返します。
こうすることで、webサーバーの負荷は下がることになります。

コンテンツ配信サービス

先程のキャッシュサーバーはwebサーバー側に置くものでしたが、webサーバーとクライアントの間(経路上)に置くキャッシュサーバがあり、それはCDN(Content Delivery Network)と呼ばれています。
CDNはいろいろな場所に存在するので、リクエストを送ったクライアントの近くにあることもあります。
そうすることでレスポンス速度に大きく寄与します。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?