shlewislee.me

Cloudflare Worker로 WKD(Web Key Directory) 설정하기

이 글은 영어 원문을 AI로 번역한 글입니다.

Web Key Directory, 줄여서 WKD는 기존의 공개 키 서버에 비해 엄청난 발전인 것 같다. 이메일에 내 개인 도메인을 사용하고 있고, 가능하면 이메일이 암호화되기를 원하기 때문에 WKD를 설정해보기로 결정했다.

방법은 아주 간단하다. .well-known/openpgpkey/ 디렉터리 아래에 몇 개의 정적 파일만 있으면 된다. 여기에 Cloudflare Workers를 사용하는 것은 잘못된 것은 아니더라도 확실히 오버킬이다.

하지만 가용성 같은 문제에 대해 신경 쓰지 않아도 된다는 의미이므로 어쨌든 이 방법을 사용하기로 했다. 이론상으로는 Cloudflare Pages를 사용하면 걱정거리가 더 줄어들어야 하지만, 무슨 이유에서인지 기대한 대로 작동하지 않았다.

Worker를 설정하기 전에, 키 파일과 해시를 준비한다:

1# Check hash and copy it.
2HASH=$(gpg-wks-client --print-wkd-hash -q you@example.com | awk '{print $1}')
3
4gpg --export you@example.com > "$HASH"

이후 해시 파일을 R2 버킷에 업로드한다.

다음 코드를 사용하여 새 Worker를 만든다:

 1export default {
 2  async fetch(request, env) {
 3    const { pathname } = new URL(request.url);
 4    const corsHeaders = {
 5      "Access-Control-Allow-Origin": "*",
 6      "Access-Control-Allow-Methods": "GET, HEAD, OPTIONS",
 7    };
 8
 9    if (request.method === "OPTIONS") {
10      return new Response(null, { headers: corsHeaders });
11    }
12
13    const domain = env.DOMAIN;
14    const hash = env.WKD_HASH;
15
16    // Strict path matching for Direct and Advanced methods
17    const isPolicy =
18      pathname === `/.well-known/openpgpkey/policy` ||
19      pathname === `/.well-known/openpgpkey/${domain}/policy`;
20
21    const isKey =
22      pathname === `/.well-known/openpgpkey/hu/${hash}` ||
23      pathname === `/.well-known/openpgpkey/${domain}/hu/${hash}`;
24
25    if (isPolicy) {
26      return new Response("", {
27        headers: { ...corsHeaders, "Content-Type": "text/plain" },
28      });
29    }
30
31    if (isKey) {
32      // Fetch from R2 bucket
33      const object = await env.WKD.get(hash);
34
35      if (object !== null) {
36        return new Response(object.body, {
37          headers: {
38            ...corsHeaders,
39            "Content-Type": "application/octet-stream",
40          },
41        });
42      }
43    }
44
45    return new Response("Not found", { status: 404 });
46  },
47};

또한 해시 파일에 사용한 버킷을 바인딩하고, 환경 변수와 라우트를 설정해야 한다.

처음에는 Worker에 사용자 지정 도메인(Custom Domain)만 설정했다. 하지만 openpgpkey. 서브도메인이 온라인 상태가 되자마자 봇들이 미친듯이 스캔하기 시작했고, 매번 Worker를 호출하여 컴퓨팅 파워(그리고 더 중요한 것은 내 무료 티어 사용 한도)를 낭비했다.

처음에는 해결책이 명확해 보였다. 라우트(Routes)만 유지하는 것이다. 하지만 Cloudflare가 openpgpkey 서브도메인에 대한 DNS 레코드를 삭제하고, 어떤 요청도 Cloudflare를 거치지 않으므로 라우트 설정이 트리거되지 않아 이 방법은 작동하지 않았다.

AAAA 100::   openpgpkey.shlewislee.me

이 (사실상 비어있는) DNS 레코드를 추가하고 CF 프록시를 거치도록 만들었더니 문제가 해결되었다. 그냥 내 서버로 향하게 할 수도 있었지만, 딱히 쓸모가 있지는 않다고 판단했다.

Reply to this post by email ↪