Logo

site iconJust lepture

Hsiaoming Yang,typlog 和 authlib 的创建者
请复制 RSS 到你的阅读器,或快速订阅到 :

Inoreader Feedly Follow Feedbin Local Reader

Just lepture RSS 预览

註冊郵箱攻擊

2023-10-01 18:19:39

我開發了一個博客和播客托管服務 Typlog,目前你看到的這個網站就是托管在 Typlog 上的。今天給大家分享一個運營 Typlog 的慘痛教訓,希望能幫助其他的開發者。

前幾天有個客戶發郵件給 Typlog,來咨詢一些問題。我回復後,過了好幾天也沒收到客戶的反饋。於是我又用自己的私人郵件去問客戶有沒有收到我的回復,答案是沒有。我有點不好的預感,於是用 Typlog 的郵箱給自己的私人郵箱發了一封郵件,不出意外地進入了垃圾箱。我們的郵箱設置沒有任何問題,DKIM、SPF、DMARC 都正常設置好了,Gmail 也全部給我們標記為 "PASS" 了,但是這封郵件就是進入了垃圾箱。

我的預感沒有錯,而且我也意識到問題出在了哪裡。進入 AWS SES 後台查看了一下,域名的口碑(domain reputation)出了問題。Typlog 的聯絡郵箱使用的是 Google Workspace,通知郵件是使用的是 SES,他們都是使用的 typlog.com 這個域名。通知郵件服務導致域名出了口碑問題,影響到了聯絡郵箱。

Complaint rate

為何我們的通知郵件服務會出問題呢?一直以來我都忽略了一個問題,我很早的時候就注意到 Typlog 有很多的垃圾註冊,但是我沒有太在意。一是我們的註冊接口是有頻率限制的,他也註冊不了多少;二是我們是一個付費服務,他註冊了不激活也做不了什麼事。直到 Typlog 的聯絡郵箱出了問題我才意識到我忽略了什麼。

因為註冊的時候,系統會發送激活郵件給用戶。如果你並沒有註冊某個服務,但是你收到了註冊郵件,你有可能會將這封郵件標記為垃圾郵件。當標記的人多了,郵件商便會認為這個域名是個發垃圾郵件的域名。即使沒有人標記垃圾郵件,但是你的郵箱經常發送郵件到不存在的郵箱地址,郵件商也會認為這個域名是個發垃圾郵件的域名。而且還有找回密碼這個接口,也是會發送郵件的。這樣就導致你發送的郵件數量更多了。更有甚者,有的機器人還會點擊激活鏈接。也許這個機器人還順便舉報了一下垃圾郵件呢。

你開發了一個服務,運營了一段時間,總是會遇到一些黑產機器人的。我還是沒有理解為什麼會有這些垃圾註冊機器人,他們會通過什麼方式為黑產者生產利益呢?

不幸中的萬幸,Typlog 的郵件列表服務是另一個域名,沒有影響到用戶的郵件列表功能。

現在我需要重建 Typlog 的域名口碑,這會是一個漫長的過程。下面是我的計劃:

  1. 首先要防止機器人的垃圾註冊,我給註冊賬戶和找回密碼頁面添加了 Turnstile 驗證。
  2. 將通知郵箱和聯繫郵箱的域名分開。
  3. 在註冊頁面添加文字說明,讓用戶檢查一下垃圾箱,以便用戶能正常註冊
  4. 尋找朋友們的幫助,用 Typlog 的聯絡郵箱和朋友們交流,請他們標記這封郵件不是垃圾郵件

如果你有更好的建議,歡迎給我留言。也希望這篇文章能幫到新的開發者。如果我再開發一個新產品的話,我會在一開始就執行如下計劃:

  • 不要使用 root domain 作為通知郵箱,比如域名是 example.com,可以使用 [email protected] 作為通知郵箱
  • 要用驗證碼服務,比如 Turnstile,hCaptcha,reCaptcha 之類的
  • 關注產品的各種狀態

個人域名郵箱免費方案

2023-08-20 15:30:07

Cloudflare Email Routing 這項服務推出來有一段時間了。今日,我將個人郵箱 ([email protected]) 從 Google Workspace 轉到了 Cloudflare Email Routing,每月節省了 6 美金。

我們知道 Cloudflare Email Routing 可以接收郵件然後轉發到你指定的另一個郵箱,但是並不能發送郵件。這樣的話,我們就不能使用自己的個人域名郵箱了。所以要搭配一個方案,讓我們可以用自己的域名發郵件。所以我另外註冊了一個 Gmail 來發郵件。

下面是我遷移的整個流程:

備份郵件

首先我們需要備份個人域名郵箱里的郵件,如果你沒有什麼重要的郵件的話,也可以不備份。不過最好還是備份一下。這裡我選擇將郵件導入到我新註冊的 Gmail 里。如果你已經有一個 @gmail.com 的郵箱了,這一步可以省略。不過我還是註冊了一個全新的 Gmail,這樣比較清爽。

進入 Gmail 的設置裡面,選擇 Accounts and Import,在下面可以找到 Check mail from other accounts,點擊 Add a mail account。在彈出的對話框里輸入自己的郵箱,按照引導會進入填寫 POP 服務的頁面。

按照官方文檔,你需要填寫的信息:

  • 用戶名:你的郵箱
  • 密碼:你的郵箱密碼
  • POP 服務器:pop.gmail.com
  • 端口:995
  • 要求 SSL:是

Important

你也許無法成功添加郵箱賬戶。這裡可能會出現錯誤提示:

Server denied POP3 access for the given username and password.

我們需要先開啓個人域名郵箱(Google Workspace Gmail)里的 POP3 功能。到你的個人郵箱設置里,選擇 Forwarding and POP/IMAP,然後開啓 POP 服務。

Enable POP

但是可能還是無法成功,這是因為 Gmail 的安全機制導致的。雖然官方文檔里說密碼使用郵箱的登錄密碼就可以了,但其實不行。這裡有兩個解決方案:

  1. 使用 App password
  2. 修改賬戶安全等級

在下面的章節里會介紹如何創建 App password,這裡先介紹一下修改賬戶安全等級。因為我們這個 Google workspace 賬戶最終是要銷戶的,所以修改賬戶安全等級並沒有什麼影響。進入賬戶安全中心,激活 Less secure app access 即可。

Less secure app access

再次嘗試添加 POP 郵箱賬戶,應該就會成功了。你需要等待一段時間才能備份完所有郵件。也許睡一覺,明天再繼續?

開啓 Cloudflare Email Routing

當郵件備份完後就可以開啓 Cloudflare Email Routing 了。進入 Cloudflare,選擇你的域名,進入 Email Routing 設置。

Email Routing

比如你註冊的 Gmail 叫 [email protected],你的個人域名郵箱是 [email protected],上面的表單可以填寫:

然後根據 Cloudflare 的提示,三步後就可以開啓 Cloudflare Email Routing 了。現在,當別人發郵件給 [email protected] 時,你的 [email protected] 郵箱就會收到郵件了。

個人域名發件人

最後我們需要讓發件人使用我們自己的域名。這一步與上面的備件郵件有些類似。進入 Gmail 的設置中心,選擇 Accounts and Import。在 Send mail as 里選擇添加一個新郵箱。

Send mail as

比如我添加自己的郵箱 [email protected],根據提示一步一步走,會進入最後的 SMTP 服務器設置:

使用 AWS SES

Warning

如果你還沒有開通 AWS SES,建議試試其他 SMTP,比如 Alibaba Direct Mail。因為 AWS SES 默認為 sandbox 環境,需要申請才能開通生產環境,但是有可能申請不通過。

之前介紹的 Gmail SMTP 方案(在文章最下面)沒有 DKIM 驗證,會導致郵件進入垃圾箱。我們可以使用其他的 SMTP 服務來發送郵件。比如 AWS SES,因爲 SES 會提供每個月 3000 封免費郵件,這對於個人用戶來説絕對夠用了。

首先你需要注冊一個 AWS 賬戶,這裏就不介紹了。注冊後,到 SES Dashboard 裏面添加自己的域名,比如我的:

SES

下一步,設置 DNS,讓 SES 支持 DKIM 認證。你將需要設置類似如下的 CNAME。注意,在 Cloudflare 裏面設置 CNAME 時要關閉 Proxy

Setup DNS

接下來,我們為這個域名創建一個 SMTP 登錄賬戶:

Create SMTP credentials

只需要一步一步跟著 AWS 的步驟來,你就能創建出 SMTP 登錄賬戶和密碼。之後,再將這個 SMTP 賬戶登記到 Gmail 裏面就可以了。

Add AWS SES SMTP credentials

我們需要設置:

  1. SMTP Server: email-smtp.us-west-2.amazonaws.com
  2. Port: 465
  3. Username:AWS SMTP Username
  4. Password:AWS SMTP Password

完成後,可以在設置頁面里將個人域名郵箱設置為默認發件人。

另外,你還可以設置一下 MAIL FROM 域名,如果沒有設置的話,收件人會看到你發的郵件 mailed-by: us-west-2.amazonses.com

MAIL FROM

使用其他 SMTP

除了 AWS SES,還有其他 SMTP 服務選擇。比如 SendGrid,比如 Alibaba Direct Mail。

  • SendGrid 提供每天 100 封免費郵件。
  • Alibaba Direct Mail 每個阿里雲主帳戶每日可獲 200 封免費郵件發送額度。

測試

最後,我們使用自己的域名郵箱發送一封郵件試試。下面是我收到的測試郵件示例:

Received email

可以看到,SPF、DKIM 都成功了。


下面是使用 Gmail SMTP 的方案,請謹慎使用。

Warning

這個方案有缺陷,沒有 DKIM 認證,只能保證 SPF pass。

這裏我們可以直接使用當前的 Gmail 賬戶,比如 [email protected]

smtp.png

我們需要設置:

  1. SMTP Server: smtp.gmail.com
  2. Port: 587
  3. Username:你的 Gmail 郵箱(就是你當前在用的這個郵箱)
  4. Password:等一下,這裡需要創建一個 App password

在上面的最後一步需要填寫一個密碼,由於 Gmail 的安全機制,你不能直接填寫賬戶密碼,這裡需要使用一個 App password。

  1. 進入賬戶安全中心
  2. 激活兩步驗證(2-Step Verification):
2-Step Verification

激活後,進入 2-Step Verification,在頁面的最下面有一個 App passwords,進入後創建一個 Mail 的 App password 即可。

App passwords

然後在密碼填寫框里使用這個生成的密碼即可。完成後,可以在設置頁面里將個人域名郵箱設置為默認發件人。

Markdown on ruby markup

2022-07-14 21:44:30

The <ruby> HTML element represents small annotations that are rendered above, below, or next to base text, usually used for showing the pronunciation of Japanese and Chinese characters. There is a <ruby> markup syntax discussion in the CommonMark Discussion, among which, I prefer the syntax designed by JuanitoFatas.

[漢字(かんじ)]
[漢字(かんじ)](https://jisho.org/search/漢字)

The benefits are obvious:

  1. The markup looks pretty and easy to understand
  2. It works well together with links

However, the syntax for separated ruby annotations is a little complex:

[[漢(かん)][字(じ)]](https://jisho.org/search/漢字)

While in mistune v3, I've added a ruby plugin for multiple annotations with the below syntax:

[漢(ㄏㄢˋ)字(ㄗˋ)]
[漢(かん)字(じ)](https://jisho.org/search/漢字)

You can group all ruby texts in [] which can reduce the use of punctuation characters.

Typlog has been updated with mistune v3, you can use ruby syntax right now in Typlog. Here are the rendered results with the ruby markup syntax:

ㄏㄢˋㄗˋ with zhuyin, hàn with pinyin, and かん with hiragana.

Display country flags emoji on Windows

2022-04-30 17:51:46

I've been using Windows for a while now. Everything goes well except it doesn't render country flags emoji. I didn't notice this until I became a Windows user.

In the Typlog admin portal, there is a region visit metric that displays country flags via emoji. It looks terrible on Windows. Here is how would it look like on Windows:

Broken country flags
Broken country flags

There are several ways to fix this problem:

I prefer the web font way, although this repo contains only a few stars on GitHub. I didn't use the code provided by country-flag-emoji-polyfill, it is the woff2 font I'm using directly in CSS. The font is a subset of "Twemoji Mozilla".

We would load the web font only on Windows because Mac and Linux can display country flags emoji well. In this way, it would reduce the HTTP requests and net bandwidth, though the font is quite small.

A simple JavaScript is required:

if (/windows/i.test(navigator.userAgent)) {
document.body.classList.add('win')
}

This code will add a win class to the <body> tag. We would only use the web font for .win in CSS:

@font-face {
font-family: 'Twemoji Country Flags';
unicode-range: U+1F1E6-1F1FF, U+1F3F4, U+E0062-E0063, U+E0065, U+E0067, U+E006C, U+E006E, U+E0073-E0074, U+E0077, U+E007F;
src: url('https://cdn.jsdelivr.net/npm/[email protected]/dist/TwemojiCountryFlags.woff2') format('woff2');
}
body {
font-family: var(--user-defined-font), sans-serif;
}
.win {
font-family: "Twemoji Country Flags", var(--user-defined-font), sans-serif;
}

Here is what the region visit metric looks like on Windows now.

Twemoji Country Flags
Display with Twemoji Country Flags

週記,垂死病中驚坐起

2022-04-09 17:42:37

春光正好,人也從憂鬱厭世的情緒中解脫出來。也是長久未寫文章了,竟對寫字產生了一種疏離生僻之感。錢鐘書談寫作時說道:我們常把自己的寫作衝動誤認為自己的寫作才能,自以為要寫就意味著會寫。我大概連寫作的衝動都在逝去,同時逝去的還有各種興趣,比如好久沒去拍照了,就連玩遊戲看電影也提不起興致。

也許是身處疫情的自我隔離,也許是漫漫冬季的蕭瑟,也許是自我間歇性的抑鬱。之前的幾個月裡,整個人如在泥潭,想要掙脫卻越陷越深,什麼都不想做,不想工作,不想起床,不想吃飯,不想洗澡,不想睡覺。現下終於恢復了,趁著這個時候紀錄一下,寫點流水帳,也算是活在了人間。

作息調整

告别了昼夜颠倒的生活,作息終於規律了起來,現在也算是早睡早起了。一天的時間安排大致如下:

  • 自然醒,時間跨度比較大,大致 6:30 ~ 8:00
  • 早餐,可能是烤麵包,可能是出門吃,也可能不吃
  • 學習日語,是的,我又一次開始學習日語了,大致是 9:30 開始
  • 處理 Typlog 的 bug,或優化代碼,或寫新功能
  • 下午,處理真正的工作(養活自己的)
  • 晚餐後,看情況,可能還是在為 Typlog 工作,可能是解決 GitHub 上的 Issue,也可能休閒
  • 11:00 ~ 12:00 睡覺

以上安排比較彈性,實際上會有一些出入。

日語學習

不記得是第幾次學習日語了,這次是在 NHK 上學習《簡明日語 2015 》,每天學習一到兩課,目前學到第九課了。這次至少要將這本書學完吧。

一點新知分享,こんにちは的漢字寫法是こんにちこんばんは的漢字寫法是こんばん。所以日語的問安並沒有「安」字,亦如我們說早安時會說「早」而省略掉「安」字。當然,我們不會簡略地說「晚」。

Typlog

Typlog 最近做了一些優化,也新增了一些功能。

  • Typlog 變快了,當然你可能也感受不到,反正我們服務器的壓力變小了點。
  • 優化了郵箱列表的任務隊列,開始記錄用戶發郵件的次數,之後會做限制,Pro 用戶每月可免費發 2000 封郵件。
  • 跳轉服務支持 wildcard matching 了。
  • 自動鏈接 embed 服務支持 App Store、IMDb、豆瓣電影以及所有支持 Open Graph 的網站了。

因為豆瓣有中國特色的圖片防盜鏈設置,豆瓣電影的卡片會出現圖片無法加載的問題,這是由於豆瓣設置了 referrer 校驗。但是在現代瀏覽器里,這種校驗是沒有意義的,除非限制必須帶有特定的 referrer。我們可以通過 referrerpolicy="no-referrer" 來防止瀏覽器發送 referrer 信息。

<img referrerpolicy="no-referrer" src="..." />

https://movie.douban.com/subject/1291843/

Authlib

修復了一些 bug,發佈了 v1.0.1 版本。接下來可能會再次投入時間到 Authlib 的改進。


鯉幟

又到了鯉魚旗飄揚的時節了,出門的時候手機隨手拍了一張,也算是拍照了吧。