#!/bin/bash################################################## AnripDdns v5.08# Dynamic DNS using DNSPod API# Original by anrip<mail@anrip.com>, http://www.anrip.com/ddnspod# Edited by ProfFan################################################################################################### 2018-11-06# support LAN / WAN / IPV6 resolution# 2019-05-24# Support Ipv6 truly (Yes, it was just claimed to, but actually not = =!)# Add another way resolving IPv6, for machines without nvram.#if you have any issues, please let me know.# https://blog.csdn.net/Imkiimki/article/details/83794355# Daleshen mailto:gf@gfshen.cn##################################################Please select IP typeIPtype=1 #1.WAN 2.LAN 3.IPv6#---------------------if [ $IPtype = '3' ]; thenrecord_type='AAAA'elserecord_type='A'fiecho Type: ${record_type}# OS Detectioncase $(uname) in'Linux')echo "OS: Linux"arIpAddress() {case $IPtype in'1')curltest=`which curl`if [ -z "$curltest" ] || [ ! -s "`which curl`" ]then#根据实际情况选择使用合适的网址#wget --no-check-certificate --quiet --output-document=- "https://www.ipip.net" | grep "IP地址" | grep -E -o '([0-9]+\.){3}[0-9]+' | head -n1 | cut -d' ' -f1wget --no-check-certificate --secure-protocol=TLSv1_2 --quiet --output-document=- "http://members.3322.org/dyndns/getip" | grep -E -o '([0-9]+\.){3}[0-9]+' | head -n1 | cut -d' ' -f1#wget --no-check-certificate --secure-protocol=TLSv1_2 --quiet --output-document=- "ip.6655.com/ip.aspx" | grep -E -o '([0-9]+\.){3}[0-9]+' | head -n1 | cut -d' ' -f1#wget --no-check-certificate --secure-protocol=TLSv1_2 --quiet --output-document=- "ip.3322.net" | grep -E -o '([0-9]+\.){3}[0-9]+' | head -n1 | cut -d' ' -f1elsecurl -k -s "http://members.3322.org/dyndns/getip" | grep -E -o '([0-9]+\.){3}[0-9]+' | head -n1 | cut -d' ' -f1#curl -L -k -s "https://www.ipip.net" | grep "IP地址" | grep -E -o '([0-9]+\.){3}[0-9]+' | head -n1 | cut -d' ' -f1#curl -k -s ip.6655.com/ip.aspx | grep -E -o '([0-9]+\.){3}[0-9]+' | head -n1 | cut -d' ' -f1#curl -k -s ip.3322.net | grep -E -o '([0-9]+\.){3}[0-9]+' | head -n1 | cut -d' ' -f1fi;;'2')ip -o -4 addr list | grep -Ev '\s(docker|lo)' | awk '{print $4}' | cut -d/ -f1;;'3')# 因为一般ipv6没有nat ipv6的获得可以本机获得#ifconfig $(nvram get wan0_ifname_t) | awk '/Global/{print $3}' | awk -F/ '{print $1}'ip addr show dev eth0 | sed -e's/^.*inet6 \([^ ]*\)\/.*$/\1/;t;d' | awk 'NR==1' #如果没有nvram,使用这条,注意将eth0改为本机上的网口设备 (通过 ifconfig 查看网络接口);;esac};;'FreeBSD')echo 'FreeBSD'exit 100;;'WindowsNT')echo "Windows"exit 100;;'Darwin')echo "Mac"arIpAddress() {ifconfig | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}'};;'SunOS')echo 'Solaris'exit 100;;'AIX')echo 'AIX'exit 100;;*) ;;esacecho "Address: $(arIpAddress)"# Get script dir# See: http://stackoverflow.com/a/29835459/4449544rreadlink() ( # Execute the function in a *subshell* to localize variables and the effect of `cd`.target=$1 fname= targetDir= CDPATH=# Try to make the execution environment as predictable as possible:# All commands below are invoked via `command`, so we must make sure that `command`# itself is not redefined as an alias or shell function.# (Note that command is too inconsistent across shells, so we don't use it.)# `command` is a *builtin* in bash, dash, ksh, zsh, and some platforms do not even have# an external utility version of it (e.g, Ubuntu).# `command` bypasses aliases and shell functions and also finds builtins# in bash, dash, and ksh. In zsh, option POSIX_BUILTINS must be turned on for that# to happen.{ \unalias command; \unset -f command; } >/dev/null 2>&1[ -n "$ZSH_VERSION" ] && options[POSIX_BUILTINS]=on # make zsh find *builtins* with `command` too.while :; do # Resolve potential symlinks until the ultimate target is found.[ -L "$target" ] || [ -e "$target" ] || { command printf '%s\n' "ERROR: '$target' does not exist." >&2; return 1; }command cd "$(command dirname -- "$target")" # Change to target dir; necessary for correct resolution of target path.fname=$(command basename -- "$target") # Extract filename.[ "$fname" = '/' ] && fname='' # !! curiously, `basename /` returns '/'if [ -L "$fname" ]; then# Extract [next] target path, which may be defined# *relative* to the symlink's own directory.# Note: We parse `ls -l` output to find the symlink target# which is the only POSIX-compliant, albeit somewhat fragile, way.target=$(command ls -l "$fname")target=${target#* -> }continue # Resolve [next] symlink target.fibreak # Ultimate target reached.donetargetDir=$(command pwd -P) # Get canonical dir. path# Output the ultimate target's canonical path.# Note that we manually resolve paths ending in /. and /.. to make sure we have a normalized path.if [ "$fname" = '.' ]; thencommand printf '%s\n' "${targetDir%/}"elif [ "$fname" = '..' ]; then# Caveat: something like /var/.. will resolve to /private (assuming /var@ -> /private/var), i.e. the '..' is applied# AFTER canonicalization.command printf '%s\n' "$(command dirname -- "${targetDir}")"elsecommand printf '%s\n' "${targetDir%/}/$fname"fi)DIR=$(dirname -- "$(readlink "$0")")# Global Variables:# Token-based AuthenticationarToken=""# Account-based AuthenticationarMail=""arPass=""# Load config#. $DIR/dns.conf# Get Domain IP# arg: domainarDdnsInfo() {local domainID recordID recordIP# Get domain IDdomainID=$(arApiPost "Domain.Info" "domain=${1}")domainID=$(echo $domainID | sed 's/.*{"id":"\([0-9]*\)".*/\1/')# Get Record IDrecordID=$(arApiPost "Record.List" "domain_id=${domainID}&sub_domain=${2}&record_type=${record_type}")recordID=$(echo $recordID | sed 's/.*\[{"id":"\([0-9]*\)".*/\1/')# Last IPrecordIP=$(arApiPost "Record.Info" "domain_id=${domainID}&record_id=${recordID}&record_type=${record_type}")recordIP=$(echo $recordIP | sed 's/.*,"value":"\([0-9a-z\.:]*\)".*/\1/')# Output IPcase "$recordIP" in[1-9a-z]*)echo $recordIPreturn 0;;*)echo "Get Record Info Failed!"return 1;;esac}# Get data# arg: type data# see Api doc: https://www.dnspod.cn/docs/records.html#arApiPost() {local agent="AnripDdns/5.07(mail@anrip.com)"#local inter="https://dnsapi.cn/${1:?'Info.Version'}"local inter="https://dnsapi.cn/${1}"if [ "x${arToken}" = "x" ]; then # undefine tokenlocal param="login_email=${arMail}&login_password=${arPass}&format=json&${2}"elselocal param="login_token=${arToken}&format=json&${2}"fiwget --quiet --no-check-certificate --secure-protocol=TLSv1_2 --output-document=- --user-agent=$agent --post-data $param $inter}# Update# arg: main domain sub domainarDdnsUpdate() {local domainID recordID recordRS recordCD recordIP myIP# Get domain IDdomainID=$(arApiPost "Domain.Info" "domain=${1}")domainID=$(echo $domainID | sed 's/.*{"id":"\([0-9]*\)".*/\1/')#echo $domainID# Get Record IDrecordID=$(arApiPost "Record.List" "domain_id=${domainID}&record_type=${record_type}&sub_domain=${2}")recordID=$(echo $recordID | sed 's/.*\[{"id":"\([0-9]*\)".*/\1/')#echo $recordID# Update IPmyIP=$(arIpAddress)recordRS=$(arApiPost "Record.Modify" "domain_id=${domainID}&sub_domain=${2}&record_type=${record_type}&record_id=${recordID}&record_line=默认&value=${myIP}")recordCD=$(echo $recordRS | sed 's/.*{"code":"\([0-9]*\)".*/\1/')recordIP=$(echo $recordRS | sed 's/.*,"value":"\([0-9a-z\.:]*\)".*/\1/')# Output IPif [ "$recordIP" = "$myIP" ]; thenif [ "$recordCD" = "1" ]; thenecho $recordIPreturn 0fi# Echo error messageecho $recordRS | sed 's/.*,"message":"\([^"]*\)".*/\1/'return 1elseecho $recordIP #"Update Failed! Please check your network."return 1fi}# DDNS Check# Arg: Main SubarDdnsCheck() {local postRSlocal lastIPlocal hostIP=$(arIpAddress)echo "Updating Domain: ${2}.${1}"echo "hostIP: ${hostIP}"lastIP=$(arDdnsInfo $1 $2)if [ $? -eq 0 ]; thenecho "lastIP: ${lastIP}"if [ "$lastIP" != "$hostIP" ]; thenpostRS=$(arDdnsUpdate $1 $2)if [ $? -eq 0 ]; thenecho "update to ${postRS} successed."return 0elseecho ${postRS}return 1fifiecho "Last IP is the same as current, no action."return 0fiecho ${lastIP}return 1}# DDNS#echo ${#domains[@]}#for index in ${!domains[@]}; do# echo "${domains[index]} ${subdomains[index]}"# arDdnsCheck "${domains[index]}" "${subdomains[index]}"#done. $DIR/dns.conf
dns.conf同文件下
# 1. Combine your token ID and token together as followsarToken="241083,69cdb4770564468d0989868d97e035ef"# 2. Place each domain you want to check as follows# you can have multiple arDdnsCheck blocksarDdnsCheck "mmdchat.com" "wk1"
# 1. Combine your token ID and token together as followsarToken="12345,7676f344eaeaea9074c123451234512d"dnspod id dnspod 密匙# 2. Place each domain you want to check as follows# you can have multiple arDdnsCheck blocksarDdnsCheck "test.org" "subdomain"主域名 子域名
