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

序章

Cloudflare は、訪問者とWebサイト所有者のサーバーの間に位置し、Webサイトのリバースプロキシとして機能するサービスです。 Cloudflareは、コンテンツ配信ネットワーク(CDN)に加えて、DDoS軽減および分散ドメインネームサーバーサービスを提供します。

Nginx は、インターネット上で最大かつ最もトラフィックの多いサイトのいくつかをホストする人気のあるWebサーバーです。 組織がNginxでWebサイトにサービスを提供し、CloudflareをCDNおよびDNSプロバイダーとして使用することは一般的です。

このチュートリアルでは、CloudflareからのOrigin CA証明書を使用してNginxが提供するWebサイトを保護し、認証されたプルリクエストを使用するようにNginxを構成します。 このセットアップを使用する利点は、すべての接続がCloudflareを通過することを保証しながら、CloudflareのCDNと高速DNS解決の恩恵を受けることです。 これにより、悪意のあるリクエストがサーバーに到達するのを防ぎます。

前提条件

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

  • Cloudflareアカウント。
  • Nginxサーバーを指すCloudflareアカウントに追加された登録済みドメイン。 これを設定するには、CloudFlareを使用してWebサイトに対するDDoS攻撃を軽減する方法に従ってください。
  • ドメイン用に構成されたNginxサーバーブロック。これは、 Ubuntu 16.04 でNginxサーバーブロック(仮想ホスト)を設定する方法に従って実行できます。

ステップ1—オリジンCATLS証明書の生成

Cloudflare Origin CAを使用すると、Cloudflareによって署名された無料のTLS証明書を生成して、Nginxサーバーにインストールできます。 Cloudflareで生成されたTLS証明書を使用することで、CloudflareのサーバーとNginxサーバー間の接続を保護できます。

Origin CAで証明書を生成するには、CloudflareダッシュボードのCryptoセクションに移動します。 そこから、 OriginCertificatesセクションのCreateCertificateボタンをクリックします。

のデフォルトオプションをそのままにして、CloudFlareに秘密鍵を生成させ、CSRを選択します。

次へをクリックすると、原産地証明書秘密鍵のダイアログが表示されます。 原産地証明書と秘密鍵の両方をCloudFlareからサーバーに転送する必要があります。

サーバー上の/etc/ssl/certsディレクトリを使用して、オリジン証明書を保持します。 /etc/ssl/privateディレクトリは秘密鍵ファイルを保持します。 両方のフォルダはすでにサーバー上に存在します。

まず、ブラウザのダイアログボックスに表示される原産地証明書の内容をコピーします。

次に、サーバーで/etc/ssl/certs/cert.pemを開いて編集します。

  1. sudo nano /etc/ssl/certs/cert.pem

証明書の内容をファイルに貼り付けます。 次に、エディターを保存して終了します。

次に、ブラウザに戻り、秘密鍵の内容をコピーします。 編集のためにファイル/etc/ssl/private/key.pemを開きます。

  1. sudo nano /etc/ssl/private/key.pem

キーをファイルに貼り付け、ファイルを保存して、エディターを終了します。

警告: CloudflareのオリジンCA証明書はCloudflareによってのみ信頼されるため、Cloudflareにアクティブに接続されているオリジンサーバーのみが使用する必要があります。 Cloudflareを一時停止または無効にすると、OriginCA証明書は信頼できない証明書エラーをスローします。

キーファイルと証明書ファイルをサーバーにコピーしたので、それらを使用するにはNginx構成を更新する必要があります。

ステップ2—NginxにOriginCA証明書をインストールする

前のセクションでは、Cloudlfareのダッシュボードを使用して原産地証明書と秘密鍵を生成し、ファイルをサーバーに保存しました。 次に、サイトのNginx構成を更新して、原産地証明書と秘密鍵を使用してCloudflareのサーバーとサーバー間の接続を保護します。

Nginxは、インストール中にデフォルトのサーバーブロックを作成します。 ドメインのカスタムサーバーブロックを既に構成しているため、存在する場合は削除します。

  1. sudo rm /etc/nginx/sites-enabled/default

次に、ドメインのNginx構成ファイルを開きます。

  1. sudo nano /etc/nginx/sites-available/example.com

ファイルは次のようになります。

/etc/nginx/sites-available/<^>example.com <^>
server {
        listen 80;
        listen [::]:80;

        root /var/www/example.com/html;
        index index.html index.htm index.nginx-debian.html;

        server_name example.com www.example.com;

        location / {
                try_files $uri $uri/ =404;
        }
}

Nginx構成ファイルを変更して次のようにします。

  • ポート80でリッスンし、すべてのリクエストをhttpsを使用するようにリダイレクトします。
  • ポート443でリッスンし、前のセクションで追加したオリジン証明書と秘密鍵を使用します。

次のようにファイルを変更します。

/etc/nginx/sites-available/<^>example.com <^>
server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;
    return 302 https://$server_name$request_uri;
}

server {

    # SSL configuration

    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    ssl        on;
    ssl_certificate         /etc/ssl/certs/cert.pem;
    ssl_certificate_key     /etc/ssl/private/key.pem;

    server_name example.com www.example.com;

    root /var/www/example.com/html;
    index index.html index.htm index.nginx-debian.html;


    location / {
            try_files $uri $uri/ =404;
    }
}

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

次に、テストして、Nginx構成ファイルのいずれにも構文エラーがないことを確認します。

  1. sudo nginx -t

問題が見つからなかった場合は、Nginxを再起動して変更を有効にします。

  1. sudo systemctl restart nginx

次に、Cloudflareダッシュボードの Crypto セクションに移動し、SSLモードをFullに変更します。 これは、CloudflareとオリジンNginxサーバー間の接続を常に暗号化するようにCloudflareに通知します。

次に、https://example.comのWebサイトにアクセスして、正しく設定されていることを確認します。 ホームページが表示され、ブラウザはサイトが安全であると報告します。

次のセクションでは、Authenticated Origin Pullsを設定して、オリジンサーバーが実際にCloudflareと通信しており、他のサーバーと通信していないことを確認します。 そうすることで、NginxはCloudflareからの有効なクライアント証明書を使用するリクエストのみを受け入れるように構成され、CloudFlareを通過していないリクエストはドロップされます。

ステップ3—認証されたオリジンプルを設定する

オリジンCA証明書は、Cloudflareが正しいオリジンサーバーと通信していることを確認するのに役立ちます。 しかし、オリジンNginxサーバーは、実際にCloudflareと通信していることをどのように確認できますか? TLSクライアント認証を入力します。

クライアント認証済みTLSハンドシェイクでは、両側が検証対象の証明書を提供します。 オリジンサーバーは、Cloudflareからの有効なクライアント証明書を使用するリクエストのみを受け入れるように構成されています。 Cloudflareを通過していないリクエストは、Cloudflareの証明書がないため、ドロップされます。 これは、攻撃者がCloudflareのセキュリティ対策を回避して、Nginxサーバーに直接接続できないことを意味します。

Cloudflareは、CAによって署名された証明書と次の証明書を提示します。

-----BEGIN CERTIFICATE-----
MIIGBjCCA/CgAwIBAgIIV5G6lVbCLmEwCwYJKoZIhvcNAQENMIGQMQswCQYDVQQG
EwJVUzEZMBcGA1UEChMQQ2xvdWRGbGFyZSwgSW5jLjEUMBIGA1UECxMLT3JpZ2lu
IFB1bGwxFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xEzARBgNVBAgTCkNhbGlmb3Ju
aWExIzAhBgNVBAMTGm9yaWdpbi1wdWxsLmNsb3VkZmxhcmUubmV0MB4XDTE1MDEx
MzAyNDc1M1oXDTIwMDExMjAyNTI1M1owgZAxCzAJBgNVBAYTAlVTMRkwFwYDVQQK
ExBDbG91ZEZsYXJlLCBJbmMuMRQwEgYDVQQLEwtPcmlnaW4gUHVsbDEWMBQGA1UE
BxMNU2FuIEZyYW5jaXNjbzETMBEGA1UECBMKQ2FsaWZvcm5pYTEjMCEGA1UEAxMa
b3JpZ2luLXB1bGwuY2xvdWRmbGFyZS5uZXQwggIiMA0GCSqGSIb3DQEBAQUAA4IC
DwAwggIKAoICAQDdsts6I2H5dGyn4adACQRXlfo0KmwsN7B5rxD8C5qgy6spyONr
WV0ecvdeGQfWa8Gy/yuTuOnsXfy7oyZ1dm93c3Mea7YkM7KNMc5Y6m520E9tHooc
f1qxeDpGSsnWc7HWibFgD7qZQx+T+yfNqt63vPI0HYBOYao6hWd3JQhu5caAcIS2
ms5tzSSZVH83ZPe6Lkb5xRgLl3eXEFcfI2DjnlOtLFqpjHuEB3Tr6agfdWyaGEEi
lRY1IB3k6TfLTaSiX2/SyJ96bp92wvTSjR7USjDV9ypf7AD6u6vwJZ3bwNisNw5L
ptph0FBnc1R6nDoHmvQRoyytoe0rl/d801i9Nru/fXa+l5K2nf1koR3IX440Z2i9
+Z4iVA69NmCbT4MVjm7K3zlOtwfI7i1KYVv+ATo4ycgBuZfY9f/2lBhIv7BHuZal
b9D+/EK8aMUfjDF4icEGm+RQfExv2nOpkR4BfQppF/dLmkYfjgtO1403X0ihkT6T
PYQdmYS6Jf53/KpqC3aA+R7zg2birtvprinlR14MNvwOsDOzsK4p8WYsgZOR4Qr2
gAx+z2aVOs/87+TVOR0r14irQsxbg7uP2X4t+EXx13glHxwG+CnzUVycDLMVGvuG
aUgF9hukZxlOZnrl6VOf1fg0Caf3uvV8smOkVw6DMsGhBZSJVwao0UQNqQIDAQAB
o2YwZDAOBgNVHQ8BAf8EBAMCAAYwEgYDVR0TAQH/BAgwBgEB/wIBAjAdBgNVHQ4E
FgQUQ1lLK2mLgOERM2pXzVc42p59xeswHwYDVR0jBBgwFoAUQ1lLK2mLgOERM2pX
zVc42p59xeswCwYJKoZIhvcNAQENA4ICAQDKDQM1qPRVP/4Gltz0D6OU6xezFBKr
LWtDoA1qW2F7pkiYawCP9MrDPDJsHy7dx+xw3bBZxOsK5PA/T7p1dqpEl6i8F692
g//EuYOifLYw3ySPe3LRNhvPl/1f6Sn862VhPvLa8aQAAwR9e/CZvlY3fj+6G5ik
3it7fikmKUsVnugNOkjmwI3hZqXfJNc7AtHDFw0mEOV0dSeAPTo95N9cxBbm9PKv
qAEmTEXp2trQ/RjJ/AomJyfA1BQjsD0j++DI3a9/BbDwWmr1lJciKxiNKaa0BRLB
dKMrYQD+PkPNCgEuojT+paLKRrMyFUzHSG1doYm46NE9/WARTh3sFUp1B7HZSBqA
kHleoB/vQ/mDuW9C3/8Jk2uRUdZxR+LoNZItuOjU8oTy6zpN1+GgSj7bHjiy9rfA
F+ehdrz+IOh80WIiqs763PGoaYUyzxLvVowLWNoxVVoc9G+PqFKqD988XlipHVB6
Bz+1CD4D/bWrs3cC9+kk/jFmrrAymZlkFX8tDb5aXASSLJjUjcptci9SKqtI2h0J
wUGkD7+bQAr+7vr8/R+CBmNMe7csE8NeEX6lVMF7Dh0a1YKQa6hUN18bBuYgTMuT
QzMmZpRpIBB321ZBlcnlxiTJvWxvbCPHKHj20VwwAz7LONF59s84ZsOqfoBv8gKM
s0s5dsq5zpLeaw==
-----END CERTIFICATE-----

Cloudflareこちらから直接証明書をダウンロードすることもできます。

この証明書をコピーします。

次に、Cloudflareの証明書を保持するファイル/etc/ssl/certs/cloudflare.crtファイルを作成します。

  1. sudo nano /etc/ssl/certs/cloudflare.crt

証明書をファイルに貼り付けます。 次に、ファイルを保存してエディターを終了します。

次に、TLS AuthenticatedOriginPullを使用するようにNginx構成を更新します。 ドメインの構成ファイルを開きます。

  1. sudo nano /etc/nginx/sites-available/example.com

次の例に示すように、ssl_client_certificateおよびssl_verify_clientディレクティブを追加します。

/etc/nginx/sites-available/<^>example.com <^>
. . .

server {

    # SSL configuration

    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    ssl        on;
    ssl_certificate         /etc/ssl/certs/cert.pem;
    ssl_certificate_key     /etc/ssl/private/key.pem;
    ssl_client_certificate /etc/ssl/certs/cloudflare.crt;
    ssl_verify_client on;

    . . .

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

次に、テストして、Nginx構成に構文エラーがないことを確認します。

  1. sudo nginx -t

問題が見つからなかった場合は、Nginxを再起動して変更を有効にします。

  1. sudo systemctl restart nginx

最後に、Authenticated Pullsを有効にするには、Cloudflareダッシュボードの Crypto セクションを開き、 Authenticated OriginPullsオプションを切り替えます。

次に、Webサイトhttps://example.comにアクセスして、正しく設定されていることを確認します。 以前と同様に、ホームページが表示されます。

サーバーがCloudflareのCAによって署名されたリクエストのみを受け入れることを確認するには、 Authenticated Origin Pulls オプションを切り替えて無効にし、Webサイトをリロードします。 次のエラーメッセージが表示されます。

リクエストがCloudflareのCAによって署名されていない場合、オリジンサーバーはエラーを発生させます。

正常に動作することがわかったので、Cloudflareダッシュボードの Crypto セクションに戻り、 Authenticated OriginPullsオプションを再度切り替えて有効にします。

結論

このチュートリアルでは、CloudflareからのOrigin CA証明書を使用して、CloudflareとNginxサーバー間のトラフィックを暗号化することにより、Nginxを利用したWebサイトを保護しました。 次に、NginxサーバーでAuthenticated Origin Pullsを設定して、Cloudflareのサーバーからのリクエストのみを受け入れ、他のユーザーがNginxサーバーに直接接続できないようにします。