通过API修改CloudFlare电子邮件路由

发布于 2022-08-12  1,515 次阅读


前言

写脚本的时候,里面需要用到CloudFlare电子邮件路由,因为是想实现“临时邮箱”的功能,所以总不可能去一个一个输入。

于是去翻了CloudFlare的官方API文档,不幸的是,在官方的API文档中并没有关于电子邮件路由的介绍。?

于是将目标改向了CloudFlare的仪表盘。通过简单的抓包,找到了仪表盘的请求url:https://dash.cloudflare.com/api/v4/zones/ZONE_ID/。发现它和CloudFlare的官方API接口很像(CloudFlare官方API接口:https://api.cloudflare.com/client/v4/zones/ZONE_ID/)。

如果能够直接请求官方的API接口,那么就可以避免复杂的登录操作。很幸运的是,我成功了,看起来,就像上一篇文章中的“google”参数一样,即便已经可以使用了,但CloudFlare并没有更新他们API文档。

通过curl调用API

添加电子邮件路由

curl -X POST https://api.cloudflare.com/client/v4/zones/ ZONE_ID /email/routing/rules \
       -H "Content-Type: application/json" \
       -H "X-Auth-Key: GLOBAL_KEY " \
       -H "X-Auth-Email: EMAIL " \
       --data '{"actions":[{"type":"forward","value":[" 目标EMAIL "]}],"matchers":[{"type":"literal","field":"to","value":" 前缀@域名 "}]}'

获取全部的电子邮件路由

curl -X GET  https://api.cloudflare.com/client/v4/zones/ ZONE_ID /email/routing/rules \
       -H "Accept: */*" \
       -H "X-Auth-Key: GLOBAL_KEY " \
       -H "X-Auth-Email: EMAIL "

删除全部电子邮件路由

curl -X PUT  https://api.cloudflare.com/client/v4/zones/ ZONE_ID /email/routing/rules \
       -H "Accept: */*" \
       -H "Content-Type: application/json" \
       -H "X-Auth-Key: GLOBAL_KEY" \
       -H "X-Auth-Email: EMAIL" \
       --data '[{"matchers":[{"type":"all"}],"actions":[{"type":"forward","value":[" 目标MAIL "]}]}]'

参数解释

ZONE_ID: CloudFlare区域ID

GLOBAL_KEY: CloudFlare的Global API Key

MAIL: CloudFlare绑定的电子邮件

目标MAIL: 电子邮件路由中已验证的目标地址

前缀@域名: 需要的电子邮件地址

为什么是删除全部电子邮件路由?

首先,我们注意到,在创建电子邮件路由的时候,发送的json中包含着两个参数matchersactions

其中matchers参数用来指定需要路由的电子邮件,actions参数用来指向目标电子邮件。

在删除的时候,在这里使用的并非DELETE请求而是PUT请求,所以所谓的删除,其实是编辑。对于每一个电子邮件路由,都有一个类似于{"matchers":[],"actions":[]}的json数据。在进行编辑时,我们将每一个这样的json数据放在[]中,类似于[{"matchers":[],"actions":[]},{"matchers":[],"actions":[]}]。这时我们需要注意,在CloudFlare的电子邮件路由中含有一个matchers参数为{"type":"all"}的一组数据,也就是无论我们最后需要发送多少组json数据,他都应该像这样[{"matchers":[],"actions":[]},{"matchers":[],"actions":[]},{"matchers":{"type":"all"},"actions":[]]}。而当我们只发送含有"matchers":{"type":"all"}参数的json数据的时候,会将其他全部的数据删除掉。

通过Python调用API

import json
import requests


class CloudFlareMail:
    global_key = ''
    cloudflare_mail = ''

    def __init__(self, zone_id):
        self.zone_id = str(zone_id)
        self.url = f'https://api.cloudflare.com/client/v4/zones/{self.zone_id}/email/routing/rules'

    def add_mail_route(self, mail_from, mail_to):  # 添加电子邮件路由
        headers = {"Content-Type": "application/json", "X-Auth-Key": self.global_key,"X-Auth-Email": self.cloudflare_mail}
        data = '{"enabled":true,"name":"","actions":[{"type":"forward","value":["' + str(mail_to) + '"]}],"matchers":[{"type":"literal","field":"to","value":"' + str(mail_from) + '"}]}'
        response = requests.post(self.url, headers=headers, data=data)
        if response.status_code == 200:
            return True
        else:
            return False

    def get_mail_route(self):  # 获取全部的电子邮件路由
        headers = {"Accept": "*/*", "X-Auth-Key": self.global_key, "X-Auth-Email": self.cloudflare_mail}
        response = requests.get(self.url, headers=headers)
        if response.status_code == 200:
            return response.text
        else:
            return False

    def del_mail_route(self, mail_from):  # 删除电子邮件路由
        headers = {"Accept": "*/*", "Content-Type": "application/json", "X-Auth-Key": self.global_key, "X-Auth-Email": self.cloudflare_mail}
        mail_routes = json.loads(self.get_mail_route())['result']
        data = '['
        for mail_route in mail_routes:
            if mail_route['matchers'][0]['type'] == 'all':
                data = data + f'{{"matchers":{mail_route["matchers"]},"actions":{mail_route["actions"]}}},'
            else:
                if mail_route['matchers'][0]['value'] == str(mail_from):
                    pass
                else:
                    data = data + f'{{"matchers":{mail_route["matchers"]},"actions":{mail_route["actions"]}}},'
        data = data.strip(',') + ']'
        data = data.replace(' ', '').replace('\'', '\"')
        response = requests.put(self.url, headers=headers, data=data)
        if response.status_code == 200:
            return True
        else:
            return False

使用

更改global_key和cloudflare_mail两个参数

通过

example = CloudFlareMail("区域ID")

的方式来创建对象。

通过

example.add_mail_route("电子邮件路由")

的方式添加电子邮件路由,返回True/False。

通过

example.del_mail_route("电子邮件路由")

的方式删除电子邮件路由,返回True/False。

使用del_mail_route()时会自动更改put时请求的参数,只需要给出需要删除的电子邮件路由即可。