在Google Cloud platform(GCP)上發送電子郵件

前言

本來想取標題為使用VPS來發送Email,但感覺得過於空泛,不過由於是記錄自己設置過程的筆記,所以有必然更具體記錄個人環境和設定。(我當初就是因為環境變數問題翻找了很久資料)

  • VPS : Google Cloud Platform
  • OS : Ubuntu 18.04 LTS
  • 郵件伺服器 : Postfix
  • 第三方供應商(用於轉發郵件) : SendGrid

所以這章標題的正式名稱應該叫:

如何使用Ubuntu 18.04 LTS在Google Cloud platform(GCP)上通過Postfix使用SendGrid來設置Send-Only SMTP伺服器

(但這樣誰會想看啊!!?)

本章目的

一直以來,我用的Email都是像這種 : ank.zgaf@gmail.com

對,就是Google免費註冊的郵箱,我想應該大部人都一樣吧?但是這樣除了很普通沒有個人特色外,加上使用gmail.com的人數眾多,所以一般email的名稱都改得很長或者不好記。

所以我就在想,有沒有可能打造一個屬於個人的電子郵箱?

如果不想折騰,世界加錢可及

從結論說起,想自己打造是可行的

現在我的個人Email是 : ivan@ank.pw 是不是簡潔有個性

收信(receive email)

這邊我分開了收信和寄信2個部分進行說明,但其實只有寄信部分包含技術涵量

靈感是來自於我有一天心血來潮,在Google Domain上購買了域名ank.pw (購買過程),發現Google Domain有個很貼心的服務叫電子郵件轉寄

但其實…如果再早幾年申請google domain,就可以擁有實際的個人域名郵箱而 不 是 轉 發! 也就不會有這篇文章

image

它可以設定成把所以原本要寄去user@domain.name的信,全部轉寄至一個實際存在的郵箱

由於domaie.name就是你已經買下的域名,這樣user的名稱想改多簡單多好記都沒問題,因為不會重覆啊。

所以以我的例子,我只需要告訴別人我的email是ivan@ank.pw就好,但實際是寄到ank@csie.io,收信功能是這樣實現的。

延伸應用

由於可以設定用於轉址的地址多達100個,因此如果只是個人用的話多到用不完。

可以利用來重覆註冊一些需要電郵驗證的用途上。

譬如我需要註冊多個不同地區的Apple ID,我只需要具備一個實際郵箱。

然後就用轉址:

  • us@ank.pw去註冊美國地區Apple ID
  • jp@ank.pw去註冊日本地區Apple ID
  • hk@ank.pw去註冊香港地區Apple ID

寄信(send email)

在開始之前,需要在GCP後台上訂閱SendGrid Email這個第三方的供應商(或Mailgun、Mailjet),為什麼呢?看看官方的說明:

By default, Compute Engine allows outbound connections on all ports but port 25, which is blocked because of the risk of abuse. All other ports are open, including ports 587 and 465. Note: Port 25 is always blocked and can’t be used, even through an SMTP relay using G Suite.

image

簡單來說: STMP的port 25是在GCP上是禁用的,不管什麼方法。

雖然可以自訂Postfix的其它port來進行寄信,但還是建議使用擁有信任的第三方供應商 (如 SendGrid),可減輕 Google Cloud 的 Compute Engine 與我們維持良好 IP 記錄的壓力。

訂閱SendGrid

image

image

image

image

image

註冊SendGrid步驟略過

註冊成功後回到GCP應該能看到這畫面 image

申請SendGrid API Key

image

image

image

注意!!!這API Key僅出現一次,請慎重記錄。

image

安裝和配置Postfix

以下步驟需要在root進行,先切換至root:

sudo su -

1. 設置umask:

umask 077

2. 安裝Postfix和相依套件:

apt-get update && apt-get install postfix libsasl2-modules -y

首次設定應該會出現提示,選擇Local Only,域名默認也行(我一開始發現這名字居然是寄信出去的域名!?後來發現寄信出去的域名可以改的)

3. 修改/etc/postfix/main.cf

a.把下面2句變成注解

#default_transport = error
#relay_transport = error

b.把這6句加入到最底

relayhost = [smtp.sendgrid.net]:2525
smtp_tls_security_level = encrypt
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
header_size_limit = 4096000
smtp_sasl_security_options = noanonymous

第1句: 新增 SendGrid SMTP 服務與使用的通訊埠 (Compute Engine 不允許使用通訊埠 25 和 587,因此請務必使用通訊埠 2525)

第2~6句: 強制執行安全資料傳輸層 (SSL)/傳輸層安全標準 (TLS) 支援,並設定 STMP 驗證

4. 修改/etc/postfix/sasl_passwd

加入API Key:

[smtp.sendgrid.net]:2525 apikey:SG.xxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

記得改成你自己的API key

5. 產生.db檔

postmap /etc/postfix/sasl_passwd

6. 驗證是否擁有.db檔

ls -l /etc/postfix/sasl_passwd*

看到這樣表示沒問題:

-rw------- 1 root root    ...  /etc/postfix/sasl_passwd
-rw------- 1 root root    ...  /etc/postfix/sasl_passwd.db

7. 刪除原有憑證

為確保安全性,刪除內含 API Key 的檔案 (該檔案已產生 .db 檔,因此也不需要了)

rm /etc/postfix/sasl_passwd

8. 設定 .db 檔案權限

並確認其它檔案都已刪除。

chmod 600 /etc/postfix/sasl_passwd.db
ls -la /etc/postfix/sasl_passwd.db

這樣表示沒問題:

-rw------- 1 root root    ...  /etc/postfix/sasl_passwd.db

9. 重新加載修改後的配置

/etc/init.d/postfix restart

10. 安装 mailutils 或 mailx

apt-get install mailutils -y

11. 測試寄信

echo '[MESSAGE]' | mail -s [SUBJECT] [EMAIL@EXAMPLE.COM]

例子:

echo 'message' | mail -s subject a.b@gmail.com

12. 查看是否成功寄出

tail -n 5 /var/log/syslog

出現以下訊息:

Apr  1 17:56:12 ank postfix/qmgr[1479]: B41F28884E: from=<root@ank.pw>, size=311, nrcpt=1 (queue active)
Apr  1 17:56:12 ank postfix/smtp[22854]: warning: /etc/postfix/main.cf, line 49: overriding earlier entry: relayhost=
Apr  1 17:56:12 ank postfix/tlsmgr[22855]: warning: /etc/postfix/main.cf, line 49: overriding earlier entry: relayhost=
Apr  1 17:56:15 ank postfix/smtp[22854]: B41F28884E: to=<ank.zgaf@gmail.com>, relay=smtp.sendgrid.net[169.38.103.42]:2525, delay=2.9, delays=0.17/0.19/2.2/0.39, dsn=2.0.0, status=sent (250 Ok: queued as AeINI12pQ5GAIoDxo65OdQ)
Apr  1 17:56:15 ank postfix/qmgr[1479]: B41F28884E: removed

在倒數第2句的最後,出現了250 Ok就表示成功寄出

但是會發現一個問題,郵件的寄出者,名稱是root,默認狀態下,名稱是你寄出時正在使用的用戶名稱,domain可能就是你設置Postfix時選擇的那個。

Q.我可不可以把寄件人名稱和domain都修改?

A.可以的

13. 修改hostname(domain)

a.把默認doname改成我自己的ank.pw

hostnamectl set-hostname ank.pw

b.修改配置文件 編輯 /etc/postfix/main.cf,修改myhostname、myorigin、mydestination

myhostname = ank.pw
myorigin = /etc/mailname
mydestination = ank.pw, $myhostname, ankweb.asia-east1-c.c.vernal-surge-271303.internal, localhost.asia-east1-c.c.vernal-surge-271303.internal, localhost

確認一下/etc/mailname裡只有一句ank.pw

14. 重啟postfix

systemctl restart postfix
/etc/init.d/postfix restart

理論上domain就改變了

15. 寄信方法

1.一句指令寄出

echo 'message' | mail -s subject a.b@gmail.com

2.Message內容以檔案寄出

mail -s 'subject' a.b@gmail.com < /home/user/mail/mail.txt

3.Message內容以檔案寄出並自訂寄件人地址

mail -s "subject" a.b@gmail.com -a From:abcd@efgh.ijkl < /home/user/mail/mail.txt

有看到這樣奇怪的郵件地址abcd@efgh.ijkl嗎?這樣郵箱當然不存在,但我們卻可以以這種寄件者名稱寄出郵件,而且可以改成其他寄件人地址。

Q.但這樣不就可以冒充別人郵件嗎?這樣不在很危險?

A.是的,這種方式又稱電子郵件欺騙(email spoofing)

Q.為什麼用假的寄件者地址還能成功寄出email?

A.就好像現實世界的寄信一樣,要順利寄出信件只需正確的收件人地址,你的回郵地址即使寫錯了也不影響寄信。

參考來源:

https://cloud.google.com/compute/docs/tutorials/sending-mail/using-sendgrid

https://www.footmark.info/linux/centos/google-cloud-create-vm-centos7/

https://computingforgeeks.com/how-to-install-and-configure-postfix-as-a-send-only-smtp-server-on-ubuntu-18-04-lts/