Linuxサーバー構築・設定,PHP

PHPでmb_strposを使い、XMLフィードから特定の文字列を抽出するコードを書きました。

こちらは、早朝にCronで自動で実行するものです。

手動(コマンド)で実行は問題なし

手動(コマンド)で実行すると期待通りの結果が出てきます。問題なさそうです。

Cronで実行すると失敗が多い

手動(コマンド)で実行すると期待通りの結果になるのに、Cronでは何故かmb_strposで抽出できていない文字列が多数出てきました。

文字コードを明示的に指定する必要がある

サーバーの内部はUTF-8ですし、PHPのソースコードもXMLフィードもUTF-8なので明示的に指定する必要など無いと思っていましたが、Cronなどで実行する場合は指定する必要があるようです。

PHPソースコードで指定

まず、PHPソースコードの上の方に以下を記載しました。

mb_internal_encoding("UTF-8");

このPHPはブラウザからアクセスして実行するのではなく、Cronで実行したいので.htaccessではなくPHPソース内に上記を記載しました。

しかし、Cronで実行すると抽出漏れが発生しています。

次に、mb_strposでも文字コードを指定しました。

mb_strpos(抽出したい文字列, "対象となる文字列", 0, "UTF-8")

これでも駄目です。Cron実行すると同様に抽出漏れが置きます。

正解はCronで文字コードを指定

結果、Cronを記述する時に以下のようにすることで解決しました。

01 9 * * * export LANG="UTF-8"; /usr/bin/php /home/*********.php

なぜCronでは上記のように文字コード指定しないと行けないのかは不明ですが、上記のようにCronで文字コードを指定することで無事解決しました。

Linuxサーバー構築・設定

SiteGuardとSwatchの連携

SiteGuardなどのWAFは不正なアクセスを事前に防いでくれて本当に助かります。

しかし、SiteGuardではアクセス毎の拒否のため、同一IPから同じようなアタックを受けることが少なくありません。

サーバー1台あたり1日数千件のログが残ります。

そのようなIPからのアクセスが、他でまともなアクセスであるわけはないと考えました。

SiteGuardで拒否したログは以下にあります。

/opt/jp-secure/siteguardlite/logs/http/detect.log
/opt/jp-secure/siteguardlite/logs/http/form.log

上記ログファイルをSwatchで読み、iptablesで全てDROPするようにしました。

swatchの設定ファイルは以下の2つ

# logfile /opt/jp-secure/siteguardlite/logs/http/form.log

watchfor /http/
pipe "/usr/local/bin/swatch_action.sh ' ' 3"
threshold track_by=/sshd.*Failed password for invalid user/,type=limit,count=3,seconds=10
# logfile /opt/jp-secure/siteguardlite/logs/http/detect.log

watchfor /http/
pipe "/usr/local/bin/swatch_action.sh ' ' 3"
threshold track_by=/sshd.*Failed password for invalid user/,type=limit,count=3,seconds=10

GoogleのBOTのIPを許可リストへ

上記の設定をしていると、GoogleBOTまで遮断していることが分かりました。

Googleには悪意はない事は明らかですが、何かから辿ってアクセスしてほしくないファイルを読みに着ているようです。

そこで、SiteGuardにGoogleのBOTのIPをホワイトリストとして設定しました。

Linuxサーバー構築・設定

自社サイトでさくらインターネットのVPS(メモリー1GB)を利用していましたが、レコード数の多いクエリーが遅くなってきました。

さくらインターネットにはスケールアップという機能があるので試してみました。

1GB→2GBへのスケールアップです。

  1. サーバーをシャットダウン
  2. コンパネよりスケールアップへ進み2GBプランを選択
  3. 15分後コンパネ右下が「完了しました」になる
  4. サーバー起動

早い時間だと5分位で終わったという記事を読みました。さくらインターネットの案内では30分~1時間ほどかかると書いてあります。

5分と1時間では大きく変わるのですが、サービスを止める必要があるので1時間は見ておいたほうが良さそうです。

私がスケールアップをした時間は土曜の13:30です。スケールアップが完了するまでに15分ほどかかりました。

スケールアップ後
仮想2Core仮想3Core
1GBメモリー2GBメモリー
SSD 100GBSSD 100GB

スケールアップ前から何かのキャンペーン中だったのかSSD100GBでした。

こちらもし容量が大きくなる場合は自分で容量を拡張する必要があります。

Linuxサーバー構築・設定

SiteGuardはとても頼りになるWAFですが、Googleには許可したい場合があると思います。

私の場合は、SiteGuardで遮断したIPアドレスはSwatchで一定期間DROPします。

GoogleのBOTが一定期間DROPされると何かと問題なのでGoogleのIPだけはSiteGuardでは安全(Accept)にしたいところです。

GoogleBOTのIPアドレスを調べてみたところかなりの数がありました。

それらをSiteGuardのカスタム・シグネチャにコピペしていく作業はとても疲れます。

そこで、SiteGuardのカスタム・シグネチャのダウンロード/アップロードの機能を利用しました。

まず、現在の設定をダウンロードし下記を追記してからアップロード。一瞬で追記されました。

Linuxサーバー構築・設定,PHP

550-5.1.1 The email account that you tried to reach does not exist. Please try 550-5.1.1

メールアドレスは正しいのにGmailから「550-5.1.1 The email account that you tried to reach does not exist. Please try 550-5.1.1」というエラーメールが返ってくることがあります。

他のメールアカウントから送信すると正常に送信されます。

SPFやDKIMの設定はされているのになぜ?となりましたが、以下が原因でした。

メール本文に問題あり

メール本文内に区切りのために「——–」「=======」などを多用すると上記のようにエラーが返ってくることが分かりました。

上記をなくすと無事エラーメールにはならなくなりました。

恐らくスパムメールのような扱いになってしまうんですね。

Linuxサーバー構築・設定

ログファイルなどlogrotaleで古いファイルが削除されてくれればよいのですが、何故か削除されずにずっと残りHDDを使い切ってしまうことがあります。

logrotaleの設定などをしっかり見直せば良いのですが時間が許さなかったりします。

また、PHPなどが生成するファイルやアップロードした画像ファイルなどでも同様可と思います。

そういう時に、一定期間経過したファイルを削除するコマンドを使います。

find /ディレクトリパス/ -name '*.log' -daystart -mtime +4  -delete

上記は4日経過したファイルを削除します。

Linuxサーバー構築・設定

例えば/homeディレクトリ内のディレクトリで容量を食っているディレクトリがあるとします。一つづつディレクトリを見ていくのは面倒です。

# du -s /home/* | sort -rn | head -10

上記コマンドで使用量の多い順に表示されます。

Linuxサーバー構築・設定,Postfix

たくさんのメールアカウントを作成して、転送先をリスト出力したいときは以下の作業。

# cd /home/
# more ./*/.forward >> /root/hogehoge.txt

Linuxサーバー構築・設定

ディレクトリ内の特定のLinuxユーザー権限のファイルを探したいときには以下(例:nobody)

find /home/ -user nobody

Linuxサーバー構築・設定

ディレクトリ内のファイルを一括削除したいのに、

bash: /bin/rm: Argument list too long

と怒られる場合があります。ファイル数が多すぎて削除できない!というエラーです。そういうときには以下。

echo *.html | xargs rm

.htmlのファイルを一括で削除したい時の例です。