使用Cloudflare API自动切换DNS

在这篇文章中,我们将探讨如何使用Cloudflare API自动切换DNS。我们将使用Uptime Kuma来监控网站运行状态,并通过webhook进行通知。我们还将运行webhookd服务来接收Uptime Kuma的请求,并在网站状态出现问题时,使用Cloudflare API切换到备用服务器。

引用

https://github.com/louislam/uptime-kuma
https://github.com/ncarlier/webhookd
https://github.com/ncarlier/webhookd/issues/82
https://www.tech-otaku.com/web-development/using-cloudflare-api-manage-dns-records/

监控网站运行状态

首先,我们需要一个工具来监控我们的网站运行状态。这里,我们选择使用Uptime Kuma,它是一个功能强大的开源监控工具,可以帮助我们实时了解网站的运行状况。
当Uptime Kuma检测到网站状态发生变化时,它可以通过webhook发送通知。我们需要运行一个webhookd服务来接收这些通知。

Uptime Kuma 发送的请求数据格式如下:
其中,heartbeat.status属性标识网站是否在线,1:在线, 0:不在线

{
    "heartbeat": {
        "monitorID": 3,
        "status": 0,
        "time": "2023-12-20 06:34:57.117",
        "msg": "Request failed with status code 502",
        "important": true,
        "duration": 60,
        "timezone": "Asia/Shanghai",
        "timezoneOffset": "+08:00",
        "localDateTime": "2023-12-20 14:34:57"
    },
    "monitor": {
        "id": 3,
        "name": "www.website.com",
        "description": null,
        "pathName": "www.website.com",
        "parent": null,
        "childrenIDs": [],
        "url": "https://www.website.com",
        "method": "GET",
        "hostname": null,
        "port": null,
        "maxretries": 3,
        "weight": 2000,
        "active": true,
        "forceInactive": false,
        "type": "http",
        "timeout": 48,
        "interval": 60,
        "retryInterval": 60,
        "resendInterval": 0,
        "keyword": null,
        "invertKeyword": false,
        "expiryNotification": false,
        "ignoreTls": false,
        "upsideDown": false,
        "packetSize": 56,
        "maxredirects": 10,
        "accepted_statuscodes": [
            "200-299"
        ],
        "dns_resolve_type": "A",
        "dns_resolve_server": "1.1.1.1",
        "dns_last_result": null,
        "docker_container": "",
        "docker_host": null,
        "proxyId": null,
        "notificationIDList": {
            "1": true,
            "2": true
        },
        "tags": [
            {
                "id": 3,
                "monitor_id": 3,
                "tag_id": 1,
                "value": "",
                "name": "website",
                "color": "#D97706"
            }
        ],
        "maintenance": false,
        "mqttTopic": "",
        "mqttSuccessMessage": "",
        "databaseQuery": null,
        "authMethod": null,
        "grpcUrl": null,
        "grpcProtobuf": null,
        "grpcMethod": null,
        "grpcServiceName": null,
        "grpcEnableTls": false,
        "radiusCalledStationId": null,
        "radiusCallingStationId": null,
        "game": null,
        "gamedigGivenPortOnly": true,
        "httpBodyEncoding": "json",
        "jsonPath": null,
        "expectedValue": null,
        "kafkaProducerTopic": null,
        "kafkaProducerBrokers": [],
        "kafkaProducerSsl": false,
        "kafkaProducerAllowAutoTopicCreation": false,
        "kafkaProducerMessage": null,
        "screenshot": null,
        "includeSensitiveData": false
    },
    "msg": "[www.website.com] [🔴 Down] Request failed with status code 502"
}

webhookd服务

首先,我们需要在我们的服务器上安装webhookd。有一点需要注意,需要使用edge-distrib, 这个镜像包含一个基本的命令,我们会使用到curl, jq.
这可以通过以下命令完成:

$ docker run -d --name=webhookd \
  -v ${PWD}/scripts:/scripts \
  -p 8080:8080 \
  ncarlier/webhookd:edge-distrib

使用Cloudflare API切换DNS

当我们的webhookd服务接收到Uptime Kuma的请求并判断网站状态出现问题时,我们可以使用Cloudflare API切换到备用服务器。Cloudflare API提供了丰富的功能,使我们能够轻松地管理我们的DNS记录。

在webhookd的scripts目录下创建脚本,脚本名称即请求路径,以example为例
我们会使用jq来获取当前网站状态,并切换DNS地址

#!/bin/bash

status = `echo "$1"| jq .heartbeat.status`
if [[ $status == "0" ]]
then
        server="backup ip"
else
        server="master ip"
fi
echo $server

EMAIL="[email protected]"; \
KEY="d5ce4f919f7fe4f91603a09d9asdfwq234214"; \
ZONE_ID="7a09e1bef9fc4d6aff813f234g45wert432t"; \
DNS_ID="f4a8ab7c0ba7f78611c444234terfde423rf34twert"; \
TYPE="A"; \
NAME="subdomain"; \
CONTENT=$server; \
PROXIED="true"; \
TTL="1";\
curl -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$DNS_ID" \
    -H "X-Auth-Email: $EMAIL" \
    -H "X-Auth-Key: $KEY" \
    -H "Content-Type: application/json" \
    --data '{"type":"'"$TYPE"'","name":"'"$NAME"'","content":"'"$CONTENT"'","proxied":'"$PROXIED"',"ttl":'"$TTL"'}'

其它

日志
docker logs webhookd 查询最新请求的hookid

time=2023-12-21T04:55:38.498Z level=INFO msg="hook executed" hook=example id=8 status=success took=1789064
time=2023-12-21T04:56:38.897Z level=INFO msg="executing hook..." hook=example id=9
time=2023-12-21T04:56:39.916Z level=INFO msg="hook executed" hook=example id=9 status=success took=1018529

然后查看webhookd 日志
https://github.com/ncarlier/webhookd?tab=readme-ov-file#webhook-logs

评论

还没有人评论,抢个沙发吧...

Viagle Blog

欢迎来到我的个人博客网站