記事の公開やプラグインのインストール、PHPのエラーなどをログとして保存するWordPressプラグインを作った

久しぶりにWordPressの公式ディレクトリにプラグインを公開しました。

https://wordpress.org/plugins/logbook/

GitHubリポジトリは以下のURLです。

https://github.com/tarosky/logbook

このプラグインは、ユーザーの様々な操作やアクティビティをログとして保存し確認できるようにするためのプラグインです。

特徴

  • ログを保存するプラグインは他にもいくつかありますが、このプラグインはいくつかの工夫(後述)によりサイトのパフォーマンスにほとんど影響を与えません。
  • 悪用されることが多いXML-RPCによるログインや記事の書き換え等を監視しており、警告として表示します。
  • ユニットテストをしっかりとやっておりエンタープライズ向けのサイトでも安心して利用できます。
  • ログを保存する機能は拡張可能であり、たとえばWooCommerce等の売り上げ等の独自のログを保存するアドオンを開発しやすくなっています。(公式なアドオンを随時追加予定)
  • WP-CLI に対応しており、コマンドラインでログを表示することができます。
  • Rest APIを装備しており遠隔監視が可能です。(Rest APIでの閲覧にはアクセストークンが必要)
  • PHPのエラーをログとして保存しており、テーマ側であれば Fatal Error(画面が真っ白になるエラー)も検出します。

ログとして保存する項目

  • WordPress
    • 本体のアップデート
    • プラグインの有効化及びアップデート
    • テーマの切り替え及びアップデート
  • 投稿、固定ページ、添付ファイルの公開、アップデート、削除
  • ユーザーのログイン
  • XML-RPCによる認証が必要なすべての操作

パフォーマンスについて

ログを保存するための多くのプラグインは、多様なニーズに応えるために無駄に多くのイベントをログとして保存しようとします。一方でこのプラグインは細かいユースケースに対してはアドオンを想定しており、ログを保存するためのイベントが最適化されており、一般ユーザーがサイトを閲覧する際のパフォーマンスに対するインパクトはほとんどありません。

また、WordPressのshutdown(PHPのregister_shutdown_function())イベントでまとめてログを保存する仕組みになっており、これはユーザーに対してコンテンツが出力された後に発火しますので、サイトの表示速度に対する悪影響がほとんどありません。

XML-RPCについて

非常に多くの場合、ブルートフォースアタックはWordPressのログイン画面に向けてではなく、xmlrpc.phpに対して行われます。

このプラグインを有効化するとxmlrpc.phpを使用した記事の書き換えを検出し、警告として表示します。

WP-CLIへの対応

独自のWP-CLIコマンドを持っており、このプラグインを有効化したサイトでは、以下のコマンドでログを取得できます。

$ wp log list
+--------------------------+------------------------------+-------+--------------+-------+
| date                     | log                          | level | ip           | login |
+--------------------------+------------------------------+-------+--------------+-------+
| 2017-11-14 18:14:43      | XML-RPC user was authenticat | warn  | 192.168.55.1 | admin |
|                          | ed.                          |       |              |       |
| 2017-11-14 18:14:43      | #1717 "Hello World!" was pub | warn  | 192.168.55.1 | admin |
|                          | lished.                      |       |              |       |
| 2017-11-14 16:18:45      | #1176 "Markup: Text Alignmen | info  | 192.168.55.1 | admin |
|                          | t" was updated.              |       |              |       |
| 2017-11-14 16:17:59      | #1178 "Markup: HTML Tags and | info  | 192.168.55.1 | admin |
|                          |  Formatting" was updated.    |       |              |       |
| 2017-11-14 14:58:29      | Plugin "user-switching/user- | info  | 192.168.55.1 | admin |
|                          | switching.php" was activated |       |              |       |
|                          | .                            |       |              |       |
| 2017-11-14 11:12:14      | WordPress was updated to 5.0 | info  | 127.0.0.1    |       |
|                          | -alpha-42173.5.0-alpha-42173 |       |              |       |
|                          | .                            |       |              |       |
| 2017-11-14 11:12:14      | Languages were updated.      | info  | 127.0.0.1    |       |
+--------------------------+------------------------------+-------+--------------+-------+

またフィルター機能を使用してログを抽出することができます。

$ wp log list --level=warn
+--------------------------+------------------------------+-------+--------------+-------+
| date                     | log                          | level | ip           | login |
+--------------------------+------------------------------+-------+--------------+-------+
| 2017-11-14 18:14:43      | XML-RPC user was authenticat | warn  | 192.168.55.1 | admin |
|                          | ed.                          |       |              |       |
| 2017-11-14 18:14:43      | #1717 "Hello World!" was pub | warn  | 192.168.55.1 | admin |
|                          | lished.                      |       |              |       |
+--------------------------+------------------------------+-------+--------------+-------+

JSONで出力することも可能です。

$ wp log list --level=warn --format=json | jq .
[
  {
    "date": "2017-11-14 18:14:43",
    "log": "XML-RPC user was authenticated.",
    "level": "warn",
    "ip": "192.168.55.1",
    "login": "admin"
  },
  {
    "date": "2017-11-14 18:14:43",
    "log": "#1717 \"Hello World!\" was published.",
    "level": "warn",
    "ip": "192.168.55.1",
    "login": "admin"
  }
]

ログの詳細画面について

各ログには詳細画面もあり具体的に何が行われたかを確認することができます。

たとえば、記事をアップデートした時にはその差分を見ることができます。

WP-CLIで操作が行われた場合は、そのコマンドも表示されます。

PHPのエラーがあった場合にはその行も表示します。

WarningやNoticeはデフォルトではログに残しませんが、デバッグモードを有効化するとそれらも保存しますので、開発環境にいれておくと便利です。

Rest APIについて

このプラグインはデフォルトでRest APIを内蔵しており、ログの一覧をRest API経由で取得することも可能です。

ログの閲覧にはアクセストークンが必要で、これは管理画面で生成することができます。

このアクセストークンを使用してログを閲覧するには、以下のようにリクエストヘッダーでトークンを指定してください。

$ curl http://example.com/wp-json/logbook/v1/logs -H "X-LogBook-API-Token: <your-access-token>"

複数サイトを管理している場合にAPIを使用して集中管理することを想定しており、そのためのダッシュボードも現在開発中です。

今後追加するかもしれない機能

  • ユーザー登録やパスワードの変更などのユーザーのアクティビティ
  • メールの送信
  • テーマカスタマイザーによる操作

アドオンについて

以下のアドオンを順次リリースしていきます。場合によっては本体に組み込むかもしれません。

  • WooCommerceの売り上げ
  • Contact Form 7などのメールの受付などの各種サードパーティプラグインと連携したアドオン
  • ログのデスクトップ通知
  • WordPress本体のRest APIでの記事等の操作をログとして保存するアドオン