Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
メール認証とRuby
Search
uvb_76
March 07, 2024
Programming
1.2k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
メール認証とRuby
uvb_76
March 07, 2024
More Decks by uvb_76
See All by uvb_76
地元にいないローカルオーガナイザーの立ち回り
uvb_76
2
1.6k
ユーザーにサブドメインの ECサイトを提供したい (あるいは) 2026年函館で一番熱くなるかもしれない言語の話
uvb_76
0
960
Rails 7.2 のリリースノートを見て思ったこと
uvb_76
0
990
Rails Girls ガイドを使って社内で Rails 講座を開催した
uvb_76
0
180
問い合わせ調査との付き合い方
uvb_76
0
270
yawaraka zouzei
uvb_76
0
2.1k
開発環境(物理)を作る
uvb_76
0
1.8k
Other Decks in Programming
See All in Programming
AWSに止められる覚悟してますか?
morizo_1984
2
520
外から家のPCの電源入れたい!をPHPで解決する
kawashimo0
1
120
Simple Storage Service(S3) is not simple
iwatsukayura
0
230
R8 の設定見直しでアプリサイズ削減
andpad
0
190
月間100万人のサービス刷新で、 技術選定をHonoに振り切った話
yutobara
8
5.8k
技術的負債を組織課題として解く-増えすぎたマイクロサービスとの戦い-
reimaru
1
2.9k
パズルゲームの作り方 / how to make puzzle games
kaityo256
PRO
2
280
Unity6 URPによる海底をテーマにしたVJシステムの解説 | Unity Shader 完全に理解した 勉強会
gam0022
0
340
プロダクトコードからライブラリの境界を見つける
elmetal
PRO
0
110
そのリトライ、死んだコネクションを使い回していませんか ── GoのHTTPクライアントとHTTP/2を実プロダクト障害から学び直す
myus4a
1
410
re:Inventに行く前に知っておきたい現地参加のノウハウ
nokomoro3
0
390
機械に任せるテスト、人が見るテスト ⽣成AIで引き直した、運⽤保守フェーズの線引き
dske104
0
170
Featured
See All Featured
Building a Modern Day E-commerce SEO Strategy
aleyda
45
9.2k
How to Grow Your eCommerce with AI & Automation
katarinadahlin
PRO
2
320
The Impact of AI in SEO - AI Overviews June 2024 Edition
aleyda
6
1.2k
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
480
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
390
How to Align SEO within the Product Triangle To Get Buy-In & Support - #RIMC
aleyda
2
1.8k
Odyssey Design
rkendrick25
PRO
2
860
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.6k
Lightning talk: Run Django tests with GitHub Actions
sabderemane
0
300
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
123
22k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
232
55k
Transcript
メール認証とRuby 2024/03/06 Gotanda.rb#57 ikaruga / Atsushi Katsuura 1
誰 ikaruga / Atsushi Katsuura GMOペパボ株式会社 EC事業部 CREチーム puts Resolv::DNS.new.getresources(
'me.ikaruga.org', Resolv::DNS::Resource::IN::TXT ).map(&:data) => ["GITHUB=ikaruga777", "TWITTER=@UVB_76", "WORK=GMO Pepabo Inc.", "
[email protected]
"] 2
https://support.google.com/a/answer/81126?hl=ja 3
4
メール認証のおさらい 色々要件はあったけど、基本SPF,DKIM,DMARC 全てはメールのなりすましを防ぐための仕組み 5
メールヘッダー 二種類のFrom ヘッダーFrom メールヘッダーの From エンベロープFrom メールヘッダーの Return-Path 6
(ちょうどいま来たメールを例に) Gmailだったらメールのメニューから「メッセージのソースを表示」をポチるとヘッダーを確 認できる # ヘッダーFrom From: Duolingo <
[email protected]
> # エンベロープFrom
Return-Path: <0100018e1341b06c-6b1b2b73-30d1-49fc-9788-8b3c5133d0c5-000000@bounces.duolingo.com> 7
SPF Sender Policy Framework メール送信元のドメインが許可されているかどうかをチェックする エンベロープFromのドメインでTXTレコード引くと v=spf1 から始まる値が取れる。 ip4: や
ip6: の後ろにIPアドレスが含まれているので、そこで送信元のIPアドレ スが引けたらPASS $ dig spf-external.shop-pro.jp TXT +short "v=spf1 ip4:210.175.7.1/32 include:srs0260.cuenote.jp ~all 8
SPF IPアドレス以外にも a , mx , include , redirect の
mechanism ではドメインを指定 できる。 ドメインに当たったらそのドメインで再帰的にTXTレコードを引いていく。 ルックアップの回数は10回まで。 https://tex2e.github.io/rfc-translater/html/rfc7208.html 4.6.4. DNS Lookup Limits にその話がある 9
(Googleから来てたメールを例に取る) メールヘッダー Return-Path: <3H5XiZRAKCgozk8wox32-xy1ozv8qyyqvo.mywsuk14qkHHHqwksv.myw@scoutcamp.bounces.google.com> Received: from mail-sor-f69.google.com (mail-sor-f69.google.com. [209.85.220.69]) From:
Google Payments <
[email protected]
> 209.85.220.69 が送信元のIPアドレス 10
Return-PathのドメインでSPFを引くと $ dig 3h5xizrakcgozk8wox32- xy1ozv8qyyqvo.mywsuk14qkhhhqwksv.myw@scoutcamp.bounces.google.com TXT +short "v=spf1 redirect=_spf.google.com" $
dig _spf.google.com TXT +short $ dig _spf.google.com TXT +short "v=spf1 include:_netblocks.google.com include:_netblocks2.google.com include:_netblocks3.google.com ~all" $ dig _netblocks.google.com TXT +short "v=spf1 ip4:35.190.247.0/24 ..( 中略).. ip4:209.85.128.0/17 .... ~all" 11
(Googleから来てたメールを例に取る) irb(main):003> IPAddr.new('209.85.128.0/17').include?('209.85.220.69') => true 12
DKIM DomainKeys Identified Mail メールを送信する際にメールの内容を用いて署名を作って認証する仕組み 送信されるメールサーバに秘密鍵を保存する 生成された署名は DKIM-Signature ヘッダーに付与される 受信者はメールヘッダーの
DKIM-Signature ヘッダーの d, s タグからレコードを見つ ける dはドメイン、sはセレクタ(鍵ローテのために複数認証系を用意してる) "#{s}._domainkey.#{d} でTXTレコードを引くと公開鍵が引けるので、それを使 って認証する。 13
(Googleから来てたメールを例に取る) メールヘッダー DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1709348127; x=1709952927;
dara=google.com; h=to:from:subject:message-id:feedback-id:reply-to:date:mime-version :from:to:cc:subject:date:message-id:reply-to; "#{s}._domainkey.#{d}" でTXTレコードを引く p= のあとが公開鍵 $ dig 20230601._domainkey.google.com TXT +short "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AM...( 略)" 14
DMARC Domain-based Message Authentication, Reporting and Conformance SPFとDKIMに加えて追加の認証をすることでなりすましを防ぐ SPFアライメント、DKIMアライメントを追加で認証する さらに、認証が通らなかったときのメールの監視の仕組みも定義されていて、送信元の
サーバー管理者が通告されたSPAMと判定されたメールの内容について把握することが できる。 設定もDNSレコードで行う 15
DMARCレコードの実例 $ dig _dmarc.google.com TXT +short "v=DMARC1; p=reject; rua=mailto:
[email protected]
" $
dig _dmarc.shop-pro.jp TXT +short "v=DMARC1; p=none; pct=100; adkim=r; aspf=r; rua=mailto:
[email protected]
; ruf=mailto:
[email protected]
;" 16
アライメント SPFアライメント エンベロープFromとヘッダーFromのドメインが一致しているかどうか DKIMアライメント ヘッダーFromのドメインと DKIM-Signature ヘッダーの d タグのドメインが一致している かどうか
17
ref: https://speakerdeck.com/azumakuniyuki/gu-iji-shu-nituite-smtpxian-dai-shi-qing- tumamishi-i?slide=14 YAPC::HiroshimaでされていたSMTPのセッションが簡潔にまとまっていて最高。 古い技術について—SMTP現代事情つまみ食い— - Speaker Deck 18
ブログ SendGrid, ベアメールのブログにわかりやすい記事がたくさんあって便利。 https://sendgrid.kke.co.jp/blog/ https://baremail.jp/blog/ 19
一応Rubyの話 20
設定されていることをどうやって確認するか SPF, DKIM, DMARCいずれもDNSレコードの内容を確認していく必要がある。 21
Resolv 標準ライブラリにDNS引いてくれるくんがいて便利。 https://github.com/ruby/resolv https://docs.ruby-lang.org/ja/3.3/library/resolv.html 22
誰 ikaruga / Atsushi Katsuura GMOペパボ株式会社 EC事業部 CREチーム puts Resolv::DNS.new.getresources(
# ← これ 'me.ikaruga.org', # ← これ Resolv::DNS::Resource::IN::TXT # ← これ ).map(&:data) # ← これ => ["GITHUB=ikaruga777", "TWITTER=@UVB_76", "WORK=GMO Pepabo Inc.", "
[email protected]
"] 23
パーサーがある https://github.com/trailofbits/spf-query SPFレコードのパーサーもいて便利 https://github.com/trailofbits/dkim-query DKIMレコードのパーサーもいて便利 https://github.com/trailofbits/dmarc DMARCレコードのパーサーもいて便利 24
spf-query 使ってみる require 'bundler/inline' gemfile do source 'https://rubygems.org' gem 'spf-query'
end domain = ARGV.first q = SPF::Query::Record.query(domain) def query(q, lookup_count) q.mechanisms.each do |mechanism| case mechanism.name when :ip4, :ip6 puts mechanism.value when :include, :redirect lookup_count += 1 return if lookup_count > 10 puts ">>" + mechanism.value # _spf サブドメインを暗黙的に引いてしまうらしい # https://github.com/trailofbits/spf-query/issues/10 records = Resolv::DNS.new.getresources(mechanism.value, Resolv::DNS::Resource::IN::TXT) spf_record = records.find do |record| record.strings.join.include?('v=spf1') end spf_record_value = spf_record.strings.join q = SPF::Query::Parser.parse(spf_record_value) query(q, lookup_count) when :a lookup_count += 1 # Resolv::DNS::Resource::IN::A でレコードを引く when :mx lookup_count += 1 # Resolv::DNS::Resource::IN::MX でレコードを引く when :ptr, :exsists lookup_count += 1 # 頑張って実装 end end end query(q, 0) 25
$ ruby parse_spf.rb _spf.google.com >>_netblocks.google.com 35.190.247.0/24 64.233.160.0/19 66.102.0.0/20 66.249.80.0/20 72.14.192.0/18
74.125.0.0/16 108.177.8.0/21 173.194.0.0/16 209.85.128.0/17 216.58.192.0/19 216.239.32.0/19 >>_netblocks2.google.com 2001:4860:4000::/36 2404:6800:4000::/36 2607:f8b0:4000::/36 2800:3f0:4000::/36 2a00:1450:4000::/36 2c0f:fb50:4000::/36 >>_netblocks3.google.com 172.217.0.0/19 172.217.32.0/20 172.217.128.0/19 172.217.160.0/20 172.217.192.0/19 172.253.56.0/21 172.253.112.0/20 108.177.96.0/19 35.191.0.0/16 130.211.0.0/22 26
まとめ 最近話題になっていたDNSを使ったメール認証のしくみのおさらいをしました Rubyでドメインに対して適切なレコードが設定されているかを確認するを1つ紹介しま した 懇親会で喋れたら喋りたい ワンクリック購読解除の適用範囲 27
仕事の話(宣伝) 3/15~の Ya8 2024 - ヤパチー 令和六年最新版(仮) で同僚が現場の話をする予定です(採択さ れていました) 以下のような現場の話が聞ける可能性があります
「メールサーバー」を自前で運用している 自前のメールサーバーやSaasを通して、ユーザーが設定した「独自ドメイン」でメール を送るための機能を提供している https://github.com/hachiojipm/ya8-2024-cfp/issues/32 28