1月 062021
 

以前のエントリで、「Nginx + quiche パッチで HTTP/3 にチャレンジ。」と、いうのを書いています。このエントリの『続編』を書いてみたいと思います。

と、いうのも色々あったからです。

簡単に書くと、あっという間にこのエントリは終わってしまいますf(^^;;。
ネタ的なモノを箇条書きにしてみると

  • nginx + quiche パッチでは SSI は動作しません
  • nginx + quiche パッチを利用した場合 RTMP モジュールが利用できないです

の二つになります。これが解れば詳細はどうでもいー。と、いう人はここでおしまいです。
『なんで?』と思った方は読み進んでくださいf(^^;;。

 
まず、上の部分の SSI についてですが、perl による index.cgi で SSI で吐き出すことと同じ動作をするモノを作成すると、無事に動作します。

以下はサンプルです。これは index.cgi 。

#!/usr/local/bin/perl
use strict;
print "Content-type: text/html\n\n";
print "<html>\n<head>\n";
print "<META HTTP-EQUIV=\"Content-type\" CONTENT=\"text/html;charset=utf-8\">\n";
print "<TITLE>IPv6 HTTP/3 Access Web page.</TITLE>¥n";
print "</head>\n<body>\n";

print "<br><h2>Hello HTTP/3 World.</h2><hr>\n";

my $word = "";
if ($ENV{'REMOTE_ADDR'} =~ /:/) {
    $word  = "===> ";
    $word .= "$ENV{'REMOTE_ADDR'} から IPv6 パケットを受け取りました。";
} else {
    $word  = "===> ";
    $word .= "$ENV{'REMOTE_ADDR'} から IPv4 パケットを受け取りました。";
}
print "$word<br><hr>\n";;

print "===> Protocol: $ENV{'SERVER_PROTOCOL'}<br>\n<hr>";
print "===> Access Port: $ENV{'SERVER_PORT'}<br>\n<hr>";

exit;

 
似たようなのを index.shtml と access.cgi でやるとこんな感じ。

こちらは index.shtml。

<HTML>
<HEAD>
<META HTTP-EQUIV="Content-type" CONTENT="text/html;charset=utf-8">
<TITLE>IPv6 HTTP/3 Access Web page.</TITLE>
</HEAD>
<BODY>
<ht>
Hello HTTP/3 World.<br>
<hr>
<!--# include file="./access.cgi"-->
<hr>
</BODY>
</HTML>

 
こちらは access.cgi。

#!/usr/local/bin/perl
use strict;
print "Content-type: text/html\n\n";
my $word = "";
if ($ENV{'REMOTE_ADDR'} =~ /:/) {
    $word  = "===> ";
    $word .= "$ENV{'REMOTE_ADDR'} から IPv6 パケットを受け取りました。";
} else {
    $word  = "---> ";
    $word .= "$ENV{'REMOTE_ADDR'} から IPv4 パケットを受け取りました。";
}
print "$word<br><hr>\n";;
print "===> プロトコル: $ENV{'SERVER_PROTOCOL'}<br>\n<hr>\n";
print "===> アクセスポート: $ENV{'SERVER_PORT'}<br>\n";
exit;

 
index.html (index.shtml) に include があると、 Nginx + quiche パッチではまともに動作しないようです。 quiche パッチを詳しく追ってはいないのですが、どうやら include 部分がそげ落ちているようです・・。 orz

まぁ、今の段階では SSI を利用しないコンテンツを用意する必要がありそうです。

 
二個目。

テレワークなどで、PC にカメラを接続する機会が多いのですが、せっかく購入したカメラ。もっと色々な用途で使ってみたい。などと思うわけです。 USB Video Class 、俗に USB な UVC カメラを FreeBSD に接続し、 webcamd や obs-studio をインストールして『ストリーミングなどしてみんべ。』などと思うわけです。
このブログでも以前に「NotePCに付いているカメラを FreeBSD で使う。」と、いうのを書いていたりしますが;-)。

更に一歩進んで obs-studio をイントールした場合、配信先に RTMP サーバが必要になります。
Nginx はモジュールとして RTMP モジュールや Stream・Stream SSL モジュールなどを利用可能ですが、HTTP/3 を有効にする quiche パッチを適用した Nginx ではこれらのもジュールは利用できません。

以下は nginx.conf の設定の抜粋です。

load_module /usr/local/libexec/nginx/ngx_stream_module.so;
load_module /usr/local/libexec/nginx/ngx_rtmp_module.so;

rtmp {
    server {
        listen 1935;
        chunk_size 4096;

        access_log /var/log/nginx/access_rtmp.log;

        application webcam {
            live on;
            record off;
            wait_video on;
        }
    }
}

 
load_module のところで早くもエラーが出ます。

# service nginx start
Performing sanity check on nginx configuration:
nginx: [emerg] dlopen() "/usr/local/libexec/nginx/ngx_stream_module.so" failed (/usr/local/libexec/nginx/ngx_stream_module.so: Undefined symbol "SSL_set_tlsext_host_name") in /usr/local/etc/nginx/nginx.conf:7
nginx: configuration file /usr/local/etc/nginx/nginx.conf test failed

 
もしくは

# service nginx start
Performing sanity check on nginx configuration:
nginx: [emerg] dlopen() "/usr/local/libexec/nginx/ngx_rtmp_module.so" failed (/usr/local/libexec/nginx/ngx_rtmp_module.so: Undefined symbol "HMAC_CTX_new") in /usr/local/etc/nginx/nginx.conf:7
nginx: configuration file /usr/local/etc/nginx/nginx.conf test failed

 
みたいな感じ。

最初、どうして、SSL 系でエラーが出るのか解らなかったのですが、ports の www/nginx/Makefile とかソースを眺めていたら解りました。以前のエントリで、Nginx + quiche パッチを適用する場合 configure オプションに –with-openssl=/usr/ports/www/nginx-http3/quiche/deps/boringssl を指定しているんですね。
RTMP や Stream モジュールを利用する場合、ベタな openssl のソースのパスを指定する必用があるのですが、 quiche パッチを適用した場合、quiche 独自の SSL のコードを参照する必用があるので、 RTMP や Steram モジュールのコンパイルが通ったとしても、いざ動作させようとすると色々とシンボル名がなかったりするのですな。

 
と、いうことで、 Nginx に quiche パッチを適用した場合は、 HTTP/3 でのアクセス可状態なサーバで、SSI を利用しないウェブサーバとして利用するみとになります。

あ。Nginx + quiche パッチを適用したウェブサーバでも HTTP/2 や HTTP/1.1 、そして HTTP/1.0 (今では w3m くらいか?) でアクセスがあった場合 (それは、つまりは TCP でアクセスがあった場合かぁ?) には SSI は動作します。あくまで HTTP/3 でアクセスがあった場合のみ SSI の記述がある index.html がまともに表示されない状態になります。

SSI 使ったり RTMP・Strerm モジュールを利用したい場合は別にコンパイルしたサラの Nginx を用意する必用があります。 quiche パッチを適用しない Nginx では SSI や RTMP のサーバとして利用できるので、仮想マシンやコンテナで別立てするのがよろしいかと思われます。

 
ちなみに、Firefox は 72 から、 macOS や iPhone は Safari 14 から HTTP/3 がサポートされるようになりました(詳細については gugu ってください;-)。 macOS や iOS から HTTP/3 でアクセスできるようになると、ウェブサーバ担当者としてもいよいよ HTTP/3 の設定をしてサーバを起動してみたくなりますなぁ;-)。 ファイアーウォールの UDP Port:443 を開けるときが、今っ!! 来ましたっ!! ;-)。