Apache + Python (mod_wsgi) の環境で Let’s Encrypt を利用すると証明書を発行できない場合がある

こんにちはkotaです。

最近は新しいサーバーの設定を行っているのですが、Let’s Encryptで証明書を発行しようとした時につまずいたポイントがあったので共有のためにもブログに残しておきます。

サーバーの設定とつまずいたポイント

設定を行っている新しいサーバーでは、サーバーソフトウェアにApacheを使っており、アプリケーションの作成にはPythonのフレームワークであるFlaskで使用しています。
また、FlaskとApacheを連携させるためにmod_wsgiというモジュールをデーモンモードで使用しています。

今回は、Flaskで作成したアプリケーションをhttpsに対応させるため、Let’s Encryptで証明書を発行したかったのですが、証明書の発行前と発行後にApacheの設定ファイルを修正しなければならず、ここで少しつまずいてしまいました。

どんな問題が起きるのか?

Let’s Encryptで証明書を発行しようとすると、Apacheの設定ファイルがチェックされるのですが、次のようなエラーが発生して証明書が発行できませんでした。

Name duplicates previous WSGI daemon definition.

どんな時にエラーが起きるのか?

今回のエラーは、mod_wsgiをデーモンモードに設定している場合に発生します。具体的には、Apacheの設定ファイルに以下のようなWSGIDaemonProcessという項目が設定してあると発生します。

WSGIDaemonProcess yourapplication user=user1 group=group1

問題となるのはmod_wsgiなので、DjangoやPyramidなどFlask以外のフレームワークでもエラーが発生します。

なぜエラーになるのか?

証明書を発行する際には以下のコマンドを実行すると思います。

certbot --apache

このコマンドを実行すると、連絡先のメールアドレスや規約に同意するか等いろいろと聞かれるので順に答えていくと、途中でhttp用の設定ファイルを元にして、https用の設定ファイルを自動で作成してくれます。httpからhttpsへのリダイレクト等も設定してくれるのでとても親切だと思います。
この後にapacheの設定が正しいかチェックされますが、上で説明したようにWSGIDaemonProcessが設定されているとここでエラーとなります。

なぜエラーになるかと言うと、自動で作成させるhttps用の設定ファイルはhttp用の設定ファイルをコピーして作成されるのですが、そうするとWSGIDaemonProcessを2か所で設定した形になってしまうからです。なので、すでに同じ名前のWSGI daemonが設定してあると注意されてしまうのです。

どうすればエラーにならないのか?

対応は簡単で、証明書を発行する前にhttp用の設定ファイルのWSGIDaemonProcessの行をコメントアウトしておけばエラーは発生しません。
証明書を発行した後は、コメントアウトを外してApacheを再起動すれば問題なく動作します。

ただ、引っかかるポイントがあったり手順が増えたりするのは面倒ですし、https用の設定ファイルを作成しないオプションがあってもいいのになぁ、と思っています。

最後に

今回はコメントアウトして対応すればいいと紹介しましたが、正直なところ対応としては微妙な感じもするので、他にいい方法を知っている方がいらっしゃればぜひ教えてください。