0
0

More than 1 year has passed since last update.

はじめに

前回記事では、goquicのリバースプロキシを使ってHTTP/3, QUIC接続を試そうとして失敗した

今回はそのリベンジ!
curl --http3コマンドでHTTP/3通信できることを確認した

今回のリバースプロキシは・・・

Nginxです!

WebサーバーのHTTP/3対応をNginxのリバースプロキシでするためのDockerイメージが出来ました

前回は、goquicをプロキシ、nginxを最終アクセス先としていたが
今回は、nginxがプロキシ、ghostが最終アクセス先とする

(予備知識)Ghostとは

Ghost is a free and open source blogging platform written in JavaScript

無料のブログプラットフォーム(らしい)です

image.png

最終アクセス先として、Ghostを採用しただけなので、Ghostについてはここまで
ひと昔前は、こういうコンテンツサイト?ブログサイト?といえばWordPressだったけど・・・

検証環境をつくる on Docker

前回記事と同様に、docker-composeで環境をつくる

コンテナ 役割
client curlコマンドを打つ役
proxy HTTP/3アクセスを受け付けるリバースプロキシ
ghost 単なるブログサイト。HTTP/3に対応していない想定

クライアント ->(ここはHTTP/3)-> プロキシ -> (ここはHTTP/2以下) -> ブログサイト

クライアントに証明書をインストールする

前回と同じく、クライアントにはサーバー証明書を入れておく
これでHTTPS通信することができるようになる

何はともあれ、クライアントのコンテナに入って作業する

docker compose up -d
docker compose exec client ash

パッケージマネージャが使えないコンテナなので、.crtファイルに直接書き込む

cat /nginx/server.crt >>/etc/ssl/certs/ca-certificates.crt

パッケージマネージャが使える環境であれば、このような直書きではなく、コマンドで証明書をインストールしましょう

いざ、接続!

クライアントからHTTP/1.1, HTTP/2, HTTP/3 の3パターンで接続してみる

HTTP/1.1

HTTP接続

curl http://proxy -I

HTTP/1.1 200 OK
Server: nginx/1.16.1
Date: Tue, 01 Aug 2023 13:37:05 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 10255
Connection: keep-alive
X-Powered-By: Express
Cache-Control: public, max-age=0
ETag: W/"280f-LG5sPxcueSIwKUCwqdjGkQDJ338"
Vary: Accept-Encoding

HTTP/2

HTTPS接続

curl https://proxy -I
HTTP/2 200
server: nginx/1.16.1
date: Tue, 01 Aug 2023 13:39:27 GMT
content-type: text/html; charset=utf-8
content-length: 10255
x-powered-by: Express
cache-control: public, max-age=0
etag: W/"280f-LG5sPxcueSIwKUCwqdjGkQDJ338"
vary: Accept-Encoding
alt-svc: h3-23=":443"; ma=86400

HTTP/3

HTTPSかつ--http3オプションを付けると、HTTP/3で接続できる

curl https://proxy -I --http3

HTTP/3 200
server: nginx/1.16.1
date: Tue, 01 Aug 2023 13:40:46 GMT
content-type: text/html; charset=utf-8
content-length: 10255
x-powered-by: Express
cache-control: public, max-age=0
etag: W/"280f-LG5sPxcueSIwKUCwqdjGkQDJ338"
vary: Accept-Encoding
alt-svc: h3-23=":443"; ma=86400

HTTPのバージョン違いでパケットがどう変わるか

HTTP1.1, 2, 3 のそれぞれの方法で接続できることがわかった
Ghostの初期サイトは軽量すぎて、アクセス速度の差がわからない

ポートスキャンをしてパケットのやり取りの総量を比べてみる

ポートスキャンの準備

Nginxのコンテナに入り

docker compose exec proxy bash

tcpdumpをインストールする

apt update && apt install -y tcpdump

# バージョン確認
tcpdump --version
tcpdump version 4.9.3
libpcap version 1.8.1
OpenSSL 1.1.1  11 Sep 2018

# キャプチャするコマンド
tcpdum -w /mnt/out.pcap

HTTP/1.1

スリーウェイハンドシェイクでかっちり通信

image.png

HTTP/2

HTTP/2については、令和5年春のネットワークスペシャリスト試験午後1問題で解説されている

  • HTTP1.1はリクエストを受けたのと同じ順序レスポンスを返す必要があるが、HTTP/2にはその制約がない
  • HTTP1.1はパイプラインで多重化している。一方、HTTP/2ストリームと呼ばれる仮想の通信路で多重化している

image.png

ヘッダーフィールドの必須フィールド

ヘッダーはHPACKアルゴリズムでバイナリに圧縮されている

:method, :scheme, :path の3つが必須フィールド

ここはもっと書くべきことがありそうだ!後で追記する!

HTTP/3

image.png

ここはもっと書くべきことがありそうだ!後で追記する!

おわりに

前回のリベンジで、リバースプロキシを使ってQUICを体感した
HTTP/3に対応していないサーバであっても
このリバースプロキシを使えば、クライアントからはあたかもHTTP/3対応のサーバが動いているように見える

HTTP/2, HTTP/3のパケットキャプチャした結果については
もっともっと中身をよくよんで勉強すべきことがありそう

記事を途中まで書いてから時間がたってしまったので、いったん放流する

付録

docker-compose.yml

version: "3.8"

services:
  client:
    image: keioni/curl-http3
    container_name: client
    hostname: client
    tty: true
    stdin_open: true
    volumes:
      - './nginx/server.crt:/nginx/server.crt'
    networks:
      net1:      
        ipv4_address: 172.23.230.30
 
  proxy:
    image: nwtgck/nginx-http3
    container_name: proxy
    hostname: proxy
    restart: always
    ports:
      - '80:80'
      - '443:443'
      - '443:443/udp'
    depends_on:
      - ghost
    volumes:
      - ./nginx/nginx.conf:/usr/local/nginx/conf/nginx.conf
      - ./nginx/server.crt:/etc/ssl/certs/server.crt
      - ./nginx/serverinstall.key:/etc/ssl/private/server.key
    networks:
      net1:      
        ipv4_address: 172.23.230.60

  ghost:
    image: ghost
    restart: always
    depends_on:
      - ghost-db
    environment:
      database__client: mysql
      database__connection__host: 172.23.230.80
      database__connection__user: root
      database__connection__password: password
      database__connection__database: ghost
    networks:
      net1:      
        ipv4_address: 172.23.230.70
  
  ghost-db:
    image: mysql
    environment:
      MYSQL_ROOT_PASSWORD: password
    networks:
      net1:      
        ipv4_address: 172.23.230.80

networks:
  net1:
    ipam:
      driver: default
      config:
        - subnet: 172.23.230.0/24

参考

糸冬了!!

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