树莓派自动解析IPV6地址

自动解析树莓派的 IPV6 地址到某个域名

<?php

// 调试模式
define('DebugModel', false);

// 域名
define('Domain', 'device.raspberrypi.org');

// Clouflare API 地址
define('ClouflareApiBase', 'https://api.cloudflare.com/client/v4');

// Clouflare API 密钥
define('ClouflareAuthKey', 'ClouflareAuthKey');

/**
 *  获取本机 IPV6 地址
 */
function getIPV6()
{
    if (!file_exists('/proc/net/if_inet6')) {
        throw new Exception("Get IPV6 Failed!");
    }
    $_ipv6 = explode(" ", file_get_contents('/proc/net/if_inet6'))[0];
    debug('Getting IPV6');
    return implode(':', str_split($_ipv6, 4));
}

/**
 *  获取顶级域名
 */
function getMainDomain($domain)
{
    $_domain = explode('.', $domain);
    $domain = [];
    $domain[] = array_pop($_domain);
    $domain[] = array_pop($_domain);
    debug('Getting Main Domain');
    return $domain[1] . '.' . $domain[0];
}

/**
 *  获取域名 Zone ID
 */
function getZoneID($domain)
{
    $mainDomain = getMainDomain($domain);
    $url = sprintf('%s/zones', ClouflareApiBase);
    debug('Send ZoneID Request');
    $dns = json_decode(httpRequest('GET', $url));
    debug('Get ZoneID Response');
    if (isset($dns->result)) {
        foreach ($dns->result as $v) {
            if ($v->name === $mainDomain) {
                return $v->id;
            }
        }
    } else {
        throw new Exception("Get ZoneID Failed!");
    }
}

/**
 *  获取域名 Record
 */
function getRecord($zoneID, $domain, $type = 'A')
{
    $url = sprintf('%s/zones/%s/dns_records', ClouflareApiBase, $zoneID);
    debug('Send RecordID Request');
    $dns = json_decode(httpRequest('GET', $url));
    debug('Get RecordID Response');
    if (isset($dns->result)) {
        foreach ($dns->result as $v) {
            if ($v->name === $domain && $v->type === $type) {
                return $v;
            }
        }
    }
    return false;
}

/**
 *  新增域名解析
 */
function setRecord($zoneID, $domain, $ipv6)
{
    $data = array(
        'name' => $domain,
        'type' => 'AAAA',
        'content' => $ipv6,
        'ttl' => 120
    );
    $url = sprintf('%s/zones/%s/dns_records', ClouflareApiBase, $zoneID);
    $response = json_decode(httpRequest('POST', $url, json_encode($data)));
    if (isset($response->result->id)) {
        return true;
    } else {
        return false;
    }
}

/**
 *  更新域名解析
 */
function updateRecord($zoneID, $recordID, $domain, $ipv6)
{
    $data = array(
        'name' => $domain,
        'type' => 'AAAA',
        'content' => $ipv6,
        'ttl' => 120
    );
    $url = sprintf('%s/zones/%s/dns_records/%s', ClouflareApiBase, $zoneID, $recordID);
    $response = json_decode(httpRequest('PUT', $url, json_encode($data)));
    if (isset($response->result->id)) {
        return true;
    } else {
        return false;
    }
}

/**
 *  发起 HTTP 请求
 */
function httpRequest($method = 'GET', $url, $post = '')
{
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_ENCODING, 'gzip');
    curl_setopt($curl, CURLOPT_HTTPHEADER, ['Authorization: Bearer ' . ClouflareAuthKey, 'Content-Type: application/json']);

    if ($method !== 'GET') {
        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $post);
    }

    $data = curl_exec($curl);
    $error = curl_error($curl);
    curl_close($curl);

    if ($error) {
        throw new Exception($error);
    } else {
        return $data;
    }
}

function debug($log)
{
    if (DebugModel) {
        $file = '/tmp/dns.log';
        $log = date('Y-m-d H:i:s') . "\t" . $log . "\n";
        echo $log;
        file_put_contents($file, $log, FILE_APPEND);
    }
}

function main($domain)
{
    $ipv6 = getIPV6();
    $zoneID = getZoneID($domain);
    $record = getRecord($zoneID, $domain, 'AAAA');
    if (isset($record->id)) {
        if ($record->content !== $ipv6) {
            debug('Update IPV6 Record');
            $update = updateRecord($zoneID, $record->id, $domain, $ipv6);
        } else {
            return debug('No Change IPV6 Record');
        }
    } else {
        debug('New IPV6 Record');
        $update = setRecord($zoneID, $domain, $ipv6);
    }
    if ($update) {
        debug('DNS Record Update Success!');
    } else {
        debug('DNS Record Update Failed!');
    }
}

main(Domain);