MySQL5.5をホームディレクトリ以下にインストールする

評価用にMySQL5.5.22をホームディレクトリ以下にインストールしてみました。

cmakeは別途インストールしてあります。

cd $HOME/src
tar xvzf mysql-5.5.22.tar.gz
cd mysql-5.5.22
cmake . -DCMAKE_INSTALL_PREFIX=$HOME/local/mysql
make
make install

$HOME/local/mysql以下に色々インストールされました。起動してみます。

cd $HOME/local/mysql
mkdir tmp
scripts/mysql_install_db
bin/mysqld_safe --port=13306 --socket=$HOME/local/mysql/tmp/mysql.sock

この環境は既にMySQLが起動しているので、ポートもUNIXドメインソケットも標準から変更しました。

接続用のmysqlクライアントは別バージョンのものでも問題ありません。

mysql -S $HOME/local/mysql/tmp/mysql.sock

シャットダウンは次のように行います。

mysqladmin shutdown -uroot -S $HOME/local/mysql/tmp/mysql.sock

PHP+Homebrewの設定(APC編)

前回記事に引き続き、PHPのエクステンションをHomebrewでインストールしていきましょう。今回はAPCです。

ただし、そのままでは次のようなエラーが出てしまいます。

[Tue Nov 15 14:12:19 2011] [error] [client 127.0.0.1] PHP Fatal error:  Unknown: apc_fcntl_unlock failed: in Unknown on line 0

これに対し、下記URL中のパッチを当てることにします。

* https://bugs.php.net/bug.php?id=59750

$ brew edit emacs
...
$

これでパッチが当たった状態でビルドされます。

$ brew install apc
Also installing dependencies: pcre
==> Downloading ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.12.tar.bz2
######################################################################## 100.0%
==> ./configure --prefix=/usr/local/Cellar/pcre/8.12 --enable-utf8 --enable-unicode-properties --enable-pcregrep-libz --ena
==> make test
==> make install
/usr/local/Cellar/pcre/8.12: 111 files, 2.8M, built in 59 seconds
==> Downloading http://pecl.php.net/get/APC-3.1.9.tgz
######################################################################## 100.0%
==> phpize
==> ./configure --prefix=/usr/local/Cellar/apc/3.1.9
==> make
==> Caveats
To finish installing APC:
 * Add the following lines to php.ini:
    [apc]
    extension="/usr/local/Cellar/apc/3.1.9/apc.so"
    apc.enabled=1
    apc.shm_segments=1
    apc.shm_size=64M
    apc.ttl=7200
    apc.user_ttl=7200
    apc.num_files_hint=1024
    apc.mmap_file_mask=/tmp/apc.XXXXXX
    apc.enable_cli=1
 * Restart your webserver
 * Copy "/usr/local/Cellar/apc/3.1.9/apc.php" to any site to see APC's usage.
==> Summary
/usr/local/Cellar/apc/3.1.9: 2 files, 208K, built in 23 seconds

PHP+Homebrewの設定(memcached編)

僕はPHP本体はMacOSX付属のものを利用しています。これはHomebrewを使う場合は標準的な方針かと思います。

一方、一部のPHP extensionはHomebrewで提供されています。これをOS付属のPHPで利用するのがHomebrew流のようです。今回はPECL::memcachedを組み込んでみましょう。

$ brew install memcached-php
Also installing dependencies: libevent, memcached, libmemcached
==> Downloading http://monkey.org/~provos/libevent-2.0.12-stable.tar.gz
######################################################################## 100.0%
==> ./configure --prefix=/usr/local/Cellar/libevent/2.0.12
==> make install
/usr/local/Cellar/libevent/2.0.12: 47 files, 2.0M, built in 91 seconds
==> Downloading http://memcached.googlecode.com/files/memcached-1.4.6.tar.gz
######################################################################## 100.0%
==> ./configure --prefix=/usr/local/Cellar/memcached/1.4.6
==> make install
==> Caveats
You can enable memcached to automatically load on login with:
    mkdir -p ~/Library/LaunchAgents
    cp /usr/local/Cellar/memcached/1.4.6/com.danga.memcached.plist ~/Library/LaunchAgents/
    launchctl load -w ~/Library/LaunchAgents/com.danga.memcached.plist

    Or start it manually:
        /usr/local/bin/memcached

    Add "-d" to start it as a daemon.
==> Summary
/usr/local/Cellar/memcached/1.4.6: 8 files, 156K, built in 18 seconds
==> Downloading http://launchpad.net/libmemcached/1.0/0.50/+download/libmemcached-0.50.tar.gz
######################################################################## 100.0%
==> ./configure --prefix=/usr/local/Cellar/libmemcached/0.50
==> make install
/usr/local/Cellar/libmemcached/0.50: 185 files, 1.6M, built in 77 seconds
==> Downloading http://pecl.php.net/get/memcached-1.0.2.tgz
######################################################################## 100.0%
==> phpize
==> ./configure --prefix=/usr/local/Cellar/memcached-php/1.0.2
==> make
==> Caveats
To finish installing memcached:
  * Add the following line to php.ini:
    extension="/usr/local/Cellar/memcached-php/1.0.2/memcached.so"
  * Restart your webserver
==> Summary
/usr/local/Cellar/memcached-php/1.0.2: 60K, built in 14 seconds
$

無事ビルドできました。

memcachedの起動

上のメッセージの通りなんですが、まずmemcachedを起動します。

$ mkdir -p ~/Library/LaunchAgents
$ cp /usr/local/Cellar/memcached/1.4.6/com.danga.memcached.plist ~/Library/LaunchAgents/
$ launchctl load -w ~/Library/LaunchAgents/com.danga.memcached.plist

PECL::memcachedの設定

php.iniに1行追加します。

extension="/usr/local/Cellar/memcached-php/1.0.2/memcached.so"

設定の反映のため、Apacheを再起動します。

$ sudo launchctl stop org.apache.httpd

自動起動の設定ファイル

以下の文章が非常に参考になった。

ただし、設定ファイルの記述ミスなどで起動に失敗した場合、エラーが/var/log/system.logに書かれていることがある。ちょっとハマった。

以下、作業ログ。

動作確認(Apache動いてるかな)

$ sudo launchctl list | grep apache
6799    -       org.apache.httpd
$

プロセスID6799番が親玉。

再起動

$ sudo launchctl stop org.apache.httpd
$ sudo launchctl list|grep apa        
6919    -       org.apache.httpd
$

ただし、plistファイルを自分のホームディレクトリ( ~/Library/LaunchAgents/ など)で管理しているような場合は「sudo launchctl list」では表示されません。自分の権限でlaunchctlコマンドを動かす必要があります。

$ launchctl list | grep mysql          
155     -       com.mysql.mysqld
205     -       0x1002059a0.anonymous.mysqld

wgetでクライアント証明書を使ってアクセスする方法

クライアント証明書で認証しているサイトに対して、wgetでアクセスする方法を紹介します。

クライアント認証を要求するサイトにアクセスしたい場合、通常であればクライアント証明書をWebブラウザに登録して利用します。

これをwgetで利用する場合、秘密鍵・CA証明書・クライアント証明書の3つを別々のファイルとして取り出す必要があります。

利用するクライアント証明書はPKCS12フォーマットのclient-cert.p12であるとしましょう。この場合に秘密鍵と証明書を取り出す方法は次の通りです。

$ openssl pkcs12 -in client-cert.p12 -clcerts -nokeys -out client-cert.crt.pem
Enter Import Password:
MAC verified OK
$ openssl pkcs12 -in client-cert.p12 -cacerts -nokeys -out ca-cert.crt.pem
Enter Import Password:
MAC verified OK
$ openssl pkcs12 -in client-cert.p12 -nocerts -nodes -out client-cert.key.pem
Enter Import Password:
MAC verified OK
$

これらのファイルをwgetコマンドラインオプションで指定することで、クライアント認証を使ったアクセスができます。

wget --certificate=client-cert.crt.pem --private-key=client-cert.key.pem --ca-certificate=ca-cert.crt.pem https://example.com/secret/

注意点など

この作業を行うと、秘密鍵を暗号化されていない状態で取り出すことになります。くれぐれも共用サーバなどで作業しないこと、また作業後はすみやかに取り出したファイルを削除することが必要です。

SSL証明書のKEYファイル・CSRファイル・CRTファイルのチェック方法

SSL証明書の発行プロセスでは、KEYファイルとCSRファイルを作ることになります。また、証明書会社からはCRTファイルが送られてきます。これらが正しいかどうかをチェックする方法を紹介します。

KEYファイルとは

KEYファイルというのが正式名称だとは思えませんが、ここではSSL通信に利用する公開鍵暗号系の秘密鍵ファイルを指します(おそらく公開鍵情報も含んでいるんだと思いますが、このあたりはよくわかっていません)。

秘密鍵ファイルは次のようなヘッダ・フッタを利用します。

-----BEGIN RSA PRIVATE KEY-----
-----END RSA PRIVATE KEY-----

下記のようにすれば、KEYファイルが正しいかどうか確認できます。

$ openssl rsa -in ssl_example_jp.key -check -noout
verify OK
$

CSRファイルとは

CSRファイルとは、SSL通信に利用する公開鍵暗号系の公開鍵に、コモンネームなどの情報を付加したものです。

これは次のようなヘッダ・フッタを利用します。

-----BEGIN CERTIFICATE REQUEST-----
-----END CERTIFICATE REQUEST-----

下記のようにすれば、CSRファイルが正しいかどうか確認できます。

$ openssl req -in ssl_example_jp.201109.csr -verify -noout
verify OK
$

また、次の手順でコモンネーム(HTTPS通信を行うFQDN)を調べることができます。

$ openssl req -in ssl_example_jp.201109.csr -text -noout | grep -i CN=
        Subject: C=JP, ST=TOKYO, L=Chiyoda-ku, O=Acme Co. Ltd., CN=ssl.example.jp
$

CN=の後ろがコモンネームです。

KEYファイルとCSRファイルそれぞれに含まれる公開鍵が同じかどうかは次のように確認できます。

$ openssl rsa -in ssl_example_jp.key -pubout -out pubkey1.txt
writing RSA key
$ openssl req -in ssl_example_jp.201109.csr -pubkey -noout -out pubkey2.txt
$ diff pubkey1.txt pubkey2.txt
$

ファイルを取り違えたような場合に、これで一定の確認ができます。

CRTファイルとは

CRTファイルとは、SSL証明書会社がCSRファイルに情報を付加して秘密鍵で暗号化したものです。サーバ証明書などとも呼ばれます。

証明書会社の秘密鍵に対応する公開鍵は各ブラウザに内蔵されているため、CSRファイルの内容を安全に送信できるというわけです。

これは次のようなヘッダ・フッタを利用します。

-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----

また、次の手順でコモンネームを調べることができます。

$ openssl x509 -in ssl_example_jp.201109.crt -noout -subject
subject= /serialNumber=****/C=JP/O=****/OU=****/OU=****/OU=****/CN=ssl.example.jp
$

一部情報を伏せましたが、CN=の後ろがコモンネームです。

さらに、証明書の有効期限を確認することもできます。

$ openssl x509 -in ssl_example_jp.201109.crt -noout -dates
notBefore=Sep  3 17:53:00 2011 GMT
notAfter=Sep  5 20:09:00 2013 GMT
$

KEYファイルとCRTファイルそれぞれに含まれる公開鍵が同じかどうかは次のように確認できます。

$ openssl rsa -in ssl_example_jp.key -pubout -out pubkey1.txt
writing RSA key
$ openssl x509 -in ssl_example_jp.201109.crt -pubkey -noout > pubkey3.txt
$ diff pubkey[13].txt
$

参考記事

memstorm

mixi Engineers’ Blog » libmemcachedで快速キャッシュ生活」で紹介されているmemstormをビルドしてみた。

memstorm開発時期よりlibmemcachedのバージョンが上がっているのと、libmemcachedを変則的な位置にインストールしているのとで少々苦労した。

  • memstorm-0.6.8
  • libmemcached-0.32
$ tar xvzf memstorm-0.6.8.tar.gz 
$ cd memstorm-0.6.8/
$ ./configure
(略)
$ LD_RUN_PATH=/opt/local/lib make INCLUDES='-I/opt/local/include/ -I/opt/local/include/libmemcached' LIBS='-L/opt/local/lib'
if gcc -DPACKAGE_NAME=\"memstorm\" -DPACKAGE_TARNAME=\"memstorm\" -DPACKAGE_VERSION=\"0.6\" -DPACKAGE_STRING=\"memstorm\ 0.6\" -DPACKAGE_BUGREPORT=\"8\" -DPACKAGE=\"memstorm\" -DVERSION=\"0.6.8\"  -I. -I. -I/opt/local/include/ -I/opt/local/include/libmemcached    -Wall -MT memstorm.o -MD -MP -MF ".deps/memstorm.Tpo" -c -o memstorm.o memstorm.c; \
        then mv -f ".deps/memstorm.Tpo" ".deps/memstorm.Po"; else rm -f ".deps/memstorm.Tpo"; exit 1; fi
memstorm.c: In function ‘engage’:
memstorm.c:112: warning: passing argument 3 of ‘memcached_behavior_set’ makes integer from pointer without a cast
memstorm.c:115: warning: passing argument 3 of ‘memcached_behavior_set’ makes integer from pointer without a cast
memstorm.c:162: warning: passing argument 5 of ‘memcached_get’ from incompatible pointer type
gcc  -Wall   -o memstorm -lmemcached memstorm.o  -L/opt/local/lib
$ ./memstorm 
memstorm: Simple CLI memcached Utility
  -s <string>  : hostname of the server to access
  -n <num>     : number of SET/GET tests to run
  -k <num>     : length of the key (default: 32, max: 250)
  -l <num>     : length of the value (default: 128)
  -b           : use non-blocking IO
  -t           : use tcp-nodelay
  -h           : print this help
$

でも、うごかねー。PROTOCOL ERRORとか怒られる。修正したら動くようになったけど、正しいかどうかは不明。

--- memstorm.c~ 2008-01-20 22:54:22.000000000 +0900
+++ memstorm.c  2009-10-14 09:13:57.000000000 +0900
@@ -84,7 +84,7 @@
   int i, kalloc = 0, valloc = 0;
   int set_succ = 0, set_fail = 0;
   int get_succ = 0, get_fail = 0;
-  uint16_t flags;
+  uint32_t flags;
   char kbuf[IOBUFSIZ];
   char vbuf[IOBUFSIZ];
   char *key = NULL, *val = NULL, *res = NULL;
@@ -109,10 +109,10 @@
   }
 
   if(set_no_delay) {
-    memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, &behave_val);
+    memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, behave_val);
   }
   if(set_no_block) {
-    memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, &behave_val);
+    memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, behave_val);
   }
 
   srand(time(NULL));
@@ -147,7 +147,7 @@
     }
 
     gettimeofday(&start_time, NULL);
-    rc = memcached_set(memc, key, klen, val, vlen, (time_t)0, (uint16_t)0);
+    rc = memcached_set(memc, key, strlen(key), val, strlen(val), (time_t)0, (uint32_t)0);
     gettimeofday(&end_time, NULL);
 
     set_accum += timedif(end_time, start_time); 
@@ -159,7 +159,7 @@
       set_fail++;
     }
     gettimeofday(&start_time, NULL);
-    res = memcached_get(memc, key, klen, &reslen, &flags, &rc);
+    res = memcached_get(memc, key, strlen(key), &reslen, &flags, &rc);
     gettimeofday(&end_time, NULL);
 
     get_accum += timedif(end_time, start_time); 

memslapも信用ならない気がするし、何を使えばいいんだ…