nginxの基本情報
Weekend OSSです。今回は、自分がメンテナンスしているnginx-buildについて話していこうと思います。よろしくお願いします。
よろしくお願いします。では、まずは基本的なところからですね、nginxがどういうソフトなのか、そして何に使われるのかを簡単に教えてもらえますか?
nginxはウェブサーバーです。ウェブサーバーとしては、昔はパッチが一番使われていたんですが、今はnginxが一番使われているんじゃないかなと思います。
なので、一番広く使われているウェブサーバーになります。
なるほど。つまり今ではnginxが最も広く使われているウェブサーバーの一つということですね。
それを踏まえて、次にじゃあなぜnginxを自分でコンパイルする必要があるのか、その理由をもう少し教えていただけますか?
そうですね。まずもうちょっと手前から説明したいかなと思うんですが、nginxは世界で一番使われているウェブサーバーなので、もちろんですね、
使ったらアプトインストールとかすればnginxは手に入るので、ほとんどの人はパッケージでインストールすれば十分なんじゃないかなと思います。
なるほど。確かに多くの人はパッケージでインストールするだけで十分ですよね。
では、その上でなぜ自分でコンパイルする必要があるのか、具体的な理由をもう少し聞かせてください。
そうですね。nginxで新しいバージョンになるともちろん新機能とかが追加されることがあるので、そういった新機能を使いたいというケースがまず一つあると思います。
新機能でいうと、特にですね、http3とかそういう新しい機能を使うとすると、利用するOpenSSLによって使える機能に差が出たりとか、
結構細かいところ、これだと使えて、これだと使えないみたいなのがいろいろあるんですね。
なので、この機能を使いたいけどパッケージだと使えないみたいなのがたまにあるので、そういったことがあると自分でコンパイルするしかないという風になりますし、
あとちょっとここ複雑なんですが、nginxって静的モジュールっていうのがあって、静的モジュールって呼ばれているものだとコンパイル時にソースコードを指定しないとそのモジュールって拡張機能みたいなやつが使えないんですね。
なので、nginxの機能を拡張してモジュールの機能を使いたいのであれば、基本的には自分でコンパイルするしかないっていうのが一昔前の状況でした。
今ではダイナミックモジュールっていう別の仕組みがあって、最近はダイナミックモジュールも結構使われているのでちょっと状況は変わりつつあるんですけど、
一昔前は静的モジュールしかなかったので、モジュール使いたいんだったらコンパイルするよねというような雰囲気でした。
なるほど、よく分かりました。つまり新しい機能を使いたいとか特定のモジュールを組み込みたい場合は、自分でコンパイルする必要が出てくるってことですね。
nginxビルドの役割
じゃあ次の話題としてnginxビルドが具体的にどんな風に役立つのかもう少し教えてもらえますか。
nginxをコンパイルするには大きく3つのソフトウェアがnginx以外に必要で、一つがOpenSSLともう一つがPCRE、一つがZlibです。
それぞれ何するかっていうとOpenSSLは有名ですね。TLS周りの処理に必要なソフトウェアになります。
なのでOpenSSL使わなくてもnginxはコンパイルできるんですが、そうするとHTTPSの配信ができなくなるという風な形になります。
あとそのPCREはパワレル互換の正規表現が使えるソフトウェアで、nginxの中で正規表現を使って設定ファイルの中で正規表現でこのURLの時にこういう設定するみたいなのが書けるんですけど、
そこの正規表現で使われています。Zlibはこれも比較的有名なんですが、gzipで使われていて、nginx上でgzip圧縮したいケースってあると思うので、そういう時にZlibが必要になってきます。
なのでこの3つのソフトウェアをインストールしないとnginxはコンパイルが基本的にはできません。
これらの3つのツールはもちろん有名なやつなので、アプトインストールとかOSのパッケージで基本的には入るんですけれども、
こちらも細かいバージョン、このバージョンを使いたいとかそういう細かい指定があると自分でコンパイル、自分でソースコードをダウンロードしてきてコンパイルするという形になるんですね。
ただやっぱり3つもあるので、3つそれぞれ1個1個ダウンロードしないといけないって結構大変じゃないですか。
nginxビルドは自分でOpenSSLとかそういうの全部ダウンロードしてきて、必要なソフトウェアをダウンロードしてきてnginxをコンパイルできるという風なソフトウェアになっています。
なのでその辺が楽に自分でソースコードを取ってこなくても勝手に取得してきてくれるので、その辺が楽なツールになりますかね。
なるほど、すごくよくわかりました。
つまりnginxビルドはOpenSSLやPCRE、Zlibといった必要なライブラリをまとめて扱いやすくして、自分で全部をダウンロードしてこなくても一括でコンパイルできる便利なツールということですね。
派生プロジェクトの説明
それでは次に関連する話として、例えばOpenSSL以外の互換ライブラリを使う場合、nginxビルドはどう役立つのか少し教えてもらえますか。
実は自分が趣味でnginxコンパイルを普段してるんですけれども、その時によく使うのはLibreSSLというOpenSSLの互換のものになります。
そういったLibreSSLを使いたいよみたいなケースでもnginxビルドは使うことができて、LibreSSLに関してはLibreSSLと指定すればLibreSSLを自動でダウンロードしてきてくれますし、
他のSSLの互換のもの、BoringSSLとかQuickTLSとかいくつかあるんですけど、その辺を使いたい場合でもURLを指定すればそのURLでダウンロードしてくれるので、それで利用することができたりします。
なるほど。LibreSSLみたいなOpenSSL互換ライブラリを使いたい場合でもnginxビルドなら指定するだけで自動でダウンロードしてくれて柔軟に使えるわけですね。
じゃあもう一つ関連する話として、nginxのステーブルとメインラインのバージョンの違いについて少し触れてもらえますか。
そうですね。nginxはステーブルとメインラインの2つのバージョンがあって、ステーブルが偶数でメインラインが奇数です。
これはNode.jsとかPerlとかも一緒なんですけど、ステーブルとメインライン両方があって、基本的にはステーブルを使うことが、本番環境だったらステーブルを使うことが推奨されています。
なのでnginxビルドはステーブル版がデフォルトだと指定されているんですが、メインライン版を使いたい場合は自分でメインラインのバージョンを指定すれば、それがダウンロードされるようになってきたりしますかね。
なるほど。そういうバージョン違いがあるんですね。本番ではステーブル版を使うのが推奨だけれど、nginxビルドならメインライン版も簡単に指定できると。
それでは次の話題として、例えばフリーエンジンやオープンレスティみたいな派生プロジェクトとの違いについても教えてもらえますか。
そうですね。nginxビルドはフリーエンジンXとオープンレスティにも対応しています。それぞれ何かというと、フリーエンジンXがそのエンジンXをフォークしたものになります。
なので純粋なエンジンXの機械のプロジェクトになりますね。オープンレスティに関しては、エンジンX自体を拡張しているものになります。
エンジンXルアーというエンジンXの設定を一部ルアーというプログラミング言語で書けるものがあるんですけど、そのエンジンXルアーって自分でコンパイルしてエンジンXをコンパイルするときに、
エンジンXルアーと一緒にコンパイルすると使えるようになるんですけど、これのコンパイルって結構面倒くさかったりするんですよね。
エンジンXルアーを実際作っているのがオープンレスティなんですけど、そのオープンレスティがエンジンXルアーとか他にもいろいろモジュールが使えるんですけど、
その辺のエンジンXの機能拡張してエンジンXルアーも入ったやつを一気にコンパイルできるっていうのがオープンレスティになります。
エンジンXルアーを使いたいときは基本的にはエンジンXルアーを自分でコンパイルするよりもオープンレスティを使った方が楽で確立だと思います。
そういうときに使える便利なソフトウェアになります。
オープンレスティもフリーエンジンXもエンジンXビルドは対応しているので、その辺を使いたい場合も利用することはできますね。
ただ個人的な感想なんですけど、オープンレスティはいいんですけど、
フリーエンジンXに関しては最近ちょっとそんなに機能追加が多くないっていうのと、
あとエンジンXが以前機能追加が滞った時期があって、その時期にフリーエンジンXで出てきたんですけど、
最近はGitHubに開発がエンジンXに移ったんですよね。
そのタイミングでエンジンX結構息吹き返していて、結構エンジンXでしか使えない機能っていうのもいくつか出てきているので、
個人的にはエンジンXの方が機能が純粋に多いのでお勧めかなと思っていたりします。
ただエンジンXビルドとしては両方とも使うことができます。
なるほど。詳しくありがとうございます。
要するにフリーエンジンはエンジンXをフォークしたもの、オープンレスティはエンジンXを拡張してルアなどを組み込んだ派生プロジェクトで、
エンジンXビルドならどちらも扱えるけれど、最近は公式エンジンXの方が機能増えてきているのでお勧めという感じなんですね。
とても参考になります。
では最後にRenovateを活用する話もちょっと伺いたいです。
エンジンXビルドとRenovateをどう組み合わせているのか教えてもらえますか。
まずRenovateの話しますね。
ただその後にもうちょっとOpenSSL周りの話とかもしたいので、その辺も話していければと思います。
Renovateなんですけれども、RenovateっていうのはLibraryのバージョンアップとかそういうのに利用できるものなんですけれども、
エンジンXビルドはかなり今Renovateを活用していて、
エンジンXだったりとかPCRE2だったりとか、あとZlibだったりとかいろんなソフトウェアがバージョンアップするんですけれども、
そのバージョンアップしたときにちゃんとエンジンXビルドのデフォルトのバージョンを最新にするようにしています。
なのでそのバージョンちゃんと追従できるようにRenovateでそのバージョンアップがあったらプレリクエストを作ってもらってマージしてリリースするっていうのをやるようにしています。
なので結構ですね、いろんなソフトウェアが思い思いのフォーマットでLibraryバージョンアップしているので、
その辺Renovateで頑張って対応できるようにしているので、結構Renovateを活用しているプロジェクトなんじゃないかなと思っているので、
OpenSSLとそのフォーク
もしRenovateでどういうことをやっているのか気になったら是非Renovateの設定を見てみると面白いんじゃないかなと思っていたりします。
なるほど。Renovateを使ってエンジンXビルドの依存Libraryのバージョンも自動的に最新化しているわけですね。
確かにRenovateの設定を見てみると面白そうですし、そういった自動化でメンテナンスが楽になるのはいいですね。
ではまだ他にもOpenSSL周りの話もあるということなので、引き続きその辺りを聞かせてください。
そうですね。OpenSSLはいくつかフォークがあって、多分比較的有名なのはLibreSSLというやつで、
これは以前OpenSSLがちょっと大きめのセキュリティインシデントを起こしたときに、
OpenBSDというセキュリティをかなり気にするOSがあるんですけれども、
そちらの人たちがOpenSSLをフォークしてバージョン、脆弱性とかを生まないようなOpenSSLを作ろうと言ってやったのがLibreSSLになります。
LibreSSLの特徴としては、新規の追加がちょっと遅いとかそういうのはあるんですけれども、
基本的に古いコードを削除したりとか、脆弱性を見そうなコードを事前に削除することで、
その脆弱性を見にくいような開発体制になっていたりします。
その代わり、OpenSSLに入っている高速化のコードとかも消えているので、
OpenSSLでパフォーマンスは出しにくいんですけれども、
セキュリティ周り安心できるようなものになっていて、
実際ですね、もし皆さんMacを使っていたら手元にOpenSSL入っていると思うんですけど、
これ実はちょっと古いLibreSSLなので、OpenSSLを使っていると思っているかもしれないですが、
実際にはLibreSSLを使っているみたいな状況があったりします。
もう1個有名なのが、Googleが作っているBowlingSSLというのがあって、
これがOpenSSLのフォークになって、Googleの社内で使われているものになります。
ChromeとかAndroidとかは実はBowlingSSLを使っているので、
結構実はOpenSSLじゃないものを我々は普段使って生きていたりします。
BowlingSSLの特徴としては、HTTP3周りの機能が独自拡張されていて、
BowlingSSLにしか元々HTTP3のAPIってなかったんですね。
LibreSSLにも実はHTTP3周りのAPIで実装されているんですが、
これはBowlingSSL互換のものになります。
なので元々、EngineXをはじめいろんなソフトウェアがHTTP3を対応するときに、
BowlingSSLのAPIで実装したので、結構BowlingSSLがデファクトスタンダードみたいになっていました。
なので、ちょっと前までHTTP3使いたいんだったら、
BowlingSSL互換のAPIを実装しているものを使う必要がありました。
もう一個、QuickTLSっていうものがあって、
QuickTLSはOpenSSLのフォークで、
これはQuickTLSっていう名前からもわかる通り、
HTTP3に対応するために、
BowlingSSLのAPIをOpenSSLに足そうって言って生まれたプロジェクトがQuickTLSになります。
なので、結構Node.jsとかがHTTP3対応するときに使ったのがこのQuickTLSだったりします。
どれ使うべきかっていうところなんですけれども、
実はですね、割と最近はOpenSSLの最新バージョンとかであれば、
OpenSSLでもHTTP3対応できるので、
特にこだわりがないんだったら、OpenSSLを使うのがいいかもしれません。
じゃあ、BowlingSSL互換のものを使いたいという場合はですね、
僕個人としてはLibreSSLをお勧めしていて、
パフォーマンスが悪いっていうデメリットはあるんですが、
あまりパフォーマンス面にこだわりがなくて、
セキュリティをちゃんと担保したいっていうのであれば、
LibreSSLが一番扱いやすいかなと思っているのと、
あとバージョニングですね。
LibreSSLはちゃんとバージョニング切ってリリースしてくれるんですよ。
なんですけど、BowlingSSLってGoogle社内でしか使われてないんですよ、基本的に。
なので、バージョニングとかタグ付けみたいなのが結構適当になっています。
なので、どれがステーブル版なのかみたいな、そういうのがよくわからないんですね。
それで問題あるかっていうと、
Google社内の人は別に社内に関係者の人、開発者の人たちがいるから、
どのバージョンを使えばいいかとかそういうのわかるんですけど、
Google社内の人間じゃない人からすると、どのバージョンを使ったらいいのかよくわからないので、
結構使いづらいっていうのがあります。
BowlingSSLとQuickTLS
そういうのもあったんで、
QuickTLSが以前は結構デファクトスタンダードみたいになりつつあったんですけど、
ちょっと最近QuickTLSの開発がどうなってるのかよくわからない状況に今なっているので、
というのも、
QuickTLSってOpenSSLにHAP3というか、
QuickのAPIを実装しようって言って最初立ち上がったプロジェクトなんで、
そのOpenSSLに今、
バーリングSSLの互換じゃないんですけれども、
Quickが使えるAPIっていうのが実装されたので、
QuickTLSの存在意義っていうのがだいぶ薄れてはきてるんですよね。
そういうのもあって、
そのQuickTLSが今ちょっとどういう開発体制なのかがちょっとわかりにくい状況に今あります。
なので、
こだわりがないんであれば、
OpenSSLの最新バージョンを使うのが今一番楽かなってありつつ、
Nginx Buildの実装
バーリングSSLのAPI使いたいんだったら、
LibreSSLが比較的使いやすいのかなとは思っています。
ただ、僕が基本趣味でLibreSSL使っていたりとか、
あとNginx BuildのLibreSSL対応とかもしたのは僕なので、
かなりLibreSSLが好きな人間の意見だっていうことは前提においてほしいかなと思っています。
なるほど。
すごく丁寧に教えていただいてありがとうございます。
つまり、OpenSSLにはLibreSSL、
ボーリングSSLといったフォークや互換実装があって、
それぞれに特徴や歴史があると。
今ならOpenSSL本家でもHTTP3に対応してきてるから、
特にこだわりがなければ本家を使えばいいし、
セキュリティ重視ならLibreSSLが使いやすいと。
しかもNginx Buildではそれらを柔軟に扱えるようにしているということですね。
とても面白いお話でした。
ではまた引き続き別の話題も掘り下げていきましょう。
Nginx BuildってGoで実装されているんですよね。
なのでそのGoで結構いろいろ複雑な処理をしていたりします。
なのでその辺ちょっと掘り下げていきましょうか。
もちろんです。
なるほど。Nginx BuildがGoで実装されているという点は面白いですね。
それならGoでどんなふうに複雑な処理をしているのか、
ぜひその辺りをもう少し聞かせてください。
例えばGoならではの工夫や苦労したポイントなんかがあれば、
ぜひ教えてください。
そうですね。Goならではというところはあんまりなくて、
というのはNginx Buildってシルスクリプトでも
すごい頑張ればできるかなぐらいの処理をやっていて、
なんでかというとNginx Buildってやっていることってそんな複雑じゃなくて、
要は各種ソースコードのダウンロードをした後にそれぞれ展開して、
それでコンフィギュアをして、その各コンフィギュアの時に
その各ソースコード、ダウンロードしてきたソースコードを
コンフィギュアのオプションに渡すっていうところでやれるので、
その後はNginx側に処理丸投げなので、
Nginx Build自体が複雑なことをしているってわけではないんですよね。
ただコンフィギュアを外から渡すようになってるんですけど、
その外から渡してきたコンフィギュアがそのまんま使えるわけじゃなくて、
その渡されてきたコンフィギュアをまた整形して、
OpenSSLのディレクトリだとかそういうの渡した上で
Nginx Configure実際に実行してるので実行しないといけないので、
その辺は自前でいろいろやらないといけないっていうのはありますかね。
なるほど。つまりNginx Build自体はGoで複雑なことをやってるというより、
各ソースコードをダウンロードして、展開して、
適切なディレクトリを指定してコンフィギュアを実行する、
その流れをうまく自動化している感じなんですね。
そのコンフィギュアのオプションを整形したり、
渡された設定をうまくNginx側に引き渡す部分がちょっとした工夫どころという感じですね。
とてもわかりやすいです。
ではまた別の角度からも話題を続けていきましょう。
そうですね。話したいところはこんなところですかね。
一旦終わりにしましょうかね。
了解です。ではここで一旦終わりにしましょう。
またいつでも続きお話できるので、気軽に声かけてくださいね。
お疲れ様でした。
お疲れ様でした。