初めに
当時の作業を思い出しながら記載しているため、間違っているところがあるかもしれません、あらかじめご了承ください。
ただ、プロキシのインフラ構成を落とし込めていれば補完して実装できると思います!
本番環境のSendGridでカスタムドメインを利用した際に、メール内リンクがhttpになっており正常にアクセスできない現象に遭遇し、そこで初めてSendGridのLink Branding機能を知りました。
(Link Brandingは、クリックトラッキング用リンクおよび開封トラッキング用の画像リンクを、sendgrid.netから独自ドメインに切りかえる機能)
開発環境のSendGridはSingle Sender Verificationのため、メール内リンクが問題なく機能していましたが、本番環境はDomain Authenticationだったため本事象が発生したようです。
GoogleCloudを利用しているため、今回はGoogleCloud上にプロキシを構築して、SendGridのトラッキングURLのSSL化を実現します。
構成
- SendGridに登録するカスタムドメインは
butterthon-dev.jpとします - SendGridのLink Brandingのドメインは
url9999.butterthon-dev.jpとします(SendGridのLink Brandingが発行するドメインです) - SendGridへアクセスするプロキシのドメインは
proxy.butterthon-dev.jpとします
手順① SendGridのドメイン認証を行う
[ Settings ] > [ Sender Authentication ] で開いた画面の [ Authentication Your Domain ] ボタンをクリックしてカスタムドメインを登録する。
表示されたCNAMEレコードおよびTXTレコードをDNSに登録。
(下記CNAMEレコードが表示された前提で進めます)
| TYPE | HOST | VALUE | 備考 |
|---|---|---|---|
| CNAME | ab9999.butterthon-dev.jp | a99999999.ab999.sendgrid.net. | - |
| CNAME | url9999.butterthon-dev.jp | sendgrid.net. | - |
| CNAME | 99999999.butterthon-dev.jp | sendgrid.net. | - |
| CNAME | s1._domainkey.butterthon-dev.jp. | s1.domainkey.a99999999.ab999.sendgrid.net. | - |
| CNAME | s2._domainkey.butterthon-dev.jp. | s2.domainkey.a99999999.ab999.sendgrid.net. | - |
| TXT | _dmarc.butterthon-dev.jp | "v=DMARC1; p=none;" |
p=none;はそのままでもいいですし、適宜変更いただいても構いません。 |
DNS登録後SendGridの画面に戻り、「I've added these records」のチェックボックスをチェックONしてから「Verify」ボタンをクリックし、「It worked!」と表示されればドメイン認証完了です
手順② プロキシ(proxy.butterthon-dev.jp)のAレコード登録
静的IPアドレスを発行し、プロキシ(proxy.butterthon-dev.jp)のAレコードとして登録します。
Terraformのコード
resource "google_compute_global_address" "IP_sendgrid_link_branding" {
name = "ip-sendgrid-link-branding"
}
| TYPE | HOST | VALUE |
|---|---|---|
| A | proxy.butterthon-dev.jp | 発行したIPアドレス |
手順③ プロキシで利用するCertificate Manager 証明書を作成
Terraformのコード
/******************************************************
* SSL証明書
*******************************************************/
resource "google_certificate_manager_dns_authorization" "cert_sendgrid_domain" {
name = "cert-sendgrid-domain"
domain = "url9999.butterthon-dev.jp"
}
resource "google_certificate_manager_dns_authorization" "cert_sendgrid_proxy_domain" {
name = "cert-sendgrid-proxy-domain"
domain = "proxy.butterthon-dev.jp"
}
resource "google_certificate_manager_certificate" "sendgrid_link_branding" {
name = "sendgrid-link-branding"
scope = "DEFAULT"
managed {
domains = [
google_certificate_manager_dns_authorization.cert_sendgrid_domain.domain,
google_certificate_manager_dns_authorization.cert_sendgrid_proxy_domain.domain,
]
dns_authorizations = [
google_certificate_manager_dns_authorization.cert_sendgrid_domain.id,
google_certificate_manager_dns_authorization.cert_sendgrid_proxy_domain.id,
]
}
}
resource "google_certificate_manager_certificate_map" "sendgrid_link_branding" {
name = "sendgrid-link-branding"
}
resource "google_certificate_manager_certificate_map_entry" "sendgrid_link_branding_url9999" {
name = "sendgrid-link-branding-url9999"
map = google_certificate_manager_certificate_map.sendgrid_link_branding.name
certificates = [google_certificate_manager_certificate.sendgrid_link_branding.id]
hostname = google_certificate_manager_dns_authorization.cert_sendgrid_domain.domain
}
resource "google_certificate_manager_certificate_map_entry" "sendgrid_link_branding" {
name = "sendgrid-link-branding"
map = google_certificate_manager_certificate_map.sendgrid_link_branding.name
certificates = [google_certificate_manager_certificate.sendgrid_link_branding.id]
hostname = google_certificate_manager_dns_authorization.cert_sendgrid_proxy_domain.domain
}
手順④ 発行したCertificate Manager 証明書のDNSレコードを登録
gcloud CLIを使用して手順②で作成したCertificate Manager 証明書のDNSレコードを表示。
gcloud certificate-manager dns-authorizations describe cert-sendgrid-domain
gcloud certificate-manager dns-authorizations describe cert-sendgrid-proxy-domain
表示されたCNAMEレコードをDNSに登録。
(下記CNAMEレコードが表示された前提で進めます)
| TYPE | HOST | VALUE |
|---|---|---|
| CNAME | _acme-challenge.url9999.butterthon-dev.jp | 999ab9c9-99d9-9999-9e9f-g99hi9jk99l9.9.authorize.certificatemanager.goog. |
| CNAME | _acme-challenge.proxy.butterthon-dev.jp | 888ab8c8-88d8-8888-8e8f-g88hi8jk88l8.8.authorize.certificatemanager.goog. |
手順⑤ SendGridのドメイン認証で登録したCNAMEレコードの値をプロキシのドメインに更新する
Certificate Manager 証明書のDNSレコード登録が完了したら、SendGridのドメイン認証で登録したCNAMEレコードのうち、urlで始まる方(url9999.butterthon-dev.jp)のCNAMEの値をプロキシのドメインproxy.butterthon-dev.jp.に更新。
※ CNAMEレコードの値を変更した後は、手順①で実施したドメインの再Verifyは行わないでください。
手順⑥ プロキシ構築
Terraformのコード
resource "google_compute_global_network_endpoint_group" "sendgrid_link_branding" {
name = "sendgrid-link-branding"
default_port = "443"
network_endpoint_type = "INTERNET_FQDN_PORT"
}
resource "google_compute_global_network_endpoint" "sendgrid_link_branding" {
provider = google-beta
global_network_endpoint_group = google_compute_global_network_endpoint_group.sendgrid_link_branding.id
fqdn = "sendgrid.net"
port = google_compute_global_network_endpoint_group.sendgrid_link_branding.default_port
}
resource "google_compute_backend_service" "sendgrid_link_branding" {
name = "sendgrid-link-branding"
enable_cdn = true
backend {
group = google_compute_global_network_endpoint_group.sendgrid_link_branding.id
}
protocol = "HTTPS"
log_config {
enable = true
sample_rate = 1.0
}
}
resource "google_compute_url_map" "sendgrid_link_branding" {
name = "sendgrid-link-branding"
default_service = google_compute_backend_service.sendgrid_link_branding.id
host_rule {
hosts = ["proxy.butterthon-dev"]
path_matcher = "all-paths"
}
path_matcher {
name = "all-paths"
default_service = google_compute_backend_service.sendgrid_link_branding.id
path_rule {
paths = ["/*"]
service = google_compute_backend_service.sendgrid_link_branding.id
}
}
}
resource "google_compute_target_https_proxy" "sendgrid_link_branding" {
name = "sendgrid-link-branding"
url_map = google_compute_url_map.sendgrid_link_branding.id
certificate_map = "//certificatemanager.googleapis.com/${google_certificate_manager_certificate_map.sendgrid_link_branding.id}"
}
resource "google_compute_global_forwarding_rule" "sendgrid_link_branding" {
name = "sendgrid-link-branding"
ip_address = google_compute_global_address.IP_sendgrid_link_branding.address
target = google_compute_target_https_proxy.sendgrid_link_branding.id
port_range = "443"
}
手順⑦ メール内リンクのURLにhttpsでアクセスできるか確認
ここまでできたら、SendGridを利用してメールを送信しましょう。
メール内リンクのhttpをhttpsに変えてブラウザからアクセスします。
ブラウザのアドレスがhttps://url9999...からhttps://独自ドメインに変わり正常にアクセスできたらトラッキングURLのSSL化はほぼ完了です。
(アクセスできない場合はどこかしらの設定が誤っています🙇)
手順⑧ SendGridにトラッキングURLのSSL化を依頼する
※ リンクが無効になっている場合は、「Sendgrid トラッキングURL SSL」とかで調べて自力で辿り着いてください!
手順⑨ メール内リンクのURLがhttpsに変わったことを確認
SendGrid社からSSL化完了の連絡がきたら、再度SendGridを利用してメールを送信しましょう。
メール内リンクがhttpsに変わっていたらトラッキングURLのSSL化完了です。
お疲れ様でした!