このブログをDreamHostからHerokuに移しました。

% cd ~/Sites/cloister
% heroku create
% heroku git push heroku master
% heroku rake db:migrate
% heroku rake db:seed

その後docs.komagata.orgをproxy.heroku.org(proxy.heroku.comの間違い!別アプリで糞ハマった!)のCNAMEに設定しただけ。DBがポスグレって聞いてたからポスグレ用の設定にしなきゃいけないのかと思ったら何もしなくていいのね。糞思いDreamHostと違って速くなった!簡単だなぁ。

追記:ドメイン全部をherokuに向けたい場合はproxy.heroku.comのアドレスを全部@のAレコードに設定すればいい。

Google App Engine の一般的質問 - Google App Engine - Google Code

SSL(HTTPS)を Google Apps ドメインの App Engine で使用できますか

Google App Engine のすべてのセキュアなトラフィックは、appspot.com ドメイン(https://your-app-id.appspot.com)から提供される必要があります。アプリケーションを Google Apps ドメイン以外から提供している場合、すべてのセキュアなトラフィックをアプリケーションの appspot ドメイン経由で転送する必要があります。

なんと。

独自ドメインでSSL使えないんだったら殆どの仕事で使えなくない?

要は、"セキュアな通信が簡単に行える環境"が無いのであれば使えないよねえ。

改善か代替案が提供される予定が無いんだとしたらやっても意味ないからどうなる予定なのか気になるなあ。

どなたかご存じでしょうかー。

2009/11/03 追記

Issue 792 - googleappengine - SSL/HTTPS Support on Google Apps domains - Project Hosting on Google Code

Per Issue #15 , SSL/HTTPS is available on *.appspot domains.

We also need it on arbitrary Google Apps domains.

とっくにAcknowledgedなIssueが上がってるんですね。

技術的にはSNI使えば楽なんじゃないかってことでこれがStartedになることはありえそうですね。(みんなでStar押そうぜ!)

現状ではEC2をproxyにして使ってる野郎どももいるみたいですが、こりゃ面倒ですな。

リビングPC的なもの(Debian Lenny)にRemedieインストール。(また)

% sudo apt-get install perl perl-modules git-core build-essential libxml2 libxml2-dev libxml-atom-perl libxml-feed-perl libxml-libxml-common-perl libxml-libxml-perl libxml-perl libxml-rss-perl libxml-xpath-perl libyaml-perl libyaml-syck-perl libsqlite3-dev sqlite3 libnet-ssleay-perl
% cd /var/www
% git clone git://github.com/miyagawa/remedie.git
% cd remedie
% sudo chown -R komagata:komagata blib pm_to_blib
% perl -MCPAN -e shell
cpan> install Bundle::CPAN
cpan> install Http::Engine
cpan> install MooseX::ConfigFromFile
cpan> install MooseX::Getopt
% env PERL_MM_USE_DEFAULT=1 cpan -i .

こちらを参考にinitファイルを前より少しだけちゃんと書く。

% sudo vi /etc/init.d/remedie
#!/bin/sh
### BEGIN INIT INFO
# Provides: remedie
# Required-Start: $remote_fs
# Required-Stop: $remote_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start remedie at boot time
# Description: Enable service provided by remedie.
### END INIT INFO

case $1 in
start)
cd /var/www/remedie/bin
sudo -u komagata env HOME=/home/komagata nohup perl ./remedie-server.pl > /dev/null 2>&1 &
;;
esac
% sudo chmod 755 /etc/init.d/remedie
% sudo update-rc.d remedie defaults 99 1

今回、リバースプロクシはnginxを使ってみました。

% sudo apt-get install nginx
% sudo vi /etc/nginx/sites-available/remedie
server {
listen 80;
server_name remedie;
location / { proxy_pass http://localhost:10010; }
}

% sudo ln -s /etc/nginx/sites-enable/remedie /etc/nginx/sites-available/remedie

Debian apacheの作法“a2ensite”のnginx版はあるんですかね?わからないので普通にシンボリックリンク張りました。(敗北)

Remedie Media Center

ヒャッハー!

動画もジャンルの細分化/深化が進んだのでこういうの必要ですよね。

関連:Remedie – Debian etch – p0t

朝から

「remedieというものがあるらしいけど、ニコ厨ってだけで致命的なのに、あんな便利そうなものを使い出したらおれは仕事をせずに餓死するから使いません。」

という話をしたら、rono23が熱心に仕事してる振りしてMacにremedie入れて俺に自慢してきた。

そんなもん見せられて入れないでいることができるわけがない。もし俺が餓死したらあんた殺人者だぞ。

ということでremedie入れてみた。

Debian etchにremedie

gitは入ってるのでclone(etchで新しいgitを使う場合はこちら

git clone git://github.com/miyagawa/remedie.git

LibXML2関係に必要なのでlibxml2-devを入れる。

sudo apt-get install libxml2-dev

CPAN祭り(HTTP::Engineだけテスト通らなかったのでforce)

sudo perl -MCPAN -e shell
install Bundle::CPAN
install Module::Install
install Feed::Find
install FindBin::libs
force install HTTP::Engine
install Image::Info
install JSON::XS
install Log::Log4perl
install MIME::Types
install MooseX::ConfigFromFile
install MooseX::Getopt
install Path::Class
install Rose::DB
install Rose::DB::Object
install String::CamelCase
install XML::RSS::LibXML
install DBD::SQLite
install Log::Dispatch
install File::Find::Rule
install XML::Atom
install XML::Feed
install Template
install DateTime::Format::ISO8601
install MooseX::ClassAttribute
install File::Find::Rule::Filesys::Virtual
install HTML::ResolveLink
install HTML::Selector::XPath
install YAML::Syck
install Cache::FileCache
install Web::Scraper
install HTML::Scrubber
install Path::Class::Unicode
install Text::Tags::Parser
install String::ShellQuote
install XML::OPML::LibXML
install Module::Install::AuthorTests
install Date::Parse
install XML::LibXML::Simple
install DBI

DBD::SQLiteがおかしいのでDBD::SQLite::Amalgamationを使う。

svn co http://svn.coderepos.org/share/lang/perl/DBD-YASQLite/trunk/ ./DBD-YASQLite
cd DBD-YASQLite
cat PLEAAAAAAAAAAASEEEEEE_READDDDDDDDDDDDDDD_MEEEEE
THIS IS FORK VERSION OF DBD::SQLite, DBD::SQLite::Amalgamination.
I want to use it, but DBD::SQLite doesn't maintained by maintener.
DBD::SQLite has a lot of known bugs.
perl Makefile.PL
make
make test
sudo make install

心の叫びを無視して続けます。

cd ../remedia
perl Makefile.PL
make
make test
perl -Ilib ./bin/remedie-server.pl

http://localhost:10010 で起動した。 ワーオ。

remedie

Apacheからremedieに転送

ローカルではApache使ってるのでremedieからlocalhost:10010にmod_proxyで飛ばす設定をしました。

sudo a2enmod proxy
sudo a2enmod proxy_http
sudo vi /etc/apache2/sites-avalable/remedie
<VirtualHost *:80>
  ServerName remedie
  DocumentRoot /var/www/
  CustomLog /var/log/apache2/remedie-access.log combined
  ErrorLog /var/log/apache2/remedie-error.log
  ProxyPass / http://localhost:10010/
  ProxyPassReverse / http://localhost:10010/
</VirtualHost>

sudo a2ensite remedie
sudo /etc/init.d/apache2 reload

mod_proxy_httpをロードしなければいけないというところでハマりました。

あとproxy.confでAllow from allしておく。 (coLinuxの中なのでWindowsからしかアクセスできないので適当)

remedie2

いぃぃやっほう! アクセスし易くなった。

自動起動

ローカルなので自動起動して欲しい。 本来デーモン化して/etc/init.d/skel を元に起動スクリプトちゃんと書くところだけど面倒だし終了時は毎回シャットダウンなので適当なスクリプトを置きました。

(多分daemonizeみたいなのがあって簡単にdaemon化できるんだとおもうんだけどperlスキルが大昔で止まっているのでいじれない・・・)

sudo vi /etc/init.d/remedie
#!/bin/sh
cd /home/komagata/works/remedie/
nohup perl -I/home/komagata/works/remedie/lib /home/komagata/works/remedie/bin/remedie-server.pl &

sudo update-rc.d remedie defaults 99 1

これでcoLinux野郎も安心。 全体を通してremedie を remedia だと思ってたところが一番ハマりました。(何て発音すんの?)

このページをブラウザのトップに設定するのは仕事に深刻な影響が出そうです。

とはいってもあまりにも便利過ぎる。俺は餓死するだろう。

参考

DNSBLクライアントのライブラリdnsbl_clientをGithubに置きました。

komagata’s dnsbl_client at master ? GitHub

Install:

% sudo gem install komagata-dnsbl_client -s http://gems.github.com

Usage:

require 'dnsbl_client'
DNSBL::Client.new('list.dsbl.org', 'niku.2ch.net').listed? '61.211.32.39' # safe ip
=&gt; false
DNSBL::Client.new('list.dsbl.org', 'niku.2ch.net').listed? '78.157.143.202' # spam ip
=&gt; true

2chのDNSBL、BBQ用のライブラリも同梱してます。

require 'dnsbl_client'
DNSBL::BBQ.listed? '61.211.32.39' # safe ip
=&gt; false
DNSBL::BBQ.listed? '78.157.143.202' # spam ip
=&gt; true

何で作ったのか

人への嫌がらせ方法も進化したのか、「玄関前に猫の死体」から「ピザの大量注文」になり、最近では「お墓の資料の大量注文」というのもあるようです。

仕事で霊園(お墓)のサイトをやっています。そこでは、お墓を買う予定のある方が興味のある霊園(を運営する石材店)にフォームから資料請求できるようになっています。

この資料請求はお墓の購入にほとんど直結するといってもいいような確度を持つ大事なものです。(お墓は高いすからね)

普通は特定の市、区全体にカラーの広告を配布してやっと1件、2件獲得できる。それがお墓の資料請求なのです。

で、やられました。お墓の資料の大量注文。オープンプロクシ経由でゲイバーに。

そのプロクシ:

% nmap xxx.xxx.xxx.xxx
Starting Nmap 4.11 ( http://www.insecure.org/nmap/ ) at 2008-09-20 20:41 JST
Interesting ports on xxx.xxx.xxx.xxx:
Not shown: 1655 closed ports
PORT     STATE    SERVICE
21/tcp   open     ftp
53/tcp   open     domain
80/tcp   open     http
88/tcp   open     kerberos-sec
135/tcp  open     msrpc
139/tcp  open     netbios-ssn
157/tcp  open     knet-cmp
179/tcp  filtered bgp
389/tcp  open     ldap
445/tcp  open     microsoft-ds
464/tcp  open     kpasswd5
554/tcp  filtered rtsp
593/tcp  open     http-rpc-epmap
636/tcp  open     ldapssl
1026/tcp open     LSA-or-nterm
1027/tcp open     IIS
1050/tcp open     java-or-OTGfileshare
1720/tcp filtered H.323/Q.931
1723/tcp open     pptp
1755/tcp filtered wms
3268/tcp open     globalcatLDAP
3269/tcp open     globalcatLDAPssl
7070/tcp filtered realserver
8080/tcp open     http-proxy
8443/tcp open     https-alt
Nmap finished: 1 IP address (1 host up) scanned in 65.058 seconds

Windowsなのでスパムメールより主にプロクシとして日本から便利に活用されてるホストみたいです。

追跡を断念して今後の予防策を調べてみたところ、知ったのが2chで使っているDNS BlacklistのBBQです。

DNSBLはスパムメール対策としてよく使われるみたいですが、スパムメール対策としては効果は微妙なようです。ですが、BBSやコメントスパム対策にはかなり効果がありそうです。

荒らしの総本山といえる2chのデータを元にメンテナンスされているBBQのブラックリストは日本で使うには一番の品質なんじゃないでしょうか。実際、上記のプロクシのIPも登録されています。

実装の方は、Apacheで直接DNSBLを使えるモジュールもありますが、完全に弾くだけでなく、どこかに退避させたりしたいのでアプリの中から使いたいところです。PHPではPEARにNet_DNSBLというライブラリがあるみたいです。Rubyで見当たらなかったので作ってみたというわけです。

まだテストもなくしょぼいコードなので何かあったらご指摘(もしくはpush)いただければと思います。

参照:

mod_proxy_balancer + mongrel_clusterを使った時にこちら大変参考にさせてもらいましたー。

つくるぶガイドブログ: capistrano で本番環境にデプロイ

ただ、一点ハマッタところが。

config/deploy.rb抜粋。

set :mongrel_conf, "#{current_path}/config/mongrel_cluster.yml" # mongrel_cluster 設定ファイル
set :mongrel_clean, true # mongrel を再起動するとき、残ってしまったプロセスをクリアします

# If you aren't deploying to /u/apps/#{application} on the target
# servers (which is the default), you can specify the actual location
# via the :deploy_to variable:
# set :deploy_to, "/var/www/#{application}" 
# 本番環境のデプロイ先のパス。何も指定しない場合 /u/apps/[アプリ名] にデプロイされます

set :deploy_to ””foo/bar”” を設定したとき、設定してるのにデフォルトの場所にデプロイしようとしてハマッタ。

コード追ってみたら set :deploy_to ””foo/var”” で ””current_path”” が設定されるので set :mongrel_conf ””path/to”” は set :deploy の後に書かないと駄目だった。(この例ではデフォルトのまま使うので問題無いですが、コメントアウトを外して使うと動かない)

ハマって泣く人が減るようにトラックバック送っときます。

・・・なんか人生の大半ハマッてるように見えるな。(強く否定できないけど)

以前に所属していた会社であるワイズノットで「10分で作るRailsアプリ for Windows」でおなじみので増井さんによるrails講習会があるというメールを頂いて行ってきました。

rails講習会メモ

日本語化

  • ActiveHeart or GetText-Ruby(better)

DBの変更管理

  • Migration
  • rake migrate
  • rake migrate VERSION=3 (古い状態に戻せる)
  • rake remote:migrate (サーバでmigrate)

デプロイ管理

  • カピストラーノ capistrano (deploy管理) (元SwitchTower)
  • commandひとつでデプロイサーバ再起動
  • rake deploy
  • rake rollback

仕事で使う場合の障壁

  • Railsで作れる人がいない
  • デザイナはSmartyしかわからない(でも意外と問題無い)
    helperをなるべく使わないとか
  • 近々デザイナ向けRails本が出るらしい
  • DreamweaverのSmarty向けextentionとかもちょっと変えれば対応できる
  • サーバがRailsに対応してない
  • 安定して稼働できるか(やっぱりノウハウが必要)
  • lighttpd+FastCGIはlighttpdが結構固まる事がある(lighttpdは開発が停滞)
  • Apache2+mod_fcgid(経験無いが不安定らしい)
  • Apache1.3+mod_fastcgiがいまのとこ一番安定している(稼働実績も多い)
  • mod_rubyだと複数アプリが使えない(プロセス間でメモリが共有されちゃう)
  • mangrel+Apache2.2 mod_proxy_balancer(最近の定番)
  • 実際遅い(動的生成が超多い)
  • cachingをたくさん使う
  • それでも遅ければスケールアウトできる(mangrel+mod_proxyでスケールアウト)

質疑応答

  • Q: scafoldからどれぐらい書き換える?
    A: それほど書き換えない(完成コード自体短い)
  • Q: UnitTestはどのくらいの粒度でやるの?
    A: Controllerはテストし辛いのであんまり。seleniumでのテストに注力。
  • Q: 大人数での開発は?
    A: みんなせいぜい2?3人。
  • Q: DB設計で気を付ける点は? A: railsのサポート関数を考えたテーブル分割を考えたりします。
  • Q: rails対応レンタルサーバは?
    A: textdrivesが多い
    rubyはメモリ制限ができないので共有サーバで動かしずらい
  • Q: DBの定義はいつ取ってるの?
    A: productionモードでは起動時にメモリ上にキャッシュしてます。
  • Q: 帳票アプリ向き?
    A: PDF吐くやつはあるけど、気合いでどうにかする。

基本的な事項が聴けて凄く良かったです。やっぱりdeploy管理が気になります!

OKWebでの質問返ってこなかった…。

………よしッ!!!(リアクション間違い)

宣言通りしようがなくJavascriptのParser自分で書いた。

本当に泥臭いから覚悟しろ!

使い方:

&lt;html&gt;
&lt;head&gt;
&lt;script src="scripts/ObjTree.js" type="text/javascript"&gt;&lt;/script&gt;
&lt;script src="scripts/prototype.js" type="text/javascript"&gt;&lt;/script&gt;
&lt;script src="scripts/feed.js" type="text/javascript"&gt;&lt;/script&gt;
&lt;script language="javascript"&gt;
var url = 'http://d.hatena.ne.jp/m-komagata/rss';        // RSS1.0
//var url = 'http://d.hatena.ne.jp/m-komagata/rss2';   // RSS2.0
//var url = 'http://p0t.jp/mt/atom.xml';                     // Atom0.3
//var url = 'http://komagata.blogspot.com/atom.xml';  // Atom0.3

url = 'proxy.php?uri=' + url;
new Ajax.Request(url, {
  onComplete : function(req) {
    var feed = new Feed(req.responseText);
    feed.parse();
    var list = '';
    feed.getItems().each(function(item) {
      list += '&lt;h2&gt;' + item.title + '&lt;/h2&gt;';
      list += '&lt;p&gt;' + item.link + '&lt;/p&gt;';
      list += '&lt;p&gt;' + item.description + '&lt;/p&gt;';
      list += '&lt;p&gt;' + item.date + '&lt;/p&gt;';
    });
    Element.update('list', list);
  }
});
&lt;/script&gt;
&lt;/head&gt;

&lt;body&gt;
&lt;div id="list" &gt;&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;

パーサー:

var Feed = Class.create();
Feed.prototype = {
  initialize : function(data) {
    this.data = data
  },
  parse : function() {
    var xotree = new XML.ObjTree();
    var tree = xotree.parseXML(this.data);
    this.data = tree;

    var kind = this.getKind();
    eval('this.parser = new ' + kind);
    this.parser.data = this.data;
    this.parser.kind = kind;
  },
  getKind : function() {
    var kind;
    if (this.data['rdf:RDF'] &&
    this.data['rdf:RDF']['-xmlns'] == 'http://purl.org/rss/1.0/') {
      kind = 'RSS10';
    } else if (this.data['rss'] && this.data['rss']['-version'] == '2.0') {
      kind = 'RSS20';
    } else if (this.data['feed'] && this.data['feed']['-version'] == '0.3') {
      kind = 'Atom03';
    } else {
      kind = 'UnknownFeed';
    }
    return kind;
  },
  getTitle : function() {
    return this.parser.getTitle();
  },
  getLink : function() {
    return this.parser.getLink();
  },
  getItems : function() {
    return this.parser.getItems();
  },
  getJSON : function() {
    return {
      title : this.getTitle(),
      link : this.getLink(),
      items : this.getItems()
    };
  }
};

var RSS10 = Class.create();
RSS10.prototype = {
  initialize : function() {},
  getTitle : function() {
    return this.data['rdf:RDF'].channel.title;
  },
  getLink : function() {
    return this.data['rdf:RDF'].channel.link;
  },
  getItems : function() {
    var items = this.data['rdf:RDF'].item;
    var res = [];
    items.each(function(item) {
      item['date'] = item['date'] || item['dc:date'];
      res.push(item);
    });
    return res;
  }
};

var RSS20 = Class.create();
RSS20.prototype = {
  initialize : function() {},
  getTitle : function() {
    return this.data['rss'].channel.title;
  },
  getLink : function() {
    return this.data['rss'].channel.link;
  },
  getItems : function() {
    var items = this.data['rss'].channel.item;
    var res = [];
    items.each(function(item) {
      item['date'] = item['date'] || item['dc:date'] || item['pubDate'];
      res.push(item);
    });
    return res;
  }
};

var Atom03 = Class.create();
Atom03.prototype = {
  initialize : function() {},
  getTitle : function() {
    var title =  this.data['feed'].title;
    if (typeof(title) == 'string') {
      return title;
    } else {
      return title['#text'];
    }
  },
  getLink : function() {
    var link = this.data['feed'].link;
    var res = '';
    if (!link['-href']) {
      link.each(function(ln) {
        if (ln['-rel'] == 'alternate') {
          res = ln['-href'];
        }
      });
    } else {
      res = this.data['feed'].link['-href'];
    }
      return res;
  },
  getItems : function() {
    var items = this.data['feed'].entry;
    var res = [];
    items.each(function(item) {
      var title = item['title'] = item.title;
      if (typeof(title) == 'string') {
        item['title'] = title;
      } else {
        item['title'] = title['#text'];
      }
      item['date'] = item['date'] || item['dc:date'] || item['created'];
      if (typeof(item.link['-href']) != 'string') {
        item.link.each(function(ln) {
          if (ln['-rel'] == 'alternate') {
            item['link'] = ln['-href'];
          }
        });
      } else {
        item['link'] = item.link['-href'] || '';
      }

      if (typeof(item.content['#cdata-section']) == 'string') {
        item['description'] = item.content['#cdata-section'];
      } else {
        item['description'] = item.content.div['#text'];
      }
      res.push(item);
    });
    return res;
  }
};

proxy.phpのソース:

&lt;?php
require_once 'PHP/Compat/Function/file_get_contents.php';
echo @file_get_contents($_GET['uri']);
?&gt;

結果:

feed-result.png

相当泥臭い。大体のフィード読めてるけどいくつか取れないのも。あとでちゃんとRSS/Atomの仕様読んでちゃんとした方法で対応したい。本題のfavicon取る機能はまだ…。

XMLをJSONに変換してくれるXML.ObjTreeが必須。

PEAR :: PEPr :: Details :: HTTP_Client_Curl, HTTP_Request_Curl

>> Description Implementation of HTTP_Client and HTTP_Request that uses the curl extension to support HTTPS over HTTP proxy, which is currently not supported by HTTP_Client and HTTP_Request classes.

PEPrにDraftで~Curlが。 何でそんなにCurlを愛す?誰かおれにCurlの素晴らしさを説いて下さい。

今まで考えないようにしてきたPHP4と5の共存について、ちょっとだけ薄目開けて取り組んでみました。

とりあえず、何とかなりそうなCLI版の方のPHP4をインストール。(Debian etch)

colinux:~% sudo apt-get install php4-cli

PHP5もインストール。

colinux:~% sudo apt-get install php5-cli

pagerみたいにalternativesが使えれば簡単に切り替えられるはず。

colinux:~% sudo update-alternatives --display php
php - status is manual.
 link currently points to /usr/bin/php4
/usr/bin/php4 - priority 40
 slave php.1.gz: /usr/share/man/man1/php4.1.gz
/usr/bin/php5 - priority 50
 slave php.1.gz: /usr/share/man/man1/php5.1.gz
Current `best' version is /usr/bin/php5.

つかえた。

colinux:~% sudo update-alternatives --set php /usr/bin/php4
colinux:~% php -v
PHP 4.4.2-1 (cli) (built: Jan 18 2006 12:33:46)
Copyright (c) 1997-2006 The PHP Group
Zend Engine v1.3.0, Copyright (c) 1998-2004 Zend Technologies

CLIに関しては安心した。でもapacheモジュールの方は・・・?

mod_php4をインストール

colinux:~% sudo apt-get install libapache2-mod-php4

そしてmod_php5をインストール

colinux:~% sudo apt-get install libapache2-mod-php5
パッケージリストを読みこんでいます... 完了
依存関係ツリーを作成しています... 完了
<strong>以下のパッケージは「削除」されます:
  libapache2-mod-php4</strong>
以下のパッケージが新たにインストールされます:
  libapache2-mod-php5
アップグレード: 0 個、新規インストール: 1 個、削除: 1 個、保留: 1 個。
2341kB 中 0B のアーカイブを取得する必要があります。
展開後に追加で 2081kB のディスク容量が消費されます。
続行しますか [Y/n]?

えー削除かよー。 etchのapache2では各モジュールのconfが/etc/apache2/mods-availableディレクトリにはいって、/etc/apache2/mods-enabledディレクトリからそっちへシンボリックリンクを張ると有効になるって感じになってるらしい。

colinux:~% ls /etc/apache2
README        conf.d   httpd.conf  mods-available  ports.conf       sites-enabled
apache2.conf  envvars  magic       mods-enabled    sites-available  ssl
colinux:~% ls /etc/apache2/mods-available
actions.load      cgid.load        imap.load        <strong>php5.load</strong>           suexec.load
asis.load         dav.load         include.load     proxy.conf          unique_id.load
auth_anon.load    dav_fs.conf      info.load        proxy.load          userdir.conf
auth_dbm.load     dav_fs.load      ldap.load        proxy_connect.load  userdir.load
auth_digest.load  deflate.load     mem_cache.load   proxy_ftp.load      usertrack.load
auth_ldap.load    disk_cache.load  mime_magic.conf  proxy_http.load     vhost_alias.load
cache.load        expires.load     mime_magic.load  rewrite.load
cern_meta.load    ext_filter.load  <strong>php4.conf</strong>        speling.load
cgi.load          file_cache.load  <strong>php4.load</strong>        ssl.conf
cgid.conf         headers.load     <strong>php5.conf</strong>        ssl.load
colinux:~% ll /etc/apache2/mods-enabled
合計 0
lrwxr-xr-x  1 root root 36 2005-12-12 23:06 cgi.load -&gt; /etc/apache2/mods-available/cgi.load
<strong>lrwxr-xr-x  1 root root 37 2006-02-20 00:38 php5.conf -&gt; /etc/apache2/mods-available/php5.conf
lrwxr-xr-x  1 root root 37 2006-02-20 00:38 php5.load -&gt; /etc/apache2/mods-available/php5.load</strong>
lrwxr-xr-x  1 root root 40 2005-12-11 18:22 userdir.conf -&gt; /etc/apache2/mods-available/userdir.conf
lrwxr-xr-x  1 root root 40 2005-12-11 18:22 userdir.load -&gt; /etc/apache2/mods-available/userdir.load

自分の手でシンボリックリンク張ったり消したりするしかないのかな? なんか仕組みがありそうな気がする!