mdadmで壊れたアレイを修復できるか? [Linux(LVM/RAID/Storage)]
※ この方法が必ず成功するかどうか、確証は全く持てないので、ダメだったとしても文句は言わないように!(笑) ※
さて。LinuxのソフトウェアRAIDでアレイを構築している状態で、ディスク以外のパーツでトラブルが発生することもある。
例えば、拡張スロットに挿しているSATAカードの故障とか、SATAのポートマルチプライヤとか、あるいはケーブル類とか。特にSATAポートマルチプライヤの故障は頻度が多い気がしてならないんだが…。個人的に。そう、あくまでも個人的に。
で、RAID5の場合、原則論としてはディスク1本の障害までは耐えられることになっているが、2本飛んだらゲームオーバーということになっている。その故障の原因は全く問われないが、ディスクそのものの故障よりも、前述のSATAカードやパーツ類の故障の場合は一気に複数のディスクがアクセス不能になる傾向にあるのもまた事実。
ディスクが壊れていなければ、アレイの中のデータが無事である可能性はある。ダメになっているかもしれないが、そこに一縷の望みをかけて「なんとか復旧」させたいと思うのもまた心情。そこで、復旧方法の一つについてここに記載しておく。
ちなみに、我が家の最近のSATAポートマルチプライヤの故障によるRAIDアレイ停止問題はコレで解決できた。
サーバ起動時のログは、こんな感じだった。ちょっと長いけど全部晒すと…
RAIDアレイを構成する9本のディスクのうち、2本がFailedの扱いになっていて、
そしてアレイをスタートするのにディスクが足りないよというエラーに。
ひとまず手動でRAIDをスタートさせてみる。
mdadm --assemble /dev/md0 --run /dev/sd[a-k]1 とか実行してみる。/dev/md0は始動するも、ディスク2本(sdi1とsdj1)がFailedの扱いになって組み込まれないので、 mdadm --misc --detail /dev/md0 で確認してもアクセスは不能に。
このような場合、2つの方法がある模様。
① 思い切ってmdadm --createをやってしまう方法
② ディスクが歯抜けになっているアレイに、Failedなディスクをaddする方法
実は、昔①を試したことがあって、1勝1敗という状況。勝率50%ではあるが今回コレを再度実行する勇気がもてなかったので(笑)、②を実施することにした。(笑)
どうやら、コレには条件があるようだ。ざっくり調べてみた限りでは、mdadm --misc --examineでディスクに保存されているアレイの情報が綺麗に一致する状態でなければならないとのこと。おそらく、RAIDの情報(管理情報?)を更新している瞬間とかにエラーになったらダメとか、そういうことなのだろうか?よく判らないのでその筋の識者の方、コメントを求む。
そんな訳で、
Jun 17 22:22:36 urd kernel: md: kicking non-fresh sdj1 from array!
Jun 17 22:22:36 urd kernel: md: kicking non-fresh sdi1 from array!
ということだったので、mdadm --misc --examine /dev/sdj1とmdadm --misc --examine /dev/sdi1 と実行してみる。
ちなみにこのコマンドを実行すると、↓こんな具合の情報が出る。
(上記の表示例は正常に起動してからのものなので、停止中とかだとちょっと違う場合も考えられる。)
幸い、「Checksum : ナントカカントカ - correct」だったので、このまま組み込んでも大丈夫かな?と思えた。思っただけで確証は全く無かったが!!
と言うわけで、sdj1とsdi1とをアレイに組み込む。コマンドはmdadm --manage /dev/md0 --add /dev/sd[ij]1だ。特にエラーも無く、sdj1とsdi1とをaddしたお^-^ みたいなメッセージがちょろっと出て終了。
mdadm --misc --detail /dev/md0で表示を確認すると、こちらも特にエラーなど無く、それぞれのディスクは「active sync」の状態に。
こいつ・・・動くぞ!?
という心境になった。(笑)しかし、アレイ自体はまだ起動していないので、あと一発コマンドを流し込んでアレイを起動する。コマンドはmdadm --manage /dev/md0 --runだ。
お・・・
エラーとか出ない!!
mdadm --misc --detail /dev/md0でも正常起動を確認!!mount /dev/md0 /mnt/local/storage とか実行してみてdf -hとか実行してみて内部のデータの無事を確認!! いや、もしかしたら何か壊れたファイルもあるかもしれないが、とりあえずサルベージは可能な状態には達した!!
とりあえず、中のデータを救い出してしまおう。そのうちに!
さて。LinuxのソフトウェアRAIDでアレイを構築している状態で、ディスク以外のパーツでトラブルが発生することもある。
例えば、拡張スロットに挿しているSATAカードの故障とか、SATAのポートマルチプライヤとか、あるいはケーブル類とか。特にSATAポートマルチプライヤの故障は頻度が多い気がしてならないんだが…。個人的に。そう、あくまでも個人的に。
で、RAID5の場合、原則論としてはディスク1本の障害までは耐えられることになっているが、2本飛んだらゲームオーバーということになっている。その故障の原因は全く問われないが、ディスクそのものの故障よりも、前述のSATAカードやパーツ類の故障の場合は一気に複数のディスクがアクセス不能になる傾向にあるのもまた事実。
ディスクが壊れていなければ、アレイの中のデータが無事である可能性はある。ダメになっているかもしれないが、そこに一縷の望みをかけて「なんとか復旧」させたいと思うのもまた心情。そこで、復旧方法の一つについてここに記載しておく。
ちなみに、我が家の最近のSATAポートマルチプライヤの故障によるRAIDアレイ停止問題はコレで解決できた。
サーバ起動時のログは、こんな感じだった。ちょっと長いけど全部晒すと…
Jun 17 22:22:36 urd kernel: md: Autodetecting RAID arrays. Jun 17 22:22:36 urd kernel: md: autorun ... Jun 17 22:22:36 urd kernel: md: considering sdk1 ... Jun 17 22:22:36 urd kernel: md: adding sdk1 ... Jun 17 22:22:36 urd kernel: md: adding sdj1 ... Jun 17 22:22:36 urd kernel: md: adding sdi1 ... Jun 17 22:22:36 urd kernel: md: adding sdh1 ... Jun 17 22:22:36 urd kernel: md: adding sdg1 ... Jun 17 22:22:36 urd kernel: md: adding sdf1 ... Jun 17 22:22:36 urd kernel: md: adding sde1 ... Jun 17 22:22:36 urd kernel: md: adding sdd1 ... Jun 17 22:22:36 urd kernel: md: adding sdc1 ... Jun 17 22:22:36 urd kernel: md: adding sdb1 ... Jun 17 22:22:36 urd kernel: md: adding sda1 ... Jun 17 22:22:36 urd kernel: md: created md0 Jun 17 22:22:36 urd kernel: md: bindJun 17 22:22:36 urd kernel: md: bind Jun 17 22:22:36 urd kernel: md: bind Jun 17 22:22:36 urd kernel: md: bind Jun 17 22:22:36 urd kernel: md: bind Jun 17 22:22:36 urd kernel: md: bind Jun 17 22:22:36 urd kernel: md: bind Jun 17 22:22:36 urd kernel: md: bind Jun 17 22:22:36 urd kernel: md: bind Jun 17 22:22:36 urd kernel: md: bind Jun 17 22:22:36 urd kernel: md: bind Jun 17 22:22:36 urd kernel: md: running: Jun 17 22:22:36 urd kernel: md: kicking non-fresh sdj1 from array! Jun 17 22:22:36 urd kernel: md: unbind Jun 17 22:22:36 urd kernel: md: export_rdev(sdj1) Jun 17 22:22:36 urd kernel: md: kicking non-fresh sdi1 from array! Jun 17 22:22:36 urd kernel: md: unbind Jun 17 22:22:36 urd kernel: md: export_rdev(sdi1) Jun 17 22:22:36 urd kernel: raid5: automatically using best checksumming function: generic_sse Jun 17 22:22:36 urd kernel: generic_sse: 5868.000 MB/sec Jun 17 22:22:36 urd kernel: raid5: using function: generic_sse (5868.000 MB/sec) Jun 17 22:22:36 urd kernel: raid6: int64x1 1339 MB/s Jun 17 22:22:36 urd kernel: raid6: int64x2 1667 MB/s Jun 17 22:22:36 urd kernel: raid6: int64x4 1523 MB/s Jun 17 22:22:36 urd kernel: raid6: int64x8 1265 MB/s Jun 17 22:22:36 urd kernel: raid6: sse2x1 2609 MB/s Jun 17 22:22:36 urd kernel: raid6: sse2x2 3160 MB/s Jun 17 22:22:36 urd kernel: raid6: sse2x4 4792 MB/s Jun 17 22:22:36 urd kernel: raid6: using algorithm sse2x4 (4792 MB/s) Jun 17 22:22:36 urd kernel: md: raid6 personality registered for level 6 Jun 17 22:22:36 urd kernel: md: raid5 personality registered for level 5 Jun 17 22:22:36 urd kernel: md: raid4 personality registered for level 4 Jun 17 22:22:36 urd kernel: raid5: device sdh1 operational as raid disk 8 Jun 17 22:22:36 urd kernel: raid5: device sdg1 operational as raid disk 5 Jun 17 22:22:36 urd kernel: raid5: device sdf1 operational as raid disk 3 Jun 17 22:22:36 urd kernel: raid5: device sdd1 operational as raid disk 7 Jun 17 22:22:36 urd kernel: raid5: device sdc1 operational as raid disk 2 Jun 17 22:22:36 urd kernel: raid5: device sdb1 operational as raid disk 6 Jun 17 22:22:36 urd kernel: raid5: device sda1 operational as raid disk 4 Jun 17 22:22:36 urd kernel: raid5: not enough operational devices for md0 (2/9 failed) Jun 17 22:22:36 urd kernel: RAID5 conf printout: Jun 17 22:22:36 urd kernel: --- rd:9 wd:7 fd:2 Jun 17 22:22:36 urd kernel: disk 2, o:1, dev:sdc1 Jun 17 22:22:36 urd kernel: disk 3, o:1, dev:sdf1 Jun 17 22:22:36 urd kernel: disk 4, o:1, dev:sda1 Jun 17 22:22:36 urd kernel: disk 5, o:1, dev:sdg1 Jun 17 22:22:36 urd kernel: disk 6, o:1, dev:sdb1 Jun 17 22:22:36 urd kernel: disk 7, o:1, dev:sdd1 Jun 17 22:22:36 urd kernel: disk 8, o:1, dev:sdh1 Jun 17 22:22:36 urd kernel: raid5: failed to run raid set md0 Jun 17 22:22:36 urd kernel: md: pers->run() failed ... Jun 17 22:22:36 urd kernel: md: do_md_run() returned -5 Jun 17 22:22:36 urd kernel: md: md0 stopped. Jun 17 22:22:36 urd kernel: md: unbind Jun 17 22:22:36 urd kernel: md: export_rdev(sdk1) Jun 17 22:22:36 urd kernel: md: unbind Jun 17 22:22:36 urd kernel: md: export_rdev(sdh1) Jun 17 22:22:36 urd kernel: md: unbind Jun 17 22:22:36 urd kernel: md: export_rdev(sdg1) Jun 17 22:22:36 urd kernel: md: unbind Jun 17 22:22:36 urd kernel: md: export_rdev(sdf1) Jun 17 22:22:36 urd kernel: md: unbind Jun 17 22:22:36 urd kernel: md: export_rdev(sde1) Jun 17 22:22:36 urd kernel: md: unbind Jun 17 22:22:36 urd kernel: md: export_rdev(sdd1) Jun 17 22:22:36 urd kernel: md: unbind Jun 17 22:22:36 urd kernel: md: export_rdev(sdc1) Jun 17 22:22:36 urd kernel: md: unbind Jun 17 22:22:36 urd kernel: md: export_rdev(sdb1) Jun 17 22:22:36 urd kernel: md: unbind Jun 17 22:22:36 urd kernel: md: export_rdev(sda1) Jun 17 22:22:36 urd kernel: md: ... autorun DONE.
RAIDアレイを構成する9本のディスクのうち、2本がFailedの扱いになっていて、
Jun 17 22:22:36 urd kernel: md: kicking non-fresh sdj1 from array! Jun 17 22:22:36 urd kernel: md: unbindJun 17 22:22:36 urd kernel: md: export_rdev(sdj1) Jun 17 22:22:36 urd kernel: md: kicking non-fresh sdi1 from array! Jun 17 22:22:36 urd kernel: md: unbind Jun 17 22:22:36 urd kernel: md: export_rdev(sdi1)
そしてアレイをスタートするのにディスクが足りないよというエラーに。
Jun 17 22:22:36 urd kernel: raid5: device sdh1 operational as raid disk 8 Jun 17 22:22:36 urd kernel: raid5: device sdg1 operational as raid disk 5 Jun 17 22:22:36 urd kernel: raid5: device sdf1 operational as raid disk 3 Jun 17 22:22:36 urd kernel: raid5: device sdd1 operational as raid disk 7 Jun 17 22:22:36 urd kernel: raid5: device sdc1 operational as raid disk 2 Jun 17 22:22:36 urd kernel: raid5: device sdb1 operational as raid disk 6 Jun 17 22:22:36 urd kernel: raid5: device sda1 operational as raid disk 4 Jun 17 22:22:36 urd kernel: raid5: not enough operational devices for md0 (2/9 failed) Jun 17 22:22:36 urd kernel: RAID5 conf printout: Jun 17 22:22:36 urd kernel: --- rd:9 wd:7 fd:2 Jun 17 22:22:36 urd kernel: disk 2, o:1, dev:sdc1 Jun 17 22:22:36 urd kernel: disk 3, o:1, dev:sdf1 Jun 17 22:22:36 urd kernel: disk 4, o:1, dev:sda1 Jun 17 22:22:36 urd kernel: disk 5, o:1, dev:sdg1 Jun 17 22:22:36 urd kernel: disk 6, o:1, dev:sdb1 Jun 17 22:22:36 urd kernel: disk 7, o:1, dev:sdd1 Jun 17 22:22:36 urd kernel: disk 8, o:1, dev:sdh1 Jun 17 22:22:36 urd kernel: raid5: failed to run raid set md0
ひとまず手動でRAIDをスタートさせてみる。
mdadm --assemble /dev/md0 --run /dev/sd[a-k]1 とか実行してみる。/dev/md0は始動するも、ディスク2本(sdi1とsdj1)がFailedの扱いになって組み込まれないので、 mdadm --misc --detail /dev/md0 で確認してもアクセスは不能に。
このような場合、2つの方法がある模様。
① 思い切ってmdadm --createをやってしまう方法
② ディスクが歯抜けになっているアレイに、Failedなディスクをaddする方法
実は、昔①を試したことがあって、1勝1敗という状況。勝率50%ではあるが今回コレを再度実行する勇気がもてなかったので(笑)、②を実施することにした。(笑)
どうやら、コレには条件があるようだ。ざっくり調べてみた限りでは、mdadm --misc --examineでディスクに保存されているアレイの情報が綺麗に一致する状態でなければならないとのこと。おそらく、RAIDの情報(管理情報?)を更新している瞬間とかにエラーになったらダメとか、そういうことなのだろうか?よく判らないのでその筋の識者の方、コメントを求む。
そんな訳で、
Jun 17 22:22:36 urd kernel: md: kicking non-fresh sdj1 from array!
Jun 17 22:22:36 urd kernel: md: kicking non-fresh sdi1 from array!
ということだったので、mdadm --misc --examine /dev/sdj1とmdadm --misc --examine /dev/sdi1 と実行してみる。
ちなみにこのコマンドを実行すると、↓こんな具合の情報が出る。
/dev/sdj1: Magic : a92b4efc Version : 0.90.00 UUID : 920f0fa0:3134624c:9777e46a:4cafd8b9 Creation Time : Mon Feb 1 23:09:17 2010 Raid Level : raid5 Used Dev Size : 1953511936 (1863.01 GiB 2000.40 GB) Array Size : 15628095488 (14904.11 GiB 16003.17 GB) Raid Devices : 9 Total Devices : 11 Preferred Minor : 0 Update Time : Mon Jun 20 04:03:47 2011 State : clean Active Devices : 9 Working Devices : 11 Failed Devices : 0 Spare Devices : 2 Checksum : 5e9e5268 - correct Events : 1521164 Layout : left-symmetric Chunk Size : 256K Number Major Minor RaidDevice State this 0 8 145 0 active sync /dev/sdj1 0 0 8 145 0 active sync /dev/sdj1 1 1 8 129 1 active sync /dev/sdi1 2 2 8 33 2 active sync /dev/sdc1 3 3 8 81 3 active sync /dev/sdf1 4 4 8 1 4 active sync /dev/sda1 5 5 8 97 5 active sync /dev/sdg1 6 6 8 17 6 active sync /dev/sdb1 7 7 8 49 7 active sync /dev/sdd1 8 8 8 113 8 active sync /dev/sdh1 9 9 8 65 9 spare /dev/sde1 10 10 8 161 10 spare /dev/sdk1
(上記の表示例は正常に起動してからのものなので、停止中とかだとちょっと違う場合も考えられる。)
幸い、「Checksum : ナントカカントカ - correct」だったので、このまま組み込んでも大丈夫かな?と思えた。思っただけで確証は全く無かったが!!
と言うわけで、sdj1とsdi1とをアレイに組み込む。コマンドはmdadm --manage /dev/md0 --add /dev/sd[ij]1だ。特にエラーも無く、sdj1とsdi1とをaddしたお^-^ みたいなメッセージがちょろっと出て終了。
mdadm --misc --detail /dev/md0で表示を確認すると、こちらも特にエラーなど無く、それぞれのディスクは「active sync」の状態に。
こいつ・・・動くぞ!?
という心境になった。(笑)しかし、アレイ自体はまだ起動していないので、あと一発コマンドを流し込んでアレイを起動する。コマンドはmdadm --manage /dev/md0 --runだ。
お・・・
エラーとか出ない!!
mdadm --misc --detail /dev/md0でも正常起動を確認!!mount /dev/md0 /mnt/local/storage とか実行してみてdf -hとか実行してみて内部のデータの無事を確認!! いや、もしかしたら何か壊れたファイルもあるかもしれないが、とりあえずサルベージは可能な状態には達した!!
とりあえず、中のデータを救い出してしまおう。そのうちに!
Gmailさんでdkimが通らない!?(続報) [備忘録]
rsa-sha256でGmailさんにdkim=passするよ!というつぶやきをもらったので、追加で調査してみたところ、どうもdkim-genkeyする段階で、/etc/mail/dkim-filter.confを記述してるかしてないかで変わってくる模様。
というのも、わたしが試したときには、
① dkim-genkey を実行する
↓
② /etc/mail/dkim-filter.conf を書く
↓
③ /etc/rc.d/init.d/dkim-filter を書く
という流れで実行し、dkim-filterの起動スクリプト内に必要な情報は書き並べたので、confの中に書くことといえば
これくらいしか書いてなかった。(笑)この状態では、dkim-filterはrsa-sha256だと思って振舞うっぽい?
実際、Gmailで確認できたメールのヘッダには「a=rsa-sha256」と記載があった。
で、dkim-genkeyする前に、dkim-filter.confに
と記述してから、dkim-genkeyをしてみると、「a=rsa-sha256」でも「dkim=pass」と、なったことが確認できた。
まとめると、「SignatureAlgorithm」を明示的に書かなかった場合、
・dkim-filter はデフォルトのアルゴリズムを rsa-sha256だと解釈する
・dkim-genkey はデフォルトのアルゴリズムをrsa-sha1だと解釈する
ということに?????????
これならこのあたりの挙動に説明は付くけども・・・・・
と、すると、sendmail.netに投げて返ってきたテストメールの
↑コレはなにをもって「GOOD」と言っているのでしょうかねえ?????
謎です。。。。。
というのも、わたしが試したときには、
① dkim-genkey を実行する
↓
② /etc/mail/dkim-filter.conf を書く
↓
③ /etc/rc.d/init.d/dkim-filter を書く
という流れで実行し、dkim-filterの起動スクリプト内に必要な情報は書き並べたので、confの中に書くことといえば
On-Badsignature accept On-NoSignature accept
これくらいしか書いてなかった。(笑)この状態では、dkim-filterはrsa-sha256だと思って振舞うっぽい?
実際、Gmailで確認できたメールのヘッダには「a=rsa-sha256」と記載があった。
で、dkim-genkeyする前に、dkim-filter.confに
SignatureAlgorithm rsa-sha256
と記述してから、dkim-genkeyをしてみると、「a=rsa-sha256」でも「dkim=pass」と、なったことが確認できた。
まとめると、「SignatureAlgorithm」を明示的に書かなかった場合、
・dkim-filter はデフォルトのアルゴリズムを rsa-sha256だと解釈する
・dkim-genkey はデフォルトのアルゴリズムをrsa-sha1だと解釈する
ということに?????????
これならこのあたりの挙動に説明は付くけども・・・・・
と、すると、sendmail.netに投げて返ってきたテストメールの
Authentication System: DomainKeys Identified Mail Result: DKIM signature confirmed GOOD Description: Signature verified, message arrived intact Reporting host: sendmail.net More information: http://mipassoc.org/dkim/ Sendmail milter: https://sourceforge.net/projects/dkim-milter/
↑コレはなにをもって「GOOD」と言っているのでしょうかねえ?????
謎です。。。。。
Gmailさんでdkimが通らない!? [備忘録]
これはメモ。
postfix+dkim_milterでメールにDKIMの署名を付けてみて、Gmailさんにテストメールを送信してみると・・・
Authentication-Results: mx.google.com; spf=pass (google.com: domain of p791@mycompany.com designates 125.***.***.149 as permitted sender) smtp.mail=p791@mycompany.com; dkim=neutral (bad format) header.i=@mycompany.com
と、なってしまう場合。
sendmail.netのテストではちゃんと通るのに。。。。。
さんざん悩んだ結果、dkim-milterの新しい目のバージョンではDKIMの署名に「rsa-sha256」を使う模様。実際、メールのヘッダをよーく見てみると、
DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=mycompany.com; s=sarah;
と、なってる。
confや起動オプションの指定は何も明示していないので、デフォルトがコレになっているようです。
が、Gmailさんはコレが理解できないらしいです。
dkim-filterの起動オプションに、「-S rsa-sha1」を付けて起動すると、アラ不思議!!
Authentication-Results: mx.google.com; spf=pass (google.com: domain of p791@mycompany.com designates 125.***.***.149 as permitted sender) smtp.mail=p791@mycompany.com; dkim=pass header.i=@mycompany.com
DKIM-Signature: v=1; a=rsa-sha1; c=simple/simple; d=mycompany.com; s=sarah;
と、DKIMの判定がpassになりました。
おそらく、dkim-filter.confに記述する方法でも良いと思うんですけどもね。
延々と苦しんだぜ・・・
postfix+dkim_milterでメールにDKIMの署名を付けてみて、Gmailさんにテストメールを送信してみると・・・
Authentication-Results: mx.google.com; spf=pass (google.com: domain of p791@mycompany.com designates 125.***.***.149 as permitted sender) smtp.mail=p791@mycompany.com; dkim=neutral (bad format) header.i=@mycompany.com
と、なってしまう場合。
sendmail.netのテストではちゃんと通るのに。。。。。
Authentication System: DomainKeys Identified Mail Result: DKIM signature confirmed GOOD Description: Signature verified, message arrived intact Reporting host: sendmail.net More information: http://mipassoc.org/dkim/ Sendmail milter: https://sourceforge.net/projects/dkim-milter/ Authentication System: Domain Keys Result: (no result present) Reporting host: More information: http://antispam.yahoo.com/domainkeys Sendmail milter: https://sourceforge.net/projects/domainkeys-milter/ Authentication System: Sender ID Result: SID data confirmed GOOD Description: Sending host is authorized for sending domain Reporting host: sendmail.net More information: http://www.microsoft.com/senderid Sendmail milter: https://sourceforge.net/projects/sid-milter/ Authentication System: Sender Permitted From (SPF) Result: SPF data confirmed GOOD Description: Sending host is authorized for sending domain Reporting host: sendmail.net More information: http://spf.pobox.com/
さんざん悩んだ結果、dkim-milterの新しい目のバージョンではDKIMの署名に「rsa-sha256」を使う模様。実際、メールのヘッダをよーく見てみると、
DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=mycompany.com; s=sarah;
と、なってる。
confや起動オプションの指定は何も明示していないので、デフォルトがコレになっているようです。
が、Gmailさんはコレが理解できないらしいです。
dkim-filterの起動オプションに、「-S rsa-sha1」を付けて起動すると、アラ不思議!!
Authentication-Results: mx.google.com; spf=pass (google.com: domain of p791@mycompany.com designates 125.***.***.149 as permitted sender) smtp.mail=p791@mycompany.com; dkim=pass header.i=@mycompany.com
DKIM-Signature: v=1; a=rsa-sha1; c=simple/simple; d=mycompany.com; s=sarah;
と、DKIMの判定がpassになりました。
おそらく、dkim-filter.confに記述する方法でも良いと思うんですけどもね。
延々と苦しんだぜ・・・
「我が家のメールサーバ」を建ててみよう~その1・とりあえずインストール~ [Linux(Mail)]
どうも最近、「自宅でLinuxサーバを・・・」というネタから遠く離れている気がしてならないのだが。(笑)まあ、このblogは私のメモでもあるのでいいといえばいいのかもしれないか。。。(笑)
てなわけで、久々(?)の「自宅でLinuxサーバ」を活用するネタ。今回はメールサーバ編。
判っていると思うが、メールサーバは特に第三者中継等でスパムメールばら撒き拠点として悪用されるリスクもあるので、そのあたりしっかり意識しておくよーに。
「メールサーバ」と一口で言っても、準備しなければならない点はWebサーバよりも多くて複雑だ。まずはメールの送信と受信で準備すべく項目は別々に存在するし、サーバからみた観点だけでなくネットワーク的にも一定量の知識が欠かせない。
メールを送信するための準備:
①当然、MTAを準備しなければならない
②DNSへの登録 (Aレコード、PTRレコード)
③プロバイダや接続環境によってはサブミッションポートやSMTP認証といった設定も必要
④第三者中継等が行われないことをしっかり確認する(こうした確認を行うサービスを提供しているサイトがあるのでこれを活用する)
メールを受信するための準備:
①当然、MTAを準備する。他にPOP3/IMAP4を処理するものも用意する
②DNSへの登録 (Aレコード、MXレコード)
③プロバイダや接続環境によってはサブミッションポートの設定も必要になることも
④自宅のルータについて、ポート開放・転送・フィルタリング等設定を行う
まず、MTAなどを用意する。
MTAとは、メールを転送してくれるエージェントのこと。sendmailとかqmailとかpostfixとかそういう連中で、プロトコルとして「SMTP」を用いる。
「手紙を書いた人間が、郵便ポストに手紙を投函する」 → SMTP
「郵便局員が郵便ポストから手紙を回収し、郵便局に送り届ける」 → SMTP
「集荷した郵便局から、配送先を管轄する郵便局へ郵便物を転送する」 → SMTP
「配送先を管轄する郵便局が、あて先の家の郵便受けまで手紙を送り届ける」 → SMTP
と、ここまでがSMTPの範疇。
しかしこれだけではメールがまだ読めない。「郵便受けから手紙を取り出す」動作が無いためである。
この動作については SMTP ではなく、POP3またはIMAP4といった別のプロトコルが管轄しているので、これはMTAではなくさらに別のエージェントを使用する。有名どころとしてはqpoperとか、dovecotとかだろうか。
極めて個人的な理由ながら、私はqmailが大嫌いなので、qmail以外の選択肢でなおかつラクチンポンで使えるものを探すと・・・
sendmailは設定で軽く死んでしまうのでpostfixをチョイス。(予定通り!w)
pop3/imap4のエージェントについては
cyrus-imapdかdovecotかだけど、ひとまずdovecotをチョイス。よって、これらのインストールとしては・・・
・・・ということになるね!
さて、メールサーバの構築としては概ね以下の手順になるかな
手順①:必要なエージェント類をインストールする
手順②:postfixの設定ファイルを適切に記述する(かならず!!)
手順③:dovecotの設定ファイルを適切に記述する(必要な場合のみ)
手順④:サービスの自動起動設定
手順⑤:ルータのポート開放・転送等の設定を導入する
メールサーバとしてはここまでだが、メールの送受信にはDNSとの連携が欠かせない。
固定されたIPアドレスをもっている場合はいざじらず、ごく一般的なネット接続サービスを利用している限りはインターネットに接続されるポイントのIPアドレスは固定されていないのが常なので、DDNSサービスを利用しなければならないことが一般的だろう。
この場合に、DDNSを自動更新したりするギミックを用意する必要が生じる。DDNSの更新ツールとして有名かつ秀逸なものには、「DiCE」だろうか。残念ながらyumではインストールできないので、コレのLinux版をビルドしてインストールすることとなる。
そんな訳で、
手順⑥:適切なDDNSサービスに登録する
※重要:MXレコードへの登録に対応しているサービスを選択すること
※重要:さらに、DiCEに対応しているサービスを選択すること
手順⑦:DiCEをダウンロード・ビルド・インストール
手順⑧:DiCEを適切に設定する
というわけで、postfixとdovecotはyumでインストール。DiCEについてはソースからビルドしてインストールということにする。
手順①:必要なエージェント類をインストールする
すでに示したとおり、yum install postfix dovecotで終了。
手順②:postfixの設定ファイルを適切に記述する(かならず!!)
インストールが終わったら、今度はpostfixの設定ファイルを編集する。
重要なファイルとしては、
/etc/postfix/master.cf
/etc/postfix/main.cf
の2個だが、ごく標準的なメールサーバの構築であれば、「/etc/postfix/main.cf」のみの編集で用は足りるはず。で、このファイルをviで開くと英語でコメントたっぷりに記述されていて、もう何から手を付けたらよいものか皆目検討もつかないのだが、重要で最低限必要な設定内容というと↓こんな具合。
たったこれだけ。重要なポイントだけかいつまんで説明すると・・・
「mail_owner = postfix」・・・postfixを動作させるLinuxユーザアカウント名。rootやnobodyは使用すべきではない。セキュリティホールのリスクを少しでも回避させるため。(完全には防げないけどな!)
「myhostname = asagi.myhome.ddns-service.com」・・・メールサーバのホスト名。「asagi」は自由につけたサーバの名前。「myhome.ddns-service.com」はDDNSサービスを申し込んだ際に発行されるはずのドメイン名。DDNSサービスによって変わるので、適切な名称を記述するように。
「mydomain = myhome.ddns-service.com」・・・このメールサーバが扱うべきメールのドメイン名。
「myorigin = $mydomain」・・・このメールサーバから送信され、ドメイン名が明示されないメールに付与されるドメイン名。変数「mydomain」と同じですよ・・・ということを指定している。
「mynetworks = 192.168.0.1/24 127.0.0.0/8」・・・このメールサーバから見て、『内側』のネットワークと見なされるネットワークアドレスの情報。『内側』のネットワークからは、自由にメールが送信できるが、これ以外(要するに『外側』)のネットワークからは、このメールサーバが管轄しているドメインにだけメールが送信できるという振る舞いになる。
「mydestination = $myhostname, $mydomain」・・・そしてこれが、このメールサーバが管轄しているメールアドレスのドメイン。繰り返しになるが、『外側』のネットワークから送信時に指定できるドメイン名はここに書いてあるものだけになる。
このように、「メールサーバの名前」「メールのドメイン名」「『内側』のネットワークアドレス」に関わる設定だけきちんとやっておけばよいということになる。
手順③:dovecotの設定ファイルを適切に記述する(必要な場合のみ)
編集すべきファイルは、/etc/dovecot.confである。が、こちらは標準のままでも問題ない。もし気になるようであれば、「listen = 」の項目にアドレスを記述しておくとかそれくらいか?
一端アーティクルを分ける。
てなわけで、久々(?)の「自宅でLinuxサーバ」を活用するネタ。今回はメールサーバ編。
判っていると思うが、メールサーバは特に第三者中継等でスパムメールばら撒き拠点として悪用されるリスクもあるので、そのあたりしっかり意識しておくよーに。
「メールサーバ」と一口で言っても、準備しなければならない点はWebサーバよりも多くて複雑だ。まずはメールの送信と受信で準備すべく項目は別々に存在するし、サーバからみた観点だけでなくネットワーク的にも一定量の知識が欠かせない。
メールを送信するための準備:
①当然、MTAを準備しなければならない
②DNSへの登録 (Aレコード、PTRレコード)
③プロバイダや接続環境によってはサブミッションポートやSMTP認証といった設定も必要
④第三者中継等が行われないことをしっかり確認する(こうした確認を行うサービスを提供しているサイトがあるのでこれを活用する)
メールを受信するための準備:
①当然、MTAを準備する。他にPOP3/IMAP4を処理するものも用意する
②DNSへの登録 (Aレコード、MXレコード)
③プロバイダや接続環境によってはサブミッションポートの設定も必要になることも
④自宅のルータについて、ポート開放・転送・フィルタリング等設定を行う
まず、MTAなどを用意する。
MTAとは、メールを転送してくれるエージェントのこと。sendmailとかqmailとかpostfixとかそういう連中で、プロトコルとして「SMTP」を用いる。
「手紙を書いた人間が、郵便ポストに手紙を投函する」 → SMTP
「郵便局員が郵便ポストから手紙を回収し、郵便局に送り届ける」 → SMTP
「集荷した郵便局から、配送先を管轄する郵便局へ郵便物を転送する」 → SMTP
「配送先を管轄する郵便局が、あて先の家の郵便受けまで手紙を送り届ける」 → SMTP
と、ここまでがSMTPの範疇。
しかしこれだけではメールがまだ読めない。「郵便受けから手紙を取り出す」動作が無いためである。
この動作については SMTP ではなく、POP3またはIMAP4といった別のプロトコルが管轄しているので、これはMTAではなくさらに別のエージェントを使用する。有名どころとしてはqpoperとか、dovecotとかだろうか。
極めて個人的な理由ながら、私はqmailが大嫌いなので、qmail以外の選択肢でなおかつラクチンポンで使えるものを探すと・・・
[root@asagi postfix]# yum search mta Loaded plugins: fastestmirror Determining fastest mirrors * addons: ftp.iij.ad.jp * base: ftp.iij.ad.jp * extras: ftp.iij.ad.jp * updates: ftp.iij.ad.jp addons | 951 B 00:00 base | 2.1 kB 00:00 base/primary_db | 2.2 MB 00:00 extras | 2.1 kB 00:00 extras/primary_db | 241 kB 00:00 updates | 1.9 kB 00:00 updates/primary_db | 446 kB 00:00 =================================================== Matched: mta ==================================================== postfix.x86_64 : メール転送エージェント postfix-pflogsumm.x86_64 : Postfix MTA 用ログサマライザ/アナライザ exim.x86_64 : The exim mail transfer agent exim-doc.noarch : Documentation for the exim mail transfer agent sendmail.x86_64 : 広く普及しているメール転送エージェント (MTA) sendmail-doc.x86_64 : Sendmail メール転送エージェントプログラムに関するドキュメント (以下略)
sendmailは設定で軽く死んでしまうのでpostfixをチョイス。(予定通り!w)
pop3/imap4のエージェントについては
[root@asagi postfix]# yum search pop3 Loaded plugins: fastestmirror Loading mirror speeds from cached hostfile * addons: ftp.iij.ad.jp * base: ftp.iij.ad.jp * extras: ftp.iij.ad.jp * updates: ftp.iij.ad.jp =================================================== Matched: pop3 =================================================== cyrus-imapd.x86_64 : A high-performance mail server with IMAP, POP3, NNTP and SIEVE support dovecot.x86_64 : Dovecot Secure imap サーバー fetchmail.x86_64 : A remote mail retrieval and forwarding utility imp-h3.noarch : The Internet Messaging Program: webmail access to IMAP/POP3 accounts. perl-Mail-POP3Client.noarch : POP3 client module for perl5
cyrus-imapdかdovecotかだけど、ひとまずdovecotをチョイス。よって、これらのインストールとしては・・・
yum install postfix dovecot
・・・ということになるね!
さて、メールサーバの構築としては概ね以下の手順になるかな
手順①:必要なエージェント類をインストールする
手順②:postfixの設定ファイルを適切に記述する(かならず!!)
手順③:dovecotの設定ファイルを適切に記述する(必要な場合のみ)
手順④:サービスの自動起動設定
手順⑤:ルータのポート開放・転送等の設定を導入する
メールサーバとしてはここまでだが、メールの送受信にはDNSとの連携が欠かせない。
固定されたIPアドレスをもっている場合はいざじらず、ごく一般的なネット接続サービスを利用している限りはインターネットに接続されるポイントのIPアドレスは固定されていないのが常なので、DDNSサービスを利用しなければならないことが一般的だろう。
この場合に、DDNSを自動更新したりするギミックを用意する必要が生じる。DDNSの更新ツールとして有名かつ秀逸なものには、「DiCE」だろうか。残念ながらyumではインストールできないので、コレのLinux版をビルドしてインストールすることとなる。
そんな訳で、
手順⑥:適切なDDNSサービスに登録する
※重要:MXレコードへの登録に対応しているサービスを選択すること
※重要:さらに、DiCEに対応しているサービスを選択すること
手順⑦:DiCEをダウンロード・ビルド・インストール
手順⑧:DiCEを適切に設定する
というわけで、postfixとdovecotはyumでインストール。DiCEについてはソースからビルドしてインストールということにする。
手順①:必要なエージェント類をインストールする
すでに示したとおり、yum install postfix dovecotで終了。
手順②:postfixの設定ファイルを適切に記述する(かならず!!)
インストールが終わったら、今度はpostfixの設定ファイルを編集する。
重要なファイルとしては、
/etc/postfix/master.cf
/etc/postfix/main.cf
の2個だが、ごく標準的なメールサーバの構築であれば、「/etc/postfix/main.cf」のみの編集で用は足りるはず。で、このファイルをviで開くと英語でコメントたっぷりに記述されていて、もう何から手を付けたらよいものか皆目検討もつかないのだが、重要で最低限必要な設定内容というと↓こんな具合。
queue_directory = /var/spool/postfix command_directory = /usr/sbin daemon_directory = /usr/libexec/postfix mail_owner = postfix myhostname = asagi.myhome.ddns-service.com mydomain = myhome.ddns-service.com myorigin = $mydomain mynetworks = 192.168.0.1/24 127.0.0.0/8 inet_interfaces = all mydestination = $myhostname, $mydomain unknown_local_recipient_reject_code = 550 alias_database = hash:/etc/aliases alias_maps = hash:/etc/aliases home_mailbox = Maildir/ mailbox_delivery_lock = fcntl, dotlock sendmail_path = /usr/sbin/sendmail.postfix newaliases_path = /usr/bin/newaliases.postfix mailq_path = /usr/bin/mailq.postfix setgid_group = postdrop html_directory = no
たったこれだけ。重要なポイントだけかいつまんで説明すると・・・
「mail_owner = postfix」・・・postfixを動作させるLinuxユーザアカウント名。rootやnobodyは使用すべきではない。セキュリティホールのリスクを少しでも回避させるため。(完全には防げないけどな!)
「myhostname = asagi.myhome.ddns-service.com」・・・メールサーバのホスト名。「asagi」は自由につけたサーバの名前。「myhome.ddns-service.com」はDDNSサービスを申し込んだ際に発行されるはずのドメイン名。DDNSサービスによって変わるので、適切な名称を記述するように。
「mydomain = myhome.ddns-service.com」・・・このメールサーバが扱うべきメールのドメイン名。
「myorigin = $mydomain」・・・このメールサーバから送信され、ドメイン名が明示されないメールに付与されるドメイン名。変数「mydomain」と同じですよ・・・ということを指定している。
「mynetworks = 192.168.0.1/24 127.0.0.0/8」・・・このメールサーバから見て、『内側』のネットワークと見なされるネットワークアドレスの情報。『内側』のネットワークからは、自由にメールが送信できるが、これ以外(要するに『外側』)のネットワークからは、このメールサーバが管轄しているドメインにだけメールが送信できるという振る舞いになる。
「mydestination = $myhostname, $mydomain」・・・そしてこれが、このメールサーバが管轄しているメールアドレスのドメイン。繰り返しになるが、『外側』のネットワークから送信時に指定できるドメイン名はここに書いてあるものだけになる。
このように、「メールサーバの名前」「メールのドメイン名」「『内側』のネットワークアドレス」に関わる設定だけきちんとやっておけばよいということになる。
手順③:dovecotの設定ファイルを適切に記述する(必要な場合のみ)
編集すべきファイルは、/etc/dovecot.confである。が、こちらは標準のままでも問題ない。もし気になるようであれば、「listen = 」の項目にアドレスを記述しておくとかそれくらいか?
一端アーティクルを分ける。
apache2で--with-mpm=worker付けてコンパイルできないとお嘆きのアナタ [Linux(Apache)]
やらかす人が結構いるようですが。。。
apache2をビルドしていて、MPMオプションを付けないで(または--with-mpm=preforkを付けて)configureしてmakeした後で--with-mpm=workerオプションを付けて再度ビルドしようとすると、環境によっては
こんなことになることが。
こんなエラーにお嘆きのアナタ!
make clean
で驚きの白さに!!(チガウ
一挙解決!この後にconfigureしてmakeしてmake installしてやってください。
というか、ビルドしなおすときにmake cleanするのは基本だよー。(笑)
某SIerから来ている人がコレに延々と悩んでいて萎えた。
apache2をビルドしていて、MPMオプションを付けないで(または--with-mpm=preforkを付けて)configureしてmakeした後で--with-mpm=workerオプションを付けて再度ビルドしようとすると、環境によっては
/usr/local/src/httpd-2.2.17/server/mpm/worker/worker.c:1203: undefined reference to `ap_thread_stacksize' collect2: ld returned 1 exit status make[1]: *** [httpd] エラー 1 make[1]: ディレクトリ `/usr/local/src/httpd-2.2.17' から出ます make: *** [all-recursive] エラー 1
こんなことになることが。
こんなエラーにお嘆きのアナタ!
make clean
で驚きの白さに!!(チガウ
一挙解決!この後にconfigureしてmakeしてmake installしてやってください。
というか、ビルドしなおすときにmake cleanするのは基本だよー。(笑)
某SIerから来ている人がコレに延々と悩んでいて萎えた。
改行コードを捨てる [小技(Linux)]
会社で、「あるテキストファイル(複数行記述されている)の改行コードを全部カットしたいんですけどー、なんかいい方法ないっすかね?」と聞かれた。彼はsedコマンドでいろいろ頑張っていたが、そういう用途には基本的にsedは不向きであることを教えて(出来ないわけじゃない)他の方法を探らせてみた。
…というか、彼はその方法を今まさに考え中だ。(笑)
コマンドを知っていても、その活用方法を知らなければ効果は半減する。英単語それ自体を知っていても、熟語とか慣用句、言い回しを知らなければ意味がないのと一緒だ。コマンドの「ボキャブラリー」をどれだけ増やせるかが問題なんだ!!
というわけで、彼が(なぜか)苦しんでいる間に、ここに正解をいくつか書いてしまおう(笑)。
なお、ここで使用するファイルは…
というファイルであるとする。
方法その1:trコマンド
てか、真っ先にコレが思いつくべきじゃないかと個人的には思うんだけども。(笑)
ファイルの一番最後の改行まで削除されてしまいコマンドプロンプトまでうしろにくっついているけどな!(大笑)
方法その2:awkコマンド
sedを思いつくならawkも忘れないで!!(笑)
trコマンドと全く一緒だ。
まあ、awkがアリだというのなら、perlでもphpでもrubyでもC/C++でもJavaでもアリじゃん…というツッコミはここでは禁止である。(笑)
方法その3:echoコマンドとcatコマンド…というか重要なのはむしろ「`」(バック・クォート)
これはtrコマンドとかとちょっと見栄えが変わるけども、「1行にする」という命題は一応クリアするぞ!?
改行がスペースに変換されて並んでますな。
さて。彼は一体どんな方法を思いつくだろうか!!!!
若人よがんばれ!!(笑)
…というか、彼はその方法を今まさに考え中だ。(笑)
コマンドを知っていても、その活用方法を知らなければ効果は半減する。英単語それ自体を知っていても、熟語とか慣用句、言い回しを知らなければ意味がないのと一緒だ。コマンドの「ボキャブラリー」をどれだけ増やせるかが問題なんだ!!
というわけで、彼が(なぜか)苦しんでいる間に、ここに正解をいくつか書いてしまおう(笑)。
なお、ここで使用するファイルは…
[root@sawako tmp]# cat /tmp/test.txt Yui Mio Ritsu Tsumugi Azusa
というファイルであるとする。
方法その1:trコマンド
てか、真っ先にコレが思いつくべきじゃないかと個人的には思うんだけども。(笑)
[root@sawako tmp]# tr -d "\n" < /tmp/test.txt YuiMioRitsuTsumugiAzusa[root@sawako tmp]#
ファイルの一番最後の改行まで削除されてしまいコマンドプロンプトまでうしろにくっついているけどな!(大笑)
方法その2:awkコマンド
sedを思いつくならawkも忘れないで!!(笑)
[root@sawako tmp]# awk '{printf "%s",$0}' /tmp/test.txt YuiMioRitsuTsumugiAzusa[root@sawako tmp]#
trコマンドと全く一緒だ。
まあ、awkがアリだというのなら、perlでもphpでもrubyでもC/C++でもJavaでもアリじゃん…というツッコミはここでは禁止である。(笑)
方法その3:echoコマンドとcatコマンド…というか重要なのはむしろ「`」(バック・クォート)
これはtrコマンドとかとちょっと見栄えが変わるけども、「1行にする」という命題は一応クリアするぞ!?
[root@sawako tmp]# echo `cat /tmp/test.txt` Yui Mio Ritsu Tsumugi Azusa [root@sawako tmp]#
改行がスペースに変換されて並んでますな。
さて。彼は一体どんな方法を思いつくだろうか!!!!
若人よがんばれ!!(笑)
ファイルを置きすぎたディレクトリでファイルの一覧が見たい時 [小技(Linux)]
1つのディレクトリの中に、ファイルを超大量に置いてはいけないということは、サーバ管理の鉄則でもありますが(特にext3とかな!)、たまーにやっちゃう人がいますね。(笑)1つのディレクトリに数千ファイルとか1万ファイルとか!!!!!!
で、そんなディレクトリでlsなんてやっちまった日にゃ…
もう、いやな予感しかしないディレクトリがありますね?^-^
では、ls -la してみましょう!!!
へんじがない。ただのしかばねのようだ・・・
てな具合になっちまう訳ですよもう。
でも、場合によっては、ど~~~~~~しても、ファイルのリストが見たいの!みたいな場合も有りますよね?
そんなあなたには、findコマンドがお役に立ちます。^-^
ひとまず、ファイル名とかはこれで確認できます。
で、そんなディレクトリでlsなんてやっちまった日にゃ…
[root@konata cache_page]# ls -la 合計 21448 drwxrwxrwx 127 dev dev 4096 4月 4 21:11 . drwxrwxrwx 3 dev dev 4096 6月 30 2009 .. (途中省略) drwxrwxrwx 2 dev dev 6254592 4月 4 21:16 pickup (さらに省略) drwxrwxrwx 362 nobody nobody 1286144 4月 4 21:17 announce drwxrwxrwx 2 dev dev 6197248 4月 4 21:17 index drwxrwxrwx 2 dev dev 86016 1月 8 16:19 index2 drwxrwxrwx 2 dev dev 2994176 3月 1 2010 index3 (以下略)
もう、いやな予感しかしないディレクトリがありますね?^-^
では、ls -la してみましょう!!!
[root@konata cache_page]# cd pickup [root@konata pickup]# ls -la
へんじがない。ただのしかばねのようだ・・・
てな具合になっちまう訳ですよもう。
でも、場合によっては、ど~~~~~~しても、ファイルのリストが見たいの!みたいな場合も有りますよね?
そんなあなたには、findコマンドがお役に立ちます。^-^
[root@konata pickup]# find . -print . ./cache_baea74f5ce6b3ee89c4d2493b93240ee_cc61cc31dd333eac4b580d ./cache_baea74f5ce6b3ee89c4d2493b93240ee_d367f0559782ffdebddfe3 ./cache_baea74f5ce6b3ee89c4d2493b93240ee_b246d51c1e42cbad61e348 ./cache_baea74f5ce6b3ee89c4d2493b93240ee_14fcf1db4202c611dd0260 ./cache_baea74f5ce6b3ee89c4d2493b93240ee_dd11224a64b71d5622c3c3 ./cache_baea74f5ce6b3ee89c4d2493b93240ee_f558391470dfa0f7cf9407 ./cache_baea74f5ce6b3ee89c4d2493b93240ee_57f72ef84cda3d2b99c158 ./cache_baea74f5ce6b3ee89c4d2493b93240ee_b5a396b0c7ff57aa323200 ./cache_baea74f5ce6b3ee89c4d2493b93240ee_c8687e129ad9c840419b77 (ファイルの一覧がだーーーーーーーっと表示)
ひとまず、ファイル名とかはこれで確認できます。
計画停電とLinux [小技(Linux)]
まずは、遅ればせながら東北関東大震災で被災された皆様には心よりお見舞い申し上げます。
さて、現在東京電力エリア内では「計画停電」真っ盛りですが、計画停電の時間が始まるまでにはなんとかしてサーバを自動でシャットダウンしたいものです。
そこで、その方法を紹介します。
atコマンドを使います。
と、その前に、まずは「atd」が起動していることを確認しましょう。
3行目の「/usr/sbin/atd」がソレです。起動していない場合は、 service atd start なりしておきましょう。自動起動の設定なら chkconfig atd on です。
そして、計画停電が6:20から開始される場合なら、5分前にシャットダウンしておくとすると
at 6:15
とか実行します。すると…
とかプロンプトが表示されますので、ここにシャットダウンコマンドを記述します。
↑まずはこんな感じ。そして、Enterキーを忘れずに押しておきましょう。2行目のプロンプトが表示されます。
↑こうなる。そしたら、「Ctrl + D」でプロンプトを抜けます。
というように、「ジョブID」とそのジョブが実行される正確な日時が表示されます。
ちなみに、atコマンドに指定した時刻が…
① まだ到来していない場合
(例)atコマンドを入力した時間が12:00で、atコマンドの引数に指定した時間が18:00だった場合
→その日の18:00に実行されます
② もう過ぎちゃった場合
(例) (例)atコマンドを入力した時間が12:00で、atコマンドの引数に指定した時間が06:00だった場合
→次の日の06:00に実行されます
ちゃんとatコマンドによるジョブが登録されたかどうか確認したい場合は、「atq」コマンドで確認できます。
atqコマンドで表示されているのは、ジョブIDが「3」で、そのジョブは2011-03-24の06:20に実行されることがわかります。
ジョブの詳細が知りたい場合は、「at -c」で見ることが出来ます。-cオプションに続けてジョブIDを指定します。
環境変数の設定が自動的に行われるので、最初びっくりするかもしれませんが、最後のほうに「shutdown -h now」がちゃんと追加されていることがわかります。
「間違えて登録しちゃった!」という場合、ジョブを削除するのは「atrm」コマンド。ジョブIDを続けて指定するとそのジョブが削除されます。
↑こんな具合。
あとは時間が来ればサーバがシャットダウンされます。
ところで、東京電力が公表している計画停電の予定に併せて、今日・明日の分だけでなくもっと先の予定まで登録しておきたい!という場合にも対応できます。
いちいちatコマンドでshutodownと書くのは面倒くさいので、まず最初に実行したいコマンドを記述したファイルを作成しておきます。例えばこんな具合。
echo "shutdown -h now" > /tmp/command.txt
atコマンドに「-f」オプションを追加ます。
先ほど紹介したときに時刻だけを記述した項目には日付も同時に指定することができます。
例えば、2011年3月31日の6:15にサーバをシャットダウンしたいなら、
at -f /tmp/command.txt 06:15 03/31/2011
と、時間と日付を指定すればOK。
なお、日付のところに「tomorrow」と書けば、「明日の」6:15に実行されるし、「今から1時間後」という指定も可能で、
at -f /tmp/command.txt now + 1 hour
と指定すればよい。他にも便利で楽しい日時の指定方法があるが、紹介してると終わらなくなるので(笑)基本的なものだけ紹介した。
さて、現在東京電力エリア内では「計画停電」真っ盛りですが、計画停電の時間が始まるまでにはなんとかしてサーバを自動でシャットダウンしたいものです。
そこで、その方法を紹介します。
atコマンドを使います。
と、その前に、まずは「atd」が起動していることを確認しましょう。
[root@haruka ~]# ps -ef | fgrep atd root 1157 16571 0 11:14 pts/5 00:00:00 fgrep atd rpcuser 2667 1 0 Jan08 ? 00:00:00 rpc.statd root 2870 1 0 Jan08 ? 00:00:00 /usr/sbin/atd
3行目の「/usr/sbin/atd」がソレです。起動していない場合は、 service atd start なりしておきましょう。自動起動の設定なら chkconfig atd on です。
そして、計画停電が6:20から開始される場合なら、5分前にシャットダウンしておくとすると
at 6:15
とか実行します。すると…
[root@haruka ~]# at 6:15 at>
とかプロンプトが表示されますので、ここにシャットダウンコマンドを記述します。
[root@haruka ~]# at 6:15 at> shutdown -h now
↑まずはこんな感じ。そして、Enterキーを忘れずに押しておきましょう。2行目のプロンプトが表示されます。
[root@haruka ~]# at 6:15 at> shutdown -h now at>
↑こうなる。そしたら、「Ctrl + D」でプロンプトを抜けます。
[root@haruka ~]# at 6:15 at> shutdown -h now at> job 1 at 2011-03-24 06:15
というように、「ジョブID」とそのジョブが実行される正確な日時が表示されます。
ちなみに、atコマンドに指定した時刻が…
① まだ到来していない場合
(例)atコマンドを入力した時間が12:00で、atコマンドの引数に指定した時間が18:00だった場合
→その日の18:00に実行されます
② もう過ぎちゃった場合
(例) (例)atコマンドを入力した時間が12:00で、atコマンドの引数に指定した時間が06:00だった場合
→次の日の06:00に実行されます
ちゃんとatコマンドによるジョブが登録されたかどうか確認したい場合は、「atq」コマンドで確認できます。
[root@haruka ~]# atq 3 2011-03-24 06:15 a root [root@haruka ~]# date 2011年 3月 23日 水曜日 11:25:23 JST
atqコマンドで表示されているのは、ジョブIDが「3」で、そのジョブは2011-03-24の06:20に実行されることがわかります。
ジョブの詳細が知りたい場合は、「at -c」で見ることが出来ます。-cオプションに続けてジョブIDを指定します。
[root@haruka ~]# at -c 3 #!/bin/sh # atrun uid=0 gid=0 # mail root 0 umask 22 HOSTNAME=haruka.mycompany.com; export HOSTNAME SHELL=/bin/bash; export SHELL (途中省略) shutdown -h now [root@haruka ~]#
環境変数の設定が自動的に行われるので、最初びっくりするかもしれませんが、最後のほうに「shutdown -h now」がちゃんと追加されていることがわかります。
「間違えて登録しちゃった!」という場合、ジョブを削除するのは「atrm」コマンド。ジョブIDを続けて指定するとそのジョブが削除されます。
[root@haruka ~]# atrm 3 [root@haruka ~]# atq
↑こんな具合。
あとは時間が来ればサーバがシャットダウンされます。
ところで、東京電力が公表している計画停電の予定に併せて、今日・明日の分だけでなくもっと先の予定まで登録しておきたい!という場合にも対応できます。
いちいちatコマンドでshutodownと書くのは面倒くさいので、まず最初に実行したいコマンドを記述したファイルを作成しておきます。例えばこんな具合。
echo "shutdown -h now" > /tmp/command.txt
atコマンドに「-f」オプションを追加ます。
先ほど紹介したときに時刻だけを記述した項目には日付も同時に指定することができます。
例えば、2011年3月31日の6:15にサーバをシャットダウンしたいなら、
at -f /tmp/command.txt 06:15 03/31/2011
と、時間と日付を指定すればOK。
なお、日付のところに「tomorrow」と書けば、「明日の」6:15に実行されるし、「今から1時間後」という指定も可能で、
at -f /tmp/command.txt now + 1 hour
と指定すればよい。他にも便利で楽しい日時の指定方法があるが、紹介してると終わらなくなるので(笑)基本的なものだけ紹介した。
クラスタシステムとssh [備忘録]
ちょっと番外編。
heartbeat等でクラスタシステムを構築した場合に、1点問題になることがある。それは「ssh」。
クラスタを構成する各ノードを指定してsshやslogin等を実行する場合は通常のサーバに対するものとなんら変わることが無いが、クラスタのVIPに対してアクセスしようとすると、クラスタの稼動系が切り替わったタイミングで…
こんな感じの(もっと違うメッセージになることもある)エラーになって困ってしまう。
これは、クラスタシステムに組み込まれているsshのキーペアがノードによって異なるために生じる問題だからだ。
上記の例(このblogでheartbeatの解説をしている環境)では、
・nfs001 … クラスタに参加しているノード その1
・nfs002 … クラスタに参加しているノード その2
・nfscl01 … クラスタシステムに割り当ててあるVIP(必ず稼動しているほうのサーバにアクセスできるアドレス)
ということになっているが、
という状態であれば、nfscl01というアドレスでアクセスできる先のサーバは「nfs001.mycompany.com」であるが、
という状態であれば、nfscl01というアドレスでアクセスできる先のサーバは「nfs002.mycompany.com」になってしまうのである。
クライアントからサーバにアクセスしたときに提示されるサーバの公開鍵が、「nfs001.mycompany.com」のものだったり、「nfs002.mycompany.com」のものだったりするから困った事態になってしまうのである。
そこで、解決方法の一つとしてよく用いられるのが、サーバ側のキーペアファイルを「nfs001.mycompany.com」と「nfs002.mycompany.com」とで同じものを用いてしまおうというもの。セキュリティ的にどうなの?という指摘があるかもしれないが、その辺はそういうことに詳しい人にお任せするとして、ここではこの方法でエラーを回避する方法を紹介する。
まず、手順は以下の通り。
①:片方のサーバのキーペアファイルを稼動系サーバからコピーして上書きする
②:サーバにアクセスするクライアントの「known_hosts」ファイルから、VIPに対するキーの記述されている行と、キーペアファイルをコピーして上書きしたクラスタノードの行を削除する
③:クラスタのVIPと、待機系サーバに対してsshあるいはsloginなどを実行する。
①:片方のサーバのキーペアファイルを稼動系サーバからコピーして上書きする
まず、サーバ側のキーペアファイルを統一する作業を行う。
サーバのsshキーペアファイルは、通常は/etc/ssh配下に保存されている。
このうちの、「ssh_host_*」の6ファイル(場合によっては4ファイルだったり、8ファイルだったりすることもあるが、その場合はそれら4ファイルまたは8ファイルの全てが対象となる。以下同じ)を、もう一方のクラスタノードからコピーしてきて上書きしてしまう。
ここでは、nfs002が稼動系でnfs001が待機系になっているので、nfs002 → nfs001とコピーすることにする。
scp -p nfs002:'/etc/ssh/ssh_host*' /etc/ssh/
これでキーペアファイルが上書きされる。なお、秘密鍵ファイルの(拡張子「.pub」が付いていない)ほうはパーミッションが600でなければならないので、必ずチェックするように。
そしたらsshdを一旦再起動する。
service sshd restart
これでサーバ側のキーペアファイルが更新された。
②:サーバにアクセスするクライアントの「known_hosts」ファイルから、VIPに対するキーの記述されている行と、キーペアファイルをコピーして上書きしたクラスタノードの行を削除する
さて。この状態だと、クライアントから見たらサーバの公開鍵が変更されているので、known_hostsに保存されている情報と食い違うこととなり、sshがエラーを返すようになってしまう。そこで、known_hostsから該当するサーバの情報を削除しなければならない。
known_hostsは、ログインディレクトリの下に「.ssh」というディレクトリが作成され、その中に保存されている。rootユーザーなら /root/.ssh/known_hosts だし、piro791というユーザーなら、おそらく /home/piro791/.ssh/known_hosts であるはずだ。
known_hostsがデカすぎて探すのが面倒なときは、わざとエラーを発生させて、そのメッセージの中から行数を取得するのがいい。(笑)例えば、このアーティクルの冒頭で紹介したsshのエラーだったら、
というように出ているので、「/root/.ssh/known_hosts」の5行目にその削除すべき行があることがわかる。これを削除すればよい。なお、サーバが複数のNICを持っていたり、Aliasアドレスを持っている場合は複数の行が記録されていることも考えられるので、それら全てを削除するように。
③:クラスタのVIPと、待機系サーバに対してsshあるいはsloginなどを実行する。
で、新しい公開鍵情報をknown_hostsに書き込む必要があるが、これはsshコマンドにやらせるのが面倒無いだろう。(コピー元になったサーバの行をコピーして編集してもいいけどね…)
こんな具合に、known_hostsに公開鍵情報を書き足してもいい?と質問してくるので、「yes」と答えればOK。
こんな具合に公開鍵が保存される。鍵交換が済んでいてパスワードなしでログインできるようになっていれば、これ以降のsshアクセスなら…
こんな風に改めて鍵交換をするまでも無くパスワードなしでアクセスすることが可能だ。
heartbeat等でクラスタシステムを構築した場合に、1点問題になることがある。それは「ssh」。
クラスタを構成する各ノードを指定してsshやslogin等を実行する場合は通常のサーバに対するものとなんら変わることが無いが、クラスタのVIPに対してアクセスしようとすると、クラスタの稼動系が切り替わったタイミングで…
[root@chiaki .ssh]# ssh nfscl01 uname -a @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY! Someone could be eavesdropping on you right now (man-in-the-middle attack)! It is also possible that the RSA host key has just been changed. The fingerprint for the RSA key sent by the remote host is 90:82:**:**:**:**:**:**:**:d1:56:72:61:05:b2:8b. Please contact your system administrator. Add correct host key in /root/.ssh/known_hosts to get rid of this message. Offending key in /root/.ssh/known_hosts:5 RSA host key for nfscl01 has changed and you have requested strict checking. Host key verification failed.
こんな感じの(もっと違うメッセージになることもある)エラーになって困ってしまう。
これは、クラスタシステムに組み込まれているsshのキーペアがノードによって異なるために生じる問題だからだ。
上記の例(このblogでheartbeatの解説をしている環境)では、
・nfs001 … クラスタに参加しているノード その1
・nfs002 … クラスタに参加しているノード その2
・nfscl01 … クラスタシステムに割り当ててあるVIP(必ず稼動しているほうのサーバにアクセスできるアドレス)
ということになっているが、
Node: nfs002.mycompany.com (6a838508-67eb-47f3-9a46-72e755b88326): online Node: nfs001.mycompany.com (47e72b74-c47c-426f-8dc4-18077e2dcd57): online Resource Group: nfs_service ipaddr (heartbeat::ocf:IPaddr): Started nfs001.mycompany.com
という状態であれば、nfscl01というアドレスでアクセスできる先のサーバは「nfs001.mycompany.com」であるが、
Node: nfs002.mycompany.com (6a838508-67eb-47f3-9a46-72e755b88326): online Node: nfs001.mycompany.com (47e72b74-c47c-426f-8dc4-18077e2dcd57): online Resource Group: nfs_service ipaddr (heartbeat::ocf:IPaddr): Started nfs002.mycompany.com
という状態であれば、nfscl01というアドレスでアクセスできる先のサーバは「nfs002.mycompany.com」になってしまうのである。
クライアントからサーバにアクセスしたときに提示されるサーバの公開鍵が、「nfs001.mycompany.com」のものだったり、「nfs002.mycompany.com」のものだったりするから困った事態になってしまうのである。
そこで、解決方法の一つとしてよく用いられるのが、サーバ側のキーペアファイルを「nfs001.mycompany.com」と「nfs002.mycompany.com」とで同じものを用いてしまおうというもの。セキュリティ的にどうなの?という指摘があるかもしれないが、その辺はそういうことに詳しい人にお任せするとして、ここではこの方法でエラーを回避する方法を紹介する。
まず、手順は以下の通り。
①:片方のサーバのキーペアファイルを稼動系サーバからコピーして上書きする
②:サーバにアクセスするクライアントの「known_hosts」ファイルから、VIPに対するキーの記述されている行と、キーペアファイルをコピーして上書きしたクラスタノードの行を削除する
③:クラスタのVIPと、待機系サーバに対してsshあるいはsloginなどを実行する。
①:片方のサーバのキーペアファイルを稼動系サーバからコピーして上書きする
まず、サーバ側のキーペアファイルを統一する作業を行う。
サーバのsshキーペアファイルは、通常は/etc/ssh配下に保存されている。
[root@nfs001 ~]# cd /etc/ssh [root@nfs001 ssh]# ls -la 合計 184 drwxr-xr-x 2 root root 4096 2月 9 12:36 . drwxr-xr-x 81 root root 4096 3月 18 04:02 .. -rw------- 1 root root 132839 9月 13 2010 moduli -rw-r--r-- 1 root root 1827 9月 13 2010 ssh_config -rw------- 1 root root 672 2月 28 14:22 ssh_host_dsa_key -rw-r--r-- 1 root root 590 2月 28 14:22 ssh_host_dsa_key.pub -rw------- 1 root root 963 2月 28 14:22 ssh_host_key -rw-r--r-- 1 root root 627 2月 28 14:22 ssh_host_key.pub -rw------- 1 root root 1675 2月 28 14:22 ssh_host_rsa_key -rw-r--r-- 1 root root 382 2月 28 14:22 ssh_host_rsa_key.pub -rw------- 1 root root 3323 9月 13 2010 sshd_config
このうちの、「ssh_host_*」の6ファイル(場合によっては4ファイルだったり、8ファイルだったりすることもあるが、その場合はそれら4ファイルまたは8ファイルの全てが対象となる。以下同じ)を、もう一方のクラスタノードからコピーしてきて上書きしてしまう。
ここでは、nfs002が稼動系でnfs001が待機系になっているので、nfs002 → nfs001とコピーすることにする。
scp -p nfs002:'/etc/ssh/ssh_host*' /etc/ssh/
これでキーペアファイルが上書きされる。なお、秘密鍵ファイルの(拡張子「.pub」が付いていない)ほうはパーミッションが600でなければならないので、必ずチェックするように。
そしたらsshdを一旦再起動する。
service sshd restart
これでサーバ側のキーペアファイルが更新された。
②:サーバにアクセスするクライアントの「known_hosts」ファイルから、VIPに対するキーの記述されている行と、キーペアファイルをコピーして上書きしたクラスタノードの行を削除する
さて。この状態だと、クライアントから見たらサーバの公開鍵が変更されているので、known_hostsに保存されている情報と食い違うこととなり、sshがエラーを返すようになってしまう。そこで、known_hostsから該当するサーバの情報を削除しなければならない。
known_hostsは、ログインディレクトリの下に「.ssh」というディレクトリが作成され、その中に保存されている。rootユーザーなら /root/.ssh/known_hosts だし、piro791というユーザーなら、おそらく /home/piro791/.ssh/known_hosts であるはずだ。
known_hostsがデカすぎて探すのが面倒なときは、わざとエラーを発生させて、そのメッセージの中から行数を取得するのがいい。(笑)例えば、このアーティクルの冒頭で紹介したsshのエラーだったら、
Offending key in /root/.ssh/known_hosts:5
というように出ているので、「/root/.ssh/known_hosts」の5行目にその削除すべき行があることがわかる。これを削除すればよい。なお、サーバが複数のNICを持っていたり、Aliasアドレスを持っている場合は複数の行が記録されていることも考えられるので、それら全てを削除するように。
③:クラスタのVIPと、待機系サーバに対してsshあるいはsloginなどを実行する。
で、新しい公開鍵情報をknown_hostsに書き込む必要があるが、これはsshコマンドにやらせるのが面倒無いだろう。(コピー元になったサーバの行をコピーして編集してもいいけどね…)
[root@chiaki .ssh]# ssh nfs001 uname -a The authenticity of host 'nfs001 (172.16.40.101)' can't be established. RSA key fingerprint is 90:82:**:**:**:**:**:**:**:d1:56:72:61:05:b2:8b. Are you sure you want to continue connecting (yes/no)?
こんな具合に、known_hostsに公開鍵情報を書き足してもいい?と質問してくるので、「yes」と答えればOK。
[root@chiaki .ssh]# ssh nfs001 uname -a The authenticity of host 'nfs001 (172.16.40.101)' can't be established. RSA key fingerprint is 90:82:**:**:**:**:**:**:**:d1:56:72:61:05:b2:8b. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'nfs001,172.16.40.101' (RSA) to the list of known hosts. Linux nfs001.mycompany.com 2.6.18-194.32.1.el5 #1 SMP Wed Jan 5 17:52:25 EST 2011 x86_64 x86_64 x86_64 GNU/Linux
こんな具合に公開鍵が保存される。鍵交換が済んでいてパスワードなしでログインできるようになっていれば、これ以降のsshアクセスなら…
[root@chiaki .ssh]# ssh nfs001 netstat -in Kernel Interface table Iface MTU Met RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg eth1 1500 0 33452 0 0 0 33410 0 0 0 BMRU eth2 1500 0 33540 0 0 0 33497 0 0 0 BMRU eth4 1500 0 986955 0 0 0 2141 0 0 0 BMRU lo 16436 0 39845 0 0 0 39845 0 0 0 LRU
こんな風に改めて鍵交換をするまでも無くパスワードなしでアクセスすることが可能だ。
/proc/cpuinfoの「flags」調査 [備忘録]
http://piro791.blog.so-net.ne.jp/2010-07-22
↑このページの/proc/cpuinfo の「flags」についての調査結果を追記しました。
AMD…もうちょっと詳しい情報が欲しいなあ。でも、別にアセンブラを使うわけでもないサーバ屋さんにはそれほど必要ないか。。。。。(笑)
↑このページの/proc/cpuinfo の「flags」についての調査結果を追記しました。
AMD…もうちょっと詳しい情報が欲しいなあ。でも、別にアセンブラを使うわけでもないサーバ屋さんにはそれほど必要ないか。。。。。(笑)