ラベル QUIC の投稿を表示しています。 すべての投稿を表示
ラベル QUIC の投稿を表示しています。 すべての投稿を表示

2021年5月5日水曜日

nginx-quic をビルドしてみた

nginx-quic をビルドしてみた

概要

nginx でも本格的に QUIC サポートが始まっており現在かなり使えるレベルにまでなっているので試してみました
Vagrant で構築した Ubuntu 18.04 上でビルドします

環境

  • Ubuntu 18.04
    • cmake 3.10
    • ninja 1.8.2
    • golang 1.10
  • Chrome 90.0.4430.85
  • nginx-quic 1.19.10
  • boringssl (revision: fe3b185e5d46e643727cbf3e7cb1edcb394f1317)

依存パッケージのインストール

  • sudo apt -y install mercurial ninja-build cmake build-essential g++ golang libpcre3 libpcre3-dev zlib1g-dev

自分の環境は上記で足りましたが他に足りないパッケージがある場合は適宜インストールしてください
OpenSSL のライブラリがないと言われる場合は後述する boringssl のビルドがうまくいっていない可能性があります

boringssl のビルド

nginx-quic のビルド

  • hg clone -b quic https://hg.nginx.org/nginx-quic
  • cd nginx-quic
  • ./auto/configure --with-debug --with-http_v3_module --with-cc-opt="-I../boringssl/include" --with-ld-opt="-L../boringssl/build/ssl -L../boringssl/build/crypto"
  • make
  • sudo make install

nginx のバイナリは /usr/local/nginx/sbin/nginx に配置されます

(Optional) サーバ証明書の作成

動作確認用の自己証明書を作成します
すでに適当なサーバ SSL 証明書がある場合はそれで代用可能です

https://hawksnowlog.blogspot.com/2021/01/how-to-generate-client-certs-on-ubuntu.html#optional-サーバ証明書の作成

nginx 起動

QUIC をオンにした nginx の設定ファイルを作成し起動します

  • cat /usr/local/nginx/conf/nginx.conf
worker_processes  1;

events {
    worker_connections  1024;
}

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

    access_log logs/access.log quic;

    server {
        listen 8443 http3 reuseport;
        listen 8443 ssl;

        ssl_certificate     /etc/nginx/certificates/domain.com.crt;
        ssl_certificate_key /etc/nginx/certificates/domain.com.key;
        ssl_protocols       TLSv1.3;

        location / {
            add_header Alt-Svc '$http3=":8443"; ma=86400';
        }
    }
}
  • sudo /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf

動作確認

http3 が使える curl クライアントを使います
QUIC が使えるクライアントはいろいろありますのでお好きなものを使ってください

これで「HTTP/3 200」と表示されれば OK です
ちなみに nginx のログを見るとちゃんと HTTP3 で通信しているのが確認できます

  • tail -f /usr/local/nginx/logs/access.log
172.17.0.2 - - [29/Apr/2021:12:04:56 +0000] "GET / HTTP/3.0" 200 790 "-" "curl/7.76.1-DEV" "quic" "h3-29"

以下の動作確認方法 ERR_QUIC_PROTOCOL_ERROR となりできません
おそらく自己証明書などの関係かなと思います

chrome を使って quic でレスポンスされているか確認してみましょう
Chrome で QUIC をオンにして再起動します

  • chrome://flags/#enable-quic

https://192.168.100.10:8443/

NET::ERR_CERT_INVALID で先に進めない場合は「thiisunsafe」をタイプしましょう

最後に

設定ファイルなどもそのまま流用できますし QUIC でないクライアントの場合は HTTP2/1.1 で返してくれるのでかなり使えそうです
ただ自分でバイナリをビルドする必要があるのでそこがまだ面倒かなと思います

docker などで公式がリリースしてくれる日も近いかもしれません

参考サイト

2019年6月21日金曜日

goquic 超入門

概要

QUIC (Quick UDP Internet Connections) は UDP 上で TCP のデータのやり取りをする高速かつ安全なプロトコルです
現在も開発が進められていますが golang でとりあえず触れる環境があったので試してみました

環境

  • Ubuntu 16.04 LTS (vagrant)
    • cmake 3.5.1
    • ninja-build 1.5.1
    • gcc 5.4
    • golang 1.12.6
  • goquic (rev: 1e49c0fcf10725575edc12e5834bc7d003da1581)

golang インストール

  • wget 'https://releases.hashicorp.com/vault/1.1.3/vault_1.1.3_linux_amd64.zip'
  • sudo tar -C /usr/local -xzf go1.12.6.linux-amd64.tar.gz
  • vim ~/.bashrc
export GOPATH="/home/vagrant/go"
export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin

一度ログアウトして再度ログインしましょう

ビルドに必要なパッケージのインストール

  • sudo apt -y install cmake
  • sudo apt -y install ninja-build

これ以外に g++ or gcc などの C/C++ のコンパイラが必要になります
自分はすでにインストールされていたので省略しています
各種バージョンは環境のところに記載しています

ソース取得

  • go get -u -d github.com/devsisters/goquic

goquic はソースからビルドして動作させます
go get で取得しましょう

ビルド

  • cd $GOPATH/src/github.com/devsisters/goquic
  • ./build_libs.sh

でビルドが始まります
失敗する場合はエラー内容を見てトラブルシューティングするしかありません
自分は一発でいけたので同じ環境 (vagrant + ubuntu/xenial) なら問題なくビルドできると思います
完了すると libgoquic.a が作成されます

  • ls -l lib/linux_amd64/libgoquic.a

server と client のサンプルをビルドする

実際に libgoquic.a を使ったサンプルのサーバとクライアントがあるのでそれをビルドして使ってみます

  • go build $GOPATH/src/github.com/devsisters/goquic/example/server.go
  • go build $GOPATH/src/github.com/devsisters/goquic/example/client.go

他に reverse_proxy.go もありますが特に使いませんでした

サーバを起動する

サーバの起動には証明書と鍵ファイルが必要になります
自分は Let’sEncrypt で取得した証明書 を使いましたが openssl や Mac であればキーチェインアクセスでも OK です

作成した証明書と鍵を指定してバイナリを実行しましょう

  • ./server -cert fullchain.pem -key privkey.pem

これで 8080 で LISTEN したサーバが起動します

動作確認

確認方法はコマンドとブラウザでもできます
コマンドの場合は以下のように実行すれば結果が取得できます

  • ./client -url "http://localhost:8080/numbers"

0 から 9999 までの数字が返ってくると思います
Chrome で https://192.168.99.200 にアクセスしても確認できます
証明書の警告が出ますが無視で OK です
トップページには動作確認ようのリンクが用意されています

「Numbers test」にアクセスすると先程コマンドで実行した結果と同じものがブラウザでも確認できます

「Files」はおそらくファイルの確認やダウンロードを確認するページかと思われます
デフォルトだと /tmp の内容を表示しているのでここにファイルなどをおけばリストやダウンロードの確認ができます
flag.StringVar(&serveRoot, "root", "/tmp", "Root of path to serve under https://127.0.0.1/files/")

おまけ: curl もやってみた

ヘッダ情報を確認しやすいので curl も実行してみました
QUIC を使っている場合ヘッダにいろいろと情報が付与されるようです
結果を貼っておきます

  • curl -k -sSL -D - https://localhost:8080
HTTP/1.1 200 OK
Alt-Svc: quic=":8080"; ma=86400; v="36,35,34,33,32,31,30"
Alternate-Protocol: 8080:quic
Content-Type: text/html; charset=utf-8
Trailer: AtEnd1, AtEnd2
Trailer: AtEnd3
Date: Thu, 20 Jun 2019 05:03:28 GMT
Transfer-Encoding: chunked

This HTTP response has both headers before this text and trailers at the end.<br/><a href='/numbers'>Numbers test (0~9999)</a><br/><a href='/files'>Files</a><br/>127.0.0.1:40472
Atend1: value 1
Atend2: value 2
Atend3: value 3

最後に

goquic で QUIC を使ったアプリにとりあえず触ってみました
これだけだと効果を実感することはできないので実際は QUIC を使っていない HTTP 環境と使ってる HTTP 環境で速度検証などをしたほうが良いかなと思います

golang だけではありますがサーバアプリの実装も難しそうではないので試しにチャレンジしてみるのも良いのかなと思います