EdgeRouter/VyOS配置DDNS动态域名

Cloudflare

市场上有很多动态域名提供商,其中最值得推荐的是Cloudflare。只要你把注册的域名转到Cloudflare下管理,动态域名本身并不收费,而且一个账户可以管理上千个子域名,没有额外费用,也不需要你实名注册,并且亲测中国境内可用。

EdgeOS/VyOS

EdgeRouter最新版本的固件本身直接支持Cloudflare APIv4,参考以下配置命令。

configure
edit service dns dynamic interface pppoe0 service custom-cloudflare
set host-name www.yoursite.com
set login your_cloudflare_email
set password your_cloudflare_global_API_key
set protocol cloudflare
set options "zone=yoursite.com"
commit;save;exit

USG

UBNT的另外一条产品线,USG系列,其装载的OS版本很老,因此无法直接支持Cloudflare DDNS。网上有很多帖子提到手动更新ddclient软件,但是一旦固件更新,就必须重新配置,非常麻烦。这里我们介绍使用shell script的方法,来定时更新域名。原始脚本参考自Tras2在Github上的帖子

首先在/config/scripts/目录下,创建一个新的script文件cloudflare-update.sh,填入以下内容,并根据你的Cloudflare账户更改文件起头的设置参数。

#!/bin/bash

# A bash script to update a Cloudflare DNS A record with the external IP of the source machine
# Used to provide DDNS service for my home
# Needs the DNS record pre-creating on Cloudflare

# Cloudflare zone is the zone which holds the record
zone="yourdomain.com"
# dnsrecord is the A record which will be updated
dnsrecord="www.yourdomain.com"
# Cloudflare authentication details, keep these private
cloudflare_auth_email="[email protected]"
cloudflare_auth_key="your_cloudflare_global_API_key"

log_file="/var/log/cloudflare.log"

# LOGGER
log() {
    if [ "$1" ]; then
        echo -e "[$(date)] - $1" >> $log_file
    fi
}

# Get the current external IP address
ip=$(curl -s -X GET https://checkip.amazonaws.com)

echo "Current IP is $ip"

if host $dnsrecord 8.8.8.8 | grep "has address" | grep "$ip"; then
  echo "$dnsrecord is currently set to $ip; no changes needed"
  exit
fi

# if here, the dns record needs updating

# get the zone id for the requested zone
zoneid=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=$zone&status=active" \
  -H "X-Auth-Email: $cloudflare_auth_email" \
  -H "X-Auth-Key: $cloudflare_auth_key" \
  -H "Content-Type: application/json" | jq -r '{"result"}[] | .[0] | .id')

echo "Zoneid for $zone is $zoneid"

# get the dns record id
dnsrecordid=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$zoneid/dns_records?type=A&name=$dnsrecord" \
  -H "X-Auth-Email: $cloudflare_auth_email" \
  -H "X-Auth-Key: $cloudflare_auth_key" \
  -H "Content-Type: application/json" | jq -r '{"result"}[] | .[0] | .id')

echo "DNSrecordid for $dnsrecord is $dnsrecordid"

# update the record
update=$(curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$zoneid/dns_records/$dnsrecordid" \
  -H "X-Auth-Email: $cloudflare_auth_email" \
  -H "X-Auth-Key: $cloudflare_auth_key" \
  -H "Content-Type: application/json" \
  --data "{\"type\":\"A\",\"name\":\"$dnsrecord\",\"content\":\"$ip\",\"ttl\":1,\"proxied\":false}")

if [[ $update == *"\"success\":false"* ]]; then
    message="API UPDATE FAILED. DUMPING RESULTS:\n$update"
    log "$message"
    echo -e "$message"
    exit 1 
else
    message="IP changed to: $ip"
    log "$message"
    echo "$message"
fi

以上脚本通过查询特定网站(https://checkip.amazonaws.com)以获取外网IP。如果使用多个WAN口,这个方法就不适用了,可以通过调用EdgeOS运行命令接口来获取端口IP地址:

ip=$(/opt/vyatta/bin/vyatta-op-cmd-wrapper show interfaces | grep pppoe0 | awk '{print $2}')

记住要将新创建的文件改成可执行模式,然后进行测试:

sudo chmod +x /config/scripts/cloudflare-update.sh
sudo /config/scripts/cloudflare-update.sh

测试成功后,我们需要通过网关配置文件来设置定时任务。具体网关配置文件的设置方法请参见UBNT的官网链接。参考的配置文件如下:

{
    "system": {
        "task-scheduler": {
            "task": {
                "update-cloudflar-dns": {
                    "executable": {
                        "arguments": "",
                        "path": "/config/scripts/cloudflare-update.sh"
                    },
                    "interval": "1m"
                }
            }
        }
    }
}

这种方法可以保证设置不会受到固件升级的影响,并且每次USG从云端更新配置时,会自动将更新任务下发到USG。

NoIP

NoIP也是网友常用的DDNS供应商,相对Cloudflare,其最大的好处是使用官方域名,完全免费。EdgeOS和USG也都内置对NoIP的支持,可以使用WebUI或者Unifi控制器直接配置。参考命令行配置如下:

configure
edit service dns dynamic interface pppoe0 
set service noip host-name yourhost.ddns.net
set service noip login yourloginID
set service noip password yourloginpasswd
set service noip server dynupdate.no-ip.com
set web checkip.dyndns.com
commit;save;exit

NoIP的免费DDNS域名服务,供应商会要求域名必须每30天至少更新一次。而EdgeOS的设计在WAN口IP不变化的情况下,不主动更新DDNS记录。因此有必要配置一个定时任务来实现每天更新一次域名。这里我们调用EdgeOS内置的运行命令接口/opt/vyatta/bin/vyatta-op-cmd-wrapper,有兴趣的朋友可以参见官网介绍

configure
edit system task-scheduler task update_noip_pppoe0 
set executable arguments 'update dns dynamic interface pppoe0'
set executable path /opt/vyatta/bin/vyatta-op-cmd-wrapper
set interval 1d
commit;save;exit

公云PubYun

公云是国内老牌DDNS提供商,这里就不赘述了,直接上干货。

configure
set service dns dynamic interface pppoe0 service custom-pubyun host-name yourdomain.f3322.net
set service dns dynamic interface pppoe0 service custom-pubyun login yourlogin
set service dns dynamic interface pppoe0 service custom-pubyun options ssl=no
set service dns dynamic interface pppoe0 service custom-pubyun password yourpasswd
set service dns dynamic interface pppoe0 service custom-pubyun protocol dyndns2
set service dns dynamic interface pppoe0 service custom-pubyun server www.pubyun.com
commit;save;exit

阿里云DDNS

阿里云的DDNS服务最近很流行。EdgeOS和VyOS都没有内置支持,我们参考网上其他的网友Jarvis脚本,做了一个参考实现。

先下载脚本文件updatealiddns.sh,然后用编辑器修改脚本开头的三个参数:

  • aliddns_ak,你的阿里云DDNS账户Access Key ID
  • aliddns_sk,你的阿里云DDNS账户Access Key Secrets
  • aliddns_domain,阿里云域名后缀

上传修改后的脚本文件到/config/scripts目录下,并使用以下命令更改文件属性为可执行。

sudo chmod +x /config/scripts/update-aliddns.sh

接下来,我们配置一个系统任务,每分钟执行一次这个脚本。

configure
set system task-scheduler task update-aliyun-ddns executable arguments 'myhostname'
set system task-scheduler task update-aliyun-ddns executable path '/config/scripts/update-aliddns.sh'
set system task-scheduler task update-aliyun-ddns interval '1m'
commit;save;exit

上述配置中,myhostname是你的二级域名。请根据实际情况修改。