Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

4

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

6 「200 OK」を返す技術

Slide 7

Slide 7 text

7 HTTP

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

19 「200.php」を準備 $ cat /tmp/200.php

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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: */*

Slide 22

Slide 22 text

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: */* >

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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) ・ ・

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

31 「503.php」を準備 $ cat /tmp/503.php

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

33 「301.php」を準備 $ cat /tmp/301.php

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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.

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

44 キャッシュ

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

46 プロキシ

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

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

Slide 57

Slide 57 text

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)

Slide 58

Slide 58 text

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

Slide 59

Slide 59 text

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

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

61 「200 OK」を阻む技術

Slide 62

Slide 62 text

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

Slide 63

Slide 63 text

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

Slide 64

Slide 64 text

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

Slide 65

Slide 65 text

65 ハブが壊れている

Slide 66

Slide 66 text

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

Slide 67

Slide 67 text

67 ケーブルが外れている

Slide 68

Slide 68 text

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

Slide 69

Slide 69 text

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

Slide 70

Slide 70 text

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

Slide 71

Slide 71 text

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

Slide 72

Slide 72 text

72 ケーブルのループ接続

Slide 73

Slide 73 text

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

Slide 74

Slide 74 text

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

Slide 75

Slide 75 text

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ミリ秒

Slide 76

Slide 76 text

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

Slide 77

Slide 77 text

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 ・ ・

Slide 78

Slide 78 text

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

Slide 79

Slide 79 text

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日)

Slide 80

Slide 80 text

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

Slide 81

Slide 81 text

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

Slide 82

Slide 82 text

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

Slide 83

Slide 83 text

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)

Slide 84

Slide 84 text

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の場合

Slide 85

Slide 85 text

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

Slide 86

Slide 86 text

86 まとめ

Slide 87

Slide 87 text

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

Slide 88

Slide 88 text

88 おまけ

Slide 89

Slide 89 text

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

Slide 90

Slide 90 text

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

Slide 91

Slide 91 text

Thanks! Have a good programming!!