梅林固件使用自定义DDNS更新aliyun DDNS的ipv6地址
移动宽带分配的ipv4是内网ip,但是可以分配ipv6地址。梅林固件默认不支持ipv6地址,只能使用自定义shell来实现。参考koolshare的aliyun ddns shell,修改为支持对aliyun ddns的ipv6地址进行更新。
移动光猫如何分配ipv6地址请自行google。
梅林固件webgui界面配置
菜单:外部网络(WAN)-> DDNS
- 启用 DDNS 客户端 - 选 “是”。
- Method to retrieve WAN IP - 选 “Internal” 。如果用光猫拔号,选哪个都是一样的,路由器传给
ddns-start
的ip是内网ip。 - 服务器 - 选 “Custom”。
- 主机名称 - 填 “自定义的域名”。
- Forced update interval (in days) - 填“72” 。每天更新72次,即每20分钟更新一次DDNS。
新建shell /jffs/scripts/ddns-start
固件的自定义DDNS shell是 /jffs/scripts/ddns-start
,需要先检查是否启用了 jffs
的script功能。
#!/bin/sh aliddns_ak="your aliyun ak" #aliyun accessKey ID aliddns_sk="your aliyun sk" #aliyun access Key aliddns_name="your host name" aliddns_domain="your-domain.net" alias echo_date='echo [$(TZ=UTC-8 date -R +%Y%m%d\ %X)]' now=`echo_date` die () { echo $1 # dbus set aliddns_last_act="$now: failed($1)" } # whatismyip.akamai.com for ipv4 [ "$aliddns_curl" = "" ] && aliddns_curl="curl -s --interface vlan2 ipv6.whatismyip.akamai.com" [ "$aliddns_dns" = "" ] && aliddns_dns="223.5.5.5" [ "$aliddns_ttl" = "" ] && aliddns_ttl="600" ip=`$aliddns_curl 2>&1` || die "$ip" #support @ record nslookup if [ "$aliddns_name" = "@" ];then current_ip=`nslookup $aliddns_domain $aliddns_dns 2>&1` else current_ip=`nslookup $aliddns_name.$aliddns_domain $aliddns_dns 2>&1` fi if [ "$?" -eq "0" ];then current_ip=`echo "$current_ip" | grep 'Address 1' | tail -n1 | awk '{print $NF}'` if [ "$ip" = "$current_ip" ] then echo "aliyunddns: skipping ${aliddns_name}.${aliddns_domain} $ip $now" |tee /tmp/aliyun_ddns_ipv6.log #web ui show without @. if [ "$aliddns_name" = "@" ] ;then nvram set ddns_hostname_x="$aliddns_domain" else # nvram set ddns_hostname_x="$aliddns_name"."$aliddns_domain" ddns_custom_updated 1 exit 0 fi fi else # fix when A record removed by manual dns is always update error unset aliddns_record_id fi timestamp=`date -u "+%Y-%m-%dT%H%%3A%M%%3A%SZ"` urlencode() { # urlencode <string> out="" while read -n1 c do case $c in [a-zA-Z0-9._-]) out="$out$c" ;; *) out="$out`printf '%%%02X' "'$c"`" ;; esac done echo -n $out } enc() { echo -n "$1" | urlencode } send_request() { local args="AccessKeyId=$aliddns_ak&Action=$1&Format=json&$2&Version=2015-01-09" local hash=$(echo -n "GET&%2F&$(enc "$args")" | openssl dgst -sha1 -hmac "$aliddns_sk&" -binary | openssl base64) curl -s "http://alidns.aliyuncs.com/?$args&Signature=$(enc "$hash")" } get_recordid() { grep -Eo '"RecordId":"[0-9]+"' | cut -d':' -f2 | tr -d '"' } query_recordid() { send_request "DescribeSubDomainRecords" "SignatureMethod=HMAC-SHA1&SignatureNonce=$timestamp&SignatureVersion=1.0&SubDomain=$aliddns_name1.$aliddns_domain&Timestamp=$timestamp" } update_record() { # Type=AAAA for ipv6 send_request "UpdateDomainRecord" "RR=$aliddns_name1&RecordId=$1&SignatureMethod=HMAC-SHA1&SignatureNonce=$timestamp&SignatureVersion=1.0&TTL=$aliddns_ttl&Timestamp=$timestamp&Type=AAAA&Value=$ip" } add_record() { # Type=AAAA for ipv6 send_request "AddDomainRecord&DomainName=$aliddns_domain" "RR=$aliddns_name1&SignatureMethod=HMAC-SHA1&SignatureNonce=$timestamp&SignatureVersion=1.0&TTL=$aliddns_ttl&Timestamp=$timestamp&Type=AAAA&Value=$ip" } #add support */%2A and @/%40 record case "$aliddns_name" in \*) aliddns_name1=%2A ;; \@) aliddns_name1=%40 ;; *) aliddns_name1="$aliddns_name" ;; esac if [ -z "$aliddns_record_id" ];then aliddns_record_id=`query_recordid | get_recordid` fi if [ -z "$aliddns_record_id" ];then aliddns_record_id=`add_record | get_recordid` echo "aliyunddns: added record $aliddns_record_id" else update_record "$aliddns_record_id" echo "aliyunddns: updated record $aliddns_record_id" fi # save to file if [ -z "$aliddns_record_id" ]; then # failed # dbus set aliddns_last_act="$now: failed" # nvram set ddns_hostname_x=`nvram get ddns_hostname_old` echo "aliyun ddns update failed" else # dbus set aliddns_record_id="$aliddns_record_id" # dbus set aliddns_last_act="$now: success($ip)" # nvram set ddns_enable_x=1 # web ui show without @. if [ "$aliddns_name" = "@" ] ;then # nvram set ddns_hostname_x="$aliddns_domain" ddns_custom_updated 1 else # nvram set ddns_hostname_x="$aliddns_name"."$aliddns_domain" ddns_custom_updated 1 fi fi
测试DDNS是否正常
更新DDNS后,可以从 /tmp/syslog.log
看到DDNS的log。
正常的log如下:
Mar 12 10:34:05 start_ddns: update CUSTOM , wan_unit 0 Mar 12 10:34:05 custom_script: Running /jffs/scripts/ddns-start (args: 192.168.11.78) Mar 12 10:34:07 ddns: Completed custom ddns update