最近WordPress へのコメントとトラックバックスパムが酷くなってきました。URL が含まれている物は承認が必要なようにしているのですが面倒です。このときにスパムはスパムだと手動で振り分けをしているので振り分けたものからIP を抜き出してアクセス制限を掛けるとましにならないかと設定してみました。
データベースから該当IP を抜き出す
MySQL からスパムを指定したIP の一覧は以下のようにして取得出来そうです。
$ cat /etc/wordpress/spamcommentip.sql
SELECT comment_author_IP FROM wordpress.wp_comments WHERE comment_approved='spam'
$ /usr/bin/mysql -umy -p < /etc/wordpress/spamcommentip.sql | /usr/bin/sort -n | /usr/bin/uniq -c| sort -n|cut -c-7|uniq -c
81 1
31 2
26 3
12 4
8 5
9 6
4 7
9 8
1 9
1 10
3 11
2 12
3 13
1 14
1 15
1 18
4 20
1 22
1 23
1 24
1 26
1 43
1 82
1 119
1 146
1 394
自動化したいので、MySQL にアクセスする為のMySQL の設定ファイルと、IP を抜き出すsqlファイルを用意します。
-
MySQL アクセスの為の設定ファイル
$ cd /etc/wordpress $ umask 077 $ sudo touch .my.conf $ sudo chown www-data.root .my.conf $ vi .my.conf cat .my.conf user=wp password=XXXXXXXXXXXXXX database=wordpress
-
IP を抜き出す為のsqlファイル
$ sudo vi /etc/wordpress/spamcommentip.sql $ cat $ cat /etc/wordpress/spamcommentip.sql SELECT comment_author_IP FROM wordpress.wp_comments WHERE comment_approved='spam'
以下のようにしてIP の一覧が取得出来るようになりました。
$ /usr/bin/mysql --defaults-file=/etc/wordpress/.my.conf < /etc/wordpress/spamcommentip.sql
apache httpd の .htaccess で指定IPアドレスからの WordPress のコメント投稿とトラックバックを制限
Debian のパッケージで WordPress を導入しているので導入パスは /usr/share/wordpress/
です。
設定ファイルは /etc/wordpress
以下です。/usr/share/wordpress/.htaccess
は /etc/wordpress/htaccess
のシンボリックリンクになっています。
アクセス制限をするには .htaccess
に deny from ip address
な感じで行けます。
さっきのIPの一覧取得時に並べ替えて同一IPをまとめて頭にdeny from
を付けるようにします。
$ /usr/bin/mysql --defaults-file=/etc/wordpress/.my.conf < /etc/wordpress/spamcommentip.sql | /usr/bin/sort -n | /usr/bin/uniq | /bin/grep -v 'comment_author_IP' | /bin/sed "s/^/ deny from /"
あまり無いと思いますが、正しいIP アドレスを登録してしまっても本文が読めるようにコメントやトラックバックだけ制限しようと思います。コメント、トラックバックは次のwp-comments-post.php / wp-trackback.php
を利用するようなのでこのファイルへのアクセスを制限します。.htaccess
の Files ディレクティブを利用して以下ような感じでいけそうです。
<Files ~ wp-comments-post.php|wp-trackback.php>
deny from ip address
</Files>
動作確認は自分のIPアドレスを一時的に登録して行いました。blog本文にはアクセス出来てコメントURL は拒否されています。
% w3m -dump_head https://matoken.org/blog/blog/2015/06/09/facebook-pgp/|head -1
HTTP/1.0 200 OK
% w3m -dump_head https://matoken.org/blog/wp-comments-post.php|head -1
HTTP/1.1 403 Forbidden
cron を使って自動的に更新するようにする
IP list は外部ファイルにして読み込むようにすると便利そうですが、Include ディレクティブは .htaccess
からは利用出来無いようなので分割ファイルを作って連結することにします。
- /etc/wordpress/htaccess_base
- 元のhtaccess
- /etc/wordpress/htaccess_spamhead
- Files ディレクティブの先頭
- /etc/wordpress/htaccess_spamiplist
- データベースから抜き出して作成した拒否IPリスト
- /etc/wordpress/htaccess_spamtail
- Files ディレクティブの末尾
- /etc/wordpress/htaccess
- 最終的に結合されて.htaccess のリンク元になるファイル
htaccess_base / htaccess_spamhead / htaccess_spamtail を用意します。
$ sudo cp -p /etc/wordpress/htaccess /etc/wordpress/htaccess_base
$ sudo sh -c "echo '<Files ~ wp-trackback.php|wp-comments-post.php>' > /etc/wordpress/htaccess_spamhead"
$ sudo sh -c "echo '</Files>' > /etc/wordpress/htaccess_spamtail"
htaccess_spamiplist / htaccess はcron で1時間毎に作成するようにします。
$ sudo -u www-data crontab -e
$ sudo -u www-data crontab -l
14 * * * * /usr/bin/mysql --defaults-file=/etc/wordpress/.my.conf < /etc/wordpress/spamcommentip.sql | /usr/bin/sort -n | /usr/bin/uniq | /bin/grep -v 'comment_author_IP' | /bin/sed "s/^/ deny from /" > /etc/wordpress/htaccess_spamiplist && /bin/cat /etc/wordpress/htaccess-base /etc/wordpress/htaccess_spamhead /etc/wordpress/htaccess_spamiplist /etc/wordpress/htaccess_spamtail > /etc/wordpress/htaccess
これで1時間毎にWordPress 上でspam と判定したコメント/トラックバックの送信元IP からコメント/トラックバックを拒否するようになりました。
うまくいくといいのですが……。
追記)
設定して数日経ちましたが,spam激減しました!