Upgrade to Pro — share decks privately, control downloads, hide ads and more …

2019-02 HTTP_DNS

2019-02 HTTP_DNS

Cybozu
PRO

May 27, 2019
Tweet

More Decks by Cybozu

Other Decks in Technology

Transcript

  1. HTTP と DNS
    サイボウズ株式会社

    View Slide

  2. DNS
    Domain Name System

    View Slide

  3. 名前って何?
    ▌hoge.cybozu.com は人間に読みやすい・覚えやすい名前
    ▌実際使われているのは IPアドレス
    ▌じゃあ hoge.cybozu.com の IPアドレスは?

    View Slide

  4. 名前解決
    ▌hoge.cybozu.com = 103.79.14.41, 103.79.14.42
    ▌ドメイン名を IPアドレスに紐づける

    View Slide

  5. 誰に聞けば良い?
    ▌dig コマンドを打ってみましょう
    ◼ 無かった場合: sudo apt install dnsutils
    ▌$> dig +noall +stats +answer hoge.cybozu.com
    bozuman.cybozu.com. 2795 IN A 103.79.14.41
    bozuman.cybozu.com. 2795 IN A 103.79.14.42
    ;; Query time: 0 msec
    ;; SERVER: 10.224.136.183#53(10.224.136.183)
    ;; WHEN: Wed May 15 16:13:32 JST 2019
    ;; MSG SIZE rcvd: 79
    ▌$> dig hoge.cybozu.com @1.1.1.1

    View Slide

  6. Recursive DNS Resolver
    ▌10.224.136.183 は何でも知っている?
    ▌hoge の IPアドレスが変わったらどうなる?
    ▌7億人が同時に名前解決したらどうなる?
    ▌そもそも 10.224.136.183 は社内の IP

    View Slide

  7. 名前解決の流れ
    https://www.cloudflare.com/learning/dns/what-is-dns/
    hoge.cybozu.com はど
    こ?
    知らん。「.」に聞いてみる 俺も知らんし、断言する権限がない。「.com」なら知ってる
    hoge.cybozu.com はどこ?
    知らん、断言する権限ない。「cybozu.com」なら知ってるはず
    hoge.cybozu.com はどこ?
    103.79.14.41, 103.79.14.42
    103.79.14.41,
    103.79.14.42
    だって
    こんちゃっす
    dns-1.cybozu.com

    View Slide

  8. Root Servers
    https://www.iana.org/domains/root/servers

    View Slide

  9. 実際に見てみましょう
    ▌$> dig +trace hoge.cybozu.com
    ▌$> dig +trace hoge.cybozu.cn
    ▌$> dig +trace hogehagehige.com

    View Slide

  10. 毎回やる?
    https://www.cloudflare.com/learning/dns/what-is-dns/
    hoge.cybozu.com はど
    こ?
    こんちゃっす
    覚えてる!
    103.79.14.41,
    103.79.14.42

    View Slide

  11. DNSレコードの種類
    ▌SOA
    ▌NS
    ▌A
    ▌AAAA
    ▌CNAME
    ▌MX
    ▌TXT
    ▌PTR
    ▌…

    View Slide

  12. SOA
    ▌ Start of Authority
    ▌ DNS Zone の権威情報
    ▌ $> dig SOA +noall +multiline +answer cybozu.com
    cybozu.com. 51 IN SOA dns-1.cybozu.com. root.io.cybozu.co.jp. (
    2019050500 ; serial
    3600 ; refresh (1 hour)
    900 ; retry (15 minutes)
    604800 ; expire (1 week)
    60 ; minimum (1 minute)
    )

    View Slide

  13. NS
    ▌Name Server
    ▌対象ドメインの権威 DNSサーバー(達)
    ▌$> dig NS +noall +answer cybozu.com
    cybozu.com. 2819 IN NS dns-1.cybozu-bk.com.
    cybozu.com. 2819 IN NS dns-1.cybozu.com.
    cybozu.com. 2819 IN NS dns-2.cybozu.com.
    cybozu.com. 2819 IN NS dns-2.cybozu-bk.com.
    cybozu.com. 2819 IN NS dns-3.cybozu.com.
    cybozu.com. 2819 IN NS dns-4.cybozu.com.

    View Slide

  14. A
    ▌Address (IPv4)
    ▌$> dig A +noall +answer cybozu.com

    View Slide

  15. AAAA
    ▌IPv6アドレス(IPv4の4倍のbit数)
    ▌$> dig AAAA +noall +answer cybozu.com
    無い
    ▌$> dig AAAA +noall +answer google.com
    google.com. 299 IN AAAA 2404:6800:4004:80a::200e

    View Slide

  16. CNAME
    ▌Canonical Name
    ▌ドメインのエイリアス
    ▌DNS レベルのリダイレクト
    ▌$> dig CNAME +noall +answer developers.cybozu.com
    developers.cybozu.com. 3593 IN CNAME d2p8ofl6yvcluu.cloudfront.net.

    View Slide

  17. MX
    ▌Mail eXchanger
    ▌メールサーバー
    ▌複数ある場合優先度も指定できる
    ▌$> dig MX +noall +answer cybozu.com

    View Slide

  18. TXT
    ▌Text: 何でもあり
    ▌定義されている特別な TXTレコードがある
    ◼ DMARC, DKIM, SPFなど
    ▌その他クラウドサービスを使う時のドメイン所有者確認など
    ▌$> dig TXT +short cybozu.com
    "v=spf1 +ip4:103.79.12.128/26 +ip4:103.79.14.16 +ip4:103.79.14.17
    include:spf.protection.outlook.com include:fc5038.cuenote.jp -all“
    ▌$> dig TXT +short matsuri.dev

    View Slide

  19. PTR
    ▌Pointer
    ▌逆名前解決
    ◼ IPアドレスからドメイン名を問い合わせる
    ▌$> dig +noall +answer -x 103.79.14.84
    84.14.79.103.in-addr.arpa. 86394 IN PTR dns-3.cybozu.com.
    ▌$> dig +short dns-3.cybozu.com
    103.79.14.84

    View Slide

  20. Zone ファイル
    $ORIGIN kaiun.lan.
    $TTL 60; 1 min
    @ IN SOA dns contact.kaiun.lan. (
    2019051701; serial
    3600 ; refresh (1h)
    900 ; retry (15m)
    3600 ; expire (1h)
    60 ; min TTL (1m)
    )
    Zoneファイルの始まりを記す。
    末尾の「.」も必要!
    Time To Live: キャシュされたレコードの
    有効時間
    $ORIGIN の略
    プライマリーDNSサーバーと連絡
    先のメールアドレス
    Zoneのバージョン番号
    他のネームサーバーへのタイミン
    グ指示

    View Slide

  21. Zone ファイル
    <$ORIGIN下の名前> IN <レコードタイプ> <レコード値>
    例)bozuman IN A 103.79.14.41

    View Slide

  22. 演習: DNSサーバーを触りましょう
    ▌Docker をインストール
    ◼ https://docs.docker.com/install/linux/docker-
    ce/ubuntu/#install-docker-ce
    ▌docker-compose をインストール
    ◼ https://docs.docker.com/compose/install/
    ▌演習用のレポジトリをクローン
    ◼ https://github.dev.cybozu.co.jp/tu-antoine/kaiun-dmz

    View Slide

  23. 構成
    ▌dns: kaiun.lan の権威 DNS (NSD)
    ▌cache: recursive DNS resolver/cache (Unbound)
    ◼ kaiun.lan に関しては dns である 172.30.0.3 に問い合わせる
    ▌client: 外から見れないので client コンテナーに入って様々なコマンドを打つ
    ▌おまけ:
    ◼ l7lb: 負荷分散、TLS termination (nginx)
    ◼ 外から見えるのは l7lb。裏で実際のウエブサーバーにリクエストを割り当てる
    ◼ web: ウエブサーバー

    View Slide

  24. 演習: DNSサーバーを触りましょう
    ▌$> docker-compose -p kaiun up --build --scale ap=3
    ▌$> docker exec -it kaiun_client_1 bash
    ▌$> dig cybozu.com
    ▌$> dig kaiun.lan
    ▌$> curl kaiun.lan

    View Slide

  25. 演習: DNSサーバーを触りましょう
    ▌zoneファイルに DNSレコードを追加 (dnsダイレクトリー下)
    ◼ kaiun.lan -> 172.30.0.6 にしましょう
    ◼ rDNS もやりましょう
    ◼ ついでに www の CNAME も追加しよう (kaiun.lan のアリアス)

    View Slide

  26. 演習: DNSサーバーを触りましょう
    ▌$> docker-compose -p kaiun up --build --scale ap=3
    ▌$> docker exec -it kaiun_client_1 bash
    ▌$> dig kaiun.lan
    ▌$> curl –v kaiun.lan
    おまけ:L7LB も見ましょう
    ◼ $> seq 5 | xargs -n1 -P5 bash -c 'curl kaiun.lan'

    View Slide

  27. HTTP
    Hypertext Transfer Protocol

    View Slide

  28. Hypertext Transfer Protocol
    ▌hyper-text:テキストを超える
    ▌複数の文書をリンクにより関連付ける仕組み
    →HTML:Hypertext Markup Language
    ▌HTTP:hypertextを送受信する手順
    ▌今では,hypertextに限らずあらゆるデータの送受信に使われる
    →演習:ファイルの受信

    View Slide

  29. 演習1:HTTPによるファイル受信
    ターミナル1
    テスト用HTTPサーバを立てる
    ターミナル2
    HTTPサーバにアクセスし,hello.txtを受信
    $ mkdir httproot
    $ cd httproot
    $ echo 'hello world' > hello.txt
    $ python3 -m http.server 8080
    $ telnet localhost 8080
    Trying 127.0.0.1...

    GET /hello.txt HTTP/1.1
    Host: 127.0.0.1:8080
    HTTP/1.0 200 OK

    hello world
    Connection closed by foreign host.
    ファイルの中身が受信できた!

    View Slide

  30. HTTPリクエスト(要求)
    ▌HTTPリクエスト:クライアントからHTTPサーバへの要求
    GET /hello.txt HTTP/1.1
    Host: 127.0.0.1:8080
    User-Agent: curl/7.47.0
    Accept: */*

    View Slide

  31. HTTPレスポンス(応答)
    ▌HTTPレスポンス:HTTPサーバからの応答
    HTTP/1.0 200 OK
    Server: SimpleHTTP/0.6 Python/3.5.2
    Date: Wed, 15 May 2019 09:11:53 GMT
    Content-type: text/plain
    Content-Length: 12
    Last-Modified: Wed, 15 May 2019 09:09:07 GMT
    hello world

    View Slide

  32. HTTP 1.Xのフォーマット
    32
    スタートライン
    ヘッダ
    ボディ
    (ないこともある)
    リクエスト レスポンス

    View Slide

  33. HTTPリクエスト

    View Slide

  34. Method: 要求の種類
    34
    ◼ GET
    ◼ POST
    ◼ DELETE
    ◼ PUT
    ◼ CONNECT

    ▌このリクエストがどのようなものか推測する手がかり
    (例:安全か、べき等か、キャッシュ可能か)
    Request line

    View Slide

  35. Request target: 要求の対象
    35
    ▌Webサーバが持つどのサービスに対
    するリクエストか
    ▌サービス
    ◼ 単なるファイル
    ◼ 動的なファイル
    ◼ DBへの書き込み
    ◼ etc.

    View Slide

  36. Version:HTTPのバージョン
    36
    ▌HTTP/X.Y というフォーマット
    「メジャーバージョンが同じなら
    後方互換性がある」…というタテマエ
    ※ HTTP/2はそもそもバイナリプロトコル
    メジャーバー
    ジョン マイナー
    バージョン

    View Slide

  37. Hostヘッダ: サーバの名前
    37
    ▌どのサーバに対するリクエストか
    ← 同じIPアドレス上に複数のHTTP
    サーバがいることがある
    (Virtual Host)

    View Slide

  38. その他のヘッダ
    38
    ◼ Controls
    ◼ Conditionals
    ◼ Content Negotiation
    ◼ Authentication Credentials
    ◼ Request Context
    ◼ 独自拡張

    View Slide

  39. Message Body: データ部分
    39
    ▌ヘッダ部分と空行(CRLF)で隔てら
    れた部分
    ▌メソッドによってあったりなかったり
    ◼ 典型的には…
    ◼ GETはボディを持たない
    ◼ PUT/POSTはボディを持つ

    View Slide

  40. HTTPレスポンス

    View Slide

  41. Status Code: リクエストの処理結果
    41
    ◼ 1XX: コネクションの情報
    ◼ 2XX: 成功
    ◼ 3XX: リダイレクト
    ◼ 4XX: クライアント側のエラー
    ◼ 5XX: サーバ側のエラー
    ▌クライアントはこれに応じてリトライしたりエ
    ラー処理をしたりする

    View Slide

  42. Status Codeに対するクライアントの反応例
    ▌302 Found → Locationヘッダに指定されたURLを見に行く
    ▌304 Not Modified → キャッシュされている結果を使う
    ▌500 Internal Server Error → 500エラーを画面に出す
    ▌401 Unauthorized → 認証パスワードを再度求める
    42

    View Slide

  43. Status Codeの罠
    ▌ステータスコードを信用しすぎてはいけない
    ◼ サーバーが実装を間違えている
    ◼ ステータスコードは200でもボディにエラーメッセージが入る
    ◼ 独自のステータスコードを返す
    43
    HTTP/1.0 200 OK
    {"status": "error"}
    200 OKなのにエラーを返す例

    View Slide

  44. Reason Phrase
    44
    ▌人間が読むための文字列
    ▌プログラムからは利用しない

    View Slide

  45. 動的コンテンツ
    ▌HTTPサーバは,受け取ったHTTPリクエストに対し,反応する
    ▌HTTPレスポンスをどうやって生成するか
    ◼ ファイルをそのまま送る
    ◼ 内容を動的に生成して送る
    ▌Webアプリ(kintoneやGaroonなど)がやっているのはこれ!

    View Slide

  46. 演習2:動的コンテンツを送信するHTTPサーバを作る
    $ curl http://localhost:8080/add/2/3
    5
    $ curl http://localhost:8080/add/-4/3
    -1
    ▌仕様
    ◼ GET /add/X/Y とすると X+Y の結果を返す
    ◼ X,Yはともに整数(値の範囲は自由に仮定していいです)
    ▌ひな形 https://gist.github.com/uchan-nos/18fdd22cdf9c358109dd938c98ca79cd
    メモ:
    演習2は20分想定.
    時間が足りなそうなら
    演習2はスキップする.

    View Slide

  47. 演習2のプログラム起動方法
    (ほぼ答え)四則演算に対応した版
    https://gist.github.com/uchan-nos/9d05dbaa7b190f890ea962cf4e81456a
    $ chmod +x simple_add_server.py
    $ ./simple_add_server.py
    $ curl http://localhost:8080/add/2/3
    5
    $
    ターミナル1
    HTTPサーバを立てる
    ターミナル2
    HTTPサーバにアクセスする

    View Slide

  48. 演習2のヒント
    ▌(ほぼ答え)四則演算に対応した版
    https://gist.github.com/uchan-nos/9d05dbaa7b190f890ea962cf4e81456a
    # X+Y
    result = arguments[0] + arguments[1]
    # レスポンスボディの作成
    self.wfile.write(バイト列)
    # 数値→バイト列の変換
    '{}'.format(数値).encode('utf-8')

    View Slide

  49. HTTPS
    HTTP Secure

    View Slide

  50. HTTP Secure
    ▌HTTPは平文プロトコル = 攻撃者が簡単に情報を盗める
    ▌HTTPS:HTTPをTLSの上に構築
    ◼ TLS:Transport Layer Security
    ▌暗号化されるので盗聴されても解読が難しい
    HTTP
    TCP/UDP
    IP
    Ethernet
    HTTP
    TCP/UDP
    IP
    Ethernet
    TLS
    アプリケーション/プレゼンテーション層
    セッション層
    トランスポート層
    ネットワーク層
    データリンク/物理層

    View Slide

  51. TLSで守りたいもの・守り方
    ▌通信相手が本物であること → デジタル署名
    ◼ (クライアント視点で)本物のサーバか?
    ◼ (サーバ視点で)本物のクライアントか?
    ▌通信内容が盗聴されないこと → 対称暗号
    ◼ クレジットカード番号などが漏洩しないように
    ▌通信内容が改竄されないこと → メッセージ認証コード
    ◼ 説明は省略

    View Slide

  52. デジタル署名:通信相手が本物であること
    認証局
    サーバB
    クライアントA
    公開鍵B
    秘密鍵B'
    公開鍵T
    秘密鍵T'
    公開鍵B
    Bのハッシュ
    一方向ハッシュ
    Bの署名
    暗号化
    証明書B
    Bの署名
    証明書B
    Bの署名
    Bのハッシュ
    復号
    比較
    公開鍵B
    一方向ハッシュ
    Bのハッシュ

    View Slide

  53. 対称暗号:通信内容が盗聴されないこと
    ▌共通鍵暗号とも呼ぶ
    ▌公開鍵暗号またはDiffie-Hellman鍵交換にて
    クライアントとサーバが鍵を共有する
    ▌公開鍵暗号より対称暗号の方が(とても)速い
    鍵K 鍵K
    サーバB
    クライアントA
    msg
    暗号化 復号
    msg

    View Slide

  54. TLSハンドシェイク
    ▌TLS通信をするには,クライアントとサーバ間で合意が必要
    ◼ 証明書のやり取り
    ◼ 共通鍵の生成と交換
    ▌開発環境のドメインにアクセスしてハンドシェイクの様子を見てみよう
    $ curl -v https://foo.cybozu-dev.com/

    View Slide

  55. $ curl -v https://foo.cybozu-dev.com/
    * Trying 192.0.2.100...
    * TCP_NODELAY set
    * Connected to foo.cybozu-dev.com (192.0.2.100) port 443 (#0)
    * ALPN, offering h2
    * ALPN, offering http/1.1
    * successfully set certificate verify locations:
    * CAfile: /etc/ssl/certs/ca-certificates.crt
    CApath: /etc/ssl/certs
    * TLSv1.2 (OUT), TLS handshake, Client hello (1):
    * TLSv1.2 (IN), TLS handshake, Server hello (2):
    * TLSv1.2 (IN), TLS handshake, Certificate (11):
    * TLSv1.2 (IN), TLS handshake, Server key exchange (12):
    * TLSv1.2 (IN), TLS handshake, Server finished (14):
    * TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
    * TLSv1.2 (OUT), TLS change cipher, Client hello (1):
    * TLSv1.2 (OUT), TLS handshake, Finished (20):
    * TLSv1.2 (IN), TLS handshake, Finished (20):
    * SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
    (続く)…
    foo.cybozu-dev.com
    にアクセスするときの
    TLSハンドシェイクの様子

    View Slide


  56. * ALPN, server accepted to use http/1.1
    * Server certificate:
    * subject: OU=Domain Control Validated; CN=*.cybozu-dev.com
    * start date: Aug 29 10:54:08 2018 GMT
    * expire date: Oct 29 01:13:38 2020 GMT
    * subjectAltName: host "foo.cybozu-dev.com" matched cert's
    "*.cybozu-dev.com"
    * issuer: … CN=Starfield Secure Certificate Authority - G2
    * SSL certificate verify ok.
    > GET / HTTP/1.1
    > Host: foo.cybozu-dev.com
    > User-Agent: curl/7.58.0
    > Accept: */*
    >
    < HTTP/1.1 200 OK

    ここからHTTPが始まる

    View Slide

  57. RFC
    57

    View Slide

  58. RFCとは
    ▌Request for Comments(コメント求む)の略
    ▌RFCの目的は色々
    ◼ インターネット標準を定める
    ◼ 情報提供
    ◼ ジョーク

    ▌RFC 2616 https://tools.ietf.org/html/rfc2616
    Hypertext Transfer Protocol -- HTTP/1.1
    58

    View Slide

  59. なぜ標準が必要か
    ▌HTTPの場合:様々なサーバ、様々なクライアント…
    59
    nginx Apache IIS 自作サーバ
    Chrome
    Firefox
    IE
    Edge
    curl
    wget
    独自クライアント

    View Slide

  60. なぜ標準が必要か
    ▌もしも標準がないと…
    ◼ メッセージがうまく処理できず、サービスが動かない
    ◼ 色んな独自仕様に対応しないといけなくなってとても大変
    ◼ セキュリティ上の抜け穴が発生する
    ※Googleのようにサーバもクライアントも自社開発する場合,自社製
    品に独自の仕様を突っ込んで普及させ,後からインターネット標準に仕
    立て上げる、ということもできる。SPDY,HTTP/2,QUIC
    60

    View Slide

  61. ググった記事よりRFC
    ▌みんな、自分が思うように相手が動いてほしいと思っている
    → 「なぜうちに合わせて○○という動作じゃないの?」
    → 「そっちこそなぜうちに合わせて××じゃないんだ!?」
    → もめる
    ▌…ということになるので、相手に合わせるのではなくRFCに合わせましょう
    ▌「正しい挙動」が知りたいときは、ググって出てくるページではなくRFCを読

    61

    View Slide

  62. RFCを読もう
    ▌RFCの中にはユーモアにあふれるものもある
    ◼ RFC1149 https://tools.ietf.org/html/rfc1149
    ◼ 「鳥類キャリアによるIPデータグラムの伝送に関する標準」
    ◼ 1990年4月1日に発表
    ▌(もちろん,ほとんどのRFCは真面目)
    ▌明日のRFC精読会をお楽しみに!

    View Slide