Ubuntu 22.04でHTTP/2サポート付きのNginxをセットアップする方法

A previous version of this tutorial was written by Sergey Zhukaev.

はじめに

Nginx は高速で信頼性のあるオープンソースのウェブサーバーです。低メモリフットプリント、高いスケーラビリティ、設定の容易さ、およびさまざまなプロトコルのサポートによって人気を博しました。

HTTP/2は、サーバーからブラウザへのページの配信に使用されるハイパーテキスト転送プロトコルの新しいバージョンです。HTTP/2は、HTTPの大きな更新版であり、ほぼ20年ぶりのものです。HTTP1.1は、ウェブページがはるかに小さかった1999年に一般に公開されました。その後、インターネットは大きく変化し、今ではHTTP 1.1の制限に直面しています。このプロトコルは、ほとんどの現代のウェブサイトの潜在的な転送速度を制限します。なぜなら、ページの一部がキューでダウンロードされるためです。前の部分が完全にダウンロードされるまで、次の部分のダウンロードが開始されません。そして、平均的な現代のウェブページは、数十の個々のCSS、JavaScript、および画像リソースをダウンロードします。

HTTP/2は、いくつかの基本的な変更をもたらすことでこの問題を解決します。

  • すべてのリクエストが順番ではなく並行してダウンロードされます。
  • HTTPヘッダーは圧縮されます。
  • ページはテキストファイルではなくバイナリとして転送され、これが効率的です。
  • サーバーはユーザーの要求なしにデータを「プッシュ」でき、これによりレイテンシの高いユーザーの速度が向上します。

HTTP/2は暗号化を必要としませんが、2つの最も人気のあるブラウザ、Google ChromeとMozilla Firefoxの開発者は、セキュリティ上の理由からHTTP/2をHTTPS接続のみサポートすると述べています。したがって、HTTP/2をサポートするサーバーを設定する場合は、HTTPSでセキュリティを確保する必要があります。

このチュートリアルでは、HTTP/2をサポートする高速かつ安全なNginxサーバーのセットアップ方法を紹介します。

前提条件

始める前に、いくつかのものが必要です:

ステップ1 — HTTP/2サポートの有効化

Nginxのインストールチュートリアルでサーバーブロックの設定手順に従っている場合、/etc/nginx/sites-available/your_domainにドメインのサーバーブロックがあり、server_nameディレクティブがすでに適切に設定されているはずです。最初の変更は、ドメインのサーバーブロックをHTTP/2を使用するように変更することです。

お好みのエディタで、ドメインの構成ファイルを開きます(例:nano):

  1. sudo nano /etc/nginx/sites-enabled/your_domain

ファイルで、ポート443に関連付けられたlisten変数を見つけます:

/etc/nginx/sites-enabled/your_domain
...
    listen [::]:443 ssl ipv6only=on; 
    listen 443 ssl; 
...

最初のものはIPv6接続用です。2番目のものはすべてのIPv4接続用です。両方でHTTP/2を有効にします。

listenディレクティブを変更してhttp2を含めます:

/etc/nginx/sites-enabled/your_domain
...
    listen [::]:443 ssl http2 ipv6only=on; 
    listen 443 ssl http2; 
...

これにより、NginxがサポートされるブラウザでHTTP/2を使用するように指示されます。

構成ファイルを保存してテキストエディタを終了します。 nanoを使用している場合は、Ctrl+Xを押してから、プロンプトが表示されたらYを押してからEnterキーを押します。

Nginxの構成ファイルを変更するときは、-tフラグを使用して構成エラーをチェックする必要があります。これは、Nginxの組み込み構文チェックコマンドを実行します:

  1. sudo nginx -t

構文にエラーがない場合、次のような出力が表示されます:

Output of sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

次に、Nginxサーバーをより制限の多い暗号リストを使用するように構成します。サーバーのセキュリティを向上させます。

ステップ2 — 古くて安全ではない暗号スイートの削除

HTTP/2には、回避すべき古くて安全でない暗号のブロックリストがあります。 暗号スイートは、転送されるデータを暗号化する方法を記述する暗号化アルゴリズムです。

使用する方法は、NginxのTLS/SSL証明書をどのように構成したかによって異なります。

Certbotを使用して証明書を取得した場合、次のファイルが作成されます:/etc/letsencrypt/options-ssl-nginx.conf。このファイルには、HTTP/2には十分に安全でない暗号が含まれています。ただし、このファイルを変更すると、将来的なCertbotの更新が適用されなくなるため、Nginxにこのファイルを使用しないよう指示し、独自の暗号リストを指定します。

ドメインのサーバーブロック構成ファイルを開きます:

sudo nano /etc/nginx/sites-enabled/your_domain

options-ssl-nginx.confファイルが含まれる行を探し、行の先頭に#文字を追加してコメントアウトします:

/etc/nginx/sites-enabled/your_domain

# include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot

その行の下に、許可される暗号を定義するために次の行を追加します:

/etc/nginx/sites-enabled/your_domain

ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;

ファイルを保存してエディタを終了します。

自己署名証明書を使用したり、サードパーティから証明書を取得し、前提条件に従って構成した場合は、テキストエディタで次のファイルを開きます:/etc/nginx/snippets/ssl-params.conf

  1. sudo nano /etc/nginx/snippets/ssl-params.conf

次の行を探します:

/etc/nginx/snippets/ssl-params.conf
...
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
...

それを次の暗号リストを使用するように変更します:

/etc/nginx/snippets/ssl-params.conf

...
ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;

ファイルを保存してエディタを終了します。

再度、nginx -tコマンドを使用して構成の構文エラーを確認します:

  1. sudo nginx -t

エラーが発生した場合は、それらを修正して再度テストします。

構成が構文チェックをパスしたら、systemctlコマンドを使用してNginxを再起動します:

  1. sudo systemctl reload nginx.service

サーバーが再起動したら、動作することを確認しましょう。

ステップ3 — HTTP/2が有効になっていることの確認

サーバーが実行され、HTTP/2と連携していることを確認しましょう。

curlコマンドを使用して、サイトにリクエストを行い、ヘッダーを表示します:

  1. curl -I -L --http2 https://your_domain

以下のような出力が表示されます:

HTTP/2 200
**Server**: nginx/1.18.0 (Ubuntu)
**Date**: Tue, 21 Jun 2022 22:19:09 GMT
**Content-Type**: text/html
**Content-Length**: 612
**Last-Modified**: Tue, 21 Jun 2022 22:17:56 GMT
**Connection**: keep-alive
**ETag**: "62b24394-264"
**Accept-Ranges**: bytes

また、HTTP/2が使用されているかをGoogle Chromeで確認することもできます。Chromeを開き、https://your_domainに移動します。Chromeの開発者ツールを開きます (表示 -> 開発 -> 開発ツール) 、そしてページをリロードします (表示 -> このページを再読み込み) 。ネットワークタブに移動し、Nameで始まるテーブルヘッダー行を右クリックし、ポップアップメニューからプロトコルオプションを選択します。

新しいプロトコル列が表示され、HTTP/2を示すh2が含まれています。これにより、HTTP/2が動作していることが示されます。

この時点で、HTTP/2プロトコルを通じてコンテンツを提供する準備が整いました。HSTSを有効にしてセキュリティとパフォーマンスを向上させましょう。

ステップ4 — HTTP Strict Transport Security(HSTS)の有効化

HTTPリクエストがHTTPSにリダイレクトされている場合でも、HTTP Strict Transport Security(HSTS)を有効にして、そのリダイレクトを行わなくてもよくなります。ブラウザがHSTSヘッダーを見つけると、一定期間、サーバーに通常のHTTP経由で接続しようとしません。常に暗号化されたHTTPS接続のみでデータを交換します。このヘッダーはまた、プロトコルのダウングレード攻撃からも保護します。

ドメインのサーバーブロック構成ファイルを再度開きます:

sudo nano /etc/nginx/your_domain

次の行をSSL暗号を含むファイルの同じブロックに追加して、HSTSを有効にします:

/etc/nginx/your_domain
server {
...
    ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
    add_header Strict-Transport-Security "max-age=15768000" always;
}
...

max-ageは秒単位で設定されます。値15768000は6ヶ月に相当します。

デフォルトでは、このヘッダーはサブドメインのリクエストに追加されません。サブドメインがあり、すべてのサブドメインにHSTSを適用したい場合は、行の最後にincludeSubDomains変数を追加してください。次のようになります:

/etc/nginx/your_domain
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains" always;

ファイルを保存し、エディターを終了します。

構文エラーがないかを再度確認します:

  1. sudo nginx -t

最後に、変更を適用するためにNginxサーバーを再起動します。

  1. sudo systemctl reload nginx.service

結論

あなたのNginxサーバーは今、HTTP/2ページを提供しています。SSL接続の強度をテストしたい場合は、Qualys SSL Labを訪れ、サーバーに対してテストを実行してください。すべてが適切に構成されている場合、セキュリティに関してA+の評価を受けるはずです。

Nginxがサーバーブロックルールを解析および実装する方法について詳しく知りたい場合は、Nginxサーバーおよびロケーションブロック選択アルゴリズムの理解を読んでみてください。

Source:
https://www.digitalocean.com/community/tutorials/how-to-set-up-nginx-with-http-2-support-on-ubuntu-22-04