しかも、各ドメインは、SSLにも対応させる。
結構、難しくないですか? Virtual Hostの書き方を把握するまで、凄く時間がかかったので、まとめておきます。
--------------------------------------------------------------------------------
***** Important Notice *****
前半の記述は、失敗版だと判明しました。 この記述だと、一番最初に読み込んだflask appが保持されて、別のflask appに切り替わりません。
この問題には、stackoverflowに、mod_wsgiの開発者であるGraham Dumpleton さん
自身が回答されていましたので、そのガイドに基づいて、再度、設定を修正しています。
このpostの後半に書きました。 最初の部分は、読み飛ばしてください。
mod_wsgiを利用した場合の基本的なVirtual Hostの書き方は、
【 複数のサブドメインを管理しているサーバで、wsgiを使う時のVirtual Hostの書き方 】
に、まとめました。
この書き方で、’wwwあり・なし’、’複数のサブドメイン’に対応することができます。
(あわせて、mod_wsgiのスクリプトがあるディレクトリ配下でも、staticなファイルは直接、ブラウザから呼び出せるようにしています。)
このポストでは、これをSSLに対応させる(Let's Encrypt) 時のVirtual Hostの書き方と注意点を書いておきます。
◆環境
CentOS 7 + Apache 2.4 + mod_wsgi 4.6.5 + Flask
で、挙動確認しています。
◆対象ドメイン
(Freenomで12か月、無料で取得したもの。DNSもすべてに同じIP Addressを指定しています。)
- mossymob.tk
- www.mossymob.tk
- taylor.mossymob.tk
***********(前半 失敗の部)***********
◆結論
Virtual Hostの記載:
conf.d ディレクトリの配下に 'vhosts_www.conf' を作り、記述しています。
[root@cnewgwb6 conf.d]# pwd
/etc/httpd/conf.d
[root@cnewgwb6 conf.d]# cat vhosts_www.conf
LoadModule wsgi_module /usr/lib64/httpd/modules/mod_wsgi.so
WSGIApplicationGroup %{GLOBAL}
WSGIDaemonProcess www user=apache group=apache
WSGIProcessGroup www
<VirtualHost *:80>
ServerName www.mossymob.tk
DocumentRoot /var/www/html
Alias /posts /var/www/html/posts <- ②
WSGIScriptAlias / /var/www/html/myapp.wsgi
<Directory "/var/www/html/">
Options Includes ExecCGI FollowSymLinks
</Directory>
</VirtualHost>
<VirtualHost *:80>
ServerName mossymob.tk <- ③
DocumentRoot /var/www/html
Alias /posts /var/www/html/posts
WSGIScriptAlias / /var/www/html/myapp.wsgi
<Directory "/var/www/html/">
Options Includes ExecCGI FollowSymLinks
</Directory>
</VirtualHost>
<VirtualHost *:80>
ServerName taylor.mossymob.tk
DocumentRoot /var/taylor/html
Alias /posts /var/taylor/html/posts
WSGIScriptAlias / /var/taylor/html/myapp.wsgi
<Directory "/var/uslife/html/">
Options Includes ExecCGI FollowSymLinks
Require all granted <- ④
</Directory>
</VirtualHost>
注意点)
①デーモン・モードについて
明示的にdeamon modeを指定してあげないと"ValueError: Unable to set value to path!" とエラーになります。 そこで、個別の<VirtualHost></VirtualHost>の中に、それぞれ記述しましたが、 "Name duplicates previous WSGI daemon definition.” というエラーになりました。
記述は、こんな感じ。
LoadModule wsgi_module /usr/lib64/httpd/modules/mod_wsgi.so
<VirtualHost *:80>
ServerName mossymob.tk
WSGIDaemonProcess www user=apache group=apache
DocumentRoot /var/www/html
WSGIScriptAlias / /var/www/html/myapp.wsgi process-group=www
<Directory "/var/www/html/">
Options Includes ExecCGI FollowSymLinks
</Directory>
</VirtualHost>
結局、個別の<VirtualHost>コンテナーの外に記述することで、このName duplicates errorを回避しました。
*maximm requests:
Use of maximum-requests is discouraged for production sites unless you really have a crippling memory leak you can't fix straight away. – Graham Dumpleton Jul 6 '11 at 5:18
②mod_wsgiとstatic file
必須ではないかもしれませんが、htmlなどの静的なファイルは、将来、mod_wsgiを介さないでブラウザに表示したいので、その為の設定です。 wsgiスクリプトが設置されたディレクトリにpostsというディレクトリを作り、その配下のファイルは、ブラウザから直接、アクセスできるようにしました。
③ wwwサブドメイン名なしのURLについて
Server Aliasを当初使っていましたが、この設定があるとLet's Encriptは上手く機能しないようです。 冗長ですが個別に<VirtualHost>の記述をすることにしました。
④Require all granted
mossymob.tk や www.mossymob.tk の<VirtualHost>の<Directory>コンテナーの中には記述不要ですが、別サブ・ドメインの時には、この記述が必須になります。 wwwは、mod_wsgiの読み込みのデフォルト・ルートになっているからでしょうか? 理由は良く分かりません。
ここまできたら、Let's Encrypt で、certbotを実行します。
コマンドは、ルート・ディレクトリで以下の実行をしました。
# certbot --apache -d mossymob.tk
-d のオプションでドメイン名を指定しなければ、一括してSSL対応になるようですが、一つずつ対応させた方が、どのドメインに問題があるか把握するのが容易です。
certbotが実行される毎に、’vhosts_www-le-ssl.conf' (自分が作成したvirtual host記述ファイル名+le-ssl.conf)が作成されます。 (後から実行したドメインの記述は、このファイル内に追加されます。
地道に全てのドメインに対して実行した後の’vhosts_www-le-ssl.conf'の内容が以下になります。
[root@cnewgwb6 conf.d]# cat vhosts_www-le-ssl.conf
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName mossymob.tk
DocumentRoot /var/www/html
Alias /posts /var/www/html/posts
WSGIScriptAlias / /var/www/html/myapp.wsgi
<Directory "/var/www/html/">
Options Includes ExecCGI FollowSymLinks
</Directory>
SSLCertificateFile /etc/letsencrypt/live/mossymob.tk-0001/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/mossymob.tk-0001/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateChainFile /etc/letsencrypt/live/mossymob.tk-0001/chain.pem
</VirtualHost>
</IfModule>
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName www.mossymob.tk
DocumentRoot /var/www/html
Alias /posts /var/www/html/posts
WSGIScriptAlias / /var/www/html/myapp.wsgi
<Directory "/var/www/html/">
Options Includes ExecCGI FollowSymLinks
</Directory>
SSLCertificateFile /etc/letsencrypt/live/www.mossymob.tk/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/www.mossymob.tk/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateChainFile /etc/letsencrypt/live/www.mossymob.tk/chain.pem
</VirtualHost>
</IfModule>
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName taylor.mossymob.tk
DocumentRoot /var/taylor/html
Alias /posts /var/taylor/html/posts
WSGIScriptAlias / /var/taylor/html/myapp.wsgi
<Directory "/var/taylor/html/">
AllowOverride None <- ②
Options Includes ExecCGI FollowSymLinks
Require all granted <- ①
</Directory>
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/uslife.mossymob.tk/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/uslife.mossymob.tk/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/uslife.mossymob.tk/chain.pem
</VirtualHost>
</IfModule>
注意点)
① <Directory "/var/taylor/html/"> の記述
基本的に、Let's Encryptのcerbotが自動で作成するconfファイルは、自分で記述したvirtual hostの記述内容をコピーしてきて、その内容にsslの対応をさせる、というものだと思います。
でも、確実にコピーがされるか、というと疑問です。 自分の場合、赤字のRequire all grantedがコピーされていませんでした。 それが certbot の正しい挙動なのか分かりませんが、再度、自分で確認した方が良いでしょう。
② AllowOverride None
この記述は、httpのオリジナルの<Virtual Host>内には記述していません。 しかし、SSLの時には、この記述がないと、うまくwsgi scriptが機能しません。 理由の把握までは出来ていません。
これが最終版。
***********(前半 失敗の部 終了 & 正答版開始)***********
Let's EncrytのcertbotでSSLを設定しようとすると、 "Name duplicates previous WSGI daemon definition.”というエラーが表示される件について、mod_wsgiの開発者 Graham Dumpleton さんは、
As the error says, you cannot use the same name for a WSGIDaemonProcess definition more than once. They have to be unique for the whole Apache instance.
If you have both 80 and 443 instances of the VirtualHost for same ServerName, you shouldn't create a separate WSGIDaemonProcess in the 443 instance. Define it in the 80 instance and reference by name from the 443 instance. That way you share the same daemon process group between 80 and 443 instances of the VirtualHost for the same ServerName.
要は、certbotを走らせると <VirtualHost *:80> をcopyする形で、<VirtualHost *:443>用の新しいファイルが作られますが、すると、その記述の中に、再び、DaemonProcessの同じ名前が使われてしまうので、こんな感じで書いて、
WSGIApplicationGroup %{GLOBAL}
WSGIRestrictEmbedded On
<VirtualHost *:80>
ServerName example.com
WSGIDaemonProcess myprocess threads=10 home=/home/ubuntu/myapp
WSGIProcessGroup myprocess
...
</VirtualHost>
<VirtualHost *:443>
ServerName example.com
WSGIProcessGroup myprocess
... ← WSGIDaemonProcess は記述しない、
</VirtualHost>
と、回答しています。
なので、ホスト名ごとに<VirtualHost>を記述したconfファイルを以下のように作ることにします。
file名:mossymob.tk.conf
LoadModule wsgi_module /usr/lib64/httpd/modules/mod_wsgi.so
WSGIApplicationGroup %{GLOBAL}
WSGIRestrictEmbedded On
<VirtualHost *:80>
ServerName mossymob.tk
WSGIDaemonProcess bear user=apache group=apache
WSGIProcessGroup bear
DocumentRoot /var/www/html
Alias /posts /var/www/html/posts
WSGIScriptAlias / /var/www/html/myapp.wsgi
<Directory "/var/www/html/">
Options Includes ExecCGI FollowSymLinks
</Directory>
</VirtualHost>
<VirtualHost *:443>
ServerName mossymob.tk
WSGIProcessGroup bear
DocumentRoot /var/www/html
Alias /posts /var/www/html/posts
WSGIScriptAlias / /var/www/html/myapp.wsgi
<Directory "/var/www/html/">
Options Includes ExecCGI FollowSymLinks
</Directory>
</VirtualHost>
WSGIApplicationGroup %{GLOBAL}
WSGIRestrictEmbedded On
<VirtualHost *:80>
ServerName mossymob.tk
WSGIDaemonProcess bear user=apache group=apache
WSGIProcessGroup bear
DocumentRoot /var/www/html
Alias /posts /var/www/html/posts
WSGIScriptAlias / /var/www/html/myapp.wsgi
<Directory "/var/www/html/">
Options Includes ExecCGI FollowSymLinks
</Directory>
</VirtualHost>
<VirtualHost *:443>
ServerName mossymob.tk
WSGIProcessGroup bear
DocumentRoot /var/www/html
Alias /posts /var/www/html/posts
WSGIScriptAlias / /var/www/html/myapp.wsgi
<Directory "/var/www/html/">
Options Includes ExecCGI FollowSymLinks
</Directory>
</VirtualHost>
そして、
# certbot --apache -d mossymob.tk
を実行。
<VirtualHost *:443>
ServerName mossymob.tk
WSGIProcessGroup bear
DocumentRoot /var/www/html
Alias /posts /var/www/html/posts
WSGIScriptAlias / /var/www/html/myapp.wsgi
<Directory "/var/www/html/">
Options Includes ExecCGI FollowSymLinks
</Directory>
SSLCertificateFile /etc/letsencrypt/live/mossymob.tk-0001/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/mossymob.tk-0001/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateChainFile /etc/letsencrypt/live/mossymob.tk-0001/chain.pem
</VirtualHost>
ServerName mossymob.tk
WSGIProcessGroup bear
DocumentRoot /var/www/html
Alias /posts /var/www/html/posts
WSGIScriptAlias / /var/www/html/myapp.wsgi
<Directory "/var/www/html/">
Options Includes ExecCGI FollowSymLinks
</Directory>
SSLCertificateFile /etc/letsencrypt/live/mossymob.tk-0001/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/mossymob.tk-0001/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateChainFile /etc/letsencrypt/live/mossymob.tk-0001/chain.pem
</VirtualHost>
* 赤字部分がLet's Encryptのcertbotにより自動で追加された部分。
この作業をSSL化したい全てのサブ・ドメインに対して実行します。
これで、本当に想定した通りの挙動になります。
confファイルを変更した後は、systemctl reload httpdの実行を忘れてはいけません。
以上です。
結構、時間がかかりましたが、これで思い通りの挙動をするようになりました。
皆様にも参考になれば。
0 件のコメント:
コメントを投稿