Linuxサーバー構築・設定

apacheサーバーが突然の高負荷。Timeout時間などを短くしても改善しませんでした。

ACCESSログなどを見ても不審なアクセスはなし。

アクセス数の多いIPアドレスを調べてみました。(153.125から始まるIPは除外)

# awk '{print $1}' /var/log/apache2/access.log | grep -v '^153\.125\.' | sort | uniq -c | sort -nr | head

間近の計測をするためにアクセスログは新しくしました。

結果を見てみるとGoogle Cloudからのアクセス。2分ほどで4000回位のアクセスがあります。

サイトの情報をごっそり抜こうとしているのでしょうか。

該当IPをファイヤーウォールで遮断しました所、ロードアベレージが60超えていたのが、0.9まで落ち着きました。

さて、どうしましょうか・・

このIPが100%原因というわけでもないので、しばらくログを監視する必要があります。10分以内でアクセスの多いIPランキングの出し方。

awk -v d="$(date --date='10 minutes ago' '+%d/%b/%Y:%H:%M')" '
$0 ~ /^\[/ { next }  
{
    gsub(/^\[/, "", $4);
    if ($4 >= d && $1 !~ /^153\.125\./) print $1;
}' /var/log/apache2/access.log | sort | uniq -c | sort -nr | head

WordPress

WordPressの管理画面にログインしようとしても、ログイン画面が表示されずサイトのトップページにリダイレクトされてしまう問題。

最初、ログインURLを変更したのかもと考えましたが違いました。

htaccessを見てもリダイレクト的な記述なし。

原因は、kusanagiのキャッシュでした。以下でログインできるようになりました。

# bcacheを無効化(重要)
kusanagi bcache off ****

ログインできたら、以下で戻しておきます。

kusanagi bcache on ****

キャッシュ破損が原因なんだろうけど・・ここに行き着くまでに結構時間かかりました・・・

MYSQL

2025年~2026年(令和7年~令和8年)祝祭日(正月として、1/2~1/3)が含まれます。以下よりダウンロードいただけます。

2025年~2026年(令和7年~令和8年)祝祭日CSV

2025-01-01 元日
2025-01-02
2025-01-03
2025-01-13 成人の日
2025-02-11 建国記念の日
2025-02-23 天皇誕生日
2025-02-24 振替休日
2025-03-20 春分の日
2025-04-29 昭和の日
2025-05-03 憲法記念日
2025-05-04 みどりの日
2025-05-05 こどもの日
2025-05-06 振替休日
2025-07-21 海の日
2025-08-11 山の日
2025-09-15 敬老の日
2025-09-23 秋分の日
2025-10-13 スポーツの日
2025-11-03 文化の日
2025-11-23 勤労感謝の日
2025-11-24 振替休日
2026-01-01 元日
2026-01-02
2026-01-03
2026-01-12 成人の日
2026-02-11 建国記念の日
2026-02-23 天皇誕生日
2026-03-20 春分の日
2026-04-29 昭和の日
2026-05-03 憲法記念日
2026-05-04 みどりの日
2026-05-05 こどもの日
2026-05-06 振替休日
2026-07-20 海の日
2026-08-11 山の日
2026-09-21 敬老の日
2026-09-23 秋分の日
2026-10-12 スポーツの日
2026-11-03 文化の日
2026-11-23 勤労感謝の日

Apache,nginx

ModPagespeedはウェブサイトのレスポンスを改善するのですが、ModPagespeedを無効化したいディレクトリやファイルが出てきます。

例えば、PhpmyadminはModPagespeedの影響で正常に動作しなくなります。

ModPagespeedを無効化したいディレクトリがある場合は.htaccessに以下を追記。

ModPagespeed off

これだけで、.htaccess配下のディレクトリ全体がModPagespeedが無効化されます。

また、特定のファイルのみ無効化したい場合は以下。

https://www.example.co.jp/?ModPagespeed=off

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のカスタム・シグネチャのダウンロード/アップロードの機能を利用しました。

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

MYSQL,WordPress

WP-Optimizeのキャッシュを使っていたのですが、KUSANAGIのbcacheでも同じなのでは・・と戻したところ、サイトが表示されなくなりました。

wp_site_cache' doesn't exist in**

のようにWordPressエラーが出てサイトが表示されません。

wp_site_cacheテーブルが無くなってしまったことが原因。

以下のようにwp_site_cacheテーブルを作って解決。

mysql -u root -p 「データベース名」
create table wp_site_cache (hash varchar(32),
    content longtext,
    device_url text,
    type varchar(20) NOT NULL,
    post_type varchar(200),
    headers text,
    user_agent text,
    server varchar(16),
    updating tinyint(1) DEFAULT 0,
    create_time datetime,
    expire_time datetime
);
create index sc_hash on wp_site_cache(hash);
create index sc_type on wp_site_cache(type);
create index sc_updating on wp_site_cache(updating);
create index sc_expire on wp_site_cache(expire_time);

Postfix

レジットカード・Amazonなどを装ったスパムメールの特徴

最近、クレジットカードやAmazonなどのネットショップを装ったスパムメールがとても多いです。

拝啓、

Amazonプライムをご利用いただき、誠にありがとうございます。この度、お客様のAmazonプライム会費のお支払い方法に問題が発生していることをお知らせいたします。

お客様のAmazonプライム会費は、過去数ヶ月にわたってご登録いただいたクレジットカードの情報によりお支払いいただいておりました。しかしながら、最近弊社のシステム上において、お客様のクレジットカード情報が正常に反映されていなかったため、会費のお支払いができていなかったことが判明いたしました。

このままでは、お客様のAmazonプライム会員資格が停止され、プライム会員特典のご利用ができなくなる恐れがございます。誠に申し訳ございませんが、早急にお支払い手続きをお願いいたします。

お支払い方法につきましては、以下の手順に従っていただきますようお願い申し上げます

※本メールは重要なお知らせのため、メールを受け取らない設定をされている方にも。
Аmazon に登録いただいたお客様に、Аmazon アカウントの情報更新をお届けします。
残念ながら、Аmazon のアカウントを更新できませんでした。
今回は、カードが期限切れになってるか、請求先住所が変更されたなど、さまざまな理由でカードの情報を更新できませんでした。
お客様のアカウントを維持するため Аmazon アカウントの 情報を確認する必要があります。下からアカウントをログインし、情報を更新してください。

三井住友カードをご利用のお客様へ
このたびは三井住友カードをご利用いただき、誠にありがとうございます。
下記のご利用照会がございましたので、お知らせいたします。
※本メールは、ご利用・請求を確定するものではありません。
ご利用日時:2024/06/03 23:50
ご利用場所:ヤマダデンキ掛川店
ご利用金額:8, 060円
カードを使用した覚えがない場合は、以下 の リ ン ク をクリ ッ ク し てカ ー ド使用の詳細を確認してください。
ご本人様の確認はこちらへ

上記のように身に覚えのないメールで有り得そうなので思わず本文中のURLをクリックしそうになります。

PCからでしたらメールのソースを開いて確認できるのですが、スマートフォンからですとそうも行きません。

スパムメールの特徴

該当するスパムメールの特徴を調べました。

IPアドレスは毎回変わる

まず、IPアドレスで個別に拒否しようと考えました。しかし、リストにするには骨の折れる作業です。どうやら送信元IPアドレスは無限にあるようです。

IPアドレスなどでの個別の拒否は現実的ではないと考えました。

逆引きの出来ないIPからの送信が多い

該当スパムメールの特徴として逆引きが出来ないメールアドレスからメール送信していることがわかりました。

逆引きの出来ないIPアドレスからのメールを拒否

Postfixの設定

上記のようなスパムメール対策として逆引きの出来ないIPアドレスからのメールは拒否するよう以下のように設定しました。

/etc/postfix/main.cf

smtpd_client_restrictions =
    permit_mynetworks,
+   reject_unknown_client,
    permit

上記を設定するだけでかなりの数のメールを拒否してくれているようです。

Swatchの設定

Postfixのみでも良いとは思うのですが、こういうスパムメールを大量に送りつけてくるようなIPアドレスは遮断してしまいたいです。

そこで、Swatchに以下の記述も追記しました。

watchfor /postfix\/smtpd.*SASL .* connect from unknown/
    pipe "/usr/local/bin/swatch_action.sh '\\\\[|\\\\]' 4"
    threshold track_by=/postfix\/smtpd.*SASL .* authentication failed:/,type=threshold,count=10,seconds=10