makoto_fujimotoのblog

株式会社進角
代表 藤本信のブログです
どうぞよろしくお願いします

お問合せフォームや独自のメール配信システムからメールを送った場合、相手に届かなかったり迷惑メールに振り分けられてしまうことがたまにあります。この様な不具合を回避するためのチェックポイントをまとめました。

  1. Fromのドメインが存在していて返信可能か
  2. メールヘッダにエンベロープFrom(Return-path)が正しく記述されているか
  3. エンベロープFromに記述したサーバが存在しているか
  4. そのドメインのDNSにMXレコードが記述されているか
  5. そのMXレコードに記述されているMTA(メールサーバ)にメールが到達可能か
  6. ドメインのDNSにSPFレコード(送信サーバのIPアドレスやネットワーク)が記述されているか
  7. 送信サーバのIPアドレスに逆引きDNSが定義されているか
  8. MTA(メールサーバ)の正引きDNSと逆引きDNSが一致しているか
  9. 送信サーバのIPアドレスがブラックリスト(Spamhaus等)に登録されていないか
  10. 送信サーバのIPアドレスにプライベートアドレスを使用していないか
  11. メール形式にHTMLやjavascriptを使用していないか
  12. メール形式にマルチパート(multipart/alternative)を使用していないか
  13. メール本文にリンクを多用していないか
  14. メール本文にSPAMによくあるキーワードが使用されていないか
  15. 共有サーバを使用していてIPアドレスが行儀の悪い他サイトと共通になっていないか

ステージングと本番系に分けた構成のWordpressサイトの同期手段としてwordmoveを使用していますが、しばらく運用していたところ、Webアクセスとは無関係にサーバ負荷が異常上昇する現象が発生しました。wordmoveの設定についてはこちらを参照。

accsess_logやtopコマンドで確認したところ、同期を実行してから間もなくしてサーバ自身からのHEADメソッドによるローカルリクエスト起きていることが判明し、その数なんと23万件以上ありました。ロードアベレージも20を超えサーバがパンクする事態となりまして、原因が分かるまでは対処療法として負荷を監視してhttpdを自動的に再起動するなどの応急処置でしのいでいました。

現象がpingバック機能に似ていたことからWP Total Hacksを始めいくつかのプラグインを試して禁止するように設定しましたが効果はありませんでした。

お手上げです。。

そこで、一時的にすべてのクエリーログを吐き出すように設定して調査したところ、負荷上昇時に気になるSQLが発行されていることが分かりました。それが以下のSQLです。
SELECT ID, post_content, meta_id FROM wp_posts, wp_postmeta WHERE wp_posts.ID = wp_postmeta.post_id AND wp_postmeta.meta_key = '_pingme' LIMIT 1
SELECT * FROM wp_postmeta WHERE meta_id = 22663
DELETE FROM `wp_postmeta` WHERE `meta_id` = 22663
SELECT pinged FROM wp_posts WHERE ID = 874
SELECT   wp_posts.* FROM wp_posts  WHERE 1=1  AND wp_posts.post_name = 'gaobijo-title_fuku-png' AND wp_posts.post_type = 'post'  ORDER BY wp_posts.post_date DESC
SELECT   wp_posts.* FROM wp_posts  WHERE 1=1  AND wp_posts.post_name = 'gaobijo-title_fuku-png' AND wp_posts.post_type = 'post'  ORDER BY wp_posts.post_date DESC
SELECT   wp_posts.* FROM wp_posts  WHERE 1=1  AND wp_posts.post_name = 'kumaayaka04-png' AND wp_posts.post_type = 'post'  ORDER BY wp_posts.post_date DESC

詳しくは分析していませんが、pingバックを禁止しているにも関わらずページ内のリンクをすべてパースして何か処理を行っているようです。そしてついにこの処理を行っていると思われるコードを発見しました。それがdo_all_pings()という関数です。この関数はwp-cron.phpという疑似バッチのトリガーから呼び出されるwp-include/default-filters.phpにてadd_actionでフックされています。同期の実行からしばらく経過してから異常が発生する現象ともつじつまが合います。
add_action( 'do_pings',    'do_all_pings',    10, 1 );

この部分をコメントアウトすることでやっと不可解な自ホストに対してのHEAD呼出し現象が止まりました。なおdefault-filters.phpはパッケージのアップデートなどにより更新されてしまうので、add_actionを無効化するスクリプトをプラグイン化して設置する方が良いそうです。以下サンプルphpです。

<?php
/*
Plugin Name: No Do Pings
Plugin URI:
Description: Remove Actions and Filters
Author: Makoto Fujimoto
Version: 1.00
Author URI:
*/
remove_action( 'do_pings', 'do_all_pings' );
?>
この様なPHPプログラムをwp-content/plugins/以下に設置して管理画面で有効化してください。

ffmpegで動画ファイルの詳細情報を取得する際にファイル名がSJISの場合ファイル指定に
難航したので解決策のメモ。

例えばWindows系ファイルシステムがマウントされたLinux系サーバでは日本語ファイル名や
フォルダ名が以下の様に文字化けしてしまうことがあります(1行目)。ファイル名は"コ ピー.mp4"

$ ls -l
-rw-rw-r--  1 fujimoto fujimoto 111044022 11月  9 16:46 2015 ?R ?s?[.mp4
-rw-rw-r--  1 fujimoto fujimoto 111044022 11月  9 16:46 2015 ああ あ.mp4
-rw-rw-r--  1 fujimoto fujimoto 111044022 11月  9 16:46 2015 あああ.mp4

これを以下の様にffmpegにコピペしても旨く行きません
$ ffmpeg -i  ?R ?s?[.mp4
$ ffmpeg -i  "?R ?s?[.mp4"
$ env LANG=ja_JP.SJIS ffmpeg -i "?R ?s?[.mp4"
ffmpeg version N-81489-ga37e6dd Copyright (c) 2000-2016 the FFmpeg developers
  built with gcc 4.4.7 (GCC) 20120313 (Red Hat 4.4.7-17)
  configuration: --enable-gpl --enable-nonfree --enable-libfdk_aac --enable-libx264
  libavutil      55. 29.100 / 55. 29.100
  libavcodec     57. 54.101 / 57. 54.101
  libavformat    57. 48.101 / 57. 48.101
  libavdevice    57.  0.102 / 57.  0.102
  libavfilter     6. 57.100 /  6. 57.100
  libswscale      4.  1.100 /  4.  1.100
  libswresample   2.  1.100 /  2.  1.100
  libpostproc    54.  0.100 / 54.  0.100
?R ?s?[.mp4: No such file or directory


なんとか直接ファイル名を渡す方法は無いものか・・・

ということでlsやfindで取得したファイル名をそのままffmpegに渡す方法でうまくいきました。
ただしリストの何番目という情報を最初に把握する必要があり、あまりスマートな方法では無いかもしれません。

カレント内のファイルの場合
$ ls -1
$ ffmpeg -i "`ls -1|sed -n 1p`"

カレント内のサブフォルダのファイルを指定する場合
$ find . -type f|grep mp4
$ ffmpeg -i "`find . -type f|grep mp4|sed -n 1p`"

動画情報の取得に成功した場合の結果
$ ffmpeg -i "`find . -type f|grep mp4|sed -n 8p`"
ffmpeg version N-81489-ga37e6dd Copyright (c) 2000-2016 the FFmpeg developers
  built with gcc 4.4.7 (GCC) 20120313 (Red Hat 4.4.7-17)
  configuration: --enable-gpl --enable-nonfree --enable-libfdk_aac --enable-libx264
  libavutil      55. 29.100 / 55. 29.100
  libavcodec     57. 54.101 / 57. 54.101
  libavformat    57. 48.101 / 57. 48.101
  libavdevice    57.  0.102 / 57.  0.102
  libavfilter     6. 57.100 /  6. 57.100
  libswscale      4.  1.100 /  4.  1.100
  libswresample   2.  1.100 /  2.  1.100
  libpostproc    54.  0.100 / 54.  0.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from './/Rs[.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 1
    compatible_brands: mp41mp42isom
    creation_time   : 2014-07-18T07:40:50.000000Z
  Duration: 00:00:44.08, start: 0.000000, bitrate: 20154 kb/s
    Stream #0:0(deu): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 2 kb/s (default)
    Metadata:
      creation_time   : 2014-07-18T07:40:50.000000Z
      handler_name    : Core Media Audio
    Stream #0:1(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709), 1920x1080, 20146 kb/s, SAR 1:1 DAR 16:9, 29.97 fps, 29.97 tbr, 30k tbn, 50 tbc (default)
    Metadata:
      creation_time   : 2014-07-18T07:40:50.000000Z
      handler_name    : Core Media Video
At least one output file must be specified

このページのトップヘ