Posts in category nginx

SSL中間証明書を改良してAndroidに対応させた

およそ3週間の間多忙で何もアウトプットできていなかったくりすです。

nginxのSSL証明書をAndroid上で信頼されないという報告を受けていたのですが、先程対応が完了したのでシェア。

問題

このnginx上ではRapidSSLを採用しており、その親ベンダはGeoTrust, Inc.であるわけですが、この両者の中間証明書をインストールしないと、一部の端末では証明書が正しく使用できませんでした。

原因

2010年頃からRSA (1024bit) は暗号強度上の理由から廃止されており、それに伴い諸CA証明書も2048bitに順次入れ替わっております。しかし、これに伴い互換性確保のために中間証明書のインストールが必須となるので、これを正しく設置していない場合SSLエラーが発生するわけです。

気を付けないといけないのは、RapidSSLの場合はRapidSSLの中間証明書と、その上位のGeoTrustの中間証明書の両方が必要であるということです。

対策

  1. RapidSSL, およびGeoTrustの中間証明書をそれぞれ入手します。
    参考文献の3番目のテキストファイルは、この2つの証明書がバンドルになったものなので、それを引っ張ってくればよいでしょう。
    $ wget https://knowledge.rapidssl.com/library/VERISIGN/INTERNATIONAL_AFFILIATES/RapidSSL/AR1548/RapidSSLCABundle.txt
    

  1. 自分のサーバ用の証明書とこれらを連結します。
    # cat /path/to/the/downloaded/RapidSSLCABundle.txt >> /path/to/your/ssl/cert.pem
    
  1. nginxを再起動します。
    # service nginx restart
    

これだけの手間でしたが、Android 4.0.3で正常に読み込まれたことを確認しましたので、一安心。

NISTの文書によると、今年の末までに1024bitのRSAは廃止され、2048bitに移行するものとされています。

参考文献

2つめのTracをホストしてみました

大学や仕事のこと、私的なことなどといったプライベートなあれこれもチケット管理しようといった考えから、公開用であるこのTracプロジェクトとは別に、認証もかけて自分専用のプロジェクトをホストしようと思いました。

同じホスト(同じサーバ)で2つのTracをホストした理由は、単にSSL証明書を節約するためです。


準備

例によって、任意のパスにTrac用のディレクトリを作成し、Trac化します。
詳細は以前の投稿を参照のほど。

trac@reimu ~:$ mkdir another_project
trac@reimu ~:$ trac-admin another_project initenv
trac@reimu ~:$ chown -R trac:www-data another_project
trac@reimu ~:$ chmod -R 775 another_project

失敗例

nginxの設定で、location /privateを設定し、パスを変える方法は失敗でした。
なぜかというと、Tracprivateというハンドラがないからです。

それから、uwsgiのSocketポートを変えただけでも、同様にだめでした。

そんなにたくさん試行錯誤はしていません。エンジニアたるものもっと失敗にぶち当たるべき。

成功例

結局、私的に使うやつなのでポート番号くらい非defaultでもいいだろということで、別のポートでlistenすることにしました。

/etc/nginx/sites-available/trac_private
server {
    listen 55555 ssl;
    server_name x86-64.jp;
    ssl_certificate /path/to/your/ssl/cert.pem;
    ssl_certificate_key /path/to/your/ssl/key.key;
    root /home/trac/another_project;
    
    location /favicon.ico { }
    location /robots.txt { }

    if ($scheme = http) {
    	return 301 https://$server_name$request_uri;
    }
    
    location / {
    	include uwsgi_params;
    	uwsgi_param REMOTE_USER $remote_user;
        uwsgi_param HTTPS on; # リクエストが勝手にHTTPになる現象をこの行で解決
    	include uwsgi_params;
    	uwsgi_pass 127.0.0.1:7778;
    	auth_basic "Trac";
    	auth_basic_user_file "/path/to/your/.htpasswd";
    }
}

uwsgi_passのSocketポート番号は、ほかに走っているuwsgiアプリケーションと違うのに気をつけてください。同じだと破滅が起こります。

このconfをsites-enabledにシンボリックリンク張って、uwsginginxを再起動して完了。

nginxとuwsgiを使ってTracをホストしよう

このTracをセットアップするのに多くの時間を費やし、文献を読みあさったのでここに手順やハマりどころをまとめておきます。

そこらの文献というのはなぜかコマンドをどの権限やパスで実行するか明記していないケースがあるので、この記事ではコマンドの説明をするときはbashっぽくプロンプトの部分から記述します。

  1. なんかサーバを用意します(当サーバはAmazon EC2上のUbuntu 12.04.2)
    以降、ホスト名はreimuと表します(このホストがreimu.x86-64.jpだから)
  1. 必要なものをパッケージマネージャなり公式サイトなりから引っ張ってきます。
    わたしはaptを使って手を抜きました。依存環境などもまるまる降ってくるし、アップデートの適用もシステムと一緒にできるという恩恵にあずかれます。
    root@reimu ~:# apt-get install nginx uwsgi uwsgi-plugin-python trac trac-git
    
    trac-gitTracgit使いたいから入れておいたもので、必須ではありません。
    で、uwsgiって結局なんなん: Uwsgi?
  1. わたしはWebサイトごとにユーザを作るスタイルを採用しているので、Trac用にユーザを作っちゃいます。
    root@reimu ~:# adduser -G www-data trac
    
    nginxが走るグループは、環境によってはwww-dataではないかもしれません(httpdとか)
    ユーザ分けとかどうでもいい場合はwww-dataさんが参照できるディレクトリを用意するだけで大丈夫です。
  1. Tracのプロジェクトが入るディレクトリを適当に作り、Tracに付属しているTrac-admin?コマンドでそのディレクトリをTrac化します。
    これは通常ユーザ(この記事の例ではtrac, Trac用のユーザを作らなかった場合はwww-data)で行います。
    trac@reimu ~:$ mkdir your_trac_project
    trac@reimu ~:$ trac-admin ~/your_trac_project initenv
    
    initenvを行っているときに、プロジェクトの名称とデータベースファイルのパスを決められます。
    これがTracのタイトルとして反映されます。たとえばこのTracなら真剣な悪ふざけになっています。 どうやらUTF-8なら2バイト文字でもいいみたいです。
  1. このへんでTracの管理者アカウントを登録しておきましょう。
    trac@reimu ~:$ trac-admin ~/your_trac_project permission add foo TRAC_ADMIN
    
    これで、ユーザfooが管理者になりましたので、fooとしてhttp-auth-basic(以下Basic認証と記述)でログインできるように設定します(後述)。

  1. Tracについての、uwsgi用とnginx用のconfigを作ります。
    わたしはこうしました:
/etc/uwsgi/apps-available/trac.xml
<uwsgi>
    <socket>127.0.0.1:7777</socket>
    <plugin>python</plugin> <!--この行が意外と重要-->
    <env>TRAC_ENV=/home/trac/project-directory</env>
    <module>trac.web.main:dispatch_request</module>
</uwsgi>
/etc/nginx/sites-available/trac
server {
    listen 80;
    listen 443 ssl;
    server_name x86-64.jp;
    ssl_certificate /path/to/ssl-cert.pem;
    ssl_certificate_key /path/to/ssl-key.key;
    root /home/trac/your_trac_project;
    
    location /favicon.ico { }
    location /robots.txt { }

    if ($scheme = http) {
    	return 301 https://$server_name$request_uri;
    }
    
    location / {
    	include uwsgi_params;
    	uwsgi_pass 127.0.0.1:7777;
    }

    location /login {
    	include uwsgi_params;
    	uwsgi_param REMOTE_USER $remote_user;
    	uwsgi_pass 127.0.0.1:7777;
    	auth_basic "Trac";
    	auth_basic_user_file "/path/to/your/.htpasswd";
    }
}
uwsgi用のconfで書いたソケットはportが7777なので、こちらのconfでもuwsgi_passを7777に設定しておきます。
このようにして、nginxにアクセスがあったとき、uwsgiを通してTracのコンテンツを引っ張りにいく設定にします。 ちなみにこのTracはSSL-enabledなので、ところどころSSLに関する設定が入っています。
  1. htpasswdを使って、Basic認証に使うアカウントを生成します。
    Apacheを入れていないUbuntuではそんなコマンドないかもしれないですが、apache-utilsをインストールすればOKです(記事は省略)
    trac@reimu ~:$ htpasswd -c /path/to/your/.htpasswd foo
    trac@reimu ~:$ chgrp www-data /path/to/your/.htpasswd
    trac@reimu ~:$ chmod 750 /path/to/your/.htpasswd
    
    これによってユーザfooが含まれる.htpasswdが生成されたので、このユーザでログインすることでTracのWebインタフェースからの管理ができるようになりました。
    個人的にはここでroot以外が.htpasswdを読めるのがきもい。まあしょうがない。
  1. 上で書いたconfigをenableします。
    root@reimu ~:# ln -s /etc/nginx/sites-available/trac /etc/nginx/sites-enabled/trac
    root@reimu ~:# ln -s /etc/uwsgi/apps-available/trac.xml /etc/uwsgi/apps-enabled/trac.xml
    
  1. uwsginginxrestartして完成。
    root@reimu ~:# service uwsgi restart
    root@reimu ~:# service nginx restart
    

ああそういえば:

エラーが発生したときは、結構な確率でパーミッションがおかしいです。
とくにTracを運用するにあたってwww-dataが読み書きできなくてはいけないファイルは、

  • your_trac_project/conf/trac.ini
  • your_trac_project/db/trac.db

が大事です。これらのファイルについてwww-dataがrとwの権限を持っているかチェックしましょう。

それからハマりどころとして、uwsgiの設定にてPythonのプラグインを使うことを明記しないとちゃんと動かなかったのでメモ。


ざっとこんなところかしら。なんか抜けがある気がするので暇な時に検証します。

参考文献

  1. TracInstallUbuntu
  2. TracNginxRecipe
  3. ラフなラボ: Nginx + uwsgi で Trac環境を作った時のメモ
  4. Cookbook recipe for nginx/uwsgi woes