はじめに
案件で、エラーログの通知などをSNS(Simple Notification Service)を使って行っています。
通知を行うにあたって、SNSトピックのサブスクリプション作成時にはプロトコルにEメールを指定し、エンドポイントにメンバーのメールアドレスをまとめたメーリングリストを指定しています。
何があったか
1月半ばを最後に、エラーログの通知がぱたりと止みました…。
しかも気づいたのは3月初め。今のところ監視体制を作っただけでこれといった運用や保守はまだ行っていないので特に大ごとになることはなかったですが、それはそれとしてエラー通知が届かないことは問題すぎるので調査することに…。
原因
サブスクリプション解除リンクの誤クリックであることが判明しました。
画像の「If you wishto stop…」の下にある青文字のリンクが、サブスクリプション解除リンクです。
調べるまで知らなかったのですが、SNSから通知されるEメール形式のメッセージには、必ずこの解除リンクがあるようです。
しかもこの解除リンク、クリックした後に「本当に解除しますか?」みたいな確認の文面などを出すことなく、いきなり「Subsciption removed!」という元気なメッセージとともにサブスクリプションを解除してきやがります。なんでだよ。
厄介なのは、サブスクリプションの作成者であろうとなかろうと、リンクをクリックすると一瞬で解除されてしまうことです。今回のようにメーリングリスト宛てに通知を行っている場合などは、誰かが誤ってリンクをクリックしてしまうだけでもサブスクリプションの解除が行われてしまいます。
ということで、非常に困るので対策することにしました。というかAWSは何故こんなものを必ず添付するようにしているんでしょうか?なんで?(半ギレ)
やったこと
とりあえずサブスクリプションを作り直しました。
ご存じの方も多いとは思いますが、サブスクリプションを作成後、以下のような確認メールが飛んできます。
このメール内の「Confirm subscription」のリンクをクリックせずに(重要)、クリップボードへコピーします。
その後、マネジメントコンソールから、再作成したSNSトピックのサブスクリプションを選択し、「サブスクリプションの確認」をクリックします。
すると、サブスクリプション確認用のURL入力画面が出てくるので、先ほどコピーしたリンクを貼ります。
これにより、サブスクリプション解除のリンクをクリックしても、解除ができないようになりました。
ためしにリンクを踏んでみたところ、「Subscription not removed」というメッセージが表示されるようになりました。なんでちょっとテンション低めなんだよ。
なんでこうなるのか?
マネジメントコンソールから確認を行うことで、サブスクリプションのConfirmationWasAuthenticated
属性が trueになるからです。
調べたところ、このConfirmationWasAuthenticated
属性は、デフォルト、かつメールから直接確認を行った場合では false になっているようです。なのでAWSの認証を通ることなく、誰でもメール内のリンクをクリックするだけでサブスクリプションの解除ができてしまうというわけです。
反対に、trueの場合はAWS認証を通る必要があるため、リンクのクリックだけではサブスクリプションの解除はできません。解除したい場合は、別途マネジメントコンソールやAWS CLIなどで解除の操作を行う必要があります。
また、既存のサブスクリプションのConfirmationWasAuthenticated
属性の変更もできないみたいです。なんでなんですかね。
おわりに
うっかりサブスクリプション解除はどうもAmazon SNSにおけるあるある問題みたいなので、今後SNSによる通知の仕組みを作る際はこの設定を必須にするよう頭の片隅に置いておこうかなーと思いました。