メールサーバのSPF(Sender Policy Framework)対応化

送信元アドレスを偽称した迷惑メール、フィッシングサイトへの誘導メールなどの被害を軽減できる仕組み。

【送信側の設定】
送信側がSPFに対応するメリットは、自分の管理ドメインになりすまされたメールの送信をSPFチェックによって判定できるようになる。(受信側が対応されていれば、自分の管理ドメインによるなりすましメール被害を軽減できる)

DNSサーバにSPFレコード(TXTレコード)を登録しておく
IN TXT v=spf1 +ip4:(送信元IPv4アドレス) -all”

MyDNSの場合には自動的にSPFレコードが追加される。
SPFレコードの詳細は送信ドメインを認証するためのSPFレコードに詳しくなろうが詳しい。

併せて、DMARCレコードにも対応しておくことが望ましい
_dmarc IN TXT v=DMARC1; p=none; rua=mailto:(集計レポートの送付先)
DMARCレコードは、MyDNSを使っている場合には、個別にレコード定義する必要がある。

【受信側】
受信側がSPFに対応するメリットは、SPFレコードが登録されたドメインにてなりすましされたメールを受信しないようにできることで、なりすましメールの被害を軽減できる。

Postfixの場合には、「備忘録」 Postfix(CentOS)でSPF対応しちゃう。に従って実装するとSPF対応できるようになる。

SPF対応するとメールヘッダに
Received-SPF: Pass (sender SPF authorized) …
のようなヘッダが付加されるようになる。

また、
$sudo grep ‘policyd-spf’ /var/log/maillog
とすることで正常に動作していることを確認することが出来る。

また、SPFチェックに引っかかる場合には、
Received-SPF: Permerror (SPF Permanent Error: Void lookup limit of 2 exceeded)
Received-SPF: Softfail (domain owner discourages use of this host)
Received-SPF: Neutral (access neither permitted nor denied)
Received-SPF: Fail (SPF fail – not authorized)
のようなヘッダが記録される。

SPFレコードが登録されていないドメインからのメールを受信した場合には、
Received-SPF: None (no SPF record)
のようなヘッダが記録される。

Received-SPF の内容については、postfix で postfix-policyd-spf-python ( or postfix-policyd-spf-perl ) を使ってSPF認証する(CentOS/ScientificLinux編)に詳しく記載されているので、参考になる。

TCPフォールバック

DNSの問い合わせに対する回答が512byteを超える場合にUDPプロトコルではなくTCPプロトコルによって応答される事象を示す。
なぜudp/53宛に問い合わせしたのになぜTCPプロトコルで応答するのか?
– MTUの最小値である576byteDNSの応答パケットとしては512byte(現在は、576byteという経路はほとんどなく、1980年当初の事情を引きずっている)を超えてしまうと経路によってはパケット分割されてしまう。1パケットで処理できるようにRFC1035にて512byte以下の応答パケットに制限されると規定されている。そのため、512byteを超える場合には、TCPプロトコルで応答する。
○備考
DNSクライアント(リゾルバ)はudpプロトコルの任意のポートをバインドして問い合わせしており、応答があるまでバインドし続ける。DNSサーバーは送信元ポートを送信先ポートにし、送信元ポートを53番ポートにして応答することで途中の(外→内の通信を制限する)F/Wを通過することができ(るように設定されていることが一般的であり)、またリゾルバは応答を受けることができる。TCPフォールバックされる場合、UDPの応答パケットにてTCPプロトコルによって再度接続確立が行われて、TCPプロトコルによって応答される。
○なぜDNSはTCPのみでやり取りしてはいけないのか?(個人的な考察)
・SYN Flood攻撃により容易にサービス拒否に追い込まれる
・スリーウェイハンドシェイクをしなければならず、DNSの応答パケットの大きさにかかわらず、絶対的な通信量が多くなってしまう
・下位互換性がなくなる
詳しくはJPRSの資料を参考にするとわかりやすい。

ゾーン転送のチェック

@ITに記載があるが、Windowsのクライアント端末からもゾーン情報の内容をチェックしたり、転送が正しく行えるかをチェックすることが出来る。
nslookupコマンドでインタラクティブモードに入った後
server (プライマリDNS)
ls -d (ゾーン情報を転送したいドメイン)
で調べることが出来る。
なお、Linuxの場合には、
dig @(ネームサーバー) (ゾーン情報を転送したいドメイン) axfr

DNSの変更を早く伝播させるか方法

違うホスティングサーバーにドメインを移行したりするときには、DNS情報が早く切り替わったほうがメールが旧サーバーと新サーバーにばらばらに届いたりする時間を短くできる。さて、DNSの変更をできる限り早く伝播させるにはどうしたらよいか?
キーポイントは、TTLとSOAレコードのRefreshにある。TTLについては、DNSのTTLで記載をしているが、SOAレコードのTTLではなく、$TTLの値を変更しておかなければならない。この時間は、セカンダリDNSを除くDNSサーバーがDNS情報に対する問い合わせ結果を保持している時間となる。
$TTLをいくら変更しても、DNSがプライマリDNSサーバーを参照するか、セカンダリDNSを参照するかまでは制御できないので、セカンダリDNSの情報をいかにはやく更新するかもポイントになる。(プライマリDNSの情報が更新されても、セカンダリDNSの情報が更新されず、その古いDNS情報を全世界のDNSサーバーのうちの一部が参照しているからだ)
@IT SOAレコードには何が記述されている?にもあるが、セカンダリDNSが定期的にプライマリDNSからデータを更新し続けることができてさえいれば、その更新間隔は、Refresh値に基づく。SOAレコードのTTLはDNS情報がないということを保持している時間でしかない。
まとまると、引越しをするにあたって必要なのは、$TTLとSOAレコードのRefresh値を短くすればするだけ良い。しかしながら、$TTLを短くしすぎると更新負荷が急激に上がる。ただ、SOAレコードのRefresh間隔は短くしておいてもゾーン情報のコピーがされるセカンダリサーバーの数が限られているので、さほど負荷は上がらない。(自分の管理していないサーバーで勝手にゾーン情報をコピーしているようなサーバーがなければの話だが。。。)
たとえば、$TTLを1800秒、Refresh値を600秒とかにしたらどうだろうか?もし変更したらしばらくはサーバーの負荷をチェックしておいたほうがDNSの設定を変更したばっかりにサーバーダウンになるようでは洒落にならない。

DNSのTTL

DNSのTTL設定といえば、SOAレコードのTTLだとずっと思っていたのだが、実はSOAレコードのTTLはスレーブDNSサーバーがプライマリDNSサーバーからDNS情報をキャッシュし続ける時間であり、ネガティブキャッシュと呼ばれているそうだ。
実は、それ以外のDNSサーバー(DNSサーバーでなくてもローカルマシンがDNSをキャッシュする場合においても)がDNS情報をキャッシュする時間は、SOAレコードに指定されたTTL時間ではない。
@IT 第2回 すべての基礎、マスター・ゾーンサーバの設定にあるように、zoneファイルの先頭のほうにあるにある$TTL指定がゾーン全体のTTLとなり、レコード個別のTTLも指定可能である。
以上の理由により、サーバー間で引越しをするようなことがあれば、事前にTTLを減らしておいて変更を早く適用できるようにする必要があるが、SOAレコードのTTLだけでなく、$TTLの値も減らしておく必要があるというわけだ。
それでは各端末において、特定のドメインの残りキャッシュ時間を知るためにはどうすればよいか。
Linuxにおいては、digコマンドが利用できるので、以下のようにやると良い。
dig @localhost www.development-network.net a ※localhostにDNSサーバーがたっている場合
※一部省略
;; ANSWER SECTION:
www.development-network.net. 900 IN A 124.98.21.52
ここに 900 という数値があれば、残り900秒でキャッシュが更新されることを示している。何度か実行してみると、900の数値が経過時間分だけ減っていることがわかる。
Windows XPにおいては、ipconfig /displaydns とするとローカルキャッシュの残り時間を知ることが出来る。
www.development-network.net
—————————————-
Record Name . . . . . : www.development-network.net
Record Type . . . . . : 1
Time To Live . . . . : 845
Data Length . . . . . : 4
Section . . . . . . . : Answer
A (Host) Record . . . : 124.98.21.52
ローカルキャッシュがクリアされる条件は、DNSサーバーを変更するか、マシンを再起動するか、ipconfig /flushdnsコマンドが発行されたときである。

ダイナミックDNS

ダイナミックDNSとは固定のグローバルIPアドレスを取得できないユーザーが自宅サーバーを公開する際にマイドメインでアクセスするために必要なDNSのこと。一般的にはDiceのようなソフトウエアを使って、IPアドレスの変更をダイナミックDNSに通知する必要がある。
ダイナミックDNSには国内にも複数サービスがあるが、実際に僕が使っているのは以下の2つ。
ddo.jp

ddo.jpのサブドメインであればフリー。それ以外は月額500円。メール転送やオフライン時のWeb転送、MXレコードの複数設定ができるので、より安定したサービスを行いたい場合に向いている。

mydns.jp

フリーのダイナミックDNS。マイドメインも無料で登録できる。POP認証によりIPアドレスの変更を通知できる。MXレコードとCNAME(最大5つ、なお*指定可)レコードが設定できる。

フィッシングとファーミング

フィッシングとファーミングの違いは以下の通り
フィッシング
何らかの方法(URL偽装)などを利用して正規のサイトとそっくりの偽サイトに誘導し、実際にログインさせることでログイン情報などを取得する。URLを注意深くチェックすればフィッシングサイトに引っかかることは少ないが、Basic認証対応のURLの場合、ライトユーザーにはチェックが難しい。このURLでアクセスできなくなっているブラウザも存在する。
Basic認証対応のURLパターン:http://(ユーザー名):(パスワード)@(ドメイン名)/
http://www.yahoo.co:jp@hogehoge.com/
というサイトがYahooのサイトと認識されても不思議はない??(でも実際のところ無理がありそうな。。。)

ファーミング
DNSの解決の仕組みを悪用して、ホスト名の解決を正規のIPアドレスではなく、悪意あるホストのIPアドレスを返答させる。これを実現するには、DNSサーバーのキャッシュ情報を書き換える(DNSポイズニング)か、hostsファイルをウィルスなどによって書き換える。
この方法が成功すれば、ユーザーが良く訪れる信用あるURLが実は詐称サイトということになる。
この検出はかなり難しい。正しいhostsファイルのMD5を保存しておいて、それが変わった時点でhostsファイルを信頼しないしかない。あとは信頼あるDNSサーバーを登録するとか。。。もはやDNSサーバーが信頼できないなんて、ありえない事態だ。