kmuto’s blog

はてな社でMackerel CREをやっています。料理と旅行といろんなIT技術

技術書典13 読書感想文その3

技術書典13の本、今日は無料系の3冊と、購入の1冊。

 

techbookfest.org

『キーボード/マウス エミュレータ解説書』

キーボード/マウスのHIDエミュレートUSBとして振る舞い、シリアル回線からコントロールできるというIC、CH9329。ベンダーID/プロダクトIDも正規のが付いていて、適当なものを使う必要もなくちゃんと認識されるとのこと。
こういうのはハッキング用の怪しい用途だろうか…と思ったけど、いろいろなコンビネーションもプログラムで指示できるから、テストやマクロ入力に便利らしい(本書ではPythonとCの例あり)。ネット上の記事で見ると自作キーボードを作るのにも使えるというのがあって、なるほど。

 

techbookfest.org

ニフティスクラム

ニフティ社のスクラムマスターたちのスクラム経験談集。

スクラムの本は業務で何冊か作ってはいるのだけど、なかなか自身の業務に適用するというところまでは到達できていない。本書の制作自体ではカンバンを進捗管理に使われたそうだけど、ほかにもスクラムのやり方をこういう風に導入していた、という話があったらぜひお伺いしたいところ。

 

techbookfest.org

プログラマーのための技術者列伝3』

「プログラミングやコンピュータに関連する人物はほとんど登場しない」の名のとおり、遊戯・楽器・兵器・印刷・宇宙開発といった分野でのエンジニアの伝記。よく知られている人物から「ほう、このような方が」までさまざまな人が登場する。昔こういう伝記集読んでいたなぁとなんとなく懐しい気持ちになった。

 

techbookfest.org

『正社員・フリーランス エンジニア徹底比較』

正社員エンジニアとフリーランスエンジニアの比較論。少々ポジショニングトークフリーランスに寄りすぎていないかなと感じたけど、あくまで筆者の業務経歴・経験からきていてフィルターはあるというただし書きは冒頭で述べられている。とはいえ、企業でのバックエンド開発2年からフリーになって未経験のAndroid開発・iPhone開発で成果を出して急成長できるというのは、元々理解力と推進力のあるつよつよエンジニアだからこそという気もしたり。

 

さて残りはあと2冊、と。

技術書典13 読書感想文その2

今日も技術書典13で買った本を少し読み進める。

techbookfest.org

『ハッキング・ラボで遊ぶために辞書ファイルを鍛える本』ipusironさんの、あいかわらずすごい情報量。
派手さこそないものの、パスワードクラッキングの上で欠かざるアイテムである辞書ファイル。ハニーポットsshログイン用意しておいて、攻撃者の試行パスワード入力(鮮度や品質の良い可能性がある)を集積する、というの正直賢いなと思った。

rockyouファイルの解析からのパスワード選択傾向分析、crunchでの文字組み合わせ辞書作成、cuppでの標的型辞書作成、KwProcessorでのキーマップウォーキング辞書作成、最後は辞書を使ってのJohn the RipperやHydraによる実行、とさまざまなツールが登場し、自分のパスワード選定に薄ら寒い思いも感じる。

 

techbookfest.org

『セキュリティチェックシートの薄い本』技術書典のTL眺めててタイトルや概要で一番興味を惹かれた1冊だったので、読むのを楽しみにしていた。

チェックシートは本来は発注者側の発注者責任を果たすためのもので、チェック項目をそもそも発注者が理解していないと意味がない。想定されるリスクに対してサービス提供者がそれにどのような低減策をとっており、それを受容できるかの判断をすべきである、というのが本書の主張で、大いに同意できる。
発注者からのおかしなチェックシートに対してどう答えるかということから始まってはいるが、大きな目標としては発注者の意識改革を求めていくことにあるのかな、と読んだ。JTCでも大元のほうは理解している方々は多いものの、そこからの1次受け、2次受けあたりが一番厄介そうな気がする。

本筋とはまったく関係ないが、ちょっと変わった組版だったので奥付を見たところ、FlightBooks https://flightbooks.pub/ で作られてるとのことだった。ベタ組み前提のようなのだけど、FlightBooksの制作利用者は和・欧・数・記号の文字をおそらく多用するので、少なくとも本文段落についてはjustify(均等割り付け)をデフォルトにしたほうがよいのではないだろうか(今は左寄せなので欧文や数字が混じるところで右側がガタつきやすい)。フォントをアウトラインにしているのはCSSタイプセットエンジンでType3系なのかな。

 

techbookfest.org

『技術書典13記念NFT発行できるかな?(仮)』お世話になっている@vvakame先生の恒例の勢い書き…かと思ったら今回大著だな!とまずそこに驚いた。しかし中身は勢い書き日記の収集だったので「そうそう、こういうのでいいんだよ…」という妙な喜びがある。

業務も技術書典もこなしつつ、毎日けっこうちゃんと進捗してるのは本当にすごいし尊敬する。

紙面に関しては、Re:VIEWてくぶスタイルのデフォルトとしてURL折り返し促進を入れちゃったほうがよさそうかなぁと思った。itemizeとfootnoteでなんでこうなりやすいのかについてはTeXの深い沼っぽくてよくわかっていない(ボックスの何かの違いかな)。コードリストのほうはminted使うようにするか(pygments前提になるのと-shell-escapeを要するのでデフォルトにはしづらい)、物理的にreレベルで改行してねという感じでよろしくお願い。

 

techbookfest.org

『メールを取り巻くテクノロジー』メールの、特にSMTP送信寄りの話。SMTPは渋谷駅みたいなもので、一度更地にして全部作り直すべきでは…というくらいな代物になっているけど、もはや壊すこともできないので、DNSの力も借りてなんとかしてみようという状態。そういった今どきのSMTP送信技術まわりをざっくり紹介している。

著者陣は高レピュテーションでsender代行を行うblastengineを開発提供していて、なるほどこういうビジネスもあるのか、と。でも確かに、昔業務でIPブロック範囲だとレピュテーション指定で到達させてくれない海外大手(日本のブロックをかなり限定していたっぽい)に届けるために別ルートでMX立てて送ったことがあったし、今はSophos Mailで送信も任せるようにして向こうに届かない問題はほぼ解決したので、送信だけでも需要は高そうではある。

これを読んでいるうちに一念発起し、ずっと「やらないとな〜」と思っていた重い腰を上げておうちサーバもSPF/DKIM/DMARCに対応したので、マジ感謝を捧げたい。

kmuto.hatenablog.com

 

 

DebianのPostfixでのSPF / DKIM / DMARC設定 with Route 53

techbookfest.org

の感想文を書こうと読み進めていたのだが、読んでいるうちにいいかげんおうちサーバのkmuto.jpもなんとかしないとな、と重い腰を上げることにした。重要な連絡メールもたまに受けているのに、spam多すぎてSMTPへの呪詛が強まっていた今日この頃だったので、ちょうどいいきっかけである。

 

実際のところ、先人の

www.hs3.org

https://www.tyksnet.com/blog/archives/2593

だけでほぼ解決してしまうので、感謝してこれを読みましょう。で終わってしまうんだけど、ネットの情報は永遠に残るわけではないので、備忘録も兼ねてやり方はほぼコピー、内容は抜粋という雑なものではあるが記録しておく。

 

OSはDebian 11 bullseye, 現状のstableバージョン。DNSAWSのRoute 53に置いている。MTAはPostfixで、ここにSPFDKIM、DMARCを設定することにした。

 

SPF

送信設定は今の時代は必須なので、さすがにこれは以前から設定している。Route 53のドメインレコードとして、

  • レコード名: 空白.ドメイン
  • レコードタイプ: TXT
  • 値: v=spf1 +ip4:IPv4アドレス +ip6:IPv6アドレス ~all (kmuto.jpでは自身で出してるので普通に自身のアドレス。メールアプライアンス系使っている場合はincludeで別途取り込む指定方法がある。~allは「それ以外は詐称の疑いがある」を示す。-allとすれば「絶対に詐称」となるが、状況によってはまずいことに陥ることもあり、~のほうがよいらしい)

これで、SPFを見る受信サーバであれば、こちらのメールサーバから出したものではない、詐称kmuto.jpメールを蹴るようにしてくれる。

 

ということで、受信サーバの立場になってSPFを見るように設定してみる。

  1. postfix-policyd-spf-pythonパッケージをインストールする。
  2. README.Debianに従い、/etc/postfix/master.cfにpolicyd-spfの呼び出しを追加する。
    policyd-spf  unix  -       n       n       -       0       spawn    user=policyd-spf argv=/usr/bin/policyd-spf
    
  3. /etc/postfix/main.cfでpolicyd-spf_time_limitを追加、smtpd_recipient_restrictionsの既存行にcheck_policy_serviceを追加する。
    policyd-spf_time_limit = 3600
    smtpd_recipient_restrictions = (既存設定), check_policy_service unix:private/policyd-spf
  4. postfixをreload。
  5. うまくできていればSPFの通った受信メールに「Received-SPF: Pass (...」が付く。mail.logログを見ていると、詐称している場合はSPF failになってrejectされていた。SPF行がないときにはNoneでスルーされる。

 

DKIM

DKIMは実際どの程度効果があるのかわからないけど、これをレピュテーションにされているケースもあるようなので、設定しておくことにした。受信時に検証でひっかけられる数がどの程度あるのかは今後のウォッチ結果次第。

  1. opendkim、opendkim-toolsパッケージをインストールする。
  2. adduser postfix opendkim でグループに追加しておく。
  3. /etc/opendkim.confを編集する。Mode svはsign/verifyの両方の意味。SubDomainsはサブドメインを使うかどうかで、自分のところでは不要なのでnoとしている。ぽんこつ雑記で書かれていたCanonicalizationについてはDebianだとデフォルトでrelaxed/simple(ヘッダは緩く・ボディはきっちり)になっていた。
    Mode sv    
    SubDomains no
    Socket local:/var/spool/postfix/opendkim/opendkim.sock
    KeyTable refile:/etc/opendkim/key.table
    SigningTable refile:/etc/opendkim/signing.table
    ExternalIgnoreList  refile:/etc/opendkim/trusted.hosts
    InternalHosts       refile:/etc/opendkim/trusted.hosts
  4. 鍵用のフォルダを用意する。ついでにPostfix用の準備も。
    sudo mkdir -p /etc/opendkim/keys/ドメイン
    sudo chown -R opendkim:opendkim /etc/opendkim
    sudo chmod 700 /etc/opendkim/keys
    sudo mkdir /var/spool/postfix/opendkim
    sudo chown opendkim:postfix /var/spool/postfix/opendkim
    
  5. /etc/default/opendkimでPostfixを使うようにしておく。
    RUNDIR=/var/spool/postfix/run/opendkim
    
  6. /etc/opendkim/signing.tableを作成。
    *@ドメイン default._domainkey.ドメイン
    
  7. /etc/opendkim/key.tableを作成。
    default._domainkey.ドメイン ドメイン:default:/etc/opendkim/keys/ドメイン/default.private
    
  8. /etc/opendkim/trusted.hostsを作成。とりあえず自身のみにしておいた。
    127.0.0.1
    ::1
    localhost
    
  9. 鍵ペアを作成する。
    sudo opendkim-genkey -b 2048 -d ドメイン -D /etc/opendkim/keys/ドメイン -s default -v
    sudo chown opendkim:opendkim /etc/opendkim/keys/ドメイン/default.txt /etc/opendkim/keys/ドメイン/default.private
    

/etc/opendkim/keys/ドメイン/default.txtに公開鍵テキストが作成されるので、これをDNS、ここではRoute 53に登録するのだが、結果が1つの行にならなかったり長すぎと怒られたりで少々ハマった。結局、「"v=DKIM…"(空白)"p=鍵…"(空白)"鍵続き…"」と二重引用符で囲んだ文字列を空白で分けた1行としてテキストエリアに書き込めば、Route 53で結合してくれた。改行文字を入れるとダメ。

DNSをテスト。key not secureはDNSSEC関連なので無視してよい。key OKなのでよさそう。

sudo opendkim-testkey -d ドメイン -s default -vvv
opendkim-testkey: using default configfile /etc/opendkim.conf
opendkim-testkey: checking key 'default._domainkey.ドメイン'
opendkim-testkey: key not secure
opendkim-testkey: key OK

あとはPostfix側で通過するメールにDKIMフィルタを通すように設定する。/etc/postfix/main.cfを編集。

milter_default_action = accept
milter_protocol = 6
smtpd_milters = local:opendkim/opendkim.sock
non_smtpd_milters = $smtpd_milters

これで、あとはpostfixとopendkimをreload。メールを送出すると、ヘッダにDKIM-Signatureが付き、GmailなどだとDKIMチェックをPassしたことも示される。

 

DMARC

最後はDMARC。

  1. Route 53に_dmarcホストTXTレコードを作成。拒否ポリシー(p=)はひとまずnone。様子を見てquarantineかrejectにすることになる。rua(サマリレポート)、ruf(失敗レポート)のメールアドレスはDNS上で公開なので、これがspam先になりそうな気もする…。
    v=DMARC1; p=none; pct=100; fo=1; rua=mailto:メールアドレス; ruf=mailto:メールアドレス"
    
  2. opendmarcパッケージをインストール。
  3. 「opendmarc-check ドメイン」でDNSレコードが正しく設定されていることを確認。
  4. /etc/opendkim.confを編集。SPFチェックはすでに設定しているので、ここでは設定しないことにした(postfix-policyd-spf-pythonのほうが設定柔軟らしい)。RejectFailuresはDNSでp=rejectとしているときにこのエントリをtrueにすると本当にDMARCエラーメールをrejectするという設定。まだおっかないので慎重めにfalseにしておいた。
    AuthservID OpenDMARC
    RejectFailures false
    Socket local:/var/spool/postfix/opendmarc/opendmarc.sock
    TrustedAuthservIDs ドメイン
    UserID opendmarc
    IgnoreHosts /etc/opendmarc/ignore.hosts
    IgnoreAuthenticatedClients true
    RequiredHeaders true
    
  5. sudo mdir /etc/opendmarcでフォルダを作成し、/etc/opendmarc/ignore.hostsにホワイトリストを記述する。許可される記法は狭め。manによるとホスト名、IPアドレス、CIDRで、ワイルドカード的なドメイン表現みたいなのはできないようだ。
    localhost
    ::1
    127.0.0.0/8
    (その他パスさせたい範囲)
    
  6. Postfix用の諸々の準備をする。
    sudo mkdir /var/spool/postfix/opendmarc
    sudo chown -R opendmarc:opendmarc /var/spool/postfix/opendmarc
    sudo chmod 750 /var/spool/postfix/opendmarc
    sudo adduser postfix opendmarc
    
  7. Postfixの設定。/etc/postfix/main.cfのDKIMのsmtpd_miltersに追加するだけ。
    smtpd_milters = local:opendkim/opendkim.sock,local:opendmarc/opendmarc.sock
    
  8. postfixとopendkimをreload。

 

メールを送出すると、受信側でDMARCチェックをして、dmarc=passのようなヘッダが付く。逆にこちらが受信したときのDMARCチェック結果は、Authentication-Results: OpenDMARC; dmarc=passのようなヘッダで示される。

 

DMARCはprocmail等で外部転送しているとまずいことになる。これまで一部の重要そうなメールはGmailに転送していたんだけど、いろいろ探しても結論としては「don't forward to Gmail」らしい。まぁDMARCの仕組みからしてもよろしくないことは理解できる。Gmail転送はいったんあきらめて、ほかの保存や通知方法をそのうち考えることにした。

 

一晩経ってざっと見た感じで、SPF→まぁまぁ蹴ってるけど正規のspam(ってなんだ)もわりと通ってくる。DKIM→よくわからん。DMARC→効いている気がする(えきねっとAmazon楽天、VISAあたりの詐称reject。今はスルーだけど、結局spamassassinで殺されていた)。

debian.orgはSPFDKIMもDMARCも設定してないっぽい。開発者から離れたのでいろいろ抜けているとは言え、ユーザーとしていくつかはウォッチしているので、debian.orgのメールをヘッダ不備で蹴るのはちと困る。

 

DMARCのquarantine設定は様子を見てそのうち変更することにしよう。MLあたりからのメールの扱いでfailしている気がするので、いきなりrejectは危なそう。