Archive for category サーバー

Qmail Tips: 存在しない宛先に届いたスパムメールを一括削除

運用ドメイン名の不特定多数のランダムなメールアドレスにスパムメールが送信されてくることがあります。

MTAがPostfixであれば、不適切な宛先に送信されてきたメールに対しては、即座にエラーを返すので、キューにそのスパムメールが蓄積されることはありません。一方で、MTAとしてQmailを使っている場合には、宛先ドメイン名が正しければ、そのメールが受信され、ローカル配送用キューに格納後に受信者への配送処理が行われます。

そのローカル配送の過程で初めて、その受信者メールボックスが存在するか否かが分かり、存在しなければ、送信者にエラーを返すことになり、そのエラーメールは、リモート配送用キューに格納されます。

大量の存在しない宛先へのメールを受信すると、Qmailが生成するエラーメールによって、リモートキューが一気に膨れ上がります。また、スパムは送信元メールアドレスが詐称されるのが、常ですから、キューのメールは捌けずに長時間滞留し続けることがあります。

そうなると正規ユーザーが当該サーバーから、メール送信をしようとしても、リモートキューのメールが多すぎて、メールが遅延する事象が起こります。

キューには、次のようなエラーメールが溜まることになります。

From: postmaster@mail.example.com
To: info@spammer.example.com
Subject: failure notice

Hi. This is the qmail-send program at mail.example.com.
I'm afraid I wasn't able to deliver your message to the following addresses.
This is a permanent error; I've given up. Sorry it didn't work out.

<hogehoge@mail.example.com>:
Sorry, no mailbox here by that name. (#5.1.1)

これは宛先「hogehoge@mail.example.com」にメールが送られてきたものの、この宛先が存在しないため、送信者である「info@spammer.example.com」に返送しようと生成されたエラーメールのサンプルです。

この「hogehoge」の部分が、ランダムとなっているエラーメールが、リモートキューに大量に溜まるので、それを一括削除することによって、メールの配送遅延を解消させます。エラーメールの一括削除は、次の手順で行います。

キューに溜まっているメール数の確認(Before)

qmHandle が入っていない場合の確認方法。

# find /var/qmail/queue/local -type f | wc -l
10
# find /var/qmail/queue/remote -type f | wc -l
2035

qmHandle が入っている場合は、次の方法で確認できます。
※qmHandle は、qmailに標準添付されないので、別途インストールが必要です。

# qmHandle -s
Messages in local queue: 10
Messages in remote queue: 2035

宛先不明のエラーメールのリストを生成する

# find /var/qmail/queue/mess -type f -exec egrep -l '^Sorry, no mailbox here by that name.' {} \; > /tmp/spam.queue

または

# find /var/qmail/queue/mess -type f -exec egrep -l '^<.*@mail.example.com>:' {} \; > /tmp/spam.queue

エラーメール(スパムメール)の一括削除

エラーメールの抽出が完了したら、Qmailのプロセスを停止してから、そのメールを削除します。次の例では、10通ずつ削除を行っています。

# cat /tmp/spam.queue | xargs -n10 rm

queue-fix によるキューの修復

削除後は、キューの整合性を修復するために queue-fix を実行します。
※queue-fix は、qmailに標準添付されないので、別途インストールが必要です。

# queue-fix -i /var/qmail/queue

キューに溜まっているメール数の確認(After)

キューの修復後に Qmailを起動し、溜まっているメール数を確認します。

# find /var/qmail/queue/local -type f | wc -l
10
# find /var/qmail/queue/remote -type f | wc -l
39

qmHandleがある場合。

# qmHandle  -s
Messages in local queue: 10
Messages in remote queue: 39

リモートキューから、約2,000通のエラーメールが削除されました。

なお、不特定多数の宛先に送信されてくるスパムメールが、一向に止む気配がないなど場合によっては、存在しない宛先に届いたメールを受信直後に削除する方法を取ることもあります。

Qmailの設定によりますが、.qmail-default などの然るべきファイルに /dev/null と書いておくことで、受信メールは削除され、エラーメールを返すことはなくなります。リモートキューにエラーメールが溜まる事象を抑えることができます。

ソフトウェア配布サイト

No Comments

Linux Tips: findで見つけたファイルへのコマンド一括実行

ファイル検索コマンド find を使って、マッチしたファイルやディレクトリに対して、一括して何かコマンドを実行したい場合、オプション(-exec)を使って、それを実現することができます。

以下は、一例ですが、CentOS-5.x(Linux)では、マニュアルの「EXAMPLES」セクションに様々な実行例が紹介されています。

特定パターンのファイルの行数を数える

ファイル名の末尾が「log」または「1桁の数字」で終わるファイルを対象に wc コマンドで行数をカウントします。

$ find /var/log/ -type f \( -name "*log" -or -name "*.[0-9]" \) -exec wc -l {} \;
1643 /var/log/messages.2
368 /var/log/messages.1
2 /var/log/httpd/access_log
2882 /var/log/httpd/error_log

特定パターンのファイルについて、ファイルサイズを調べる

ファイル名の末尾が「log」または「1桁の数字」で終わるファイルを対象に du コマンドでサイズを表示します。

$ find /var/log/ -type f \( -name "*log" -or -name "*.[0-9]" \) -exec du -h {} \;
128K    /var/log/messages.2
28K     /var/log/messages.1
4.0K    /var/log/httpd/access_log
344K    /var/log/httpd/error_log

特定パターンのファイルを一括して圧縮

Linuxのログ世代管理ツール「logrotate」は、デフォルトでログを圧縮しない設定(nocompress)になっており、それを圧縮する設定(compress)に変えたいケースがあります。その場合、既存のログファイルを次のコマンドを使って一括して圧縮することができます。

該当ファイルの一覧表示。

$ find /var/log -type f -name "*.[0-9]"
/var/log/messages.1
/var/log/messages.2
/var/log/httpd/access_log.1
/var/log/httpd/access_log.2
/var/log/httpd/error_log.1
/var/log/httpd/error_log.2

圧縮処理の実行。

$ find /var/log -type f -name "*.[0-9]" -exec gzip {} \;

実行結果の確認。

$ find /var/log -type f -name "*.gz"
/var/log/messages.1.gz
/var/log/messages.2.gz
/var/log/httpd/access_log.1.gz
/var/log/httpd/access_log.2.gz
/var/log/httpd/error_log.1.gz
/var/log/httpd/error_log.2.gz

ファイルの所有者を一括して rootに変更する

特定ユーザー(root)が所有していないファイルの所有者を一括で変更します。

該当ファイルの一覧表示。

$ find log/ ! -user root -name "*.[0-9]" -ls
2619934  332 -rw-rw-r--   1 zabbix   zabbix     333562  6月  1 04:02 log/zabbix/zabbix_agentd.log.1
2619915   20 -rw-r-----   1 nginx    adm         18720  6月  7 04:02 log/nginx/access.log.2
2619919    4 -rw-r-----   1 nginx    adm           264  6月  6 14:57 log/nginx/error.log.1
2619918   76 -rw-r-----   1 nginx    adm         72575  6月  7 04:02 log/nginx/error.log.2
2619921   40 -rw-r-----   1 nginx    adm         37950  6月  6 04:02 log/nginx/access.log.3
2619849   20 -rw-r-----   1 nginx    adm         18853  6月  7 03:59 log/nginx/access.log.1

所有者の一括変更。

$ find log/ ! -user root -name "*.[0-9]" -exec chown root:root {} \;

実行結果の確認。

$ find log/zabbix log/nginx -name "*.[0-9]" -ls
2619934  332 -rw-rw-r--   1 root     root       333562  6月  1 04:02 log/zabbix/zabbix_agentd.log.1
2619915   20 -rw-r-----   1 root     root        18720  6月  7 04:02 log/nginx/access.log.2
2619919    4 -rw-r-----   1 root     root          264  6月  6 14:57 log/nginx/error.log.1
2619918   76 -rw-r-----   1 root     root        72575  6月  7 04:02 log/nginx/error.log.2
2619921   40 -rw-r-----   1 root     root        37950  6月  6 04:02 log/nginx/access.log.3
2619849   20 -rw-r-----   1 root     root        18853  6月  7 03:59 log/nginx/access.log.1

特定パターンのファイルについて、パーミッションを一括変更する

パーミッションが 600 ではないファイルを一括して、パーミッションを 600 に一括変更します。

該当ファイルの一覧表示。

find ./log -type f ! -perm 600 -ls
2619933   28 -rw-r--r--   1 root     logcheck    26925  6月  6 22:46 ./log/messages
2619906    8 -rw-r--r--   1 root     logcheck     7393  6月  2 04:02 ./log/messages.1.gz
2619923   24 -rw-r--r--   1 root     root        22166  5月 27 19:39 ./log/messages.2.gz
2619914    8 -rw-r--r--   1 nginx    adm          6325  6月  7 11:59 ./log/nginx/access.log
2619917    4 -rw-r--r--   1 nginx    adm           231  6月  7 07:48 ./log/nginx/error.log

パーミッションの一括変更。

$ find ./log -type f ! -perm 600 -exec chmod 600 {} \;

実行結果の確認。

$ ls -l ./log/messages* ./log/nginx/*
-rw------- 1 root  logcheck 26925  6月  6 22:46 ./log/messages
-rw------- 1 root  logcheck  7393  6月  2 04:02 ./log/messages.1.gz
-rw------- 1 root  root     22166  5月 27 19:39 ./log/messages.2.gz
-rw------- 1 nginx adm       6325  6月  7 11:59 ./log/nginx/access.log
-rw------- 1 nginx adm        231  6月  7 07:48 ./log/nginx/error.log

このように find コマンドのオプション(-exec)を使うことで、効率的に処理を行うことができます。
検索したいディレクトリの階層数(-maxdepth)などのオプションと組み合わせるのも有効です。

No Comments

Apache Range Header DOS 検証補助ツール

Apache HTTPD 1.3/2.xにおいて、RangeヘッダーのDOS脆弱性(CVE-2011-3192)が先日発見されました。

リモートから、Apacheに冗長なRangeヘッダーのリクエストを送信することによって、サーバーのメモリやCPU資源を大きく消費させることができるというものです。なお、最新のアドバイザリでは、1.3に関しては脆弱ではないものの、RangeヘッダーDOSを受けた場合には、それなりに高負荷になるとの指摘があります。

その対策として、Apache開発チームが提示した方法の一つに mod_setenvif や mod_rewrite のモジュールを使って、冗長なRangeヘッダーのリクエストがあった場合には、Rangeヘッダーを無視したり、あるいは、そのリクエストを拒否するというものがあります。

その対策設定をした場合の事後チェックが簡単にできるPerlプログラムを作成しました。
このプログラムを使うことで、mod_setenvif や mod_rewriteを用いた制限が有効であるかを調べることができます。

http://code.google.com/p/apache-range-header-test/wiki/JapaneseManual

以下がその実行例です。例では、Range-Headerで10個の範囲指定をしたリクエストをホストに送信します。「Warning」が返ってきた場合には、制限が効いておらず、Range-Header の要求を Apacheが正常に受け入れられたことを示します。

$ ./httprangetest.pl foo.example.local
[Warning] foo.example.local: Host can accept more than 5 ranges.

次の結果では、Range-Headerの制限が効いており、Range-Headerが無視されています。

$ ./httprangetest.pl bar.example.local
[Info] bar.example.local: Host ignored Range-Header.

次のように第一引数を数値にして、Range-Headerでの範囲指定を任意の数値にすることができます。例では、2個の範囲指定であるため、制限には引っかからず、Apache がリクエストを受け入れています。このプログラムでは、6個以上の範囲指定をApacheが受け入れた場合には、Warning を出します。アドバイザリでは6個以上の範囲指定を制限しており、それに合わせた形です。

$ ./httprangetest.pl 2 bar.example.local
[Info] bar.example.local: Host can accept 2 ranges.

mod_setenvif や mod_rewrite のモジュールを使って、制限を実施した。あるいは、これから実施しようとされている人には、このプログラムを使うと検証が楽になるかもしれません。

なお、RangeヘッダーDOSの脆弱性が閉じられているかどうかを検証するものではないので、その点はご注意ください。

(CVE-2011-3192)

No Comments

Mongodb のバックアップスクリプト

先日から社内がMongoDB一色です。どうもこんにちは、岩本@サーバー事業部です。

とゆうわけで、MongoDBのバックアップスクリプト書きました。

弊社はサーバー監視にNagiosを使っているので、通知部分にはNagios絡みのコマンドを書いてますが

適当に変更してお使いください。

#!/bin/bash

OUTPUT=”/backup”
MONGOBIN=”/usr/local/mongodb/bin”
MONGOUSER=”ユーザー”
MONGOPASS=”パスワード”
PHASE=”DB Dump”
FILEDATE=`date +”%Y-%m-%d” –date “1 day ago”`
HOSTNAME=`hostname | cut -d “.” -f 1`

$MONGOBIN/mongodump -u $MONGOUSER -password=$MONGOPASS -o $OUTPUT/mongo_dump
STATUS=$?
if [ “$STATUS” = “0” ] ; then

PHASE=”Archive to Dump”
cd $OUTPUT
/bin/tar czvf $OUTPUT/mongodb_$FILEDATE.dump.tar.gz ./mongo_dump
STATUS=$?
rm -rf $OUTPUT/mongo_dump

if [ “$STATUS” = “0” ] ; then
PHASE=”Backup is OK”
# 成功時の通知
/root/bin/check_result_via_nsca.sh  $HOSTNAME MONGODB_BACKUP 0 “$PHASE”
fi

else
# 失敗時の通知
/root/bin/check_result_via_nsca.sh  $HOSTNAME MONGODB_BACKUP 2 “$PHASE”
fi

変なところがあれば、随時突っ込みください。

No Comments

CentOS5.5 に MongoDBのインストール

今年もあと1ヶ月と少しになりました。年をとる毎に1年てほんと早いよねぇーと、すっかり社内でももちきりです。

どうもこんにちは、岩本@サーバー事業部です。

ソリューションぶのo2先輩より、とある案件で使うためサーバーに

「MongoDBをインストールしろ」とのご命令を受けましたので、その時のログです。

MongoDBはコンパイルが必要なく、

# cd /usr/local/src
# wget http://fastdl.mongodb.org/linux/mongodb-linux-i686-1.6.4.tgz
# tar zxvf mongodb-linux-i686-1.6.4.tgz
# mv mongodb-linux-i686-1.6.4 mongodb
# mv mongodb /usr/local

# /usr/local/mongodb/bin/mongod

以上!

って言ったら怒られたので、ここから起動スクリプトの作成。

http://ringio-blog.appspot.com/2010/10/mongodb-startup-script

こちらのサイトを参考にさせていただきました。

lockファイルがあると、うまく起動しない時があるらしく、lockファイルを消す処理を入れました。

# vi /etc/init.d/mongod

#!/bin/sh
#
# chkconfig: – 85 15
# description: MongoDB daemon
#   #
# pidfile: /var/run/mongod.pid
# config: /etc/.conf

# Source function library.
. /etc/rc.d/init.d/functions

# parameter
mongoHome=/usr/local/mongodb
mongod=${mongoHome}/bin/mongod
mongodbpath=/var/mongodb
logfile=/var/log/mongod.log
pidfile=/var/run/mongod.pid
mongoconf=/etc/mongodb.conf

RETVAL=0

start() {
KIND=”MongoDB”

if test -e ${pidfile} ; then
echo “already running”

else
if test -e ${mongodbpath}/mongod.lock ; then
rm -f ${mongodbpath}/mongod.lock
fi

echo -n $”Starting $KIND services: ”

${mongod} –pidfilepath=${pidfile} –dbpath=${mongodbpath} –logappend –logpath=${logfile} –config=${mongoconf} –fork
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && touch ${mongodbpath}/mongod.lock || RETVAL=1
return $RETVAL
fi
}

stop() {
echo
KIND=”MongoDB”
echo -n $”Shutting down $KIND services: ”
killproc $mongod
RETVAL=$?
[ $RETVAL -eq 0 ] && rm -f ${mongodbpath}/mongod.lock ${pidfile}
echo “”
return $RETVAL
}

restart() {
stop
start
}

status() {
KIND=”MongoDB”

if test -e ${pidfile} ; then
echo “mongod is running”
echo “if mongod could not run, please remove pidfile”
else
echo “mongod is not running”
fi
}

case “$1″ in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
status)
status
;;
*)
echo $”Usage: $0 {start|stop|status|restart}”
exit 2
esac

exit $?

さらに、認証の設定

# vi /etc/mongodb.conf

noauth = false
auth = true

DBユーザーの作成

# mongo
> use admin
> db.addUser(“username”, “password”)

ユーザー認証の確認

# mongo
> db.auth(“username”, “password”)

以上。これで、o2氏にもご納得いただけたかと。

変なところがあれば、ご指摘頂けると幸いです。

No Comments

xargs と exec

今日は中秋の名月だとか、どうりで朝から体毛がよく伸びるが図です。こんにちは。岩本@サーバー事業部です。

Linuxサーバーで差分バックアップを行う際、findを使って差分ファイルを抜き出し、

tarで圧縮をするのが一般的かと思います。

1日以内の更新ファイルを見つけて、tarで圧縮

find $BACKUPDIR -mtime -1 -type f | xargs tar czvf /misc/backup/backup_daily.tar.gz

しかし、上記だとファイル名にスペースや文字化けが入っていると、xargsがクォート処理されていないため

うまく動いてくれません。

そこでっ

find $BACKUPDIR -mtime -1 -type f -exec tar czvf /misc/backup/backup_daily.tar.gz “{}”  ;

でも、これだと、検索アイテム毎に処理を行うのでリソースを食いますし、

元ファイル毎に圧縮ファイルが上書きされていきます。(tarのオプションで上書きは解消できるはず?)

で、色々と調べていくと、おしりの”{}”  ;を”{}” +と変更することで、逐次ではなく、検索結果をまとめて処理してくれるとか。

find $BACKUPDIR -mtime -1 -type f -exec tar czvf /misc/backup/backup_daily.tar.gz “{}” +

とゆうわけで、xargsとexecの覚書です。

No Comments

CentOSにDAG(rpmforge)のyumリポジトリの追加

もうすっかり9月ですね、岩本@サーバー事業部です。

CentOSを新規でインストールする時、標準のyumリポジトリでは足りず、DAGを利用する際、

yumリポジトリの追加方法の覚書です。なぜかいつもよく忘れます。

DAGのサイトより

左側メニュー

[RPM packages]

ページ中段
[Getting started Please read “Installation and Configuration” from the FAQ to get started quickl.]

にて、各OS毎のリポジトリ追加方法が載っています。

CentOS5はRedHatEL5のリポジトリを使います。

# rpm -Uhv http://apt.sw.be/redhat/el5/en/i386/rpmforge/RPMS/rpmforge-release-0.3.6-1.el5.rf.i386.rpm

No Comments

XenServerにてゲストが利用してるLVの確認方法

貯めたネタがあるので、今日は連投します。(風邪薬のせいで若干ハイテンション気味です)

こんにちは、岩本@サーバー事業部です。

 

XenServerのストレージにローカルストレージ/iSCSIを使用している場合、ゲスト毎にストレージ上にLVが作成されます。

 

# lvscan
  inactive          ‘/dev/VG_XenStorage-1900116f-b4b4-fdea-e83b-08b642faab9f/MGT’ [4.00 MB] inherit
  ACTIVE            ‘/dev/VG_XenStorage-1900116f-b4b4-fdea-e83b-08b642faab9f/VHD-8aeae1da-f7f6-477a-884c-06abeacddc48’ [20.05 GB] inherit
  ACTIVE            ‘/dev/VG_XenStorage-1900116f-b4b4-fdea-e83b-08b642faab9f/VHD-981729b9-14ce-405c-a743-94dcb77bf93b’ [30.07 GB] inherit
  ACTIVE            ‘/dev/VG_XenStorage-1900116f-b4b4-fdea-e83b-08b642faab9f/VHD-855febe4-f8b1-4de9-90fa-50391a26583b’ [20.05 GB] inherit

 

各LVがどのゲストになるかの確認方法です。

 

XenServerのコンソールより

# xe vbd-list
uuid ( RO)             : 328c4578-0a4b-93d8-325b-e9e3f967edac
          vm-uuid ( RO): b4685f2a-9ebf-de2e-34b1-76e2c8103638
    vm-name-label ( RO): Sanma
         vdi-uuid ( RO): 855febe4-f8b1-4de9-90fa-50391a26583b
            empty ( RO): false
           device ( RO): xvda

uuid ( RO)             : 8c9d52ba-1886-2be1-f076-f7562866beb8
          vm-uuid ( RO): 0439c4c8-291e-6f81-c33b-8f0cd187ec88
    vm-name-label ( RO): CentOS 5.3 (2)
         vdi-uuid ( RO): <not in database>
            empty ( RO): true
           device ( RO): xvdd

uuid ( RO)             : ee5bce08-2b16-74fb-9886-247a132755e9
          vm-uuid ( RO): c36e9b1f-168d-fca0-5c41-7b43cd15baca
    vm-name-label ( RO): work-station
         vdi-uuid ( RO): 8aeae1da-f7f6-477a-884c-06abeacddc48
            empty ( RO): false
           device ( RO): xvda

uuid ( RO)             : e65d09c7-ac24-f33d-1467-11367bc1d78d
          vm-uuid ( RO): c36e9b1f-168d-fca0-5c41-7b43cd15baca
    vm-name-label ( RO): work-station
         vdi-uuid ( RO): <not in database>
            empty ( RO): true
           device ( RO): xvdd

uuid ( RO)             : 67eb6f35-1316-6fad-d80b-a60ddf860195
          vm-uuid ( RO): b4685f2a-9ebf-de2e-34b1-76e2c8103638
    vm-name-label ( RO): Sanma
         vdi-uuid ( RO): <not in database>
            empty ( RO): true
           device ( RO): xvdd

uuid ( RO)             : 3ebe3b3e-9778-d153-2c23-20d7f5c15377
          vm-uuid ( RO): 0439c4c8-291e-6f81-c33b-8f0cd187ec88
    vm-name-label ( RO): CentOS 5.3 (2)
         vdi-uuid ( RO): 981729b9-14ce-405c-a743-94dcb77bf93b
            empty ( RO): false
           device ( RO): xvda

 

 

[vdi-uuid]のUUIDがコマンド[LVSCAN] での一覧[‘/dev/VG_XenStorage-xxxxxxxx/VHD-]以下の値となります。

No Comments

XenServer5.6でのLVMの結合

前回の記事よりすっかりご無沙汰となってしまい、もうすぐ夏休みですね。

こんにちは、岩本@サーバー事業部です。

 

XenSever5.6になり、LVMの結合のコマンドも若干の変更があったので、その覚書です。

 

# xe host-call-plugin host-uuid=<host-UUID> plugin=coalesce-leaf fn=leaf-coalesce args:vm_uuid=<VM-UUID>

 

基本的な機能は同じですが、コマンドが長くなってるのと、ホストのUUIDを指定するようになっています。

 

XenSeverでは、スナップショットの作成は数秒ででき(ゲスト容量による)、スナップショットを外部に書き出すことで

なんちゃって無停止バックアップ+VMベースのバックアップを実装できそうでしたが

LVMの増加とLVMの結合時間をかんがえると、弊社での利用は難しいかなといった感じです。残念。

No Comments

XenServer5.5でのLVMの統合

気がつけば、もうすぐゴールデンウィークですね。どこかに出かけられるご予定はありますか?

こんにちは、岩本@サーバー事業部です。

 

今日は、XenServer5.5のコマンドの覚書

XenServer5.5でゲストのスナップショットをとると、スナップショット毎にLVMが作成され、ストレージが圧迫されていきます。

 

XenServer5.5 Update1では、スナップショット毎にできたLVMの結合ができるようになりました。

http://support.citrix.com/article/CTX123400

 

XenServerホストより

    # coalesce-leaf –u <uuid of VM>

    ただし、スナップショットが残ったままだと、LVMの結合ができません。

    また、コマンドを実行すると、ゲストはコマンドが完了するまで一時停止状態となります。

    40GBのゲストで、LVMの結合には約1分強程かかりました。(環境により変わります、参考までに)

No Comments