分享一个unraid 的DDNS userscript,支持ipv6

  • r
    ryon
    1. #!/bin/bash
    2. ################################################## AnripDdns v5.08# Dynamic DNS using DNSPod API# Original by anrip<[email protected]>, http://www.anrip.com/ddnspod# Edited by ProfFan#################################################
    3. ################################################## 2018-11-06 # support LAN / WAN / IPV6 resolution
    4. # 2019-05-24# Support Ipv6 truly (Yes, it was just claimed to, but actually not = =!)# Add another way resolving IPv6, for machines without nvram.
    5. #if you have any issues, please let me know.# https://blog.csdn.net/Imkiimki/article/details/83794355# Daleshen mailto:[email protected]
    6. #################################################
    7. #Please select IP typeIPtype=3 #1.WAN 2.LAN 3.IPv6#---------------------if [ $IPtype = '3' ]; then record_type='AAAA'else record_type='A'fiecho Type: ${record_type}
    8. # OS Detectioncase $(uname) in 'Linux') echo "OS: Linux" arIpAddress() {
    9. 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' ' -f1 wget --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' ' -f1 else curl -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
    10. #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' ' -f1 fi ;; '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 br0 | 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 ;; *) ;;esac
    11. echo "Address: $(arIpAddress)"
    12. # Get script dir# See: http://stackoverflow.com/a/29835459/4449544rreadlink() ( # Execute the function in a *subshell* to localize variables and the effect of `cd`.
    13. target=$1 fname= targetDir= CDPATH=
    14. # 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.
    15. 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. fi break # Ultimate target reached. done targetDir=$(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" = '.' ]; then command 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}")" else command printf '%s\n' "${targetDir%/}/$fname" fi)
    16. DIR=$(dirname -- "$(readlink "$0")")
    17. # Global Variables:
    18. # Token-based AuthenticationarToken=""
    19. # Load config
    20. #. $DIR/dns.conf
    21. # Get Domain IP# arg: domainarDdnsInfo() { local domainID recordID recordIP # Get domain ID domainID=$(arApiPost "Domain.Info" "domain=${1}") domainID=$(echo $domainID | sed 's/.*{"id":"\([0-9]*\)".*/\1/') # Get Record ID recordID=$(arApiPost "Record.List" "domain_id=${domainID}&sub_domain=${2}&record_type=${record_type}") recordID=$(echo $recordID | sed 's/.*\[{"id":"\([0-9]*\)".*/\1/') # Last IP recordIP=$(arApiPost "Record.Info" "domain_id=${domainID}&record_id=${recordID}&record_type=${record_type}") recordIP=$(echo $recordIP | sed 's/.*,"value":"\([0-9a-z\.:]*\)".*/\1/') # Output IP case "$recordIP" in [1-9a-z]*) echo $recordIP return 0 ;; *) echo "Get Record Info Failed!" return 1 ;; esac}
    22. # Get data# arg: type data# see Api doc: https://www.dnspod.cn/docs/records.html#arApiPost() { local agent="AnripDdns/5.07([email protected])" #local inter="https://dnsapi.cn/${1:?'Info.Version'}" local inter="https://dnsapi.cn/${1}" if [ "x${arToken}" = "x" ]; then # undefine token local param="login_email=${arMail}&login_password=${arPass}&format=json&${2}" else local param="login_token=${arToken}&format=json&${2}" fi wget --quiet --no-check-certificate --secure-protocol=TLSv1_2 --output-document=- --user-agent=$agent --post-data $param $inter}
    23. # Update# arg: main domain sub domainarDdnsUpdate() { local domainID recordID recordRS recordCD recordIP myIP # Get domain ID domainID=$(arApiPost "Domain.Info" "domain=${1}") domainID=$(echo $domainID | sed 's/.*{"id":"\([0-9]*\)".*/\1/') #echo $domainID # Get Record ID recordID=$(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 IP myIP=$(arIpAddress) recordRS=$(arApiPost "Record.Modify" "domain_id=${domainID}&sub_domain=${2}&record_type=${record_type}&record_id=${recordID}&record_line_id=0&value=${myIP}") recordCD=$(echo $recordRS | sed 's/.*{"code":"\([0-9]*\)".*/\1/') recordIP=$(echo $recordRS | sed 's/.*,"value":"\([0-9a-z\.:]*\)".*/\1/') # Output IP if [ "$recordIP" = "$myIP" ]; then if [ "$recordCD" = "1" ]; then echo $recordIP return 0 fi # Echo error message echo $recordRS | sed 's/.*,"message":"\([^"]*\)".*/\1/' return 1 else echo $recordIP #"Update Failed! Please check your network." return 1 fi}
    24. # DDNS Check# Arg: Main SubarDdnsCheck() { local postRS local lastIP local hostIP=$(arIpAddress) echo "Updating Domain: ${2}.${1}" echo "hostIP: ${hostIP}" lastIP=$(arDdnsInfo $1 $2) if [ $? -eq 0 ]; then echo "lastIP: ${lastIP}" if [ "$lastIP" != "$hostIP" ]; then postRS=$(arDdnsUpdate $1 $2) if [ $? -eq 0 ]; then echo "update to ${postRS} successed." return 0 else echo ${postRS} return 1 fi fi echo "Last IP is the same as current, no action." return 1 fi echo ${lastIP} return 1}
    25. # DDNS#echo ${#domains[@]}#for index in ${!domains[@]}; do# echo "${domains[index]} ${subdomains[index]}"# arDdnsCheck "${domains[index]}" "${subdomains[index]}"#done
    26. # 1. Combine your token ID and token together as followsarToken="xxxxxx,xxxxxxxxxxxxxxxxxxxx"
    27. # 2. Place each domain you want to check as follows# you can have multiple arDdnsCheck blocksarDdnsCheck "domain" "your_subdomain"
    复制代码



    修改最后的artoken和arddnscheck,放在unraid插件userscript下自定义内容里面,设置定期执行。
    这个脚本不支持中文,所以原文里面有个record_line参数是默认,改成了record_line_id=0.
    如果是IPV6,确认下自己的网卡信息,修改代码内容里面的br0为你自己的机器网卡信息,比如eth0.
  • 牧羊人
    mark备用,虽然有点不明白。
  • a
    anguswen
    unraid下有ddns的docker的吧,感觉设置要简单一点。
  • r
    ryon
    回复3#anguswen
    支持ipv6的就没有 iOS fly ~
  • l
    lilarcor
    回复1#ryon
    需要用dnspod? iOS fly ~
  • a
    anguswen
    回复4#ryon

    我是用的cloudflare ddns,有支持ipv6的docker,其他的倒真没试过。
  • r
    ryon
    回复5#lilarcor
    其实就是为了dnspod做的 iOS fly ~