nginx http/3を動かす

nginx
この記事は約8分で読めます。

NginxでHTTP/3を動かしてみます。HTTP/3はQUICというプロトコルに基づいているようです。詳しくは理解していないので追々学んでいきたいと思います。まずは、ローカルで動かしてどのようなデータやり取りが行われているのかwiresharkで覗くところから。

Dockerコンテナでビルドします。gistでレシピが公開されているのでそれに倣います。

 

ビルドすると以下のエラーとなってしまいました。

#13 58.57 auto/configure: error: invalid option "--with-http_quic_module"

どうも上記のオプションは--with-http_v3_moduleに統合された?ようなので削除します。

参考: https://hg.nginx.org/nginx-quic/rev/33226ac61076

最終的に以下のようにしました。

FROM nginx:1.21.4 AS build

WORKDIR /src
RUN apt-get update && \
    apt-get install -y git gcc make g++ cmake perl libunwind-dev golang && \
    git clone https://boringssl.googlesource.com/boringssl && \
    mkdir boringssl/build && \
    cd boringssl/build && \
    cmake .. && \
    make

RUN apt-get install -y mercurial libperl-dev libpcre3-dev zlib1g-dev libxslt1-dev libgd-ocaml-dev libgeoip-dev && \
    hg clone https://hg.nginx.org/nginx-quic   && \
    hg clone http://hg.nginx.org/njs -r "0.6.2" && \
    cd nginx-quic && \
    hg update quic && \
    auto/configure nginx -V 2>&1 | sed "s/ \-\-/ \\\ \n\t--/g" | grep "\-\-" | grep -ve opt= -e param= -e build= \
                   --build=nginx-quic --with-debug  \
                   --with-http_v3_module --with-stream_quic_module \
                   --with-cc-opt="-I/src/boringssl/include" --with-ld-opt="-L/src/boringssl/build/ssl -L/src/boringssl/build/crypto" && \
    make

FROM nginx:1.21.4
COPY nginx.conf /etc/nginx/nginx.conf
RUN mkdir -p /certs
# https://letsencrypt.org/docs/certificates-for-localhost/
COPY localhost.crt /certs/localhost.crt
COPY localhost.key /certs/localhost.key
COPY --from=build /src/nginx-quic/objs/nginx /usr/sbin
RUN /usr/sbin/nginx -V
EXPOSE 10443

nginx.conf

user  nginx;
worker_processes  1;

events {
    worker_connections 1024;
}

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;

http {
    include mime.types;
    default_type application/octet-stream;
    sendfile on;

    log_format quic '$remote_addr - $remote_user [$time_local] '
    '"$request" $status $body_bytes_sent '
    '"$http_referer" "$http_user_agent" "$http3"';

    root /usr/share/nginx/html;
    access_log /var/log/nginx/access.log quic;

    server {
        # for better compatibility it's recommended
        # to use the same port for quic and https
        listen 10443 http3 reuseport;
        listen 10443 ssl http2;

        ssl_certificate /certs/localhost.crt;
        ssl_certificate_key /certs/localhost.key;
        ssl_protocols TLSv1.3;


        location / {
            # required for browsers to direct them into quic port
            add_header Alt-Svc 'h3=":10443";h3-29=":10443"; ma=86400';
        }
    }
}

ビルドしてコンテナ起動します。

$ openssl req -x509 -out localhost.crt -keyout localhost.key   -newkey rsa:2048 -nodes -sha256   -subj '/CN=localhost' -extensions EXT -config <( \
   printf "[dn]\nCN=localhost\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:localhost\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth")
$ docker build -t nginx-http3 .
$ docker run -it -p 10443:10443 -p 10443:10443/udp --rm --name http3 nginx-http3:latest
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2021/12/16 15:25:28 [notice] 1#1: using the "epoll" event method
2021/12/16 15:25:28 [notice] 1#1: nginx/1.21.4 (nginx-quic)
2021/12/16 15:25:28 [notice] 1#1: built by gcc 10.2.1 20210110 (Debian 10.2.1-6) 
2021/12/16 15:25:28 [notice] 1#1: OS: Linux 5.10.47-linuxkit
2021/12/16 15:25:28 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2021/12/16 15:25:28 [notice] 1#1: start worker processes
2021/12/16 15:25:28 [notice] 1#1: start worker process 31

curlでアクセスしてみます。

$ docker run -it --rm ymuski/curl-http3 curl -k -IL https://192.168.3.5:10443 --http3
HTTP/3 200
server: nginx/1.21.4
date: Thu, 16 Dec 2021 15:20:57 GMT
content-type: text/html
content-length: 615
last-modified: Tue, 02 Nov 2021 14:49:22 GMT
etag: "61814ff2-267"
alt-svc: h3=":10443";h3-29=":10443"; ma=86400
accept-ranges: bytes
172.17.0.1 - - [16/Dec/2021:15:37:53 +0000] "HEAD / HTTP/3.0" 200 149 "-" "curl/7.76.1-DEV" "h3"

RFC9000 https://www.rfc-editor.org/rfc/rfc9000.html

参考

コメント

タイトルとURLをコピーしました