구독해서 새 게시물에 대한 알림을 받으세요.

우리가 Cloudflare Workers를 이용해 DMARC 관리를 구축한 방법

2023-03-17

7분 읽기
이 게시물은 English, 繁體中文, Français, Deutsch, 日本語, Español简体中文로도 이용할 수 있습니다.

DMARC 보고서란

How we built DMARC Management

DMARC는 도메인 기반 메시지 인증, 보고, 적합성을 의미합니다. 이는 이메일 피싱스푸핑 방어에 도움이 되는 이메일 인증 프로토콜입니다.

DMARC를 사용하면 이메일을 전송할 때 SPF(발신자 정책 프레임워크), DKIM(도메인키 식별 메일) 등 인증 방법을 지정하는 DNS 레코드를 설정하여 이메일의 진위 여부를 확인할 수 있습니다. 이메일이 이러한 인증 검사에 실패하면 DMARC는 수신자의 이메일 공급자가 메시지를 격리하거나 완전히 거부하여 메시지를 처리하는 방법을 알려줍니다.

이메일 피싱과 스푸핑 공격이 점점 더 정교해지며 널리 퍼지고 있는 오늘날의 인터넷 환경에서 DMARC의 중요성은 점점 더 커지고 있습니다. 도메인 소유자는 DMARC를 구현하면 이러한 공격으로 인해 발생하는 신뢰 상실, 평판 손상, 재정 손실 등의 부정적인 영향으로부터 브랜드와 고객을 보호할 수 있습니다.

DMARC는 피싱 및 스푸핑 공격으로부터의 방어하는 기능 외에도 보고 기능도 제공합니다. 도메인 소유자는 어떤 메시지가 DMARC 검사를 통과했고 통과하지 못했는지, 메시지의 출처가 어디인지 등 이메일 인증 활동에 대한 보고서를 받을 수 있습니다.

DMARC 관리에는 도메인에 DMARC 정책을 구성하고 유지 관리하는 활동이 포함됩니다. DMARC를 효과적으로 관리하려면 이메일 인증 활동을 모니터링하고 분석하며 필요 시 DMARC 정책을 조정하거나 업데이트해야 합니다.

효과적인 DMARC 관리에 필요한 몇 가지 주요 구성 요소는 다음과 같습니다.

  • DMARC 정책 설정: 도메인의 DMARC 레코드를 구성하여 인증 검사에 실패한 메시지를 처리하기 위한 적절한 인증 방법과 정책을 지정합니다. DMARC DNS 레코드의 모습은 다음과 같습니다.

v=DMARC1; p=reject; rua=mailto:[email protected]

이는 우리가 DMARC 버전 1을 사용하도록 지정합니다. 우리의 정책은 DMARC 확인에 실패한 경우 이메일을 거부하고 공급자가 DMARC 보고서를 보내야 하는 이메일 주소를 거부하는 것입니다.

  • 이메일 인증 활동 모니터링: DMARC 보고서는 도메인 소유자가 이메일 보안과 전달 가능성을 보장하고 업계 표준과 규정을 준수하는 데 중요한 도구입니다. 도메인 소유자는 DMARC 보고서를 정기적으로 모니터링하고 분석하면 이메일 위협을 식별하고 이메일 캠페인을 최적화하며 이메일 인증을 전반적으로 개선할 수 있습니다.

  • 필요 시 조정 수행: 도메인 소유자는 DMARC 보고서 분석을 기반으로 이메일 메시지를 적절하게 인증하고 피싱과 스푸핑 공격으로부터 보호하는 데 DMARC 정책 조정이나 인증 방법이 필요할 수 있습니다.

  • 이메일 공급자 및 타사 벤더와의 협업: 효과적으로 DMARC를 관리하려면 이메일 공급자 및 타사 벤더와 협업하여 DMARC 정책을 제대로 구현하고 적용하고 있는지 확인해야 합니다.

오늘 Cloudflare에서는 DMARC 관리를 출시했습니다. 구축 방법은 다음과 같습니다.

구축 방법

Cloudflare에서는 클라우드 기반 보안과 성능 솔루션의 선두 공급업체로서 특별한 접근 방식으로 제품을 테스트합니다. 자사 도구와 서비스를 "시험적으로 사용"합니다. 즉, 우리 사업을 운영하는 데 사용합니다. 이를 통해 어떠한 문제나 버그가 발생하여 고객에게 영향을 미치기 전에 이를 파악할 수 있습니다.

Cloudflare에서는 개발자가 전역 네트워크에서 코드를 실행할 수 있는 서버리스 플랫폼인 Cloudflare Workers 등 자사 제품을 내부적으로 사용하고 있습니다. 2017년 플랫폼 출시 이후 Workers 생태계는 크게 성장했습니다. 현재 수천 명의 개발자가 이 플랫폼에서 애플리케이션을 구축하고 배포하고 있습니다. Workers 생태계의 힘은 개발자가 이전에는 불가능했거나 비현실적이었던 정교한 애플리케이션을 구축하여 클라이언트와 가까운 곳에서 실행할 수 있다는 점입니다. Workers를 사용하면 API를 구축하고 동적 콘텐츠를 생성하고 실시간 처리를 수행할 수 있습니다. 가능성은 사실상 무한합니다. Cloudflare에서는 Workers를 사용하여 Radar 2.0과 같은 서비스나 Wildebeest와 같은 소프트웨어 패키지를 구동했습니다.

최근 Cloudflare의 이메일 라우팅 제품이 Workers와 통합되어 Workers 스크립트를 통해 수신 이메일 처리가 가능합니다. 문서 내용: “Email Workers를 사용하면 Cloudflare Workers의 강력한 기능을 활용하여 이메일을 처리하고 복잡한 규칙을 생성하는 데 필요한 로직을 구현할 수 있습니다. 이러한 규칙에 따라 이메일을 수신했을 때 어떤 일이 발생하는지가 결정됩니다.” 규칙과 확인된 주소는 모두 Cloudflare API를 통해 구성할 수 있습니다.

간단한 Email Worker의 모습은 다음과 같습니다.

아주 간단하지요?

export default {
  async email(message, env, ctx) {
    const allowList = ["[email protected]", "[email protected]"];
    if (allowList.indexOf(message.headers.get("from")) == -1) {
      message.setReject("Address not allowed");
    } else {
      await message.forward("inbox@corp");
    }
  }
}

수신 이메일을 프로그래밍 방식으로 처리할 수 있는 기능이 있는 이 플랫폼은 확장 가능하고 효율적인 방식으로 수신 DMARC 보고서 이메일을 처리할 수 있는 완벽한 방법인 것 같습니다. 또한 이메일 라우팅과 Workers는 전 세계에서 오는 수 많은 이메일을 수신하는 어려운 작업도 처리합니다. 필요했던 기능을 대략적으로 설명하면 다음과 같습니다.

  1. 이메일 수신 및 보고서 추출

  2. 분석 관련 플랫폼에 관련 세부 정보 게시

  3. 원시 보고서 저장

Email Workers를 사용하면 첫 번째 기능은 쉽게 수행할 수 있습니다. email() 핸들러가 있는 worker를 생성하기만 하면 됩니다. 이 핸들러는 SMTP 봉투 요소, 사전 구문 분석된 버전의 이메일 헤더, 전체 원시 이메일을 읽을 수 있는 스트림을 수신합니다.

두 번째 기능의 경우에도 Workers 플랫폼을 살펴보면 Workers Analytics 엔진을 확인할 수 있습니다. 보고서의 내용과 이후에 수행하려는 쿼리에 따라 적절한 스키마를 정의하기만 하면 됩니다. 그런 다음 GraphQL 또는 SQL API를 사용하여 데이터를 쿼리할 수 있습니다.

세 번째 기능의 경우 R2 개체 스토리지만 살펴보면 됩니다. Worker에서 R2를 액세스하는 것은 단순합니다. 이메일에서 보고서를 추출한 후 나중을 위해 R2에 저장합니다.

이 기능을 영역에서 사용할 수 있는 관리형 서비스로 구축했고 편의성을 위해 대시보드 인터페이스에 추가했지만, 실제로는 서버, 확장성 성능을 걱정할 필요 없이 자신의 계정에서 Cloudflare Workers상에 나만의 DMARC 보고서 프로세서를 배포할 수 있습니다.

아키텍처

Email Workers는 이메일 라우팅 제품의 주요 기능입니다. 이메일 라우팅 구성 요소는 모든 노드에서 실행되므로 어떤 노드에서도 수신 이메일을 처리할 수 있으며, 이는 모든 Cloudflare 데이터 센터의 Email 수신 BGP 접두사를 알려주므로 중요합니다. Email Worker에 이메일을 보내는 것은 이메일 라우팅 대시보드에서 규칙을 설정하는 것만큼 쉽습니다.

이메일 라우팅 구성 요소가 Worker에 전달할 규칙과 일치하는 이메일을 수신하면, 최근에 오픈 소스로 지원하고 모든 노드에서도 실행되는 자사 버전의 workerd 런타임에 연결됩니다. 이 상호 작용을 관장하는 RPC 스키마는 Capnproto 스키마에 정의되어 있으며, 이메일 본문을 읽을 때 Edgeworker로 스트리밍될 수 있습니다. Worker 스크립트가 이 이메일로 전달하기로 결정한 경우 Edgeworker는 원본 요청에서 전송된 기능을 사용하여 이메일 라우팅에 연결합니다.

DMARC 보고서의 맥락에서 수신 이메일을 처리하는 방식은 다음과 같습니다.

jsg::Promise<void> ForwardableEmailMessage::forward(kj::String rcptTo, jsg::Optional<jsg::Ref<Headers>> maybeHeaders) {
  auto req = emailFwdr->forwardEmailRequest();
  req.setRcptTo(rcptTo);

  auto sendP = req.send().then(
      [](capnp::Response<rpc::EmailMetadata::EmailFwdr::ForwardEmailResults> res) mutable {
    auto result = res.getResponse().getResult();
    JSG_REQUIRE(result.isOk(), Error, result.getError());
  });
  auto& context = IoContext::current();
  return context.awaitIo(kj::mv(sendP));
}
  1. 처리 중인 이메일의 수신자를 가져옵니다. 이것은 사용된 RUA입니다. RUA는 특정 도메인과 관련한 집계 DMARC 처리 피드백을 보고해야 할 위치를 나타내는 DMARC 구성 매개변수입니다. 이 수신자는 메시지의 “to” 속성에서 찾을 수 있습니다.

    const ruaID = message.to

  2. 도메인에서 무제한으로 DMARC 보고서를 처리할 수 있으므로 Workers KV를 사용하여 각 도메인의 일부 정보를 저장하고 이 정보를 RUA의 키로 저장합니다. 이는 또한 이러한 보고서를 수신해야 하는지 여부도 알려줍니다.

    const accountInfoRaw = await env.KV_DMARC_REPORTS.get(dmarc:${ruaID})

  3. 이 시점에서 전체 이메일을 구문 분석하기 위해 arrayBuffer로 읽어야 합니다. 보고서의 크기에 따라 무료 Workers 요금제의 한도에 도달할 수 있습니다. 이 경우 문제가 없는 Workers Unbound 리소스 모델로 전환하는 것이 좋습니다.

    const rawEmail = new Response(message.raw) const arrayBuffer = await rawEmail.arrayBuffer()

  4. 원시 이메일 구문 분석에는 무엇보다도 MIME 부분의 구문 분석이 포함됩니다. 구문 분석 수행에 사용할 수 있는 여러 라이브러리가 있습니다. 예를 들어, postal-mime을 사용할 수 있습니다.

    const parser = new PostalMime.default() const email = await parser.parse(arrayBuffer)

  5. 이메일을 구문 분석했으므로 이제 첨부 파일에 액세스할 수 있습니다. 이 첨부 파일은 DMARC 보고서 자체이며 압축할 수 있습니다. 장기 보관을 위해 가장 먼저 압축된 형태로 R2에 저장합니다. 이들 에메일은 이후 관심이 있는 보고서를 재처리하거나 조사할 때 유용하게 사용할 수 있습니다. 이 작업은 R2 바인딩에서 put()을 호출하는 것만큼 간단합니다. 이후 쉽게 검색할 수 있도록 현재 시간을 기준으로 보고서 파일을 여러 디렉터리에 분산하는 것을 권장합니다.

    await env.R2_DMARC_REPORTS.put( ${date.getUTCFullYear()}/${date.getUTCMonth() + 1}/${attachment.filename}, attachment.content )

  6. 이제 첨부 파일 mime 유형을 살펴볼 필요가 있습니다. DMARC 보고서의 원시 형식은 XML이지만, 압축할 수 있습니다. 이 경우 먼저 보고서의 압축을 풀어야 합니다. DMARC 리포터 파일은 여러 압축 알고리즘을 사용할 수 있습니다. 어떤 알고리즘을 사용하는지 MIME 유형으로 확인합니다.Zlib로 압축된 보고서의 경우 pako를 사용할 수 있고 ZIP으로 압축된 보고서의 경우 unzipit를 선택하는 것이 좋습니다.

  7. 보고서의 원시 XML 형식을 확보했다면 구문 분석할 때 fast-xml-parser가 잘 작동한 것입니다. DMARC 보고서 XML의 모습은 다음과 같습니다.

  8. 이제 보고서의 데이터를 모두 손에 넣었습니다. 지금부터는 데이터를 표시하려는 방법에 따라 많이 달라집니다. Cloudflare의 목표는 보고서에서 추출한 의미 있는 데이터를 대시보드에 표시하는 것이었습니다. 그래서 풍부한 데이터를 푸시할 수 있는 분석 플랫폼이 필요했습니다. 그것이 바로 Workers Analytics Engine입니다. 이 분석 엔진을 사용하면 worker에서 데이터를 엔진으로 전송할 수 있고, GraphQL API를 노출하여 이후 데이터와 상호 작용할 수 있으므로 이 작업에 완벽합니다. 여기까지가 바로 대시보드에 표시할 데이터를 얻는 방법입니다.

향후에는 보고서를 비동기적으로 처리하고 클라이언트가 처리를 완료할 때까지 기다리지 않도록 워크플로우에서 Queues를 통합하는 방안도 고려하고 있습니다.

const ruaID = message.to

Workers 인프라에만 의존하여 엔드투엔드 방식으로 이 프로젝트를 구현했으므로 확장성, 성능, 스토리지, 보안 문제를 걱정하지 않고 단순하지 않은 앱을 구축하는 것이 가능하며 유리하다는 점을 증명했습니다.

const accountInfoRaw = await env.KV_DMARC_REPORTS.get(dmarc:${ruaID})

오픈 소스

const rawEmail = new Response(message.raw)
const arrayBuffer = await rawEmail.arrayBuffer()

앞서 언급했듯이 Cloudflaredptj는 활성화하여 사용할 수 있는 관리형 서비스를 구축했으므로 대신 관리해 드리겠습니다. 하지만 계정에서 직접 배포하신 후 자체 DMARC 보고서를 관리할 수도 있습니다. 쉽고 무료입니다. 이를 지원하기 위해 위에서 설명한 방식대로 DMARC 보고서를 처리하는 오픈 소스 버전의 Worker를 출시합니다. https://github.com/cloudflare/dmarc-email-worker

const parser = new PostalMime.default()
const email = await parser.parse(arrayBuffer)

데이터를 표시할 대시보드가 없는 경우에도 Worker에서 분석 엔진을 쿼리할 수 있습니다. 또는 관계형 데이터베이스에 저장하려는 경우 D1을 사용할 수 있습니다. 가능성은 무궁무진하며 이러한 도구로 무엇을 구축하실지 기대가 됩니다.

await env.R2_DMARC_REPORTS.put(
    `${date.getUTCFullYear()}/${date.getUTCMonth() + 1}/${attachment.filename}`,
    attachment.content
  )

기여해 주시고 직접 만들어시면 귀 기울여 듣겠습니다.

<feedback>
  <report_metadata>
    <org_name>example.com</org_name>
    <[email protected]</email>
   <extra_contact_info>http://example.com/dmarc/support</extra_contact_info>
    <report_id>9391651994964116463</report_id>
    <date_range>
      <begin>1335521200</begin>
      <end>1335652599</end>
    </date_range>
  </report_metadata>
  <policy_published>
    <domain>business.example</domain>
    <adkim>r</adkim>
    <aspf>r</aspf>
    <p>none</p>
    <sp>none</sp>
    <pct>100</pct>
  </policy_published>
  <record>
    <row>
      <source_ip>192.0.2.1</source_ip>
      <count>2</count>
      <policy_evaluated>
        <disposition>none</disposition>
        <dkim>fail</dkim>
        <spf>pass</spf>
      </policy_evaluated>
    </row>
    <identifiers>
      <header_from>business.example</header_from>
    </identifiers>
    <auth_results>
      <dkim>
        <domain>business.example</domain>
        <result>fail</result>
        <human_result></human_result>
      </dkim>
      <spf>
        <domain>business.example</domain>
        <result>pass</result>
      </spf>
    </auth_results>
  </record>
</feedback>

마지막 한마디

이 게시물을 통해 Workers 플랫폼에 대한 이해가 한층 더 깊어졌기를 바랍니다. 현재 Cloudflare는 이 플랫폼을 활용하여 당사 서비스 대부분을 구축하고 있으며 귀사에서도 가능하다고 생각합니다.

오픈 소스 버전에 자유롭게 기여하시고 무엇을 할 수 있는지 보여 주세요.

또한 이메일 라우팅에서는 Email Workers API의 기능적 측면을 더 확장하고 있지만, 그 내용은 곧 다른 블로그에서 다룰 예정입니다.

Cloudflare에서는 전체 기업 네트워크를 보호하고, 고객이 인터넷 규모의 애플리케이션을 효과적으로 구축하도록 지원하며, 웹 사이트와 인터넷 애플리케이션을 가속화하고, DDoS 공격을 막으며, 해커를 막고, Zero Trust로 향하는 고객의 여정을 지원합니다.

어떤 장치로든 1.1.1.1에 방문해 인터넷을 더 빠르고 안전하게 만들어 주는 Cloudflare의 무료 앱을 사용해 보세요.

더 나은 인터넷을 만들기 위한 Cloudflare의 사명을 자세히 알아보려면 여기에서 시작하세요. 새로운 커리어 경로를 찾고 있다면 채용 공고를 확인해 보세요.
Security Week (KO)Email Security (KO)보안DMARC

X에서 팔로우하기

André Cruz|@edevil
Cloudflare|@cloudflare

관련 게시물

2024년 10월 08일 오후 1:00

Cloudflare acquires Kivera to add simple, preventive cloud security to Cloudflare One

The acquisition and integration of Kivera broadens the scope of Cloudflare’s SASE platform beyond just apps, incorporating increased cloud security through proactive configuration management of cloud services. ...

2024년 10월 06일 오후 11:00

Enhance your website's security with Cloudflare’s free security.txt generator

Introducing Cloudflare’s free security.txt generator, empowering all users to easily create and manage their security.txt files. This feature enhances vulnerability disclosure processes, aligns with industry standards, and is integrated into the dashboard for seamless access. Strengthen your website's security today!...