デプロイチェックリスト

インターネットは敵対的な環境です。Django プロジェクトをデプロイする前に、セキュリティ、パフォーマンス、運用を念頭に置いて、時間をかけて設定を見直すべきです。

Django には多くの セキュリティ機能 があります。いくつかはビルトインで、常に有効です。その他は任意となっており、これは常に適切とは限らなかったり、開発に対しては不便だったりするためです。たとえば、HTTPS を強制することは、すべてのウェブサイトに対して適切とは言えず、またローカル開発では実践的ではありません。

パフォーマンスの最適化は、利便性とのトレードオフとなるもう 1 つの要素です。たとえば、キャッシュは本番環境では役立ちますが、ローカル開発では役立ちません。同様に、エラーレポートの必要性にも大きな違いがあります。

以下のチェックリストは、次の設定項目を含みます:

  • Django が想定するレベルのセキュリティを提供するために適切に設定する必要があるもの;

  • 環境によって異なると思われるもの;

  • オプションのセキュリティ機能を有効にするもの;

  • パフォーマンスの最適化を有効にするもの;

  • エラーレポートを提供するもの;

これらの設定の多くは機密性が高く、機密情報として扱うべきです。プロジェクトのソースコードを公開する場合、開発用の適切な設定を公開し、本番用にはプライベートな設定モジュールを使用するのが一般的な慣習です。

manage.py check --deploy を実施しよう

以下で説明しているチェックのいくつかは、check --deploy オプションを使用して自動化できます。オプションのドキュメントで説明しているとおり、本番環境の設定に対してこのチェックを実施してください。

Switch away from manage.py runserver

The runserver command is not designed for a production setting. Be sure to switch to a production-ready WSGI or ASGI server. For a few common options, see WSGI servers or ASGI servers.

最重要な設定

SECRET_KEY

シークレットキーは、長いランダム文字列で、秘匿される必要があります。

本番環境で使われるキーは、他の場所で使われておらず、ソースコントロール中に記述してしまわないよう十分注意してください。これにより、攻撃者がキーを取得してしまう恐れを軽減できます。

設定モジュールにシークレットキーを直接書き込む代わりに、環境変数から読み込む方法を検討してください:

import os

SECRET_KEY = os.environ["SECRET_KEY"]

もしくはファイルから読み込みます:

with open("/etc/secret_key.txt") as f:
    SECRET_KEY = f.read().strip()

シークレットキーをローテーションする場合は、 SECRET_KEY_FALLBACKS: が使用できます:

import os

SECRET_KEY = os.environ["CURRENT_SECRET_KEY"]
SECRET_KEY_FALLBACKS = [
    os.environ["OLD_SECRET_KEY"],
]

古いシークレットキーが SECRET_KEY_FALLBACKS から適時に削除されていることを確認してください。

DEBUG

デバッグは、本番環境では決して有効化してはいけません。

プロジェクトの開発中は DEBUG = True だったはずですが、これはブラウザ内の全トレースバックといった便利な機能を使えるようにするためです。

しかし、本番環境に対してはこれはまったく不適切です。なぜなら、プロジェクトに関する多くの情報を公にしてしまうからです: ソースコードからの引用、ローカル変数、設定、使われているライブラリ、等。

環境に合わせた設定

ALLOWED_HOSTS

DEBUG = False のとき、ALLOWED_HOSTS が適切に設定されない限り Django は一切動作しません。

この設定は、いくつかの CSRF 攻撃からあなたのサイトを保護するために必要です。もしワイルドカードを使用した場合、Host HTTP のバリデーションを自分自身で行う必要があります。さもなければ、この種の攻撃に脆弱なサイトとなってしまいます。

加えて、Django の手前にいるウェブサーバーにも、ホストを検証するよう設定をする必要があります。これにより、不適切なホストに対して、Django にリクエストを転送する代わりに、エラーページを表示したりリクエストを無視するようにできます。そして、Django のログ内で誤ったエラーが起きる (もしくは設定しだいでは E メールが送信される) のを防ぎます。たとえば、nginx では認識されないホストに対してデフォルトサーバーが "444 No Response" を返します:

server {
    listen 80 default_server;
    return 444;
}

CACHES

もしキャッシュを使うなら、開発環境と本番環境とでコネクションパラメータは異なるでしょう。そうでない場合、デフォルトは ローカルメモリのキャッシュ に設定されています。

キャッシュサーバーは認証に弱点を持っています。あなたのアプリケーションからのコネクションだけを受け入れるようにしてください。

DATABASES

データベースの接続パラメータは、開発環境と本番環境でおそらく異なります。

データベースパスワードは非常に機密的なものです。SECRET_KEY と同様の方法で保護してください。

セキュリティを最大限に確保するためには、データベースサーバーがアプリケーションサーバーからの接続のみを許可するようにしてください。

もしデータベースのバックアップの設定をしていなければ、今すぐに行ってください!

STATIC_ROOTSTATIC_URL

静的ファイルは、開発用サーバーでは自動的に提供されます。本番環境では、collectstatic が静的ファイルをコピーする STATIC_ROOT ディレクトリを設定する必要があります。

より詳しくは 静的ファイル (画像、JavaScript、CSS など) を管理する を参照してください。

MEDIA_ROOTMEDIA_URL

メディアファイルは、あなたのユーザーによってアップロードされます。彼らは信用なりません! ウェブサーバーが決してこれらを解読しようとしないようにしてください。たとえば、ユーザーが .php ファイルをアップロードしたとき、ウェブサーバーはその内容を実行するべきではありません。

この機会に、こうしたファイルに対するバックアップ戦略をチェックしておきましょう。

HTTPS

ユーザーにログインさせるあらゆるウェブサイトは、アクセストークンを平文で送信するのを防ぐため、サイト全体の HTTPS を強制するべきです。Django では、アクセストークンはログインとパスワード、セッションクッキー、パスワードリセットトークンを含みます。(パスワードリセットトークンを E メール送信する場合、それほど保護されてはいません。)

ユーザーアカウントや admin などの機密性の高いエリアを保護するだけでは不十分です。なぜなら、HTTP と HTTPS で同じセッションクッキーが使用されるためです。Web サーバーは、すべての HTTP トラフィックを HTTPS にリダイレクトし、HTTPS リクエストのみを Django に送信する必要があります。

一度 HTTPS をセットアップしたら、以下の設定項目が有効になります。

パフォーマンスの最適化

DEBUG = False をセットすることで、複数の開発向けの機能が無効化されます。さらに、以下の設定を調整できます。

セッション

パフォーマンスを向上させるために キャッシュを使ったセッション の使用を検討してください。

データベースバックアップセッションを使用している場合は、不要なデータを保存しないように セッションストアのクリア を定期的に行ってください。

CONN_MAX_AGE

永続的なデータベース接続 を有効化すると、リクエストのプロセス時間の多くの部分に対するデータベースアカウントへの接続において、高速になります。

限られたネットワーク性能の仮想化ホストにおいて、とても効果的です。

TEMPLATES

キャッシュされたテンプレートローダーを有効にすると、レンダリングが必要になるたびに各テンプレートをコンパイルする必要がなくなるので、パフォーマンスが劇的に向上します。 DEBUG = False の場合、キャッシュテンプレートローダーは自動的に有効になります。詳しくは django.template.loaders.cached.Loader を参照してください。

エラーのレポート

あなたの書いたコードを本番環境に送信するまでは、頑強であることが望まれますが、予期しないエラーを除外することはできません。ありがたいことに、Django はエラーをキャッチして適切にお知らせします。

LOGGING

本番環境に置く前に、ロギング設定を見直しましょう。また、トラフィックを受け取ったらすぐにそれらが想定通り動作していることを確認してください。

ロギングに関する詳細は ロギング を参照してください。

ADMINSMANAGERS

ADMINS は、500 エラーの通知を E メールで受け取ります。

MANAGERS は、404 エラーの通知を受け取ります。IGNORABLE_404_URLS により不要なレポートをフィルタリングできます。

E メールによるエラーレポートの詳細は、エラーレポートの管理 を参照してください。

E メールによるエラーレポートはスケールしない

あなたの受信箱がレポートであふれかえる前に、Sentry などのエラーモニタリングツールの導入を検討してください。Sentry もログを集計することができます。

デフォルトのエラービューをカスタムする

Django には、いくつかの HTTP に対して、デフォルトのビューとテンプレートが用意してあります。ルートのテンプレートディレクトリに以下のテンプレートを作成することで、独自のテンプレートに置き換えることができます: 404.html, 500.html, 403.html, and 400.html 。99%のWebアプリケーションは、これらのテンプレートを使用した デフォルトのエラービュー で事足りるはずですが、 これらをカスタマイズする こともできます。

Back to Top