カテゴリー別アーカイブ: Linux

PostfixでOP25B対応@so-net

OP25BはOutbound Port 25 Blockingの略でまあ内容はそのまま25番ポートの外向きの接続をブロックするってやつで、要するに直接SMTPを外部にしゃべるなってやつです。
でまあ、代わりにプロバイダが用意しているMTAにリレーして、代理配送を頼むっていうお話。

今まではrelayhostにmail.au-one.netだかを設定していて問題なかったんだけども、なんか先日突然ブロックされました。
KDDIなんだからええやんと思うわけですが、方針を変えたようです。
ので、プロバイダはso-netなので切り替えようとしたわけですが、so-netではrelayhostを指定するだけではAuthentication requiredが帰ってくる。
SMTP認証を要求されるということでして、その設定も必要に。
ところがプロバイダのメールなんて使ってないし、IDもなんもかんも覚えてない上に、書類を紛失して再発行依頼する羽目に。
書類が届いたところでようやく設定です。

main.cf

relayhost = [mail.so-net.ne.jp]:587

smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/smtpauth
smtp_sasl_security_options = noanonymous
smtp_sasl_mechanism_filter = LOGIN, PLAIN, CRAM-MD5

smtpauth

[mail.so-net.ne.jp]:587 xxxxxx@xxx.so-net.ne.jp:PASSWORD
# chmod 640 smtpauth
# postmap smtpauth

をしてpostfix再起動。

# echo test | mail xxx@example.com

とかやって外部にメール配送できるかチェック。
ダメだったら/var/log/mail.logとかでどこでこけてるか確認して何とか。

コマンドラインのmysqlでmysqldからのメッセージが文字化けする

データベースの中身に入っているデータが文字化けするとかじゃないです。
ターミナルでサーバ機に接続して、そこからmysqlコマンドでデータベースに接続して、そこでSQLかちゃかちゃ打ち込んでたりすると、コマンドの実行結果そのものとは別にちょっとしたメッセージが出るじゃないですか。
えーといまいちわかりにくいですね、まあエラーメッセージに顕著なんですよ。

ERROR 1064 (42000): Something is wrong in your syntax  : ‘lock’ ノユカ・ : 1 ケヤフワ
ERROR 1141 (42000): ・譯シ・カ。シ ‘root’ (・ロ・ケ・ネ ‘%’ 、ホ・?・カ。シ) 、マオト、オ、・ニ、、、?サ、・
ERROR 1044 (42000): ・譯シ・カ。シ ‘root’@’localhost’ 、ホ ‘information_schema’ ・ヌ。シ・ソ・ル。シ・ケ、リ、ホ・「・ッ・サ・ケ、ン、キ、゙、ケ

とかこんな感じ。
で、これ前々から気にはなっていたんだけども、ずっと放置していて、まあいい加減直したいなと。
そこでまず、この文字化けの文字コードはなんだろうと。
SJISでもUTFでもないんだよなーっていじってたらでましたEUC。

mysql> grant lock tables on information_schema.* to root;
ERROR 1044 (42000): ユーザー ‘root’@’localhost’ の ‘information_schema’ データベースへのアクセスを拒否します

EUCとかどこにも使ってる覚えないんですけど、っていうかサーバ基本的にUTF8なんですけど、っていうことでしらべていたらこちらに答えが。

んで、「/etc/my.conf」の設定行をコメントアウトして、MySQLをリスタート、経過観察を繰り返すこと数回。

わ、わかりました。

以下のように、コメントアウトして試したところ、文字化けしたエラーメッセージが出なくなりました。

[mysqld]
#language = /usr/local/mysql/share/mysql/japanese

でも、日本語のエラーメッセージではなく、デフォルトの英語に戻ってしまった。

気になって、エラーメッセージを出力するソースを見てみたところ、Shift-JISとEUC-JPしか、用意されていないことが判明しました。
UTF-8の要求しても、EUC-JPの出力で返されていたので、文字化けが起こるのも当然だな

はい、うちでもlanguage設定しています。
MySQLはUTF-8で設定しています。
文字化けの文字コードはEUCでした。
完全に一致。

よし。コメントアウトして終わりと。

information_schemaのmysqldumpがうまくいかない

先日MySQLを5.0から5.1にバージョンアップしました。
出てることに気づいてなかったんです。
別にあげなくても困らないんですけど、なんとなくあたらしもの好きということで。
5.5はdebianだとexperimentalだったのでやめました。

で、まあ、5.1にしたらちょいちょい問題が出たんですけど、まあエラーログ眺めてなんとかしたんですよ。
skip-bdbオプションあったらうごかないとか。(たぶん削除されたんでしょう)
default-character-setがdeprecatedになってcharacter_set_server使えとか。

そんなこんなでとりあえずうごかしはじめて問題なさそうだったので数日、ふとroot宛てのメールを見ると日々cronで回しているmysqlのバックアップさんからエラー通知。

mysqldump: Got error: 1044: _桼____ ‘root’@’localhost’ __ ‘information_schema’ _ǡ____١____ؤΥ____________ݤ__ޤ_ when using LOCK TABLES

なんか化け化けですけど、とりあえずエラーコード1044ってことでいいすかね。

でまあ、ぐぐってみたら結構でてくる。
正しいエラーメッセージはこうらしい。

mysqldump: Got error: 1044: Access denied for user ‘root’@’localhost’ to database ‘information_schema’ when using LOCK TABLES

権限が無いといっているようにみえる。
rootなんですけど。。。

んで、解決策としては、mysqldumpのオプションに、–single-transactionをつければいいらしい。
LOCK TABLES権限をユーザに与えてもいいって書いてるところもあるんだけど、rootでやってるから全権限あるんすよね。
一応権限確認したら all on *.* だったし。
ということで、試してみたらいけた。

mysqldump –add-drop-database –add-drop-table -e –add-locks –quick –quote-names -u root –password=XXXXXXXXXX –single-transaction information_schema > /backup/information_schema.sql

みたいな感じで。
rootにgrantはしっぱいした。
ほかのユーザならうまくいくのかもね。

Minecraftサーバの導入

例のごとくWindowsではなくてLinuxの話です。
まあ管理ツールの使い方なんかはWindowsでも参考になるかもしれない。

導入環境は以下の感じ

OS: Debian GNU/Linux sid
kernel: 3.2.0-1-amd64
CPU: Intel(R) Core(TM)2 Duo CPU E6850  @ 3.00GHz
memory: 4GB
jre: sun-java6-jre 6.26-3

なお、このマシンはxenで仮想化した64bitゲストOSだけど普通にいけた。

ということで、まずインストール先ディレクトリを決める。
今回は /usr/local/minecraft をインストール先ディレクトリにした。

ということでサーバ本体をダウンロードしてそこに配置。
この辺においてある。
exeじゃなくてjarを拾ってこよね。

で、これでjre入ってればサーバ起動できるんだけど、色々とそれだと制御に難があるので、シェルスクリプトを導入する。
screenコマンドを使っているので、もし入ってなかったら入れること。
元はhttp://www.minecraftwiki.net/wiki/Server_startup_scriptのものなんだけど、ちょっと問題点を修正してあるのが以下。
-Djava.net.preferIPv4Stack=trueを入れていないとIPv6でバインドされて接続できなかった。

#!/bin/bash
# /etc/init.d/minecraft
# version 0.3.6 2011-10-17 (YYYY-MM-DD)
 
### BEGIN INIT INFO
# Provides:   minecraft
# Required-Start: $local_fs $remote_fs
# Required-Stop:  $local_fs $remote_fs
# Should-Start:   $network
# Should-Stop:    $network
# Default-Start:  2 3 4 5
# Default-Stop:   0 1 6
# Short-Description:    Minecraft server
# Description:    Starts the minecraft server
### END INIT INFO
 
#Settings
SERVICE='minecraft_server.jar'
OPTIONS='nogui'
USERNAME='minecraft'
WORLD='world'
MCPATH='/usr/local/minecraft'
BACKUPPATH='/usr/local/minecraft/backup'
CPU_COUNT=1
INVOCATION="java -Xmx1024M -Xms1024M -Djava.net.preferIPv4Stack=true -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalPacing -XX:ParallelGCThreads=$CPU_COUNT -XX:+AggressiveOpts -jar $SERVICE $OPTIONS"
 
ME=`whoami`
as_user() {
  if [ $ME == $USERNAME ] ; then
    bash -c "$1"
  else
    su - $USERNAME -c "$1"
  fi
}
 
mc_start() {
  if  pgrep -u $USERNAME -f $SERVICE > /dev/null
  then
    echo "$SERVICE is already running!"
  else
    echo "Starting $SERVICE..."
    cd $MCPATH
    as_user "cd $MCPATH && screen -dmS minecraft $INVOCATION"
    sleep 7
    if pgrep -u $USERNAME -f $SERVICE > /dev/null
    then
      echo "$SERVICE is now running."
    else
      echo "Error! Could not start $SERVICE!"
    fi
  fi
}
 
mc_saveoff() {
  if pgrep -u $USERNAME -f $SERVICE > /dev/null
  then
    echo "$SERVICE is running... suspending saves"
    as_user "screen -p 0 -S minecraft -X eval 'stuff "say SERVER BACKUP STARTING. Server going readonly..."15'"
    as_user "screen -p 0 -S minecraft -X eval 'stuff "save-off"15'"
    as_user "screen -p 0 -S minecraft -X eval 'stuff "save-all"15'"
    sync
    sleep 10
  else
    echo "$SERVICE is not running. Not suspending saves."
  fi
}
 
mc_saveon() {
  if pgrep -u $USERNAME -f $SERVICE > /dev/null
  then
    echo "$SERVICE is running... re-enabling saves"
    as_user "screen -p 0 -S minecraft -X eval 'stuff "save-on"15'"
    as_user "screen -p 0 -S minecraft -X eval 'stuff "say SERVER BACKUP ENDED. Server going read-write..."15'"
  else
    echo "$SERVICE is not running. Not resuming saves."
  fi
}
 
mc_stop() {
  if pgrep -u $USERNAME -f $SERVICE > /dev/null
  then
    echo "Stopping $SERVICE"
    as_user "screen -p 0 -S minecraft -X eval 'stuff "say SERVER SHUTTING DOWN IN 10 SECONDS. Saving map..."15'"
    as_user "screen -p 0 -S minecraft -X eval 'stuff "save-all"15'"
    sleep 10
    as_user "screen -p 0 -S minecraft -X eval 'stuff "stop"15'"
    sleep 7
  else
    echo "$SERVICE was not running."
  fi
  if pgrep -u $USERNAME -f $SERVICE > /dev/null
  then
    echo "Error! $SERVICE could not be stopped."
  else
    echo "$SERVICE is stopped."
  fi
}
 
mc_update() {
  if pgrep -u $USERNAME -f $SERVICE > /dev/null
  then
    echo "$SERVICE is running! Will not start update."
  else
    MC_SERVER_URL=http://s3.amazonaws.com/MinecraftDownload/launcher/minecraft_server.jar?v=`date | sed "s/[^a-zA-Z0-9]/_/g"`
    as_user "cd $MCPATH && wget -q -O $MCPATH/minecraft_server.jar.update $MC_SERVER_URL"
    if [ -f $MCPATH/minecraft_server.jar.update ]
    then
      if `diff $MCPATH/$SERVICE $MCPATH/minecraft_server.jar.update >/dev/null`
      then
        echo "You are already running the latest version of $SERVICE."
      else
        as_user "mv $MCPATH/minecraft_server.jar.update $MCPATH/$SERVICE"
        echo "Minecraft successfully updated."
      fi
    else
      echo "Minecraft update could not be downloaded."
    fi
  fi
}
 
mc_backup() {
   echo "Backing up minecraft world..."
   if [ -d $BACKUPPATH/${WORLD}_`date "+%Y.%m.%d_%H.%M"` ]
   then
     for i in 1 2 3 4 5 6
     do
       if [ -d $BACKUPPATH/${WORLD}_`date "+%Y.%m.%d_%H.%M"`-$i ]
       then
         continue
       else
         as_user "cd $MCPATH && cp -r $WORLD $BACKUPPATH/${WORLD}_`date "+%Y.%m.%d_%H.%M"`-$i"
         break
       fi
     done
   else
     as_user "cd $MCPATH && cp -r $WORLD $BACKUPPATH/${WORLD}_`date "+%Y.%m.%d_%H.%M"`"
     echo "Backed up world"
   fi
   echo "Backing up $SERVICE"
   if [ -f "$BACKUPPATH/minecraft_server_`date "+%Y.%m.%d_%H.%M"`.jar" ]
   then
     for i in 1 2 3 4 5 6
     do
       if [ -f "$BACKUPPATH/minecraft_server_`date "+%Y.%m.%d_%H.%M"`-$i.jar" ]
       then
         continue
       else
         as_user "cd $MCPATH && cp $SERVICE "$BACKUPPATH/minecraft_server_`date "+%Y.%m.%d_%H.%M"`-$i.jar""
         break
       fi
     done
   else
     as_user "cd $MCPATH && cp $SERVICE "$BACKUPPATH/minecraft_server_`date "+%Y.%m.%d_%H.%M"`.jar""
   fi
   echo "Backup complete"
}
 
mc_command() {
  command="$1";
  if pgrep -u $USERNAME -f $SERVICE > /dev/null
  then
    pre_log_len=`wc -l "$MCPATH/server.log" | awk '{print $1}'`
    echo "$SERVICE is running... executing command"
    as_user "screen -p 0 -S minecraft -X eval 'stuff "$command"15'"
    sleep .1 # assumes that the command will run and print to the log file in less than .1 seconds
    # print output
    tail -n $[`wc -l "$MCPATH/server.log" | awk '{print $1}'`-$pre_log_len] "$MCPATH/server.log"
  fi
}
 
#Start-Stop here
case "$1" in
  start)
    mc_start
    ;;
  stop)
    mc_stop
    ;;
  restart)
    mc_stop
    mc_start
    ;;
  update)
    mc_stop
    mc_backup
    mc_update
    mc_start
    ;;
  backup)
    mc_saveoff
    mc_backup
    mc_saveon
    ;;
  status)
    if pgrep -u $USERNAME -f $SERVICE > /dev/null
    then
      echo "$SERVICE is running."
    else
      echo "$SERVICE is not running."
    fi
    ;;
  command)
    if [ $# -gt 1 ]; then
      shift
      mc_command "$*"
    else
      echo "Must specify server command (try 'help'?)"
    fi
    ;;
 
  *)
  echo "Usage: $0 {start|stop|update|backup|status|restart|command "server command"}"
  exit 1
  ;;
esac
 
exit 0

 

minecraft実行用のユーザを作成する。(useradd minecraftで上等)

minecraftインストール先ディレクトリのパーミッションもそのユーザに変えておこう。

#Settingsの部分を自分の環境に合わせて /etc/init.d/minecraft に配置して chmod 755 minecraft。

これで

# /etc/init.d/minecraft start

とか

# /etc/init.d/minecraft restart

とかできるようになる。

できなかったらなんかができてない。

で、あとはサーバ起動/終了時に自動で起動/停止するようにサービス登録。

debian系なら

# update-rc.d minecraft defaults

cronで定期バックアップなんかもできる。

/etc/init.d/minecraft backupを登録すればいい。

このスクリプトを通してサーバコマンドを打つこともできる。

# /etc/init.d/minecraft command list

みたいな。

 

で、あとはServer.propertiesの編集。

デフォルトでかかれている以上のものがあるんで、http://www.minecraftwiki.net/wiki/Server.propertiesを参照した方が良い。

訳してもいいけどわかんないんだったら日本のwikiでも大体乗ってる。

で、一通り設定が終わったら、サーバ管理でスクリプト経由でコマンドをうてるっていっても、いちいち端末起動して接続してsuしてコマンド打ってってやっぱ面倒なので、普段はrcon使いましょ。

あ、普段使ってるデスクトップがLinuxでそのLinuxでminecraftをうごかしているっていうのは例外です。

ということで

enable-rcon=true

rcon-passwordはお任せ。

これはいいって感じではないんだけど、まあとりあえずうごくレベルのは転がってたから、無いよりはきっとましなので一応紹介。

http://www.minecraftforum.net/topic/852452-minecraft-rcon-tool-by-r3b0rn/

http://www.minecraftforum.net/topic/842376-minecraft-server-rconquery-utility/

これいいよ!っていうrconツールあったら教えてほしいです。

あとは各種ポート解放(通常ゲームポート 25565, rconポート 25575)をFirewallおよびルータで実行。

たぶんこんな感じでおっけーなはず。

おつかれさまでございます。

WesternDigital春のRMA祭り

さて、今年もやって参りましたRMA祭りの開催です。
今回はサーバ機で2本、個人用マシンで1本、いずれもWesternDigital社製ハードディスクに異常が検出されました。

いい加減にしろよくそがおいこのゴミカスマジで紀伊店のか。

あ、すいません、思わず心の声が聞こえてしまったようで。
お気になさらず先へ進みましょう。

いつからでしょうか、そう遠くない頃合いに、サーバ機のrootあてにsmartctlからメールが届いていました。
smartctlからのメールなんて良いことが書いてあるわけがないわけでして、案の定SMART値に異常があるよというお話でした。
でまあ確認してみたところ

Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
# 1  Short offline       Completed: read failure       90%      2317         17715224

ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
197 Current_Pending_Sector  0x0032   195   195   000    Old_age   Always       -       1461

おい、Current_Pending_Sector 1461ってどこまで深刻化してから通知よこすんだよ、もうこんなディスクつかえねーから。
そして一通りディスクをしらべてみると、別のディスクでも144でてる。
こいつも交換対象だな。

だがサーバ機ははRAID5で運用しているので、二本同時に引っこ抜くのは当然できない。
どう見ても重度な方のディスクをとりあえず引っこ抜いて、縮退モードで運用し、RMA申請して帰ってきたら再構築、そしたら次に危ない子を引っこ抜いて。。。という流れで対処しようと思う。
金持ちじゃないんで、代替ディスクを用意してすぐに交換するなんてことはしません。

で、デスクトップの方ですが、こちら2Tのディスクを2本使っているうちの1本で不良セクタが発生。
最近なんか調子悪かったのでRAID0を解除してデータを整理してスキャンディスクしたら判明。
一本は元気なようで、とりあえずはその一本で間に合うので、調子の悪い子はサーバ機のHDDのRMAが終わってからRMAすることに。

ということで、それぞれのディスクがRMA申請できるか保証をチェック
したところ、一匹できないのがまざってた。
デスクトップのやつ。

CFDでRMA申請を可能にする申請をだす

こいつはまあどうせ後回しだし。
別の二台のRMAが終わった頃にはRMAできるようになってるでしょ。

ということで、一番重傷な子をとりあえずRMA申請。

んじゃ、取り外そう。

。。。てどのディスクなんだっけ。
いや、諸々の問題からDom0上でRAID5を構築しているわけではなく、DomUで構築しておりまして。
んと、Dom0では/dev/sdeだから。。。DomUでは。。。/dev/xvdb4らしい。
xm conでDomUにコンソール接続して。。。

# mdadm /dev/md3 --fail /dev/xvdb4
[1799713.802196] md/raid:md3: Disk failure on xvdb4, disabling device.
[1799713.802198] md/raid:md3: Operation continuing on 4 devices.
mdadm: set /dev/xvdb4 faulty in /dev/md3

# mdadm /dev/md3 --remove /dev/xvdb4
[1799899.247128] md: unbind<xvdb4>
[1799899.247142] md: export_rdev(xvdb4)
mdadm: hot removed /dev/xvdb4 from /dev/md3

# mdadm -D /dev/md3
*snip*
          State : clean, degraded
 Active Devices : 4
Working Devices : 4
 Failed Devices : 0
  Spare Devices : 0

*snip*

    Number   Major   Minor   RaidDevice State
       6     202       17        0      active sync   /dev/xvdb1
       1     202       18        1      active sync   /dev/xvdb2
       2     202       19        2      active sync   /dev/xvdb3
       3       0        0        3      removed
       4     202       21        4      active sync   /dev/xvdb5

さて、xenのDomUの設定ファイルのストレージの記述からも外して、物理的にHDDを引っこ抜く。

前SeagateのRMAで返送されたときの箱をとってあるので、それにHDDをつっこむ。
RMA手順指示書を二部プリントアウトして、一部は二カ所ほど署名をして箱に同梱。
一部は郵便局で送り状やらインボイスやらを記入するときの参考資料として持って行く。
RMA labelは張った方が早くなるらしいといわれているけど、張って1ヶ月、張らずに2週間を経験してるので面倒だからもう張らないことにした。
Western Digitalの人と直接やりとりしたときも、ラベルつくって張ってね、とか一言も言われなかったし。

じゃ、郵便局行ってくるか。
おかげで英語で住所書くの慣れた。

XenカーネルでのNICのカスタマイズ

Xenを使って仮想化しているマシンではネットワークも仮想化される。
そのあたりはこちら参照。

でまあそういうことで、ethtoolなんかでNICの設定をしたい場合は、通常と異なりeth0とかをいじるのではなくて、Dom0でpethをいじるのが正解。
普通はpeth0になってるだろう。

実際にethtoolをたたいてみたら、仮想NICであるethの方はろくに情報が出力されないはずだ。
それに対してpethの方はちゃんと出力されるはず。

# ethtool eth0
Settings for eth0:
        Link detected: yes
# ethtool peth0
Settings for peth0:
        Supported ports: [ TP ]
        Supported link modes:   10baseT/Half 10baseT/Full
                                100baseT/Half 100baseT/Full
                                1000baseT/Full
        Supports auto-negotiation: Yes
        Advertised link modes:  10baseT/Half 10baseT/Full
                                100baseT/Half 100baseT/Full
                                1000baseT/Full
        Advertised pause frame use: No
        Advertised auto-negotiation: Yes
        Speed: 1000Mb/s
        Duplex: Full
        Port: Twisted Pair
        PHYAD: 1
        Transceiver: internal
        Auto-negotiation: on
        MDI-X: off
        Supports Wake-on: pumbg
        Wake-on: g
        Current message level: 0x00000001 (1)
        Link detected: yes

こんな感じ。

ということでXenカーネルでうごかしてるマシンのNICの設定をいじりたい場合は、pethをいじりましょう。

Postfixで迷惑メール対策

最近スパムが多くて、良いスパム対策はないかと物色。
で、なんか売り文句によると99%のスパムメール撲滅できるというものが。
基本的なコンセプトはこちらに詳しく書いてある。

  • メールサーバがメール中継サーバからのSMTPアクセスは受け入れるがエンドユーザーコンピュータからの直接のSMTPアクセスは拒絶するという単純なもの
  • SMTPアクセスをかけてきたクライアントのFQDNの特徴に基づいて、クライアントがメール中継サーバか、エンドユーザー回線につながったコンピュータかを推定することができる
  • うまく管理されているメール中継サーバのほとんどは、逆引きで得られるFQDNを持つ。逆引きFQDNのないIPアドレスからのSMTPアクセスは、少しの例外を除いて拒絶すればよい。
  • 正規表現を使うことによって、エンドユーザー用回線の逆引きFQDNとメール中継サーバの逆引きFQDNを区別する
  • メールサーバがこれらの規則によってSMTPアクセスを拒絶する時は、「後で再試行せよ」を意味する応答コード「450」を 返すべきである。そうすれば、これらの規則のいずれかに引っかかる正当なメール中継サーバを、後で述べるホワイトリスト(許可リスト)を作ることによって 救済することができる。
  • HELOコマンドが宛先サーバのIPアドレスまたは受信者のドメイン名を通知している
  • 送信者ドメインの検索失敗
  • 内容の検査

なるほどね。
エンドユーザ回線を拒絶するのはでかそうだ。
この方式をS25R(Selective SMTP Rejection)方式というそうだ。
そして、この方式とは別にGreylistingという方式がある。
Greylistingは簡単に言えば、再送要求を一旦返して、ちゃんと再送してきたものを受け取る方式。
S25RとGreylistingを組み合わせた方式がRgrey方式として紹介されている。
また、意図的な応答遅延を行うことで配送タイムアウトが通常のMTAよりも速いものを切り落とすtarpittingという方式もある。
これは、通常、スパム業者は大量のメールを配送する関係から、応答の遅いMTAには配送を早々とあきらめるよう設定されていることが多いことを利用したもの。
S25R+tarpittingによる、Starpitという手法も紹介されている。
そして、全部ごった煮のパターン、S25R + tarpiptting + Greylistingを組み合わせたtaRgrey方式が紹介されていた。
taRgrey方式の簡単な説明は以下の通り。

taRgreyとは、メールサーバ上でスパムやウイルスメールを排除するためのフィルタの手法で、 S25Rとtarpittingとgreylistingというスパム判定手法を組み合わせて使うというものです。
S25Rにより、動的IPっぽいFQDNからの接続からは怪しいと判断し、tarpitting(応答の遅延)を行います。tarpittingを待ちき れずに送信元が接続を切った後、再度送ってきた場合にはgreylisting(再送のチェック)により救済します。S25Rとtarpittingと greylistingと、全てのフィルタを抜けれなかったものだけがスパムとして排除されます。

さて、じゃあtaRgrey方式で、といきたいところだが、ここにかかれている方法はパッチを当てなければならない。
aptでパッケージ管理している関係上、できるだけdebian非公式パッチは当てたくない。
なので、パッチを使わないで実装する方向とする。

ということでどこでチェックしようかpostfixの設定を眺めることしばらく。
smtpd_recipient_restrictionsでやるのがいいかなあ、という結論。
PostfixでのGreylistingはpostgreyを使う。
ホワイトリストは許可して、S25R方式で怪しい奴らにgreylistingをかける。
それを通ったものにはtarpittingをかける。
という流れにする。

postgreyをインストール。

# aptitude install postgrey
/etc/default/postgrey
POSTGREY_OPTS="--inet=127.0.0.1:10023"

127.0.0.1をつけないとipv6でbindしてた。
いや別にいいんだけど。

main.cf
smtpd_recipient_restrictions = permit_mynetworks,
permit_sasl_authenticated,
reject_unauth_destination,
check_client_access regexp:$config_directory/white-list.txt,
check_client_access regexp:$config_directory/permit_client_nots25r,
check_policy_service inet:127.0.0.1:10023,
check_client_access regexp:$config_directory/tarpitting,
permit
white-list.txt

http://www.gabacho-net.jp/anti-spam/white-list.txtのものを使用
permit_client_nots25r
/.(internetdsl|adsl|sdi).tpnet.pl$/ WARN
/^user.+.mindspring.com$/ WARN
/^[0-9a-f]{8}.(.+.)?virtua.com.br$/ WARN
/.catv.broadband.hu$/ WARN
/[0-9a-f]{4}.[a-z]+.pppool.de$/ WARN
/.dip[0-9]+.t-ipconnect.de$/ WARN
/.dip.t-dialin.net$/ WARN
/.dyn.optonline.net$/ WARN
/.(adsl|cable).wanadoo.nl$/ WARN
/.ipt.aol.com$/ WARN
!/(^unknown$)|(^[^.]*[0-9][^0-9.]+[0-9].*.)|(^[^.]*[0-9]{5})|(^([^.]+.)?[0-9][^.]*.[^.]+..+.[a-z])|(^[^.]*[0-9].[^.]*[0-9]-[0-9])|(^[^.]*[0-9].[^.]*[0-9].[^.]+..+.)|(^(dhcp|dialup|ppp|[achrsvx]?dsl)[^.]*[0-9])/ OK
/./ WARN
tarpitting
/./ sleep 65

main.cfでのsmtpd_recipient_restrictionsで基本的な認可のあとに
ホワイトリストによる認証(check_client_access regexp:$config_directory/white-list.txt)
S25RでOKなものの認可(check_client_access regexp:$config_directory/permit_client_nots25r)
微妙なやつらをpostgreyでgreylistチェック(check_policy_service inet:127.0.0.1:10023)
それも抜けたのはtarpitting(check_client_access regexp:$config_directory/tarpitting)
という感じ。

設定してからしばらくログ眺めてたけど良い感じでスパムをブロックしてくれている。
SPFの設定もしようかと思ったけど、あっちは転送時にfailしたりしちゃうことがあるみたいだから、とりあえず今回はやめておいた。
postfix-policyd-spfパッケージ入れてちょいちょいいじれば使えそうなんだけどね。

mdadmで構築したRAID5のチャンクサイズを変更してみた

やり方は簡単で

# mdadm -G -c512 --backup-file=/path/to/backup /dev/mdX

これでチャンクサイズが512kbになる。
ストライピング(RAID0)でも同じだろう。

ところで、5台構成(うち一台欠落中)のRAID5でやるとえらい遅いんだが。。。
renice -20 -p xxx
とかやって優先度かえても遅い。

# cat /proc/mdstat
Personalities : [raid1] [raid6] [raid5] [raid4]
md3 : active raid5 sda3[0] sde1[4] sdd1[2] sdb3[1]
      5857284096 blocks super 1.2 level 5, 1024k chunk, algorithm 2 [5/4] [UUU_U]
      [>....................]  reshape =  0.2% (4300800/1464321024) finish=6868.2min speed=3542K/sec

3.5Mしかでてないっすよ。。。
5日ほどかかるようで。。。

reshape中にマシン停止するとどうなるのかは怖くて試せない。

しらべてみると、reshape中に再起動とかさせても平気らしいです。
こちらで実験してました。
いやー、mdadmよくできてる。

LinuxでのHDDのチューニング

そういえばすっかり忘れていたHDDのチューニング。
昔はhdparmでチューニングすることで、HDDの速度が結構伸びたものだ。
ついでにサーバ機なので静音化と省電力化も図りたい。
ということでしらべ直す。
hdparmで速度に関係しそうなオプションは以下のあたり。

 -a   Get/set fs readahead
 -A   Get/set the drive look-ahead flag (0/1)
 -c   Get/set IDE 32-bit IO setting
 -d   Get/set using_dma flag
 -m   Get/set multiple sector count
 -M   Get/set acoustic management (0-254, 128: quiet, 254: fast)
 -Q   Get/set DMA queue_depth (if supported)
 -W   Get/set drive write-caching flag (0/1)
 -X   Set IDE xfer mode (DANGEROUS)

続きを読む LinuxでのHDDのチューニング

mdadmでRAID ARRAYのホームホストや名前を変える

レスキューディスクでアレイを作ったらホームホストがそのときのレスキューのホスト名になっちゃってて、ようするにdebianになっちゃってたんで、なんとかしたいと思ったわけですはい。

アレイを組み立てるっていうかassembleするときに–update=で指定できるようで。
でもシステム領域含まれてるんでまたレスキュー使わないといけないんですね、はい。

ということでレスキューに潜り込んで、ホスト名を目的のものにちゃんと設定します。
じゃなかったらassembleの時にオプションで–homehost=で指定します。

# mdadm -A /dev/md1 /dev/sd[ab]1 --update=homehost

ホスト名ちゃんとしたの指定してなかったら

# mdadm -A /dev/md1 /dev/sd[ab]1 --homehost=hogehoge --update=homehost

みたいな感じ。
アレイがすでに起動してたら一回停止してからやりましょう。
アレイのメタデータのバージョンが1系ならmdadm -Dで出てきます。

Name : hogehoge:2  (local to host hogehoge)

のところ。
homehostと今のホストが正しければlocal to host hogehogeのところが出てきます。
mdadm -Dsでかぶってる名前のやついたら一回アレイをとめて

# mdadm -A /dev/md1 /dev/sd[ab]1 --update=name

とかしましょう。
解消されるはずです。

ちなみにmd1とかmd2とかのデバイス名を変えたい場合も同じ感じで、アレイが動いていれば停止して、アセンブルしてやって名前更新かけてやればいいです。

できあがったらシステムをルートにしてシェルを実行して、mdadm -Ds>>/etc/mdadm/mdadm.confたたいて今までのアレイ情報はコメントアウトしましょう。
念のためupdate-initramfs -uk allたたいておいた方が良いかもしれません。
特にデバイス名を変更した場合は必須だと思います。