[初心者向け]Webサービスを利用する際のDNSからTCPコネクションについて再入門

[初心者向け]Webサービスを利用する際のDNSからTCPコネクションについて再入門

おはようございます、もきゅりんです。

AWSは毎日のようにアップデートや新たなサービスを提供しています。AWSのみならず、IT業界全般では、次々と進化が繰り広げられています。それを見聞き、触りながら、追い掛けるだけでも大変なことだと思います。

そんな中、ふと、自分は新しいものを追い掛ける上で、ごく当たり前のようにして使っているものに、もう少し理解を深めたいと思った瞬間がありました。

知ろうとすると、底は見えないのですが、とりあえず、下図のような単純な構成を用いて、どのようにクライアントはWebサービスを利用しているのかを、復習も兼ねつつ、少しだけ深堀っていきたいと思いました。

対象は、何となくAWSを触っているような、駆け出しITエンジニアさんです。IT業界で長く生息する方々には一般常識レベルのことが多いかと思います。

simple_architecture

まずは、xxxx.jp、zzzz.comなどをブラウザに入力した際の動きから確認していきます。

client_dns

DNS(Domain Name System)とは、ご存知の通り、ローマ字とピリオドを使った名前からIPアドレスに自動的に変換するものです。

Route53のブラックベルトから、わかりやすい図を転載して用語で補足していきます。

route53_example

『出典:AWS Black Belt Tech シリーズ 2016 - Amazon Route 53 p.007』

ここで登場するものを中心に用語をまとめていきます。

用語

①ネームサーバー

ネームサーバーとは、ドメイン名を管理しているホストやソフトウェアのことです。ネームサーバは、それぞれのドメイン階層ごとに配置されています。(.com,.example.com,...) それぞれのネームサーバーは、ドメイン階層ごとで情報を管理しています。それぞれのドメインの階層ごとで管理する情報に応答するネームサーバを指して、「②権威DNSサーバ」とも呼びます。

それぞれのネームサーバーは下の階層のネームサーバーのIPアドレスを知っており、③ルートサーバーをトップにしてTree構造のようにして結ばれています。なお、ネームサーバーとDNSサーバーは同一の概念のようです。

④リゾルバ

DNSに問い合わせを行うホスト、ソフトウェアをリゾルバといいます。 ご自身が今、利用しているPCもリゾルバとなります。 リゾルバやネームサーバーは、新たに知った情報をしばらく⑤キャッシュしておき、毎回問い合わせる手間を防ぎます。その設定値をTTL(Time To Live)と呼び、それぞれのデータ(レコード)に設定されています。

⑥ゾーン

ある権威DNSサーバが管理する範囲を⑥「ゾーン」と呼びます。(Route53で作成するホストゾーンです。)

名前解決で起点となるルートネームサーバは、ルートゾーンを管理します。そのゾーンのDNS(名前解決)のための情報を「ゾーンファイル」と呼びます。

ゾーンファイルを構成する1件1件の情報(AレコードやNSレコードですね)が、「DNSレコード」または「リソースレコード」と呼ばれます。

主なレコード

下記表が主なレコードです。

タイプ 内容
A ホスト名とIPアドレスの対応
NS ドメインのゾーン情報を管理するDNSサーバ
CNAME ホストの別名になります。この名前で他のDNSレコードを定義できません。
MX メールサーバーのホスト名
SOA ゾーンの管理のための情報や設定などを記述したもの

もう少しSOAレコードについて触れます。

形式として、下記のようになっており、

[認証局ドメイン] [ゾーン管理者のドメイン]
[ゾーンのシリアル番号] [更新時間] [再試行時間]
[期限が切れる時間] [負の結果をキャッシュする TTL]

ゾーンの管理を行うDNSサーバのFQDN(ホスト名まで含むドメイン名)や、管理者に連絡が取れるメールアドレス、ゾーン情報の新旧を判別するためのシリアルナンバー(改訂する度に増加する)が順に記載されています。

続く3つの情報は、セカンダリネームサーバがプライマリのネームサーバから入手したゾーン情報を、どう扱うかを指定するものです。各データはそれぞれ秒数で指定されています。

digコマンドで弊社クラスメソッドのSOAレコードを確認してみましょう。ANSWER SECTIONに上記形式で内容が記載されています。

# SOAレコード
$ dig soa classmethod.jp

; <<>> DiG 9.10.6 <<>> soa classmethod.jp
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 4338
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;classmethod.jp.			IN	SOA

;; ANSWER SECTION:
classmethod.jp.		1127	IN	SOA	ns-266.awsdns-33.com. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400

;; Query time: 625 msec
;; SERVER: 172.20.10.1#53(172.20.10.1)
;; WHEN: Fri Oct 18 12:33:09 JST 2019
;; MSG SIZE  rcvd: 124

なお、AWSで重要なのは、ALIASレコードです。AWS独自の仮想リソースレコードです。DNSクエリに対して、ホストゾーン内のリソースレコードセット、ELBやCloudFrontといったAWSサービスのエンドポイントのIPアドレスを直接返します。

通常はCNAMEを利用するのですが、 CNAMEの同一の名前で他のDNSレコードを定義してはいけない(ドメイン自身はNSレコードで使用されてしまう)というDNSにおける制限と、AWSでは、エンドポイントのIPアドレスが変化してしまうため、Aレコードで設定できないといった点を、ALIASレコードを利用すると解消できます。

DNSからIPアドレスを調べてみる

digコマンドで弊社クラスメソッドのAレコードを確認します。 (CloudFrontのIPが返却されますが。)

# Aレコード
$ dig classmethod.jp
; <<>> DiG 9.10.6 <<>> classmethod.jp
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 42387
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;classmethod.jp.			IN	A

;; ANSWER SECTION:
classmethod.jp.		77	IN	A	13.225.166.3
classmethod.jp.		77	IN	A	13.225.166.72
classmethod.jp.		77	IN	A	13.225.166.4
classmethod.jp.		77	IN	A	13.225.166.42

;; Query time: 53 msec
;; SERVER: 172.20.10.1#53(172.20.10.1)
;; WHEN: Fri Oct 18 12:32:11 JST 2019
;; MSG SIZE  rcvd: 107

ちなみに、CloudFrontのDNSの仕組みは下図です。

cdn_dns

『出典:20190730 AWS Black Belt Online Seminar Amazon CloudFrontの概要 p.015』

これで、ネームサーバからIPアドレスを取得できました。

digコマンドのレスポンスの細かい内容については、弊社ブログにも参考となるものがあります。

DNSド素人がdigコマンドとRoute 53を使って、DNSについてあれこれ学んでみた

ところでIPアドレスとは何だったでしょうか? IPアドレスが返ると何が嬉しいのでしょう。

そもそもIPアドレスとは

IPアドレスとは、ネットワークに接続されているすべてのホストの中から、通信を行う宛先の識別子です。ネットワークインターフェイス(NIC) *1ごとに、1つ以上のIPアドレスが必要となります。

IPアドレスがわかるとルーター *2によって、ルーティング(経路制御) *3されて、別のルーターを辿り、さらにルーティングされて、を繰り返し、最終的に目的のサーバまで、IPアドレスを頼りに(IPアドレスをもとにMACアドレス宛に)配送されます。 *4なお、ルーティングする設定がルーティングテーブルとなります。

IPアドレスからコンピュータを識別するMACアドレスに到着し、ようやく目的地に辿り着くことができました。

TCPコネクション

hoge.comを閲覧するためには、HTTPまたはHTTPSプロトコルが必要とします。今、HTTPを利用するとすれば、通常80番のポート番号になります。 宛先となるサーバは80番ポートを開放していて、デーモンプロセスが80番で待機しているとします。 クライアントとなる私のPCは、HTTPのサービスを利用するため、hoge.comに対してポート80番宛にTCP *5コネクションのリクエストを送信します。リクエストを受けたサーバは確認、というリスポンスを返し、さらにリクエストした私のPCが、確認というレスポンスを受信した、というレスポンスを返します。 *6

今対象のサーバにssh接続して、上記の状態を確認してみます。

サーバにnginxをインストールして起動させます。

現在、httpサービスが80番ポートで待ち受け状態なのが分かります。また、sshサービスが外部ホストとコネクションを確立しているのも分かります。(netstat -naで数値表示になります。)

[ec2-user@ip-172-31-47-94 ~]$ netstat -a
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 0.0.0.0:sunrpc          0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:http            0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:ssh             0.0.0.0:*               LISTEN
tcp        0      0 localhost:smtp          0.0.0.0:*               LISTEN
tcp        0    244 ip-172-31-47-94.ap-:ssh g1-27-253-251-144:34344 ESTABLISHED ESTABLISHED

今、仮にRoute53でmoqrin.comというドメインを購入して、AレコードにサーバのパブリックIPを設定したとします。

buy domain

A record setting

digでmoqrin.comのIPアドレスを取得します。

$ dig moqrin.com
; <<>> DiG 9.10.6 <<>> moqrin.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 61986
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;moqrin.com. IN A

;; ANSWER SECTION:
moqrin.com. 4502 IN A 13.113.246.204

;; Query time: 191 msec
;; SERVER: 172.20.10.1#53(172.20.10.1)
;; WHEN: Fri Oct 18 12:47:00 JST 2019
;; MSG SIZE  rcvd: 100

telnetでmoqrin.comの80番ポートに接続してみます。上記のIPアドレス:80に接続していることが見て分かります。

curl -v telnet://moqrin.com:80
* Rebuilt URL to: telnet://moqrin.com:80/
*   Trying 13.113.246.204...
* TCP_NODELAY set
* Connected to moqrin.com (13.113.246.204) port 80 (#0)

httpサービスと外部ホスト(自分のPC)とがTCPコネクションが確立されたことが分かります。

[ec2-user@ip-172-31-47-94 ~]$ netstat -a
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 0.0.0.0:sunrpc          0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:http            0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:ssh             0.0.0.0:*               LISTEN
tcp        0      0 localhost:smtp          0.0.0.0:*               LISTEN
tcp        0    244 ip-172-31-47-94.ap-:ssh g1-27-253-251-144:34344 ESTABLISHED
tcp        0      0 ip-172-31-47-94.ap:http g1-27-253-251-144:45641 ESTABLISHED

わたしのPCからインターネットへ

最近は光回線を利用していることが多いようなので、FTTH(Fiber TO The Home) *7を利用していることとします。 私のPCからのインターネットへの経由は、家にある無線LAN *8を通り、DefaultGateway(ルーター)を出て、ONU *9によって光に変換されて、OLT(一般的には電話局内) *10を辿り、NGN網 *11から網終端装置を通じてISP(Internet Service Provider)に接続され、ISPの内部ネットワークを経て、ISPのルータからインターネットに接続されます。

home_internet

まとめ

ここまでで、わたしのPCからドメインxxxx.comからIPアドレスの取得、IPアドレス:ポート番号へのTCPコネクションまでを確認してきました。

この確立されたTCPの通信路を使って、HTTPプロトコルの送受信のやり取りを行います。

いわゆる、GETやPOSTなどです。

次回、[初心者向け]Webサービスを利用する際のHTTPについて再入門に続きます。

参考:

脚注

  1. NIC(Network Interface Card)
    ネットワークに接続するための機器。コンピュータにははじめから内蔵されていることが多い。なお、NICには、同一ネットワーク上で、コンピュータを識別するためのMACアドレスが割り当てられています。
  2. NIC(Network Interface Card)
    ルーターとは、あるAネットワークとあるBネットワークとを接続する装置です。
  3. 宛先のIPアドレスのホストまでパケットを伝達すること。
  4. IPアドレスによってルーターまで行けますが、最終的なホストまでは届きません。最終的なホストに至るにはMACアドレスが必要です。
  5. コネクション型のネットワークプロトコル
  6. スリーウエイハンドシェーク
    プログラムの受信側から、OSに◯◯ポートで待つ、と連絡してLISTEN状態になります。 送信側は、TCPレイヤーがパケットを送信し、受信側が了解フラグを立てて、パケットを送り、送信側が了解と送り、コネクションが確立される。
  7. FTTHとは、高速の光ファイバーをユーザの自宅や会社の建物内に直接引き込む手法のことです。
  8. LANケーブルを無線LANルータ機器につなげることで、無線LAN(Wi-Fi)を利用することができる。
  9. ONU(Optical Network Unit) 光を電気信号に変換する装置
  10. OLT(Optical Line Terminal) 企業側の終端装置
  11. https://www.isdn-info.co.jp/next/ngn.html