ICPC 模擬国内予選 2020 スタッフ参加記

問題

あなたは ICPC OB/OG の会が開催する ICPC 模擬国内予選 2020 のスタッフとして、選手に詳細案内を送付する仕事を任されている。

詳細案内は、模擬国内予選で使われるジャッジシステムの URL とログインに必要なチーム番号、パスワード、そしてチーム名と所属を含む文字列であり、与えられたテンプレートにチームごとに異なる文字列を埋め込むことによって表される。

あなたは詳細案内を「すごく難しい天才以外お断りプロトコル」(SMTP) を使って送付しなければならない。 プログラマーであるあなたは SMTP を使って詳細案内を送信するプログラムを作成することにした。

入力

入力は以下の形式で表される

N
A_1 T_1 S_1 I_1 P_1
A_2 T_2 S_2 I_2 P_2
...
A_N T_N S_N I_N P_N
L
M_1
M_2
...
M_L

最初の行は送付先のメールアドレスの数 N (1 ≦ N ≦ 103) を表す整数からなる。

2行目から続く N 行はそれぞれ i 番目の詳細案内の送付に必要な情報としてメールアドレス A_i、チーム名 T_i、所属 S_i、チーム番号 I_i、パスワード P_i を表す文字列からなる。

N + 2 行目は詳細案内のテンプレートの行数 L (1 ≦ L ≦ 103) を表す整数からなる。続く L 行は詳細案内のテンプレートを表す文字列を表す。このテンプレートのいずれかの行は、チーム名を埋め込むべき箇所を表す $team、所属を埋め込むべき箇所を表す $affiliation、チーム番号を埋め込むべき箇所を表す $login、パスワードを埋め込むべき箇所を表す $password を含む。テンプレートの文字列は 100 KiB を超えない。

出力

出力はない。

得点

模擬国内予選の終了までに「詳細案内のメールが届いていない」という旨の連絡を受け取った数を X とする。N - X があなたの得点となる。

入力例

6
king-1@example.com ___KING___ The_University_of_Tokyo 1 aaaaaaaa
king-2@example.com ___KING___ The_University_of_Tokyo 1 aaaaaaaa
good-yamikin-1@example.net good_yamikin Tokyo_Institute_of_Technology 2 bbbbbbbb
good-yamikin-2@example.net good_yamikin Tokyo_Institute_of_Technology 2 bbbbbbbb
good-yamikin-3@example.net good_yamikin Tokyo_Institute_of_Technology 2 bbbbbbbb
gazeru-1@example.org gazeru Kyoto_University 3 cccccccc
11
ICPC 国際大学対抗プログラミングコンテスト模擬国内予選 2020
チーム $team ($affiliation) の皆様
模擬国内予選への参加登録ありがとうございます.
このメールでは自動審判システムの情報についてお知らせします.
今年も自動審判システムとして国内予選本番で使われるものと同様の Web ベースの審判システムを利用します.
自動審判システムへのログインには,チーム番号とパスワードが必要です.
チーム番号: $login
パスワード: $password
審判システムの URL はこちらです.
    http://icpc2020.jag-icpc.org/icpc2020/common/login_ja.php
参加者は事前にチュートリアルにもよく目を通しておいてください.

部分点解法

JAG で運用しているサーバーで動いている Postfix を使ってメールを送信する方法が愚直解として考えられます。事実として、数年前まではこの方法でも問題なくメールを配信できていました。しかし昨年の模擬国内予選では「メールが届いていない。迷惑メールフォルダにも入っていない」という問い合わせが殺到してしまいました。さらに、去年までは1チーム1メールアドレスまでの登録としていたところ、利便性のため今年は1チーム3メールアドレスまで登録できるように変更したため、問い合わせがさらに増えることが予想されました。そのため今年は別の方法を探すことを余儀なくされました。

部分点解法の問題点

GmailOutlook.com をはじめとする多くのメールサービスプロバイダーでは、以前にも増して悪意あるメールへの対策が厳しくなってきています。悪意あるメールを判定する方法としてはメールの内容を調べることも重要ですが、「怪しい IP アドレス」から送信されているかどうか、という特徴量も強い影響を持っています。「怪しい IP アドレス」からメールが大量に送信されている場合、受信側のメールサーバーではそのメールを迷惑メールフォルダに隔離することさえなく捨ててしまう場合もあるようです。

この IP アドレスの怪しさは「レピュテーション」(評判)と呼ばれています。レピュテーションの算出方法はメールサービスプロバイダーの実装に依存し、悪用を防ぐため通常は公開されていませんが、一般論として以下のような要素が考慮されていると言われています*1

  1. 存在しないメールアドレスにメールを送ってくる IP アドレスはレピュテーションを低くする(無差別にスパムメールを送信している疑いがあるため)
  2. ユーザーがよく「迷惑メールを報告」ボタンを押すようなメールを送ってくる IP アドレスはレピュテーションを低くする
  3. スパムメール業者がよく利用しているホスティングサービス(レンタルサーバーや IaaS)の IP アドレス帯はレピュテーションを低くする
  4. これまであまりメールを送ってこなかった IP アドレスから急にたくさんのメールが送られてきたら警戒する

JAG で運用しているサーバーからメールを送信する方法は 3. と 4. の観点で大きく不利でした。3. については現在利用しているホスティングサービスのレピュテーションがどうなのか私は知りませんが、一般論としてレンタルサーバーに付与される IP アドレスは基礎的なレピュテーションにあまり期待できません。4. についてはかなり致命的で、平常時は1週間のうちにせいぜいに10通程度のメールしか送信していない IP アドレスから数時間のうちに何百通もメールが届くようなことがあれば、ブロックするように実装するのは妥当な考えでしょう。

満点解法

地道にメールの送信数を増やして JAG のサーバーの IP アドレスのレピュテーションを高くするというのが正攻法ですが、模擬国内予選は1年に1回の開催のためこの方法をとることはできません。

代わりに SendGridAmazon SES といったメール配信サービスを使います。これらのサービスを使ってメールを送信すると、高いレピュテーションを持った IP アドレスからメールが送信されるため、メールの到達率が格段に上昇します。

悪意のある利用者がメール配信サービスを使ってしまえばレピュテーションの意味がなくなってしまうのではと思われるかもしれませんが、メール配信サービス側では以下のような対策が行われています。

  • 利用に事前審査が必要
  • 送信元(メール配信サービス側)でも独自のレピュテーションを計算
    • 送信先のメールアドレスからバウンスメール(いわゆる MAILER-DAEMON)が返ってきたり、迷惑メールとしての通報があるとレピュテーションが低下
    • レピュテーションが一定のしきい値を下回ると送信をブロック。再審査が通るまで利用を制限

今回は SendGrid を利用しました。SendGrid は月に12,000通までの送信は無料で利用できるというのが大きな利点です。また、これは ICPC 特有の事情ですが、SendGrid の日本の販売代理店である構造計画研究所は以前に ICPC のスポンサーを数年間していたことがあり、もし審査で渋い反応をされたときでもアピールしやすいのではないかということもありました。

結果的に、この方法は功を奏し、数百通のメールを配信することができました。今年も「メールが届いていない」という問い合わせは何件かありましたが、申し込みに使っていたメールアドレスを勘違いしていたというような原因によるものであり、SendGrid 側でなにか問題が起きていたという事例はありませんでした。さすが大手のメール配信サービスだなという感想です。

おわりに

最近はコンテストにはあまり参加できておらず問題を作るのも解くのも現役のときと比べると難しさを感じており作問作業ではほとんど貢献できていなかったのですが、本業の知見を活かしてインフラ面での貢献できたのはよかったです。