まずお前は何者だ
中小企業のシステム担当平社員。前任者が家庭の事情からフル勤務できなくなり、なし崩しでシステム担当になったため、知識はほぼゼロの状態で毎回ギリギリの綱渡りをしています。
何をしたか
会社のメールシステムにブラウザから操作できるRoundcubeを使用していますが、この度Roundcubeの脆弱性が発表され、こりゃヤバイってんで更新することにしました。
更新作業についてはWebサービスのプロバイダ作成のマニュアルを参考に、Roundcube Ver.1.16.11への更新は大きな問題なく終了しました。ここまでは。
ぶっちゃけて言うとうちはZenlogicのホスティングサービスを利用しています。
何が起きたか
表面上は何も起きていませんでしたが、エラーログを眺めてみると今までパスワードを間違えてのログイン失敗くらいしか記録されていなかったログが大量の見知らぬエラーで流されていきます。どうやらメールを受信するたびに何らかのエラーが発生しているようです。
[19-Aug-2025 13:37:24 +0900]: <4coc6bmu> DB Error: [1] no such table: collected_addresses (SQL Query: SELECT * FROM "collected_addresses" WHERE "user_id" = '7' AND "type" = '2' AND ("email" LIKE 'hoge@hogehoge.hoge') ORDER BY "name" ASC, "email" ASC LIMIT 10) in /virtual/htdocs/www/roundcube/program/lib/Roundcube/rcube_db.php on line 577 (GET /roundcube/?_task=addressbook&_action=photo&_email=hoge%40hogehoge.hoge&_error=1&_bgcolor=transparent)
実際のエラーログを少し加工してありますが大体こんな感じ。どうも受信したメールの送信アドレスを記録する"collected_addresses"という名前のテーブルが無くて困ってるみたいですね(他人事)。
しかし、この時点で私にはデータベースに関する知識が全くないのでお手上げです。サービスプロバイダにも問い合わせてみましたが、メールシステムの導入まではサポートできるが、そこから先の各ソフトについてはサポートできないとのことでした。まあそうよね。
この時点で社員から不具合の報告などはなく、 「エラーは吐いてるけど、なんか動いてるからヨシッ!」 ということでおうちに帰りました。
翌日出社すると、やっぱりきてましたよ不具合報告。なんでも 「ブラウザ上で作っておいたメールの定型文が全て消え、新規作成もできない」 とのこと。急いでエラーログを確認すると、上記とほぼ同様のエラーでやはり定型文を記録するテーブルが無くて保存に失敗している様子。実害が出たことで動かざるを得なくなりました。
対処法の調査
サービスプロバイダ作成のRoundcubeのアップデートマニュアルでは、アップデート前に「sqlite.db」のバックアップを取って、アップデート後にバックアップから上書きするように指示があったので、この「sqlite.db」が肝であり、すべてのデータが記録されているデータベースファイルであることは間違いない。
こいつに該当する名前の「テーブル」を作成してあげれば解決しそうな気がする。
あとは同様のケースで悩んでいる憐れな子羊を検索して探すだけです。どうやら"collected_addresses"というテーブル名が重要そうなので"Roundcube collected_addresses"で検索すると出てくるじゃないですか1個目に。
この質問者はRoundcubeのバージョンを1.4から1.5.2に上げたところ、メールを受信するたびにこのエラーが出るようになったと。おんなじや!
この方はMariaDBを使っているみたいだけど、起きてることが一緒なら対処法も大して変わらんやろ。読み進めてみると対処法っぽいものが書かれてトピックが閉じられている!これだ!これで解決だ!
You need to update the DB schema.
DBスキーマを更新する必要があるやで。
DBスキーマ is 何?
まあ待て、途方に暮れるのは手を尽くしてから。その下に親切そうな人が補足してくれてるじゃないかよく読め。
For anyone else finding this via search engine, the procedure is in the UPGRADING file. At present, performing the update looks like this:
検索エンジンでこの情報を見つけた方のために、手順はUPGRADINGファイルに記載されています。現時点では、アップデートの実行手順は以下のとおりです。
root@roundcube:/usr/local/www/roundcube # ./bin/update.sh
What version are you upgrading from? Type '?' if you don't know.
?
Executing database schema update.
Updating database schema (2018021600)... [OK]
Updating database schema (2018122300)... [OK]
Updating database schema (2019092900)... [OK]
Updating database schema (2020020100)... [OK]
Updating database schema (2020020101)... [OK]
Updating database schema (2020091000)... [OK]
Updating database schema (2020122900)... [OK]
This instance of Roundcube is up-to-date.
Have fun!
よし来たこれだ。だが読んでも結局なんだかわからない。しかし、ヒントは確実に得られたぞ。
試行錯誤パート
Roundcubeのルートフォルダに「UPGRADING」というドキュメントを発見。読んでみると下の方に「SQLite database upgrade」って小見出しがあるじゃん。読もう。
Versions older than 0.9 were supporting SQLite v2 only. Newer versions require
database in v3 format. The best what you can do is to convert database file
to the new format using command line tools:
古いバージョンはSQLite v2で動いてたけど、新しいバージョンはv3やねん。v3仕様に変換せなあかんからコマンドラインで以下を実行してな
sqlite OLD.DB .dump | sqlite3 NEW.DB
ちょっと待ってコマンドラインとかやめてくれませんか聞いてないです怖いです。保留!
保留してよく考えたらうちの場合はプロバイダの指示に従って古いRoundcubeを全削除、まっさらなところに最新版をインストールして古いsqlite.dbを移植する形でアップデートしているので、多分この方法は使わない、と思う。
よく見たらその下にもうちょっと何か書いてあるね。
Other tools
In case you need to only update the database schema you can use updatedb.sh script.
For example, to update the Roundcube core database run:
データベーススキーマのみを更新する必要がある場合は、updatedb.sh スクリプトを使用できます。
例えば、Roundcube コアデータベースを更新するには、次のコマンドを実行します。
./bin/updatedb.sh --package=roundcube --dir=SQL
ちょっと待ってこれもコマンドラインでしょ。待ってくれ、サーバ上のディレクトリを指定とかできる気がしないんだ。ん、今 update the database schema って言わなかった? 気のせい?
まあまあ、とりあえず「bin」フォルダの「updatedb.sh」の中身を改めてみよう、実行ファイルっぽい雰囲気出してるけどテキストエディタで開けば中身読めるでしょ。最初に説明があるぞ。
PURPOSE:
Update database schema
これやん!
これやけど!
これをどうしたらええんや(泣)
手掛かり
一旦落ち着いて「updatedb.sh」を実行するコマンドをよく見ると、「SQL」っていうディレクトリで実行するっぽい。
「SQL」を開くとさらに「sqlite」って名前のディレクトリが。これじゃん。
このファイル名の感じ、10桁の数字! さっき上の方で見た! これやで!
解決へ
この明らかに日付っぽいファイル名、もしかして更新パッチのようなものなのでは?と雑に推理して、適当にファイルを開いて中身を拝見しましょうか。
そんでファイルを開いていくうちに見つけましたよ。
CREATE TABLE collected_addresses (
大当たり。核心にして確信ですよ。なにをって? 勝利を。
正直に申し上げるとここから先は10代からパソコンを弄ってきた経験と勘で動いたので根拠とか一切ないのですが、まずは「sqlite.db」の中身を確認するため窓の杜から「DB Browser for SQLite」をダウンロード。
インストールしてsqlite.dbを開いてみると、やっぱり"collected_addresses"なんてテーブルはないわね。
ここにさっきの日付っぽい名前の拡張子.sqlのファイルをドロップして実行したら勝ちでしょ!多分!
というわけで、もう一度冷静になってバックアップを取っておいた古いRoundcubeのsqliteフォルダを確認しますと「2014042900.sql」が最新のファイルのようです。11年もほっとかれてたんか。
それでは「2015030800.sql」以降最新までの15ファイルを「sqlite.db」に対して実行。"collected_addresses"他たくさんのテーブルが新たに作られたのを確認し、ドキドキしながらサーバの「sqlite.db」を上書きします。
勝ちました
やったぜ。
"collected_addresses"が増えています。ほかにも"filestore"と"responses"が増えてますね。"responses"は定型文が保存できない件のエラーで出てきていたテーブル名になります。
そして直後から1日に何百行も吐き出されていたエラーログが止まりました。
今回の対処の前でもRoundcubeに求める受信メールの閲覧とメールの送受信は問題なく行えており、「定型文? ローカルのメモ帳にでも書いとけ!」で解決だったところを「エラーログ垂れ流し気持ち悪い。許せん」という個人的な感情のみに突き動かされて解決にたどり着きました。
Zenlogicさんも「危ないからRoundcube更新せぇ!」ってアナウンスするなら「sqlite.dbも一緒にアップグレードしてな」くらいのことは教えてくれてもいいと思うの。まあ、それは多くを望み過ぎか。
何はともあれ、全然勉強しないシステム管理者が検索と勘だけを頼りに弄ったことのないデータベースを弄った記録が、誰かの役に立てばいいなと思って記録した次第です。疲れました。