著者は、 Diversity in Tech Fund を選択して、 Write forDOnationsプログラムの一環として寄付を受け取りました。

序章

レートリミッターは、悪意のあるブルートフォース攻撃が通常Webログインの背後に配置される機密リソースにアクセスするのを防ぐのに役立つため、実稼働環境には不可欠です。 また、分散型サービス拒否(DDoS)攻撃を阻止する上でも積極的な役割を果たします。 NginxのようなWebサーバーは、レート制限を実装するためのネイティブツールを提供し、要求を処理するために使用するリソースが少なくなります。

このチュートリアルでは、Node.jsの簡易ログインが受信するトラフィックの量を制限するようにNginxを設定します。 一定期間のリクエストの最大数を定義し、レートリミッターをテストし、ユーザーに表示される429エラーページをカスタマイズするようにNginxを構成します。

前提条件

このチュートリアルを完了するには、次のものが必要です。

  • sudo権限とファイアウォールを持つ非rootユーザーで構成された1つのCPUと1GBのRAMを備えたNode.jsを実行しているUbuntu20.04サーバー。 Nginxレートリミッターは、RAMよりも多くのCPUを使用できるというメリットがあることに注意してください。 root以外のユーザーをセットアップしてファイアウォールを構成するには、ガイド「 Ubuntu20.04を使用したサーバーの初期セットアップ」を参照してください。

  • サーバー上にアプリケーションマネージャーPM2がセットアップされたNode.jsアプリ。これは、チュートリアル Ubuntu20.04で本番用にNode.jsアプリケーションをセットアップする方法に従って実行できます。

  • SSL証明書が設定されたNginxがインストールされています。これは、チュートリアル Ubuntu20.04にNginxをインストールする方法とUbuntu20.04でLet’sEncryptを使用してNginxを保護する方法に従って実行できます。

  • 登録済みドメイン。 Freenom から無料で入手するか、所有している既存のドメイン名を使用できます。

  • DNS Aレコードで、アプリケーションとドメイン名がNginxレート制限アプリケーションのIPv4アドレスを指している。 ガイド共通ドメインレジストラからDigitalOceanネームサーバーをポイントする方法に従って、これを設定します。 このチュートリアルでは、login.your_domain.comを使用します。

  • ログインとエラーのWebページを作成するには、HTMLとCSSにある程度精通していると役立ちます。 HTMLとCSSの詳細については、HTMLを使用してWebサイトを構築する方法およびCSSを使用してWebサイトを構築する方法を参照してください。

ステップ1—Node.jsアプリを設定する

レートリミッターは通常、APIまたはアプリケーションの前にあります。 このチュートリアルでは、レートリミッターの背後にあるログインとなるNode.jsアプリケーションを使用します。

最初のステップとして、プロジェクトの依存関係をインストールし、ログインフォームを作成し(オプションのスタイルを使用)、アプリケーションが実行されていることをテストします。 まず、ソースファイルとnpmの依存関係が保存される新しいプロジェクトフォルダーを作成します。

次のコマンドを使用して、アプリケーションファイル用の新しいフォルダーを作成します。

  1. sudo mkdir /srv/rate-limited-login

前提条件のチュートリアルで作成したroot以外のユーザーsammyにフォルダーの所有権を割り当てます。

  1. sudo chown sammy /srv/rate-limited-login

sammy がフォルダを所有するようになったため、ディレクトリ内のファイルを作成および変更するために毎回sudoを使用する必要はありません。

作成した/srv/rate-limited-loginディレクトリに切り替えます。

  1. cd /srv/rate-limited-login

新しいnpmリポジトリを初期化します。

  1. npm init

npmからの情報を入力します(またはEnterキーを押してデフォルト値のままにします)。

コードの記述に進む前に、Node.jsアプリケーション内でHTTPリクエストをルーティングできるように、Expressをnpm依存関係としてインストールして保存する必要があります。

  1. npm install express --save

Expressは、npmによって管理されるnode_modulesフォルダーの下にインストールされます。 --saveフラグを使用すると、Expressがpackage.json構成ファイルに追加されます。

Expressを依存関係として設定して、この記事の後半でレート制限の背後に配置されるHTTPルートを作成します。 プロジェクトフォルダ/srv/rate-limited-loginには、Expressがログイン目的のHTTPリクエストを処理し、ログインフォーム自体を含むWebサイトにサービスを提供できるようにするソースコードが含まれます。 /srv/rate-limited-loginには次の3つのファイルが含まれます。

  • index.jsは、Expressエンドポイントに関連するコードをホストして、静的ファイルを提供し、ログインアプリケーションルートへのPOST /リクエストを処理します。
  • public/index.htmlにはHTMLログインフォームが含まれます。
  • public/login.cssには、ログインフォームのCSSスタイル(オプション)があります。

まず、index.jsファイルを作成して編集します。

  1. nano index.js

以下のコードを追加して、ポート8080のフォルダーpublicからHTTPルートPOST / および静的ファイルを提供するアプリケーションを作成します。

/srv/rate-limited-login/index.js
const express = require('express');
const path = require('path');
const app = express();
const listeningPort = 8080;

app.use('/', express.static(path.join(__dirname, 'public')));

app.post('/', (request, response) => {
    response.send("Logging in...");
});

app.listen(listeningPort, () => {
    console.log(`Rate Limited Login listening on port ${listeningPort}!`);
});

Expressは、Node.jsを使用してindex.jsが実行されるたびにHTTPリクエストを処理します。 /srv/rate-limited-login/publicの下に保存されているすべてのファイルは、Webサーバーを介して到達可能であり、http://localhost:8080へのHTTPPOSTリクエストは、Logining…というフレーズのWebサイトを返します。

次に、ログインフォームのHTMLとCSSをホストするパブリックフォルダーを作成します。

  1. mkdir /srv/rate-limited-login/public

新しいフォルダに移動します。

  1. cd /srv/rate-limited-login/public

index.htmlという名前のファイルを作成します。

  1. nano index.html

ログイン用のファイルにHTMLフォームを追加します。

/srv/rate-limited-login/public/index.html
<html>

    <head>
        <title>Login</title>
        <link href="https://fonts.googleapis.com/css2?family=Quicksand:[email protected]&display=swap" rel="stylesheet">
        <link rel="stylesheet" href="login.css">
    </head>

    <body>
        <div id="login-container">
            <h1>Rate Limited Login</h1>
            <form id="login-form" method="POST">
                <label for="user">Username</label>
                <input type="text" name="user" id="user">
                <label for="password">Password</label>
                <input type="password" name="password" id="password">
                <button type="submit">Login</button>
            </form>
        </div>
    </body>

</html>

ログインフォームを作成したので、ユーザーがログインフォームに入力して送信ボタンを押すたびに、index.jsファイル内で以前に構成したPOST /ルートに対してリクエストが送信されます。

スタイリングを追加したい場合は、login.cssファイルを作成できます。

  1. nano login.css

次のコードを使用して、背景としてグラデーションを追加し、デフォルトのフォントを変更し、テキストを中央に配置して、本文がブラウザの高さの100% ofを取るようにすることができます。

/srv/rate-limited-login/public/login.css
body {
    background: linear-gradient(132deg, rgba(184,231,209,1) 35%, rgba(0,255,190,1) 100%);
    font-family: 'Quicksand', sans-serif;
    overflow: hidden;
    height:100%;
    text-align: center;
}

メインヘッダーテキストのサイズを大きくすることができます。

/srv/rate-limited-login/public/login.css
...
h1 {
    font-size: 1.5em;
}
...

幅、パディング、マージンを追加しながら、ログインフォームコンテナの背景としてグラデーションを追加できます。

/srv/rate-limited-login/public/login.css
...
#login-container {
    background: linear-gradient(132deg, rgba(225,255,249,1) 35%, rgba(182,230,231,1) 100%);
    margin: 2em auto;
    padding: 1em;
    width: 25em;
}
...

フォームの左側にラベルを配置するには、本文中心のテキストを上書きします。

/srv/rate-limited-login/public/login.css
...
#login-form label {
    display: block;
    font-size: 1.1em;
    margin-left: 1.2em;
    text-align: left;
}
...

最後に、フォームフィールドの境界線、線の高さ、幅、間隔を定義できます。

/srv/rate-limited-login/public/login.css
...
#login-form input, button{
    border: 0.05em solid rgb(184,231,209);
    font-size: 1em;
    line-height: 1.7em;
    margin: 1em 1em 1.5em 1em;
    padding: 0.2em;
    width: 90%;
}
...

これで、ログインアプリケーションを実行するために必要なすべてのファイルができました。

次のコマンドを使用してアプリケーションを起動します。

  1. node /srv/rate-limited-login/index.js

出力は次のようになります。

Output
Rate Limited Login listening on port 8080!

アプリケーションを停止するには、LinuxおよびWindowsユーザーの場合はCTRL+Cを、Mac環境の場合はCMD+Cを押します。

これで、アプリケーションはポート8080で実行されます。 POST / HTTPリクエストをリッスンし、/publicフォルダーの下のファイルを/に提供します。 POST /エンドポイントは文字列Logging in...を返し、GET /は次に作成するログインHTMLフォームを提供します。

これで、アプリケーションが実行されました。 ただし、サーバーへの現在のセッションを閉じると、実行は停止します。 サーバーからログアウトした後もNode.jsインスタンスを実行し続けるには、Node.jsアプリケーションのプロセスマネージャーであるPM2を使用します。

このチュートリアルの前提条件では、PM2を実行するNode.jsアプリケーションを作成しました。 次に、PM2を使用してログインアプリケーションを管理し、サーバーからログアウトした後でも実行できるようにします。

PM2を使用してアプリケーションを起動します。

  1. pm2 start /srv/rate-limited-login/index.js --name rate-limited-login

--nameフラグを使用すると、PM2プロセスにラベル(この場合は rate-limited-login )を付けることができます。

起動後に実行される保存済みPM2アプリケーションの既存のリストに新しいアプリケーションを追加します。

  1. pm2 save

アプリケーションが実行されていることをテストするには、アプリケーションにPOSTリクエストを送信します。

  1. curl -X POST http://localhost:8080/

すべてが正しく構成されている場合、出力は次のようになります。

Output
Logging in...

注:実際のログインには、このチュートリアルでは考慮されていない追加のセキュリティがあることに注意してください。 OWASP認証チートシートに従って、認証セキュリティガイドラインの詳細を確認できます。 Passport などのサードパーティライブラリも認証目的で使用でき、悪意のある攻撃を防ぐのに役立つセキュリティメカニズムがすでに組み込まれています。

アプリケーションを設定したので、レートリミッターを設定する準備が整いました。

ステップ2—レートリミッターを設定する

この時点で、Nginxはトラフィックをログインアプリケーションにリダイレクトします。 このステップでは、limit_req_zonelimit_req、およびlimit_req_statusの3つのNginxディレクティブを使用してレート制限を実装します。

最初のlimit_req_zoneは、リクエストを制限する基準、以前のリクエストのデータを追跡するためにNginxに与えるメモリの量、および一定期間のレート制限を指定します。

レートリミッターは、このチュートリアルの前提条件セクションで以前に作成したものと同じ構成ブロックに設定されます。 login.your_domain.comのブロック構成ファイルを開きます。

  1. sudo nano /etc/nginx/sites-available/login.your_domain.com

新しいlimit_req_zoneNginxディレクティブを追加します。

/etc/nginx/sites-available/login.your_domain.com
...
limit_req_zone $binary_remote_addr zone=login_limit:10m rate=5r/s
server {
...

前の行は、Nginxのリクエストが1秒あたり5リクエストの割合でIPアドレスに基づいている必要があり、以前のIPの記録を維持するために10メガバイトを割り当てる必要があることを示しています。

(クライアントのIPアドレスをキーとして使用するのではなく)他の基準に基づいてリクエストを制限するには、$geoip_country_codeを使用して国ごとのリクエストを許可できます。 他のNginx変数に基づいてトラフィックを並べ替えることもできます。

次に使用するディレクティブはlimit_reqです。これは、レート制限を適用する範囲と、burstsdelaysなどの追加設定があるかどうかを示します。アプリケーションにとって有益です。 (後のステップで、これらの追加パラメーターについて詳しく学習します。)

もう一度、login.your_domain.comのブロック構成ファイルを開きます。

  1. sudo nano /etc/nginx/sites-available/login.your_domain.com

limit_req Nginxディレクティブを採用して、レート制限を実行するコンテキストを定義します。

/etc/nginx/sites-available/login.your_domain.com
...
server {
    ...
    location / {
    limit_req zone=login_limit;
    ....
}
...

アプリケーションのニーズに応じて、limit_reqディレクティブは、Nginx構成ブロックファイルのserverまたはlocationコンテキスト内に存在できます。

追加する最後のディレクティブはlimit_req_statusです。 デフォルトでは、ユーザーがレートリミッターのしきい値をトリガーすると、Nginxは503 Service UnavailableHTTPコードを提供します。 実際、Nginxが許可するように設定されているよりも多くのリクエストを行っているのはクライアントである場合、サーバーが期待どおりに機能していないという印象を与える可能性があるため、メッセージは誤解を招く可能性があります。 より透過的な代替手段は、ディレクティブlimit_req_statusを使用してレート制限をトリガーし、429 Too Many RequestsHTTPコードを返すことです。

login.your_domain.comのブロック構成ファイルを開きます。

  1. sudo nano /etc/nginx/sites-available/login.your_domain.com

Nginxディレクティブを追加して、デフォルトのHTTP応答コードを変更します。limit_req_status

/etc/nginx/sites-available/login.your_domain.com
...
limit_req_status 429
server {
...

limit_req_zonelimit_reqlimit_req_status Nginxディレクティブをlogin.your_domain.comのブロック構成ファイルに追加すると、次のような内容になります。

/etc/nginx/sites-available/login.your_domain.com
limit_req_zone $binary_remote_addr zone=login_limit:10m rate=5r/s;
limit_req_status 429;

server {
        root /var/www/login.your_domain.com/html;
        index index.html index.htm index.nginx-debian.html;
        server_name login.your_domain.com;

        location / {
          limit_req zone=login_limit;
          proxy_pass http://localhost:8080;
          proxy_http_version 1.1;
          proxy_set_header Upgrade $http_upgrade;
          proxy_set_header Connection 'upgrade';
          proxy_set_header Host $host;
          proxy_cache_bypass $http_upgrade;
        }

    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/login.your_domain.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/login.your_domain.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}

server {
    if ($host = login.your_domain.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    listen 80;
    listen [::]:80;
    server_name login.your_domain.com;
    return 404; # managed by Certbot

}

最後に、現在のNginx構成をリロードします。

sudo service nginx reload

login.your_domain.comにアクセスし、 429エラーページが表示されるまで何度も更新することで、レート制限が設定されていることをテストできます。 ただし、この方法は、1秒間に数個ではなく数十個の要求をトリガーしようとしている場合、拡張できない場合があります。 次のステップでは、負荷テストツールを使用して、レートリミッターが開始するタイミングを効果的にテストします。

ステップ3—Apacheベンチマークを使用してレート制限が機能することを確認する

ブラウザはタブごとにページをロードすることしかできません。これは、同時接続をテストし、レート制限がいつトリガーされるかを確認するのに理想的ではありません。 代わりに、k6ApacheBenchmarkなどの負荷テストツールを使用できます。 このステップでは、Apache Benchmarkを使用します。これは、CLIが単一ページにアクセスするためのスクリプトコードを必要としないためです。

次のコマンドを使用してApacheBenchmarkをインストールします。

  1. sudo apt install apache2-utils -y

テストを実行するには、100の同時接続と合計100のログイン要求を起動します。

  1. ab -c 100 -n 100 https://login.your_domain.com/

Apache Benchmarkがテストを終了すると、多くのデータポイントが表示されます。 レートリミッターが期待どおりに機能しているかどうかを評価するには、次の行に注目してください。

Output
... Time taken for tests: 0.180 seconds ... Non-2xx responses: 99 ...

1秒あたり5リクエストのレート制限を設定すると、最大で200ミリ秒ごとのリクエストが許可されます。

これらのリクエストが実際に429ステータスのエラーであるかどうかを確認するには、別の端末で負荷テストを実行しているときにNginxのエラーログを表示します。

新しいターミナルを開き、次のコマンドを実行します。

  1. sudo tail -f /var/log/nginx/error.log

出力は次のようになります。

Output
[error] 17133#17133: *6346 limiting requests, excess: 0.540 by zone "login_limit", client: 203.0.113.0, server: login.your_domain.com, request: "GET / HTTP/1.0", host: "login.your_domain.com"

上記の出力エントリの一部を強調表示しているexcessは、リクエストが具体化するレート制限しきい値を超えた後の1ミリ秒あたりのリクエスト数を表します。

login_limitは、Nginxブロック構成ファイル内で指定したレート制限グループを表します。 設定が異なる2つ以上のレートリミッターがある場合は、それらを区別するために異なるゾーンを設定します。

clientは訪問者のIPアドレスを示し、hostrequestはそれぞれ、アクセスされたドメインと行われた要求の種類を表します。

次の手順では、このターミナルウィンドウを開いたままにして、レートリミッタの動作の変更が設定の変更にどのように影響するかを確認できます。

これで、レート制限が期待どおりに機能していることを確認できます。 次のステップでは、追加の構成を使用してNginxを微調整し、より現実的なワークロードを実現します。

ステップ4—バーストと遅延の設定

前述のように、1秒あたり5リクエストのレート制限があるということは、200ミリ秒ごとのリクエストが許可されることを意味します。 これは、画像、HTML、CSS、JSファイルなどのアセットを使用してリクエストを頻繁に行うWebサイトのようなアプリケーションには不十分な場合があります。

Nginxが提供するソリューションの1つは、エラーを返す前に多数の追加リクエストを受け取るburstキューを用意することです。 ただし、このキューに依存して短期間に複数の要求を許可すると、要求が同時にではなく処理されるようにキューに入れられるため、パフォーマンスの問題が発生する可能性があります。 この問題を解決するには、nodelayディレクティブを構成して、Nginxが処理される各リクエストの間に次のリクエストを開始するまで待機する必要がないようにすることができます。

delayburstと組み合わせて使用するハイブリッドアプローチもあります。 これにより、リクエストがNginxによってドロップされないようにバーストキューを作成できますが、キューに入れられたアイテムのごく一部のみを同時に処理できます。

このステップでは、レートリミッターを構成する際に、これらのアプローチを組み合わせてさまざまな動作を実現する方法を確認するために、これらすべてのアプローチを検討します。 Nginxバーストキューを設定し、より高度な構成を使用して、制限された数のリクエストが時間ペナルティなしでレートリミッターを通過できるようにします。 これにより、ユーザーはWebサイトにアクセスする全体的なエクスペリエンスを向上させることができます。

バーストキューを設定することから始めます。 burstlimit_reqディレクティブに追加すると、後で処理するためにキューに入れる要求の数を定義できます。 このようにして、429エラーを返す代わりに、最大10個の追加のアセットリクエストを受け入れるようにNginxに指示できます。 デフォルトでは、画像、JSファイル、およびCSSファイルは、レートリミッターが指示するのと同じ速度で提供されます(この場合、リクエストごとに200ミリ秒)。

まず、サイトの構成ファイルを開きます。

  1. sudo nano /etc/nginx/sites-available/login.your_domain.com

最大10個のリクエストをキューに入れるようにNginxを構成します。

/etc/nginx/sites-available/login.your_domain.com
...
limit_req zone=login_limit burst=10;
...

Nginx構成を更新します。

  1. sudo service nginx reload

abを再度実行して、レートリミッターの変更をテストします。

  1. ab -c 100 -n 100 https://login.your_domain.com/

次の出力が表示されます。

Output
... Time taken for tests: 2.004 seconds ... Non-2xx responses: 89 ...

1秒あたり5リクエスト(または1分あたり300リクエストに相当)のレート制限では、10の同時Webアセットリクエストは2秒(200ミリ秒ごとに1つ)かかり、ユーザーエクスペリエンスを損ないます。

ただし、limit_req内でnodelayを使用すると、Nginxは、各リクエスト間で200ミリ秒待機することなく、バーストキュー内のリクエストを処理できます。

この構成を設定するには、Nginxブロック構成ファイルを開きます。

  1. sudo nano /etc/nginx/sites-available/login.your_domain.com

nodelayを有効にすると、リクエスト間で待機することなく、バーストキュー内のリクエストを処理できます。

/etc/nginx/sites-available/login.your_domain.com
...
limit_req zone=login_limit burst=10 nodelay;
...

次のコマンドでNginxをリロードします。

  1. sudo service nginx reload

最後に、バーストキュー内のキューに入れられたリクエストが遅延していないことを確認します。

  1. ab -c 100 -n 100 https://login.your_domain.com/

出力は次のようになります。

Output
... Time taken for tests: 0.233 seconds ... Non-2xx responses: 89 ...

同じ数の10個のリクエストは、順番が処理されるのを待ってロックされることはなく、以前はユーザーが待たなければならなかった2秒は、ネットワークとサーバーの処理がそれらを配信するのにかかる時間だけに短縮されます。

Nginxがバーストキューのスロットをクリアする前に同じユーザーが11番目のアセットを取得しようとした場合、リクエストは拒否されます。

nodelayを使用すると、同時リクエストが可能な限り高速に処理されるため、ユーザーエクスペリエンスが向上します。 一方、nodelayを使用しないと、リクエスト間に待機間隔が適用されるため、アプリケーションへのリクエストのフローがより制御されます。

Nginx 1.15.7以降、delayではこれら2つのアプローチを組み合わせることができます。 バーストキュー全体から遅延をバイパスできるリクエストの数を定義できます。

このアプローチを使用するには、Nginxブロック構成ファイルを開くことから始めます。

  1. sudo nano /etc/nginx/sites-available/login.your_domain.com

nodelaydelayに置き換えて、最大4つのリクエストを遅延なく処理できるようにします。

/etc/nginx/sites-available/login.your_domain.com
...
limit_req zone=login_limit burst=10 delay=4;
...

現在のNginx構成を更新します。

  1. sudo service nginx reload

最後に、delayが期待どおりに機能していることを確認します。

  1. ab -c 100 -n 100 https://login.your_domain.com/

出力は次のようになります。

Output
... Time taken for tests: 1.205 seconds ... Non-2xx responses: 89 ...

nodelayを使用している場合と同様に、最大4つのリクエストでリクエスト間のレート制限の遅延を回避できます。

バーストキュー内の残りの6つの要求は、レートリミッターが指定する待機時間(この例では、これらの6つの要求の間の200ms)で受け入れられます。

過度の使用を抑制し、Nginxで大量のトラフィックを処理することを拒否しながら、最初のリクエストをすばやく配信できるようになりました。 ユーザーエクスペリエンスをさらに向上させるために、Webサイトのデザインにより適合した429エラーページを提供できます。

ステップ5— 429エラーページのカスタマイズ(オプション)

訪問者がアプリケーションに対して許可されているリクエストの数を超えるたびに、Nginxが提供するHTMLページを含む429エラー応答が発生します。 アプリケーションのユーザーエクスペリエンスを向上させるために、429エラーページを通常のページの形式と一致させることができます。 このステップでは、Nginxによって提供されるパーソナライズされたエラーページを作成します。

429エラー用のフォルダーを作成します。

  1. sudo mkdir -p /usr/share/nginx/errors/429

新しい429.htmlファイルを作成します。

  1. sudo nano /usr/share/nginx/errors/429/429.html

429エラーが発生したときに返すコンテンツを定義します。

/usr/share/nginx/errors/429/429.html
<html>

<head>
    <title>Error 429</title>
    <link href="https://fonts.googleapis.com/css2?family=Bangers&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="/errors/429/429.css">
    <script></script>
</head>

<body>
    <div id="login-container">
        <h1>Error 429 - Too many requests</h1>
        <p>You have been rate limited.</p>
    </div>
</body>

</html>

429エラーページにCSSスタイルを追加します。

  1. sudo nano /usr/share/nginx/errors/429/429.css

スタイリングを追加して、グラデーションを背景として定義し、デフォルトのフォントを変更し、テキストを中央に配置して、本文が100% ofのブラウザーの高さになるようにすることができます。

/usr/share/nginx/errors/429/429.css
body {
    background: linear-gradient(132deg, rgba(184,231,209,1) 35%, rgba(0,255,190,1) 100%);
    font-family: Arial, Helvetica, sans-serif;
    height: 100%;
    overflow: hidden;
    text-align: center;
}

サイズを大きくして、ヘッダーのフォントを変更することもできます。

/usr/share/nginx/errors/429/429.css
...
h1 {
    font-size: 2em;
    font-family: 'Bangers', cursive;
}
...

429エラーでファイルを提供する準備ができたので、Nginxブロック構成を構成します。

  1. sudo nano /etc/nginx/sites-available/login.your_domain.com

Nginxディレクティブerror_pageを追加して、以前に作成したHTMLファイルパスを記述し、/usr/share/nginx/errors/errorsで一般公開します。 最終的なNginx構成ブロックは次のようになります。

/etc/nginx/sites-available/login.your_domain.com
...
server {
        ...
        error_page 429 /errors/429/429.html;
        ...
}
...

Nginxをリロードして、新しい変更を反映します。

  1. sudo service nginx reload

終了するには、login.your_domain.comにアクセスし、レートリミッターをトリガーして新しい429エラーページが表示されるまで更新します。 テストするには、burstdelayを一時的に削除し、許可されるリクエストの数を減らして429エラーをより簡単にトリガーすることを検討してください。

結論

この記事全体を通して、ログインへの着信リクエストをレート制限して、インターネットからのトラフィックが多すぎるのを防ぐようにNginxを構成および調整しました。 このチュートリアルで学んだことを適用して、Webアプリケーションのセキュリティを強化できます。

次のステップとして、Nginx製品のドキュメントプロキシされたHTTPリソースへのアクセスの制限を確認して、IPごとの帯域幅または接続数を制限する方法を学ぶことを検討してください。 高度な構成例にアクセスして、ジオローカリゼーションに基づいて許可リストを作成することもできます。 最新のNginx開発については、Nginxのブログを読むことを検討してください。

セキュリティの詳細については、DigitalOceanのセキュリティチュートリアル、MeganSnyderのSecuring Your Deploy に関する講演、MasonEggerのFoundations of ComputerSecurityに関するプレゼンテーションをご覧ください。