サーバからメール送信する際にやったが良い3つのおまじない

メール送るプログラムはすぐ出来るけど、何か特定のプロバイダで受け取ってくれないよ〜
ちゃんと受け取ってもらえるようにするにはどうしたら良いの?
という訳でたぶん↓の3つのおまじないをクリアすればOKですよというお話です。

1.逆引きIPアドレス登録

今時・・・みたいな話はよく聞きますが送る側から考えると大した手間では無いのでやっておきましょう。

レンタルサーバVPSの場合は大抵ツール上から設定可能になってるかと思います。

2.SPFレコード登録

オレはオレで有る。うそうそほんまほんま。という訳でTXTレコードにSPF(Sender Policy Framework)を登録しておきましょう。

↓のリンクが分かり良かったです。
http://salt.iajapan.org/wpmu/anti_spam/admin/tech/explanation/spf/

my3594.netはサーバ1台しかいないのでこんな感じです。

$ nslookup
> set type=txt
> my3594.net
Server:         163.43.128.4
Address:        163.43.128.4#53

Non-authoritative answer:
my3594.net      text = "v=spf1 +ip4:163.43.129.184/32 -all"

3.ホスト名・ドメイン名を正しく設定

Postfixだと↓な感じで

$ cat /etc/postfix/main.cf | grep my3594.net
myhostname = my3594.net
mydomain = my3594.net

sendmailだと
/etc/mail/local-host-names
/etc/mail/sendmail.cfかsubmit.cf
とかにたぶんに有る。

qmailは触った事無いので分かりましぇん。

の3点で大体のプロバイダは受け取ってくれるようになるかと思います。
まぁ答えは全て/var/log/maillogの中に有る・・・。

tmpfsでディレクトリ下に作れるサブディレクトリの数の上限

ext3のサブディレクトリの最大数はよく見るんですが
tmpfsの最大値がよく分からんので試してみました。

↓検証用

use strict;
use warnings;
use Fatal qw(mkdir);

my $counter = 0;
while (1) {
    mkdir "/dev/shm/dir_$counter";
    $counter++;
}
Can't mkdir(/dev/shm/dir_223827): No space left on device at

という改めて訳で数えてみると22万程でした。

$ ls -lha /dev/shm/ | wc -l
223830

ext3が32000なのと比べると大きいですね。

ただ、ext3が最大数に達すると「Too many links」と吐くのに対しtmpfsだと「No space left on device」とでます。

この違いはずばり!!・・・・何でしょね。

2011-08-18 追記
なんかtmpfsは変幻自在みたいでした・・・。なるほろ。

http://www.momonga-linux.org/archive/Momonga-devel.ja/msg03395.html

inode数を増やすには、mountのオプションにnr_inodes=<inode数>を追加してください。
nr_inodes=0とすると、inode数が無制限になるようです。

none                    /var/tmp                tmpfs   defaults,size=12G,nr_inodes=0 0 0

バーチャルNICの起動指定にはONPARENT

バーチャルNICというのかIPエイリアスと言うのか定かでは有りませんが、eth1は上げておいてeth1:1はdownさせておきたい!と言った時にちとはまりましたのでメモ。

/etc/sysconfig/network-scripts/eth1にONBOOT=yesと書いて
/etc/sysconfig/network-scripts/eth1:1にONBOOT=noと書いて

service network restart

ネットワークを再起動するとアレレ?eth1もeth1:1も上がっちゃう・・・。

ふーむと調べると↓を発見。
http://www.jp.redhat.com/support/errata/RHBA/RHBA-2006-0094J.html

別名付きデバイスについてONBOOTではなくONPARENTを使用

との事でバーチャルNIC(eth1:1)の方はONBOOTがyesだろうがnoだろうがONPARENT=yesの時は上がってONPARENT=noの時は上がらないという事。

ほんとか?と思って検証しましたが本当でしたとさ。

バーチャルNICの起動指定にはONPARENTを使いましょうという話でした。

表と裏を行ったり来たり

お尻に&を付けてバックグランド実行とかやると思うんですが、「あっ。やべっ!」って時にどうしてます?というお話。ちなみに今までわたくしはpid特定してkillってました・・・。

特に止める時に限定した話では無いですが便利なのが「fg」と「bg」。フォアグラウンドとバックグラウンドという訳です。

以下サンプルになります。

まず10秒寝るスクリプト(sleep.pl)を用意してと。

sleep 10;

バックグランドで実行してfgで戻して止める(Ctrl+c)というのが↓。

$ perl sleep.pl &
[1] 92576
$ fg
/usr/local/bin/perl sleep.pl
^C

fgで裏のプロセスが表に出てきてくれます。

逆もまた似たような感じで。表で起動して一時停止(Ctrl+z)してbgで裏においやると。

$ perl sleep.pl
^Z
[1]+  Stopped                 /usr/local/bin/perl sleep.pl
$ bg
[1]+ /usr/local/bin/perl sleep.pl &

これは中々便利ですよ〜。

IPアドレスのレンジをパパッとライス

パパッとライスはGoogleIMEが勝手にやった事なので気にしないで下さい。

という事でIPアドレスのレンジで固まる事が多々あります。
何かっていうと192.168.0.0/24とかだとピンと来るんですが
192.168.0.64/26とかだと若干固まり192.168.0.0/30とかだと
完全に集中して計算しないと開始と終わり名古屋のIPアドレスが分かりましぇん。
しかもその結果が間違えてたりするという目も当てられない状態となってしまいます。

助けてCPAN〜という事で開始と終点のIPアドレスがすぐ分かるモジュールが・・・やっぱり有るんです。
http://search.cpan.org/~miker/NetAddr-IP/:NetAddr::IP

という訳で即答出来るようにスクリプトをこしらえました。

↓サンプル

use strict;
use warnings;

use Perl6::Say;
use NetAddr::IP;

my @ip = qw(
192.168.0.0/32
192.168.0.0/24
192.168.0.0/22
192.168.0.0/30
);

for my $i (@ip) {
    say(NetAddr::IP->new($i)->range);
}

出力は斯様になります。

192.168.0.0 - 192.168.0.0
192.168.0.0 - 192.168.0.255
192.168.0.0 - 192.168.3.255
192.168.0.0 - 192.168.0.3

ワンライナーだとこんな感じかなぁ。もうちょっとすっきりすると嬉しいけど。

$ perl -MNetAddr::IP -le "print NetAddr::IP->new('192.168.0.0/24')->range"

これで喋りながらこっそり出せるね!

今時点のタイムスタンプ出したいだけならPOSIXで良いんじゃないかと。


明けましておめでとうございます。
今年は週1本でブログを書いて飛躍の年としたいと思っております。

という訳で新年1発目はド基本の日付関連。
気持ちは分かるんですが、やっぱり今時点のタイムスタンプ出したいだけならPOSIXで十分じゃ無かろうかと思う訳です。
日曜大工にブルドーザー的な大袈裟さが有るんじゃないかなぁと、という訳で理論武装するためにこんなに違うんだというベンチとってみました。

use strict;
use warnings;

use DateTime ();
use Time::Piece ();
use POSIX ();

use Benchmark;

our $FORMAT = '%Y-%m-%d %H:%M:%S';

sub posix {
    my $d = POSIX::strftime($FORMAT, localtime());
    return $d;
}

sub time_piece {
    my $d = Time::Piece->new->strftime($FORMAT);
    return $d;
}

sub datetime {
    my $d = DateTime->now(time_zone => 'Asia/Tokyo')->strftime($FORMAT);
    return $d;
}

my $b = Benchmark::timethese(10000, {
            posix   => \&posix,
            time_piece => \&time_piece,
            datetime => \&datetime,
          });

Benchmark::cmpthese($b);

ほんで結果。

Benchmark: timing 10000 iterations of datetime, posix, time_piece...
  datetime:  8 wallclock secs ( 6.93 usr +  0.01 sys =  6.94 CPU) @ 1441.44/s (n=10000)
     posix:  0 wallclock secs ( 0.14 usr +  0.02 sys =  0.16 CPU) @ 64000.00/s (n=10000)
            (warning: too few iterations for a reliable count)
time_piece:  1 wallclock secs ( 0.50 usr +  0.00 sys =  0.50 CPU) @ 20000.00/s (n=10000)
              Rate   datetime time_piece      posix
datetime    1441/s         --       -93%       -98%
time_piece 20000/s      1287%         --       -69%
posix      64000/s      4340%       220%         --

という訳でPOSIXが断然早い!と胸を貼って言えるようになりました。コード量も全くと言って良い程変わりませんしね。
当たり前の事ですが適材適所でこそモジュールは光を放つんでしょうねぇ。

と新年早々物思いに耽ってみました。