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

ブラウザの向こう側で「200 OK」を返すまでに何が起きているのか調べてみた #phperkaigi

ブラウザの向こう側で「200 OK」を返すまでに何が起きているのか調べてみた #phperkaigi

PHPerKaigi 2023で発表したスライドです。

akase244

March 24, 2023
Tweet

More Decks by akase244

Other Decks in Programming

Transcript

  1. ブラウザの向こう側で
    「200 OK」を返すまでに
    何が起きているのか調べてみた
    PHPerKaigi 2023
    March 23 - 25, 2023.

    View Slide

  2. @akase244
    2
    var_dump(
    (new Me())
    ->WebApplicationEngineer()
    ->InfrastructureEngineer()
    );

    View Slide

  3. 3
    アイコンの作者と家系図
    カネウチカズコさん
    (@mutsuking)

    View Slide

  4. 4

    View Slide

  5. ▸ 「200 OK」を返す技術
    ▸ 「200 OK」を阻む技術
    ▸ まとめ
    5
    アジェンダ

    View Slide

  6. 6
    「200 OK」を返す技術

    View Slide

  7. 7
    HTTP

    View Slide

  8. 8
    HTTPはサーバーとクライアントで構成されている
    引用元: https:/
    /developer.mozilla.org/ja/docs/Learn/Common_questions/Web_mechanics/What_is_a_web_server

    View Slide

  9. 9
    TCP/IPは階層型のプロトコル
    引用元: 「HTTPの教科書」 https:/
    /www.shoeisha.co.jp/book/detail/9784798126258

    View Slide

  10. 10
    HTTPの歴史
    HTTP/1.0
    (1996年)
    HTTP/2
    (2015年)
    HTTP/0.9
    (1991年)
    HTTP/1.1
    (1997年)
    HTTP/3
    (2022年)

    View Slide

  11. 11
    HTTPの歴史
    HTTP/1.0
    (1996年)
    HTTP/2
    (2015年)
    HTTP/0.9
    (1991年)
    HTTP/1.1
    (1997年)
    HTTP/3
    (2022年)

    View Slide

  12. 12
    HTTP/0.9
    引用元: https:/
    /www.w3.org/Protocols/HTTP/AsImplemented.html

    View Slide

  13. 13
    HTTP/2、HTTP/3
    引用元: https:/
    /fortee.jp/phpcon-2022/proposal/b96e9fc6-52a0-4eb2-a8dc-2a890bd0cac6

    View Slide

  14. 14
    TCPコネクション
    コネクション確立
    データ送信(HTTPリクエスト/HTTPレスポンス)
    コネクション切断

    View Slide

  15. 15
    3 ウェイ ハンドシェイク (TCPハンドシェイク)
    引用元: https:/
    /www.cloudflare.com/ja-jp/learning/ddos/glossary/tcp-ip/

    View Slide

  16. 16
    HTTPサーバーを準備
    引用元: https:/
    /developer.mozilla.org/ja/docs/Learn/Common_questions/Web_mechanics/What_is_a_web_server

    View Slide

  17. 17
    dockerコマンドを利用してビルトインwebサーバーを起動
    $ docker pull php:8.2.4-cli-alpine
    $ docker container run \
    --rm \
    -v /tmp:/tmp \
    -w /tmp \
    -p 127.0.0.1:8080:8080 \
    -it php:8.2.4-cli-alpine \
    php -S 0.0.0.0:8080
    参考: https:/
    /www.php.net/manual/ja/features.commandline.webserver.php

    View Slide

  18. 18
    HTTPリクエストのリクエストメッセージに注目
    引用元: https:/
    /developer.mozilla.org/ja/docs/Learn/Common_questions/Web_mechanics/What_is_a_web_server

    View Slide

  19. 19
    「200.php」を準備
    $ cat /tmp/200.php
    echo 'Hello, PHP.' . PHP_EOL;

    View Slide

  20. 20
    HTTPクライアントとしてcurlコマンドを利用
    引用元: https:/
    /developer.mozilla.org/ja/docs/Learn/Common_questions/Web_mechanics/What_is_a_web_server

    View Slide

  21. 21
    curlコマンドでGETメソッドを実行
    $ curl http://localhost:8080/200.php --http1.0 -v
    * Trying 127.0.0.1:8080...
    * TCP_NODELAY set
    * Connected to localhost (127.0.0.1) port 8080 (#0)
    > GET /200.php HTTP/1.0
    > Host: localhost:8080
    > User-Agent: curl/7.68.0
    > Accept: */*

    View Slide

  22. 22
    curlコマンドでHEADメソッドを実行
    $ curl http://localhost:8080/200.php --http1.0 -vI
    * Trying 127.0.0.1:8080...
    * TCP_NODELAY set
    * Connected to localhost (127.0.0.1) port 8080 (#0)
    > HEAD /200.php HTTP/1.0
    > Host: localhost:8080
    > User-Agent: curl/7.68.0
    > Accept: */*
    >

    View Slide

  23. 23
    「form.php」を準備
    $ cat /tmp/form.php








    View Slide

  24. 24
    curlコマンドでPOSTメソッドを実行
    $ curl http://localhost:8080/form.php \
    --http1.0 \
    -d "foo=bar" \
    --trace-ascii -
    == Info: Trying 127.0.0.1:8080...
    == Info: TCP_NODELAY set
    == Info: Connected to localhost (127.0.0.1) port 8080 (#0)


    View Slide

  25. 25
    curlコマンドでPOSTメソッドを実行
    => Send header, 155 bytes (0x9b)
    0000: POST /form.php HTTP/1.0
    0019: Host: localhost:8080
    002f: User-Agent: curl/7.68.0


    0068: Content-Type: application/x-www-form-urlencoded
    0099:
    => Send data, 7 bytes (0x7)
    0000: foo=bar

    View Slide

  26. 26
    HTTPレスポンスのレスポンスメッセージに注目
    引用元: https:/
    /developer.mozilla.org/ja/docs/Learn/Common_questions/Web_mechanics/What_is_a_web_server

    View Slide

  27. 27
    「404.php」が存在しないことを確認
    $ ls /tmp/404.php
    ls: cannot access '/tmp/404.php': No such file or directory

    View Slide

  28. 28
    400番台(クライアントエラー)
    $ curl http://localhost:8080/404.php --http1.0 -i
    HTTP/1.0 404 Not Found
    Host: localhost:8080
    Date: Tue, 03 Jan 2023 10:04:48 GMT
    Connection: close
    Content-Type: text/html; charset=UTF-8
    Content-Length: 540

    View Slide

  29. 29
    HTTP/1.0で追加されたBasic認証・Digest認証

    View Slide

  30. 30
    400番台(クライアントエラー)


    header('WWW-Authenticate: Basic Realm="Basic Auth"');
    header('HTTP/1.0 401 Unauthorized');
    echo "Please Auth." . PHP_EOL;
    exit;


    参考: https://www.php.net/manual/ja/features.http-auth.php

    View Slide

  31. 31
    「503.php」を準備
    $ cat /tmp/503.php
    header('HTTP/1.0 503 Service Unavailable');

    View Slide

  32. 32
    500番台(サーバーエラー)
    $ curl http://localhost:8080/503.php --http1.0 -i
    HTTP/1.0 503 Service Unavailable
    Host: localhost:8080
    Date: Tue, 03 Jan 2023 10:08:48 GMT
    Connection: close
    X-Powered-By: PHP/8.2.0
    Content-type: text/html; charset=UTF-8

    View Slide

  33. 33
    「301.php」を準備
    $ cat /tmp/301.php
    header("HTTP/1.0 301 Moved Permanently");
    header("Location: https://phperkaigi.jp/2023/");

    View Slide

  34. 34
    300番台(リダイレクト)
    $ curl http://localhost:8080/301.php --http1.0 -i
    HTTP/1.0 301 Moved Permanently
    Host: localhost:8080
    Date: Tue, 03 Jan 2023 10:11:18 GMT
    Connection: close
    X-Powered-By: PHP/8.2.0
    Location: https://phperkaigi.jp/2023/
    Content-type: text/html; charset=UTF-8

    View Slide

  35. 35
    200番台(成功)
    $ curl http://localhost:8080/200.php --http1.0 -i
    HTTP/1.0 200 OK
    Host: localhost:8080
    Date: Wed, 28 Dec 2022 08:21:16 GMT
    Connection: close
    X-Powered-By: PHP/8.2.0
    Content-type: text/html; charset=UTF-8
    Hello, PHP.

    View Slide

  36. 36
    HTTPメッセージのフォーマット
    引用元: https:/
    /developer.mozilla.org/ja/docs/Web/HTTP/Messages

    View Slide

  37. 37
    リクエストメッセージのフォーマット
    引用元: https:/
    /developer.mozilla.org/ja/docs/Web/HTTP/Overview
    ・・・・リクエストライン

    View Slide

  38. 38
    レスポンスメッセージのフォーマット
    引用元: https:/
    /developer.mozilla.org/ja/docs/Web/HTTP/Overview
    ・・・・ステータスライン

    View Slide

  39. 39
    RFC 9112 : HTTP/1.1 「2.1. Message Format」
    引用元: https:/
    /www.rfc-editor.org/rfc/rfc9112#name-message-format

    View Slide

  40. 40
    告白に学ぶ HTTP Status Code - エラー編 -
    引用元: https:/
    /www.slideshare.net/shinichitakahashi790/20171005-http-status-code

    View Slide

  41. 41
    告白に学ぶHTTPステータスコード 〜エラー編〜
    引用元: https:/
    /llminatoll.booth.pm/items/1036373

    View Slide

  42. 42
    Cookie / セッション
    引用元: https:/
    /twitter.com/hashtag/phperkaigi

    View Slide

  43. 43
    PHPで学ぶ、セッションの基本と応用
    引用元: https:/
    /fortee.jp/phperkaigi-2021/proposal/9f8863cc-39b8-4bf7-aed7-f5be070c3bfb

    View Slide

  44. 44
    キャッシュ

    View Slide

  45. 45
    RFC911*から振り返るHTTPの仕様
    引用元: https:/
    /fortee.jp/phpcon-2022/proposal/b96e9fc6-52a0-4eb2-a8dc-2a890bd0cac6

    View Slide

  46. 46
    プロキシ

    View Slide

  47. 47
    プロキシ
    ● フォワードプロキシ
    ● リバースプロキシ
    ● キャッシュサーバー
    ● 透過型プロキシ

    View Slide

  48. 48
    プロキシ
    ● フォワードプロキシ
    ● リバースプロキシ
    ● キャッシュサーバー
    ● 透過型プロキシ

    View Slide

  49. 49
    フォワードプロキシ
    引用元: https:/
    /www.cloudflare.com/ja-jp/learning/cdn/glossary/reverse-proxy/

    View Slide

  50. 50
    リバースプロキシ
    引用元: https:/
    /www.cloudflare.com/ja-jp/learning/cdn/glossary/reverse-proxy/

    View Slide

  51. 51
    HTTP/1.1の主な機能
    ● 高速化(Keep-Alive)
    ● 暗号化(TLS)
    ● メソッドの拡張
    ● バーチャルホストのサポート
    ● Chunked方式のサポート
    ● データURIスキーム

    View Slide

  52. 52
    HTTP/1.1の主な機能
    ● 高速化(Keep-Alive)
    ● 暗号化(TLS)
    ● メソッドの拡張
    ● バーチャルホストのサポート
    ● Chunked方式のサポート
    ● データURIスキーム

    View Slide

  53. 53
    Keep-Alive(持続的接続)
    引用元: https:/
    /developer.mozilla.org/ja/docs/Web/HTTP/Connection_management_in_HTTP_1.x

    View Slide

  54. 54
    Keep-Aliveが無効な状態をcurlコマンドで確認
    $ curl --http1.0 -v \
    https://phperkaigi.jp/2023/ \
    https://phperkaigi.jp/coc.html \
    https://phperkaigi.jp/privacy.html



    View Slide

  55. 55
    Keep-Aliveが無効な状態をcurlコマンドで確認
    * Connected to phperkaigi.jp (160.16.230.152) port 443 (#0)


    * Closing connection 0


    * Connected to phperkaigi.jp (160.16.230.152) port 443 (#1)


    * Closing connection 1


    * Connected to phperkaigi.jp (160.16.230.152) port 443 (#2)


    * Closing connection 2

    View Slide

  56. 56
    Keep-Aliveが有効な状態をcurlコマンドで確認
    $ curl --http1.1 -v \
    https://phperkaigi.jp/2023/ \
    https://phperkaigi.jp/coc.html \
    https://phperkaigi.jp/privacy.html



    View Slide

  57. 57
    Keep-Aliveが有効な状態をcurlコマンドで確認
    * Connected to phperkaigi.jp (160.16.230.152) port 443 (#0)


    * Connection #0 to host phperkaigi.jp left intact
    * Found bundle for host phperkaigi.jp: 0x564fcdd7f030 [serially]
    * Re-using existing connection! (#0) with host phperkaigi.jp
    * Connected to phperkaigi.jp (160.16.230.152) port 443 (#0)


    * Connection #0 to host phperkaigi.jp left intact
    * Found bundle for host phperkaigi.jp: 0x564fcdd7f030 [serially]
    * Re-using existing connection! (#0) with host phperkaigi.jp
    * Connected to phperkaigi.jp (160.16.230.152) port 443 (#0)

    View Slide

  58. 58
    TLSハンドシェイク
    引用元: https:/
    /www.cloudflare.com/ja-jp/learning/ssl/what-happens-in-a-tls-handshake/

    View Slide

  59. 59
    DNSを制するものはインターネットを制す!DNSの世界
    引用元: https:/
    /fortee.jp/phperkaigi-2021/proposal/71d673b5-b64f-4e32-8e71-4800b022b237

    View Slide

  60. 60
    HTTPリクエストの送信からHTTPレスポンスの受信までの流れ
    1. DNSルックアップ
    2. 3ウェイハンドシェイクでTCPコネクション確立
    3. TLSハンドシェイクでHTTPS通信確立
    4. HTTPクライアントからHTTPリクエストを送信
    5. HTTPサーバーがHTTPリクエストを受信
    6. HTTPサーバーからHTTPレスポンスを送信
    7. HTTPクライアントがHTTPレスポンスを受信
    参考: https:/
    /developer.mozilla.org/ja/docs/Web/Performance/How_browsers_work

    View Slide

  61. 61
    「200 OK」を阻む技術

    View Slide

  62. 62
    「200 OK」が返ってこない場合

    View Slide

  63. 63
    クライアントとインターネット間の問題
    引用: https:/
    /en.wikipedia.org/wiki/Client%E2%80%93server_model

    View Slide

  64. 64
    ルーターなどの機器の電源が入っていない

    View Slide

  65. 65
    ハブが壊れている

    View Slide

  66. 66
    ケーブルが断線している

    View Slide

  67. 67
    ケーブルが外れている

    View Slide

  68. 68
    機器の設定でWiFiがオフの状態

    View Slide

  69. 69
    パソコン本体のネットワークインターフェースが壊れている

    View Slide

  70. 70
    ネットワークのサービスが停止
    $ sudo systemctl is-active network-manager.service
    inactive

    View Slide

  71. 71
    広告ブロックなどのブラウザの拡張機能が通信を遮断

    View Slide

  72. 72
    ケーブルのループ接続

    View Slide

  73. 73
    プロキシやファイアウォールでブロックされている

    View Slide

  74. 74
    HOSTSファイルの戻し忘れ
    $ cat /etc/hosts
    127.0.0.1 localhost
    192.168.0.1 phperkaigi.jp
    192.168.0.2 phpcon.php.gr.jp
    192.168.0.3 phpcon.fukuoka.jp
    192.168.0.4 phpcon.hokkaido.jp
    192.168.0.5 phpcon-sendai.net
    192.168.0.6 phpcon.okinawa.jp
    192.168.0.7 conference2019.laravel.jp

    View Slide

  75. 75
    ルーターのIPアドレスにpingを実行
    $ ping -c 3 192.168.0.1
    PING 192.168.0.1 (192.168.0.1) 56(84) バイトのデータ
    64 バイト応答 送信元 192.168.0.1: icmp_seq=1 ttl=64 時間=0.434ミリ秒
    64 バイト応答 送信元 192.168.0.1: icmp_seq=2 ttl=64 時間=0.307ミリ秒
    64 バイト応答 送信元 192.168.0.1: icmp_seq=3 ttl=64 時間=0.415ミリ秒
    --- 192.168.0.1 ping 統計 ---
    送信パケット数 3, 受信パケット数 3, パケット損失 0%, 時間 2050ミリ秒
    rtt 最小/平均/最大/mdev = 0.307/0.385/0.434/0.055ミリ秒

    View Slide

  76. 76
    ルーターのweb画面にアクセス

    View Slide

  77. 77
    www.yahoo.co.jp のようなドメインにping、curlを実行
    $ ping -c 3 www.yahoo.co.jp
    PING edge12.g.yimg.jp (183.79.250.251) 56(84) バイトのデータ
    64 バイト応答 送信元 183.79.250.251 (183.79.250.251): icmp_seq=1
    ttl=56 時間=21.2ミリ秒


    $ curl -I https://www.yahoo.co.jp
    HTTP/2 200
    server: ATS


    View Slide

  78. 78
    インターネット上の問題
    引用: https:/
    /en.wikipedia.org/wiki/Client%E2%80%93server_model

    View Slide

  79. 79
    DNS、CDN、クラウド事業者の障害
    ● AWSの冷却システムの障害(2019年8月23日)
    ● Cloudflareの障害(2020年7月17日)
    ● AWSのAmazon CloudFrontの障害(2020年9月26日)
    ● Fastlyの障害(2021年6月8日)
    ● AkamaiのDNSサービス「Edge DNS」で障害(2021年7月23日)
    ● AWSのDirect Connectの障害(2021年9月2日)
    ● Cloudflareの障害(2022年6月21日)
    ● Microsoft Azureの障害(2023年1月25日)

    View Slide

  80. 80
    サーバーとインターネット間の問題
    引用: https:/
    /en.wikipedia.org/wiki/Client%E2%80%93server_model

    View Slide

  81. 81
    サーバーの電源が入っていない

    View Slide

  82. 82
    HTTPサーバーが起動していない
    $ sudo service httpd status
    httpd (pid 8097) is running...
    $ sudo systemctl is-active httpd.service
    active
    initスクリプトの場合
    systemdの場合

    View Slide

  83. 83
    HTTPサーバーが起動していない
    $ ss -ln |grep ':443 '
    tcp LISTEN 0 511 *:443 *:*
    $ sudo lsof -i:443
    COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
    nginx 127021 root 7u IPv4 10913 0t0 TCP *:https
    (LISTEN)
    nginx 127023 nginx 7u IPv4 10913 0t0 TCP *:https
    (LISTEN)

    View Slide

  84. 84
    HTTPサーバーの設定ファイルの書式ミス
    $ sudo httpd -t
    Syntax OK
    $ sudo nginx -t
    nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    nginx: configuration file /etc/nginx/nginx.conf test is
    successful
    Apacheの場合
    Nginxの場合

    View Slide

  85. 85
    HTTPサーバーは起動しているが
    レスポンスがない、レスポンスが遅い
    ● webアプリケーションやデータベースで
    ○ 処理に時間が掛かっている
    ○ エラーが発生している
    ● ◯◯砲やDDoS攻撃で高負荷が発生してレスポンスが返せない
    ● 設定ミス
    ○ ロードバランサーでヘルスチェックエラーが発生
    ○ ファイアウォールで意図せずブロックしていた
    ○ リダイレクトループが発生
    ● DNSにレコードを登録していなかった / 間違って登録していた
    ● SSL/TLSサーバ証明書の設定漏れ、有効期限切れ etc…

    View Slide

  86. 86
    まとめ

    View Slide

  87. 87
    まとめ
    ● webに関する技術の範囲はとても広い。
    ● 一気に理解することは難しいので、積み上げていくことが大事。
    ● 自分が興味のあるところから少しずつでも知識の幅を広げてみては?
    ● 理解の幅が広がることで、その知識がアプリケーション開発やトラブル対応の
    手助けになっていく。

    View Slide

  88. 88
    おまけ

    View Slide

  89. 89
    RFC 9113 : HTTP/2 「4.1. Frame Format」
    引用元: https:/
    /www.rfc-editor.org/rfc/rfc9113#name-frame-format

    View Slide

  90. 90
    HTTP/2 以降には「OK」は返ってこない
    HTTP/1.1 まで HTTP/2 以降

    View Slide

  91. Thanks! Have a good
    programming!!

    View Slide