Ubuntu16.04でCloudflareとNginxを使用してWebサイトをホストする方法
著者は、 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解決の恩恵を受けることです。 これにより、悪意のあるリクエストがサーバーに到達するのを防ぎます。
前提条件
このチュートリアルを完了するには、次のものが必要です。
- Ubuntu16.04初期サーバーセットアップガイドに従ってセットアップされた1つのUbuntu16.04サーバー。これには、sudo非rootユーザーとファイアウォールが含まれます。
- Ubuntu 16.04にNginxをインストールする方法に示すように、サーバーにNginxがインストールされています。
- 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
を開いて編集します。
sudo nano /etc/ssl/certs/cert.pem
証明書の内容をファイルに貼り付けます。 次に、エディターを保存して終了します。
次に、ブラウザに戻り、秘密鍵の内容をコピーします。 編集のためにファイル/etc/ssl/private/key.pem
を開きます。
sudo nano /etc/ssl/private/key.pem
キーをファイルに貼り付け、ファイルを保存して、エディターを終了します。
警告: CloudflareのオリジンCA証明書はCloudflareによってのみ信頼されるため、Cloudflareにアクティブに接続されているオリジンサーバーのみが使用する必要があります。 Cloudflareを一時停止または無効にすると、OriginCA証明書は信頼できない証明書エラーをスローします。
キーファイルと証明書ファイルをサーバーにコピーしたので、それらを使用するにはNginx構成を更新する必要があります。
ステップ2—NginxにOriginCA証明書をインストールする
前のセクションでは、Cloudlfareのダッシュボードを使用して原産地証明書と秘密鍵を生成し、ファイルをサーバーに保存しました。 次に、サイトのNginx構成を更新して、原産地証明書と秘密鍵を使用してCloudflareのサーバーとサーバー間の接続を保護します。
Nginxは、インストール中にデフォルトのサーバーブロックを作成します。 ドメインのカスタムサーバーブロックを既に構成しているため、存在する場合は削除します。
sudo rm /etc/nginx/sites-enabled/default
次に、ドメインのNginx構成ファイルを開きます。
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構成ファイルのいずれにも構文エラーがないことを確認します。
sudo nginx -t
問題が見つからなかった場合は、Nginxを再起動して変更を有効にします。
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
ファイルを作成します。
sudo nano /etc/ssl/certs/cloudflare.crt
証明書をファイルに貼り付けます。 次に、ファイルを保存してエディターを終了します。
次に、TLS AuthenticatedOriginPullを使用するようにNginx構成を更新します。 ドメインの構成ファイルを開きます。
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構成に構文エラーがないことを確認します。
sudo nginx -t
問題が見つからなかった場合は、Nginxを再起動して変更を有効にします。
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サーバーに直接接続できないようにします。