├── .github └── workflows │ └── release.yml ├── README.md ├── ddns-go ├── Makefile └── file │ ├── ddns-go-call.libexec │ ├── ddns-go.init │ └── luci-ddns-go.uci-default ├── doc ├── ddnsgo1.png ├── ddnsgo2.png ├── ddnsgo3.png └── ddnsgo4.png └── luci-app-ddns-go ├── Makefile ├── htdocs └── luci-static │ └── resources │ └── view │ └── ddns-go │ ├── config.js │ ├── ddns-go.js │ └── log.js ├── po ├── templates │ └── ddns-go.pot └── zh_Hans │ └── ddns-go.po └── root ├── etc ├── config │ └── ddns-go └── ddns-go │ ├── ddns-go-config.yaml │ └── localtime └── usr └── share ├── ddns-go └── ddns-go-default.yaml ├── luci └── menu.d │ └── luci-app-ddns-go.json └── rpcd └── acl.d └── luci-app-ddns-go.json /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Build packages 2 | 3 | on: 4 | push: 5 | tags: 6 | - v* 7 | 8 | jobs: 9 | build: 10 | name: Build ${{ matrix.arch }} 11 | runs-on: ubuntu-latest 12 | strategy: 13 | fail-fast: false 14 | matrix: 15 | arch: 16 | - aarch64_cortex-a53 17 | - aarch64_cortex-a72 18 | - aarch64_generic 19 | - arm_arm1176jzf-s_vfp 20 | - arm_arm926ej-s 21 | - arm_cortex-a15_neon-vfpv4 22 | - arm_cortex-a5_vfpv4 23 | - arm_cortex-a7 24 | - arm_cortex-a7_neon-vfpv4 25 | - arm_cortex-a8_vfpv3 26 | - arm_cortex-a9 27 | - arm_cortex-a9_neon 28 | - arm_cortex-a9_vfpv3-d16 29 | - arm_fa526 30 | - arm_mpcore 31 | - arm_xscale 32 | - i386_pentium-mmx 33 | - i386_pentium4 34 | - mips64_octeonplus 35 | - mips_24kc 36 | - mips_4kec 37 | - mips_mips32 38 | - mipsel_24kc 39 | - mipsel_24kc_24kf 40 | - mipsel_74kc 41 | - mipsel_mips32 42 | - x86_64 43 | 44 | steps: 45 | - uses: actions/checkout@v4 46 | with: 47 | fetch-depth: 0 48 | 49 | - name: Building packages 50 | uses: sbwml/openwrt-gh-action-sdk@main 51 | env: 52 | ARCH: ${{ matrix.arch }}-openwrt-24.10 53 | FEEDNAME: packages_ci 54 | PACKAGES: luci-app-ddns-go 55 | NO_REFRESH_CHECK: true 56 | 57 | - name: Upload artifacts 58 | uses: actions/upload-artifact@v4 59 | with: 60 | name: ${{ matrix.arch }} 61 | path: bin/packages/${{ matrix.arch }}/packages_ci/*.ipk 62 | 63 | - name: Upload packages 64 | uses: ncipollo/release-action@v1 65 | with: 66 | name: ${{ github.ref_name }} 67 | token: ${{ secrets.GITHUB_TOKEN }} 68 | allowUpdates: true 69 | replacesArtifacts: true 70 | artifacts: "bin/packages/${{ matrix.arch }}/packages_ci/*.ipk" 71 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 访问数:![hello](https://views.whatilearened.today/views/github/sirpdboy/deplives.svg)[![](https://img.shields.io/badge/TG群-点击加入-FFFFFF.svg)](https://t.me/joinchat/AAAAAEpRF88NfOK5vBXGBQ) 2 | ### 访问数:[![](https://visitor-badge.glitch.me/badge?page_id=sirpdboy-visitor-badge)] [![](https://img.shields.io/badge/TG群-点击加入-FFFFFF.svg)](https://t.me/joinchat/AAAAAEpRF88NfOK5vBXGBQ) 3 | 4 | ![screenshots](https://raw.githubusercontent.com/sirpdboy/openwrt/master/doc/说明1.jpg) 5 | 6 | 本项目是 ([ddns-go](https://github.com/jeessy2/ddns-go.git)) 在 OpenWrt 上的移植。 7 | 8 | # luci-app-ddns-go 9 | 10 | luci-app-ddns-go 自动获得你的公网 IPv4 或 IPv6 地址,并解析到对应的域名服务。支持的域名服务商 Alidns(阿里云) Dnspod(腾讯云) Cloudflare 华为云 Callback 百度云 porkbun GoDaddy 11 | 12 | [![若部分图片无法正常显示,请挂上机场浏览或点这里到末尾看修复教程](https://visitor-badge.glitch.me/badge?page_id=sirpdboy-visitor-badge)](#解决-github-网页上图片显示失败的问题) [![](https://img.shields.io/badge/TG群-点击加入-FFFFFF.svg)](https://t.me/joinchat/AAAAAEpRF88NfOK5vBXGBQ) 13 | 14 | [luci-app-ddns-go ddns-go动态域名插件](https://github.com/sirpdboy/luci-app-ddns-go) 15 | ====================== 16 | 17 | 18 | 请 **认真阅读完毕** 本页面,本页面包含注意事项和如何使用。 19 | 20 | ## 功能说明: 21 | 22 | ### ddns-go动态域名插件 23 | #### 自动获得你的公网 IPv4 或 IPv6 地址,并解析到对应的域名服务。 24 | 25 | 26 | 27 | - [ddns-go](#ddns-go) 28 | - [版本](# 版本说明) 29 | - [特性](#特性) 30 | - [使用方法](#使用方法) 31 | - [说明](#说明) 32 | - [界面](#界面) 33 | - [捐助](#捐助) 34 | 35 | 36 | 37 | ## 版本说明 38 | 39 | ## 2025.5.14 luci-app-ddns-go 1.5.2 40 | ## 2025.5.12 luci-app-ddns-go 1.5.1 41 | - 更新日志: 42 | - 适配最新OPENWRT24.10,JS版本。老版18.06用LUA分支。 43 | 44 | 45 | ## 特性 46 | 47 | - 支持Mac、Windows、Linux系统,支持ARM、x86架构 48 | - 支持的域名服务商 `Alidns(阿里云)` `Dnspod(腾讯云)` `Cloudflare` `华为云` `Callback` `百度云` `porkbun` `GoDaddy` 49 | - 支持接口/网卡获取IP 50 | - 支持以服务的方式运行 51 | - 默认间隔5分钟同步一次 52 | - 支持多个域名同时解析,公司必备 53 | - 支持多级域名 54 | - 网页中配置,简单又方便,可设置 `登录用户名和密码` / `禁止从公网访问` 55 | - 网页中方便快速查看最近50条日志,不需要跑docker中查看 56 | - 支持webhook通知 57 | - 支持TTL 58 | - 支持部分dns服务商传递自定义参数,实现地域解析等功能 59 | 60 | ## 使用方法 61 | 62 | - 将luci-app-ddns-go添加至 LEDE/OpenWRT 源码的方法。 63 | 64 | ### 下载源码方法: 65 | 66 | ```Brach 67 | 68 | # 下载源码 69 | 70 | git clone https://github.com/sirpdboy/luci-app-ddns-go.git package/ddns-go 71 | make menuconfig 72 | 73 | ``` 74 | ### 配置菜单 75 | 76 | ```Brach 77 | make menuconfig 78 | # 找到 LuCI -> Applications, 选择 luci-app-ddns-go, 保存后退出。 79 | ``` 80 | 81 | ### 编译 82 | 83 | ```Brach 84 | # 编译固件 85 | make package/ddns-go/luci-app-ddns-go/compile V=s 86 | ``` 87 | 88 | ## 说明 89 | 90 | -源码来源:https://github.com/sirpdboy/luci-app-ddns-go 91 | -源码来源:https://github.com/jeessy2/ddns-go.git 92 | -你可以随意使用其中的源码,但请注明出处。 93 | 94 | ![screenshots](https://raw.githubusercontent.com/sirpdboy/openwrt/master/doc/说明2.jpg) 95 | 96 | ## 界面 97 | 98 | ![screenshots](./doc/ddnsgo1.png) 99 | 100 | ![screenshots](./doc/ddnsgo2.png) 101 | 102 | ![screenshots](./doc/ddnsgo3.png) 103 | 104 | ![screenshots](./doc/ddnsgo4.png) 105 | 106 | 107 | 108 | 109 | ## 使用与授权相关说明 110 | 111 | - 本人开源的所有源码,任何引用需注明本处出处,如需修改二次发布必告之本人,未经许可不得做于任何商用用途。 112 | 113 | 114 | # My other project 115 | 116 | - 路由安全看门狗 :https://github.com/sirpdboy/luci-app-watchdog 117 | - 网络速度测试 :https://github.com/sirpdboy/luci-app-netspeedtest 118 | - 计划任务插件(原定时设置) : https://github.com/sirpdboy/luci-app-taskplan 119 | - 关机功能插件 : https://github.com/sirpdboy/luci-app-poweroffdevice 120 | - opentopd主题 : https://github.com/sirpdboy/luci-theme-opentopd 121 | - kucat酷猫主题: https://github.com/sirpdboy/luci-theme-kucat 122 | - kucat酷猫主题设置工具: https://github.com/sirpdboy/luci-app-kucat-config 123 | - NFT版上网时间控制插件: https://github.com/sirpdboy/luci-app-timecontrol 124 | - 家长控制: https://github.com/sirpdboy/luci-theme-parentcontrol 125 | - 定时限速: https://github.com/sirpdboy/luci-app-eqosplus 126 | - 系统高级设置 : https://github.com/sirpdboy/luci-app-advanced 127 | - ddns-go动态域名: https://github.com/sirpdboy/luci-app-ddns-go 128 | - 进阶设置(系统高级设置+主题设置kucat/agron/opentopd): https://github.com/sirpdboy/luci-app-advancedplus 129 | - 网络设置向导: https://github.com/sirpdboy/luci-app-netwizard 130 | - 一键分区扩容: https://github.com/sirpdboy/luci-app-partexp 131 | - lukcy大吉: https://github.com/sirpdboy/luci-app-lukcy 132 | 133 | ## 捐助 134 | 135 | ![screenshots](https://raw.githubusercontent.com/sirpdboy/openwrt/master/doc/说明3.jpg) 136 | 137 | | 图飞了😂 | 图飞了😂 | 138 | | :-----------------: | :-------------: | 139 | |![xm1](https://raw.githubusercontent.com/sirpdboy/openwrt/master/doc/支付宝.png) | ![xm1](https://raw.githubusercontent.com/sirpdboy/openwrt/master/doc/微信.png) | 140 | 141 | 142 | 图飞了😂 143 | 144 | -------------------------------------------------------------------------------- /ddns-go/Makefile: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: GPL-3.0-only 2 | # 3 | # Copyright (C) 2021-2025 sirpdboy 4 | # 5 | # This is free software, licensed under the Apache License, Version 2.0 . 6 | # 7 | include $(TOPDIR)/rules.mk 8 | 9 | PKG_NAME:=ddns-go 10 | PKG_VERSION:=6.9.4 11 | PKG_RELEASE:=11 12 | 13 | PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz 14 | PKG_SOURCE_URL:=https://codeload.github.com/jeessy2/ddns-go/tar.gz/v$(PKG_VERSION)? 15 | PKG_HASH:=skip 16 | 17 | 18 | PKG_LICENSE:=AGPL-3.0-only 19 | PKG_LICENSE_FILES:=LICENSE 20 | PKG_MAINTAINER:=herboy2008 21 | 22 | PKG_BUILD_DEPENDS:=golang/host 23 | PKG_BUILD_PARALLEL:=1 24 | PKG_BUILD_FLAGS:=no-mips16 25 | 26 | GO_PKG:=github.com/jeessy2/ddns-go/v6 27 | GO_PKG_LDFLAGS_X:=main.version=$(PKG_VERSION) 28 | 29 | include $(INCLUDE_DIR)/package.mk 30 | include $(TOPDIR)/feeds/packages/lang/golang/golang-package.mk 31 | 32 | define Package/ddns-go 33 | TITLE:=A Linux web GUI client of ddns-go 34 | SECTION:=net 35 | CATEGORY:=Network 36 | SUBMENU:=Web Servers/Proxies 37 | DEPENDS:=$(GO_ARCH_DEPENDS) +ca-bundle 38 | URL:=https://github.com/jeessy2/ddns-go 39 | USERID:=ddns-go:ddns-go 40 | endef 41 | 42 | define Package/ddns-go/description 43 | ddns-go is a automatically obtain your public IPv4 or IPv6 address and resolve it to the corresponding domain name service, 44 | support Alidns Dnspod Cloudflare Hicloud Callback Baiducloud porkbun GoDaddy Google Domains. 45 | endef 46 | 47 | define Package/ddns-go/install 48 | $(call GoPackage/Package/Install/Bin,$(1)) 49 | 50 | $(INSTALL_DIR) $(1)/etc/init.d 51 | $(INSTALL_BIN) $(CURDIR)/file/ddns-go.init $(1)/etc/init.d/ddns-go 52 | $(INSTALL_DIR) $(1)/usr/libexec 53 | $(INSTALL_BIN) $(CURDIR)/file/ddns-go-call.libexec $(1)/usr/libexec/ddns-go-call 54 | $(INSTALL_DIR) $(1)/etc/uci-defaults 55 | $(INSTALL_BIN) $(CURDIR)/file/luci-ddns-go.uci-default $(1)/etc/uci-defaults/luci-ddns-go 56 | endef 57 | 58 | $(eval $(call GoBinPackage,ddns-go)) 59 | $(eval $(call BuildPackage,ddns-go)) 60 | -------------------------------------------------------------------------------- /ddns-go/file/ddns-go-call.libexec: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright (C) 2023-2025 sirpdboy herboy2008@gmail.com https://github.com/sirpdboy/luci-app-ddns-go 4 | # 5 | 6 | logfile="/var/log/ddns-go.log" 7 | lang=$(uci get luci.main.lang 2>/dev/null) 8 | if [ -z "$lang" ] || [[ "$lang" == "auto" ]]; then 9 | lang=$(echo "${LANG:-${LANGUAGE:-${LC_ALL:-${LC_MESSAGES:-zh_cn}}}}" | awk -F'[ .@]' '{print tolower($1)}' | sed 's/-/_/' 2>/dev/null) 10 | fi 11 | 12 | translate() { 13 | # 处理特殊字符 14 | local lua_script=$(cat <"${logfile}" 26 | 27 | elif [ "$1" == "child" ]; then 28 | shift 29 | command_name=$1 30 | shift 31 | "$command_name" "$@" 32 | fi 33 | -------------------------------------------------------------------------------- /ddns-go/file/ddns-go.init: -------------------------------------------------------------------------------- 1 | #!/bin/sh /etc/rc.common 2 | # 3 | # Copyright (C) 2021-2023 sirpdboy https://github.com/sirpdboy/luci-app-ddns-go 4 | # 5 | # This file is part of ddns-go . 6 | # 7 | # This is free software, licensed under the Apache License, Version 2.0 . 8 | # 9 | 10 | 11 | START=99 12 | USE_PROCD=1 13 | NAME=ddns-go 14 | PROG=/usr/bin/ddns-go 15 | CONFDIR=/etc/ddns-go 16 | CONF=$CONFDIR/ddns-go-config.yaml 17 | 18 | get_tz() 19 | { 20 | SET_TZ="" 21 | 22 | [ -e "/etc/localtime" ] && return 23 | 24 | for tzfile in /etc/TZ /var/etc/TZ 25 | do 26 | [ -e "$tzfile" ] || continue 27 | tz="$(cat $tzfile 2>/dev/null)" 28 | done 29 | 30 | [ -z "$tz" ] && return 31 | 32 | SET_TZ=$tz 33 | } 34 | 35 | init_yaml(){ 36 | [ -d $CONFDIR ] || mkdir -p $CONFDIR 2>/dev/null 37 | cat /usr/share/ddns-go/ddns-go-default.yaml > $CONF 38 | } 39 | 40 | xappend() { param="$param $1"; } 41 | 42 | append_parm() { 43 | local section="$1" 44 | local option="$2" 45 | local switch="$3" 46 | local default="$4" 47 | local _tmp 48 | config_get _tmp "$section" "$option" "$default" 49 | [[ -z "$_tmp" ]] && return 50 | [[ x$default = x && x$_tmp = x0 ]] && return 51 | [[ x$default = x && x$_tmp = x1 ]] && xappend "$switch" || xappend "$switch $_tmp" 52 | } 53 | 54 | start_instance() { 55 | local cfg="$1" param 56 | config_get_bool enabled $cfg enabled 1 57 | config_get delay $cfg delay 0 58 | [[ x$enabled = x1 ]] || return 1 59 | [[ -s ${CONF} ]] || init_yaml 60 | [ $(awk -F. '{print $1}' /proc/uptime) -lt "120" ] && sleep $delay 61 | 62 | config_get_bool logger $cfg logger 1 63 | config_get port $cfg port '9876' 64 | append_parm "$cfg" 'time' '-f' '300' 65 | append_parm "$cfg" 'ctimes' '-cacheTimes' '5' 66 | append_parm "$cfg" 'dns' '-dns' '223.5.5.5' 67 | append_parm "$cfg" 'noweb' '-noweb' 68 | append_parm "$cfg" 'skipverify' '-skipVerify' 69 | procd_open_instance 70 | get_tz 71 | [[ -z "$SET_TZ" ]] || procd_set_param env TZ="$SET_TZ" 72 | procd_set_param command /bin/sh -c " 73 | ${PROG} -l :$port -c \"$CONF\" ${param} >> /var/log/ddns-go.log 2>&1 & 74 | DDNS_GO_PID=\$! 75 | { 76 | while true; do 77 | LOG_SIZE=\$(ls -l /var/log/ddns-go.log | awk '{print int(\$5/1024)}') 78 | if [ \$LOG_SIZE -gt 100 ]; then 79 | tail -n 100 /var/log/ddns-go.log > /var/log/ddns-go.log.tmp 80 | mv /var/log/ddns-go.log.tmp /var/log/ddns-go.log 81 | fi 82 | sleep 3600 83 | done 84 | } & 85 | LOG_MANAGEMENT_PID=\$! 86 | trap \"kill -TERM \$DDNS_GO_PID; kill -TERM \$LOG_MANAGEMENT_PID; exit\" SIGINT SIGTERM EXIT 87 | wait \$DDNS_GO_PID 88 | " 89 | [[ "x$logger" == x1 ]] && procd_set_param stderr 1 90 | procd_set_param respawn 91 | procd_close_instance 92 | } 93 | 94 | start_service() { 95 | config_load 'ddns-go' 96 | config_foreach start_instance 'basic' 97 | } 98 | 99 | service_triggers() { 100 | procd_add_reload_trigger "ddns-go" 101 | } 102 | -------------------------------------------------------------------------------- /ddns-go/file/luci-ddns-go.uci-default: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | [ -s "/etc/ddns-go/localtime" ] && mv -f /etc/ddns-go/localtime /etc/localtime 4 | /etc/init.d/ddns-go enable 5 | /etc/init.d/ddns-go start 6 | rm -f /tmp/luci* 7 | exit 0 8 | -------------------------------------------------------------------------------- /doc/ddnsgo1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sirpdboy/luci-app-ddns-go/d1b8e88c6d2b03b582bed40e29fb58fb3c0789c7/doc/ddnsgo1.png -------------------------------------------------------------------------------- /doc/ddnsgo2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sirpdboy/luci-app-ddns-go/d1b8e88c6d2b03b582bed40e29fb58fb3c0789c7/doc/ddnsgo2.png -------------------------------------------------------------------------------- /doc/ddnsgo3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sirpdboy/luci-app-ddns-go/d1b8e88c6d2b03b582bed40e29fb58fb3c0789c7/doc/ddnsgo3.png -------------------------------------------------------------------------------- /doc/ddnsgo4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sirpdboy/luci-app-ddns-go/d1b8e88c6d2b03b582bed40e29fb58fb3c0789c7/doc/ddnsgo4.png -------------------------------------------------------------------------------- /luci-app-ddns-go/Makefile: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: GPL-3.0-only 2 | # 3 | # Copyright (C) 2021-2025 sirpdboy 4 | # https://github.com/sirpdboy/luci-app-ddns-go 5 | # This is free software, licensed under the Apache License, Version 2.0 . 6 | # 7 | include $(TOPDIR)/rules.mk 8 | 9 | PKG_NAME:=luci-app-ddns-go 10 | PKG_VERSION:=1.5.4 11 | PKG_RELEASE:=20250601 12 | 13 | PKG_MAINTAINER:=sirpdboy 14 | PKG_CONFIG_DEPENDS:= 15 | 16 | LUCI_TITLE:=LuCI Support for Dynamic ddns-go Client 17 | LUCI_DEPENDS:=+ddns-go 18 | LUCI_PKGARCH:=all 19 | 20 | define Package/$(PKG_NAME)/conffiles 21 | /etc/config/ddns-go 22 | /etc/ddns-go/ddns-go-config.yaml 23 | endef 24 | 25 | include $(TOPDIR)/feeds/luci/luci.mk 26 | 27 | # call BuildPackage - OpenWrt buildroot signature 28 | -------------------------------------------------------------------------------- /luci-app-ddns-go/htdocs/luci-static/resources/view/ddns-go/config.js: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2021-2025 sirpdboy herboy2008@gmail.com https://github.com/sirpdboy/luci-app-ddns-go */ 2 | 'use strict'; 3 | 'require view'; 4 | 'require fs'; 5 | 'require ui'; 6 | 'require uci'; 7 | 'require form'; 8 | 'require poll'; 9 | 10 | 11 | async function checkProcess() { 12 | // 先尝试用 pidof 13 | try { 14 | const pidofRes = await fs.exec('/bin/pidof', ['ddns-go']); 15 | if (pidofRes.code === 0) { 16 | return { 17 | running: true, 18 | pid: pidofRes.stdout.trim() 19 | }; 20 | } 21 | } catch (err) { 22 | // pidof 失败,继续尝试 ps 23 | } 24 | 25 | // 回退到 ps 26 | try { 27 | const psRes = await fs.exec('/bin/ps', ['-C', 'ddns-go', '-o', 'pid=']); 28 | const pid = psRes.stdout.trim(); 29 | return { 30 | running: pid !== '', 31 | pid: pid || null 32 | }; 33 | } catch (err) { 34 | return { running: false, pid: null }; 35 | } 36 | } 37 | function renderStatus(isRunning, listen_port, noweb) { 38 | var statusText = isRunning ? _('RUNNING') : _('NOT RUNNING'); 39 | var color = isRunning ? 'green' : 'red'; 40 | var icon = isRunning ? '✓' : '✗'; 41 | var html = String.format( 42 | '%s %s %s', 43 | color, icon, _('DDNS-Go'), statusText 44 | ); 45 | 46 | if (isRunning && res.pid) { 47 | html += ' (PID: ' + res.pid + ')'; 48 | } 49 | 50 | if (isRunning && noweb !== '1') { 51 | html += String.format( 52 | ' %s', 53 | window.location.origin, 54 | listen_port, 55 | _('Open Web Interface') 56 | ); 57 | } 58 | 59 | return html; 60 | } 61 | 62 | return view.extend({ 63 | load: function() { 64 | return Promise.all([ 65 | uci.load('ddns-go') 66 | ]); 67 | }, 68 | 69 | render: function(data) { 70 | var m, s, o; 71 | var listen_port = (uci.get('ddns-go', 'config', 'port') || '[::]:9876').split(':').slice(-1)[0]; 72 | var noweb = uci.get('ddns-go', 'config', 'noweb') || '0'; 73 | 74 | m = new form.Map('ddns-go', _('DDNS-GO'), 75 | _('DDNS-GO automatically obtains your public IPv4 or IPv6 address and resolves it to the corresponding domain name service.')); 76 | 77 | // 状态显示部分 78 | s = m.section(form.TypedSection); 79 | s.anonymous = true; 80 | s.render = function() { 81 | var statusView = E('p', { id: 'control_status' }, 82 | ' ' + _('Checking status...')); 83 | 84 | var pollInterval = poll.add(function() { 85 | return checkProcess() 86 | .then(function(res) { 87 | statusView.innerHTML = renderStatus(res.running, listen_port, noweb); 88 | }) 89 | .catch(function(err) { 90 | console.error('Status check failed:', err); 91 | statusView.innerHTML = '⚠ ' + _('Status check error') + ''; 92 | }); 93 | }, 5); // 每5秒检查一次 94 | 95 | return E('div', { class: 'cbi-section', id: 'status_bar' }, [ 96 | statusView, 97 | E('div', { 'style': 'text-align: right; font-style: italic;' }, [ 98 | E('span', {}, [ 99 | _('© github '), 100 | E('a', { 101 | 'href': 'https://github.com/sirpdboy', 102 | 'target': '_blank', 103 | 'style': 'text-decoration: none;' 104 | }, 'by sirpdboy') 105 | ]) 106 | ]) 107 | ]); 108 | } 109 | 110 | 111 | s = m.section(form.NamedSection, 'config', 'basic'); 112 | 113 | o = s.option(form.Flag, 'enabled', _('Enable')); 114 | o.default = o.disabled; 115 | o.rmempty = false; 116 | 117 | o = s.option(form.Value, 'port', _('Listen port')); 118 | o.default = '[::]:9876'; 119 | o.rmempty = false; 120 | 121 | o = s.option(form.Value, 'time', _('Update interval')); 122 | o.default = '300'; 123 | 124 | o = s.option(form.Value, 'ctimes', _('Compare with service provider N times intervals')); 125 | o.default = '5'; 126 | 127 | o = s.option(form.Value, 'skipverify', _('Skip verifying certificates')); 128 | o.default = '0'; 129 | 130 | o = s.option(form.Value, 'dns', _('Specify DNS resolution server')); 131 | o.value('223.5.5.5', _('Ali DNS 223.5.5.5')); 132 | o.value('223.6.6.6', _('Ali DNS 223.6.6.6')); 133 | o.value('119.29.29.29', _('Tencent DNS 119.29.29.29')); 134 | o.value('1.1.1.1', _('CloudFlare DNS 1.1.1.1')); 135 | o.value('8.8.8.8', _('Google DNS 8.8.8.8')); 136 | o.value('8.8.4.4', _('Google DNS 8.8.4.4')); 137 | o.datatype = 'ipaddr'; 138 | 139 | o = s.option(form.Flag, 'noweb', _('Do not start web services')); 140 | o.default = '0'; 141 | o.rmempty = false; 142 | 143 | o = s.option(form.Value, 'delay', _('Delayed Start (seconds)')); 144 | o.default = '60'; 145 | 146 | return m.render(); 147 | } 148 | }); 149 | -------------------------------------------------------------------------------- /luci-app-ddns-go/htdocs/luci-static/resources/view/ddns-go/ddns-go.js: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2021-2025 sirpdboy herboy2008@gmail.com https://github.com/sirpdboy/luci-app-ddns-go */ 2 | 3 | 'use strict'; 4 | 'require view'; 5 | 'require fs'; 6 | 'require ui'; 7 | 'require uci'; 8 | 'require form'; 9 | 'require poll'; 10 | 11 | return view.extend({ 12 | load: function() { 13 | return uci.load('ddns-go'); 14 | }, 15 | 16 | checkRunning: function() { 17 | return fs.exec('/bin/pidof', ['ddns-go']).then(function(pidRes) { 18 | if (pidRes.code === 0) return { isRunning: true }; 19 | return fs.exec('/bin/ash', ['-c', 'ps | grep -q "[d]dns-go"']).then(function(grepRes) { 20 | return { isRunning: grepRes.code === 0 }; 21 | }); 22 | }); 23 | }, 24 | 25 | render: function() { 26 | var self = this; 27 | 28 | return this.checkRunning().then(function(checkResult) { 29 | var isRunning = checkResult.isRunning; 30 | var port = uci.get('ddns-go', 'config', 'port') || '[::]:9876'; 31 | var noweb = uci.get('ddns-go', 'config', 'noweb') ; 32 | port = port.split(':').pop(); 33 | 34 | var container = E('div'); 35 | console.log('Debug: isRunning=' + isRunning + ', noweb=' + noweb + ', port=' + port); 36 | if (!isRunning || noweb === '1') { 37 | if (!isRunning) { 38 | var message = _('DDNS-GO Service Not Running'); 39 | } 40 | if (noweb === '1') { 41 | var message = _('DDNS-GO Web Interface Disabled'); 42 | } 43 | 44 | container.appendChild(E('div', { 45 | style: 'text-align: center; padding: 2em;' 46 | }, [ 47 | E('img', { 48 | src: 'data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMjQiIGhlaWdodD0iMTAyNCIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCI+PHBhdGggZmlsbD0iI2RmMDAwMCIgZD0iTTk0Mi40MjEgMjM0LjYyNGw4MC44MTEtODAuODExLTE1My4wNDUtMTUzLjA0NS04MC44MTEgODAuODExYy03OS45NTctNTEuNjI3LTE3NS4xNDctODEuNTc5LTI3Ny4zNzYtODEuNTc5LTI4Mi43NTIgMC01MTIgMjI5LjI0OC01MTIgNTEyIDAgMTAyLjIyOSAyOS45NTIgMTk3LjQxOSA4MS41NzkgMjc3LjM3NmwtODAuODExIDgwLjgxMSAxNTMuMDQ1IDE1My4wNDUgODAuODExLTgwLjgxMWM3OS45NTcgNTEuNjI3IDE3NS4xNDcgODEuNTc5IDI3Ny4zNzYgODEuNTc5IDI4Mi43NTIgMCA1MTItMjI5LjI0OCA1MTItNTEyIDAtMTAyLjIyOS0yOS45NTItMTk3LjQxOS04MS41NzktMjc3LjM3NnpNMTk0Ljk0NCA1MTJjMC0xNzUuMTA0IDE0MS45NTItMzE3LjA1NiAzMTcuMDU2LTMxNy4wNTYgNDggMCA5My40ODMgMTAuNjY3IDEzNC4yMjkgMjkuNzgxbC00MjEuNTQ3IDQyMS41NDdjLTE5LjA3Mi00MC43ODktMjkuNzM5LTg2LjI3Mi0yOS43MzktMTM0LjI3MnpNNTEyIDgyOS4wNTZjLTQ4IDAtOTMuNDgzLTEwLjY2Ny0xMzQuMjI5LTI5Ljc4MWw0MjEuNTQ3LTQyMS41NDdjMTkuMDcyIDQwLjc4OSAyOS43ODEgODYuMjcyIDI5Ljc4MSAxMzQuMjI5LTAuMDQzIDE3NS4xNDctMTQxLjk5NSAzMTcuMDk5LTMxNy4wOTkgMzE3LjA5OXoiLz48L3N2Zz4=', 49 | style: 'width: 100px; height: 100px; margin-bottom: 1em;' 50 | }), 51 | E('h2', {}, message) 52 | ])); 53 | } else { 54 | var iframe = E('iframe', { 55 | src: window.location.protocol + '//' + window.location.hostname + ':' + port, 56 | style: 'width: 100%; min-height: 100vh; border: none;' 57 | }); 58 | container.appendChild(iframe); 59 | } 60 | 61 | poll.add(function() { 62 | return self.checkRunning().then(function(checkResult) { 63 | var newStatus = checkResult.isRunning; 64 | if (newStatus !== isRunning) { 65 | window.location.reload(); 66 | } 67 | }); 68 | }, 5); 69 | 70 | poll.start(); 71 | 72 | return container; 73 | }); 74 | }, 75 | 76 | handleSaveApply: null, 77 | handleSave: null, 78 | handleReset: null 79 | }); -------------------------------------------------------------------------------- /luci-app-ddns-go/htdocs/luci-static/resources/view/ddns-go/log.js: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2021-2025 sirpdboy herboy2008@gmail.com https://github.com/sirpdboy/luci-app-ddns-go */ 2 | 'use strict'; 3 | 'require dom'; 4 | 'require fs'; 5 | 'require poll'; 6 | 'require uci'; 7 | 'require view'; 8 | 'require form'; 9 | 10 | return view.extend({ 11 | render: function () { 12 | var css = ` 13 | /* 日志框文本区域 */ 14 | #log_textarea pre { 15 | padding: 10px; /* 内边距 */ 16 | border-bottom: 1px solid #ddd; /* 边框颜色 */ 17 | font-size: small; 18 | line-height: 1.3; /* 行高 */ 19 | white-space: pre-wrap; 20 | word-wrap: break-word; 21 | overflow-y: auto; 22 | } 23 | /* 5s 自动刷新文字 */ 24 | .cbi-section small { 25 | margin-left: 1rem; 26 | font-size: small; 27 | color: #666; /* 深灰色文字 */ 28 | } 29 | `; 30 | 31 | var log_textarea = E('div', { 'id': 'log_textarea' }, 32 | E('img', { 33 | 'src': L.resource(['icons/loading.gif']), 34 | 'alt': _('Loading...'), 35 | 'style': 'vertical-align:middle' 36 | }, _('Collecting data ...')) 37 | ); 38 | 39 | var log_path = '/var/log/ddns-go.log'; 40 | var lastLogContent = ''; 41 | 42 | var clear_log_button = E('div', {}, [ 43 | E('button', { 44 | 'class': 'cbi-button cbi-button-remove', 45 | 'click': function (ev) { 46 | ev.preventDefault(); 47 | var button = ev.target; 48 | button.disabled = true; 49 | button.textContent = _('Clear Logs...'); 50 | fs.exec_direct('/usr/libexec/ddns-go-call', ['clear_log']) 51 | .then(function () { 52 | button.textContent = _('Logs cleared successfully!'); 53 | button.disabled = false; 54 | button.textContent = _('Clear Logs'); 55 | // 立即刷新日志显示框 56 | var log = E('pre', { 'wrap': 'pre' }, [_('Log is clean.')]); 57 | dom.content(log_textarea, log); 58 | lastLogContent = ''; 59 | }) 60 | .catch(function () { 61 | button.textContent = _('Failed to clear log.'); 62 | button.disabled = false; 63 | button.textContent = _('Clear Logs'); 64 | }); 65 | } 66 | }, _('Clear Logs')) 67 | ]); 68 | 69 | poll.add(L.bind(function () { 70 | return fs.read_direct(log_path, 'text') 71 | .then(function (res) { 72 | var newContent = res.trim() || _('Log is clean.'); 73 | 74 | if (newContent !== lastLogContent) { 75 | var log = E('pre', { 'wrap': 'pre' }, [newContent]); 76 | dom.content(log_textarea, log); 77 | log.scrollTop = log.scrollHeight; 78 | lastLogContent = newContent; 79 | } 80 | }).catch(function (err) { 81 | var log; 82 | if (err.toString().includes('NotFoundError')) { 83 | log = E('pre', { 'wrap': 'pre' }, [_('Log file does not exist.')]); 84 | } else { 85 | log = E('pre', { 'wrap': 'pre' }, [_('Unknown error: %s').format(err)]); 86 | } 87 | dom.content(log_textarea, log); 88 | }); 89 | })); 90 | 91 | return E('div', { 'class': 'cbi-map' }, [ 92 | E('style', [css]), 93 | E('div', { 'class': 'cbi-section' }, [ 94 | clear_log_button, 95 | log_textarea, 96 | E('small', {}, _('Refresh every 5 seconds.').format(L.env.pollinterval)), 97 | E('div', { 'class': 'cbi-section-actions cbi-section-actions-right' }) 98 | ]), 99 | E('div', { 'style': 'text-align: right; font-style: italic;' }, [ 100 | E('span', {}, [ 101 | _('© github '), 102 | E('a', { 103 | 'href': 'https://github.com/sirpdboy', 104 | 'target': '_blank', 105 | 'style': 'text-decoration: none;' 106 | }, 'by sirpdboy') 107 | ]) 108 | ]) 109 | 110 | 111 | ]); 112 | } 113 | 114 | //handleSaveApply: null, 115 | //handleSave: null, 116 | //handleReset: null 117 | }); 118 | -------------------------------------------------------------------------------- /luci-app-ddns-go/po/templates/ddns-go.pot: -------------------------------------------------------------------------------- 1 | msgid "" 2 | msgstr "" 3 | 4 | msgid "DDNS-GO" 5 | msgstr "" 6 | 7 | msgid "DDNS-GO automatically obtains your public IPv4 or IPv6 address and resolves it to the corresponding domain name service." 8 | msgstr "" 9 | 10 | msgid "Base Setting" 11 | msgstr "" 12 | 13 | msgid "Status check error:" 14 | msgstr "" 15 | 16 | msgid "Checking status..." 17 | msgstr "" 18 | 19 | msgid "DDNS-GO Control panel" 20 | msgstr "" 21 | 22 | msgid "Open Web Interface" 23 | msgstr "" 24 | 25 | msgid "Log" 26 | msgstr "" 27 | 28 | msgid "Clear Logs..." 29 | msgstr "" 30 | 31 | msgid "Logs cleared successfully!" 32 | msgstr "" 33 | 34 | msgid "Clear Logs" 35 | msgstr "" 36 | 37 | msgid "NOT RUNNING" 38 | msgstr "" 39 | 40 | msgid "RUNNING" 41 | msgstr "" 42 | 43 | msgid "DDNS-GO Service Not Running" 44 | msgstr "" 45 | 46 | msgid "Please enable the DDNS-GO service" 47 | msgstr "" 48 | 49 | msgid "Open Web Interface" 50 | msgstr "" 51 | 52 | msgid "Set the DDNS-TO access port" 53 | msgstr "" 54 | 55 | msgid "Collecting data..." 56 | msgstr "" 57 | 58 | msgid "update interval" 59 | msgstr "" 60 | 61 | msgid "Skip verifying certificates" 62 | msgstr "" 63 | 64 | msgid "Compare with service provider N times intervals" 65 | msgstr "" 66 | 67 | msgid "Specify DNS resolution server" 68 | msgstr "" 69 | 70 | msgid "Do not start web services" 71 | msgstr "" 72 | 73 | msgid "Delayed Start (seconds)" 74 | msgstr "" 75 | -------------------------------------------------------------------------------- /luci-app-ddns-go/po/zh_Hans/ddns-go.po: -------------------------------------------------------------------------------- 1 | msgid "" 2 | msgstr "Content-Type: text/plain; charset=UTF-8" 3 | 4 | msgid "DDNS-GO" 5 | msgstr "DDNS-GO" 6 | 7 | msgid "DDNS-GO automatically obtains your public IPv4 or IPv6 address and resolves it to the corresponding domain name service." 8 | msgstr "DDNS-GO自动获得你的公网 IPv4 或 IPv6 地址,并解析到对应的域名服务." 9 | 10 | msgid "Base Setting" 11 | msgstr "基本设置" 12 | 13 | msgid "Status check error:" 14 | msgstr "状态检查错误:" 15 | 16 | msgid "Checking status..." 17 | msgstr "检查状态..." 18 | 19 | msgid "DDNS-GO Control panel" 20 | msgstr "DDNS-GO操作台" 21 | 22 | msgid "Open Web Interface" 23 | msgstr "打开 Web 界面" 24 | 25 | msgid "Log" 26 | msgstr "日志" 27 | 28 | msgid "Clear Logs..." 29 | msgstr "清除日志..." 30 | 31 | msgid "Logs cleared successfully!" 32 | msgstr "日志清除成功!" 33 | 34 | msgid "Clear Logs" 35 | msgstr "清除日志" 36 | 37 | msgid "NOT RUNNING" 38 | msgstr "未运行" 39 | 40 | msgid "RUNNING" 41 | msgstr "运行中" 42 | 43 | msgid "DDNS-GO Service Not Running" 44 | msgstr "DDNS-GO服务未启用" 45 | 46 | msgid "DDNS-GO Web Interface Disabled" 47 | msgstr "DDNS-GO WEB服务禁用" 48 | 49 | msgid "Open Web Interface" 50 | msgstr "打开Web界面" 51 | 52 | msgid "Set the DDNS-TO access port" 53 | msgstr "设置访问端口" 54 | 55 | msgid "Collecting data..." 56 | msgstr "收集数据..." 57 | 58 | msgid "update interval" 59 | msgstr "更新间隔" 60 | 61 | msgid "Skip verifying certificates" 62 | msgstr "跳过验证证书" 63 | 64 | msgid "Compare with service provider N times intervals" 65 | msgstr "间隔N次与服务商比对" 66 | 67 | msgid "Specify DNS resolution server" 68 | msgstr "指定DNS解析服务器" 69 | 70 | msgid "Do not start web services" 71 | msgstr "不启动web服务" 72 | 73 | msgid "Delayed Start (seconds)" 74 | msgstr "开机延时启动(秒)" 75 | -------------------------------------------------------------------------------- /luci-app-ddns-go/root/etc/config/ddns-go: -------------------------------------------------------------------------------- 1 | config basic 'config' 2 | option enabled '0' 3 | option logger '1' 4 | option port '9876' 5 | option time '300' 6 | option ctimes '5' 7 | option skipverify '0' 8 | option delay '0' 9 | option dns '223.5.5.5' 10 | -------------------------------------------------------------------------------- /luci-app-ddns-go/root/etc/ddns-go/ddns-go-config.yaml: -------------------------------------------------------------------------------- 1 | ipv4: 2 | enable: true 3 | gettype: url 4 | url: https://myip4.ipip.net, https://ddns.oray.com/checkip, https://ip.3322.net 5 | netinterface: br-lan 6 | domains: 7 | - "" 8 | ipv6: 9 | enable: false 10 | gettype: url 11 | url: https://myip6.ipip.net, https://speed.neu6.edu.cn/getIP.php, https://v6.ident.me 12 | netinterface: "" 13 | ipv6reg: "" 14 | domains: 15 | - "" 16 | dns: 17 | name: alidns 18 | id: "" 19 | secret: "" 20 | user: 21 | username: "" 22 | password: "" 23 | webhook: 24 | webhookurl: "" 25 | webhookrequestbody: "" 26 | notallowwanaccess: true 27 | ttl: "" 28 | -------------------------------------------------------------------------------- /luci-app-ddns-go/root/etc/ddns-go/localtime: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sirpdboy/luci-app-ddns-go/d1b8e88c6d2b03b582bed40e29fb58fb3c0789c7/luci-app-ddns-go/root/etc/ddns-go/localtime -------------------------------------------------------------------------------- /luci-app-ddns-go/root/usr/share/ddns-go/ddns-go-default.yaml: -------------------------------------------------------------------------------- 1 | ipv4: 2 | enable: true 3 | gettype: url 4 | url: https://4.ipw.cn,https://myip4.ipip.net,https://ddns.oray.com/checkip,https://ip.3322.net 5 | netinterface: br-lan 6 | domains: 7 | - "" 8 | ipv6: 9 | enable: false 10 | gettype: url 11 | url: https://6.ipw.cn, https://speed.neu6.edu.cn/getIP.php, https://v6.ident.me 12 | netinterface: "" 13 | ipv6reg: "" 14 | domains: 15 | - "" 16 | dns: 17 | name: alidns 18 | id: "" 19 | secret: "" 20 | user: 21 | username: "" 22 | password: "" 23 | webhook: 24 | webhookurl: "" 25 | webhookrequestbody: "" 26 | notallowwanaccess: true 27 | ttl: "" 28 | -------------------------------------------------------------------------------- /luci-app-ddns-go/root/usr/share/luci/menu.d/luci-app-ddns-go.json: -------------------------------------------------------------------------------- 1 | { 2 | "admin/services/ddns-go": { 3 | "title": "DDNS-GO", 4 | "order": 58, 5 | "action": { 6 | "type": "firstchild" 7 | }, 8 | "depends": { 9 | "acl": [ "luci-app-ddns-go" ], 10 | "uci": { "ddns-go": true } 11 | } 12 | }, 13 | 14 | "admin/services/ddns-go/config": { 15 | "title": "Base Setting", 16 | "order": 10, 17 | "action": { 18 | "type": "view", 19 | "path": "ddns-go/config" 20 | } 21 | }, 22 | 23 | "admin/services/ddns-go/ddns-go": { 24 | "title": "DDNS-GO Control panel", 25 | "order": 20, 26 | "action": { 27 | "type": "view", 28 | "path": "ddns-go/ddns-go" 29 | } 30 | }, 31 | 32 | "admin/services/ddns-go/log": { 33 | "title": "Log", 34 | "order": 30, 35 | "action": { 36 | "type": "view", 37 | "path": "ddns-go/log" 38 | } 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /luci-app-ddns-go/root/usr/share/rpcd/acl.d/luci-app-ddns-go.json: -------------------------------------------------------------------------------- 1 | { 2 | "luci-app-ddns-go": { 3 | "description": "Grant UCI access for luci-app-ddns-go", 4 | "read": { 5 | "file": { 6 | "/etc/init.d/ddns-go": [ "exec" ], 7 | "/usr/libexec/ddns-go-call": [ "exec" ], 8 | "/bin/pidof": [ "exec" ], 9 | "/bin/ps": [ "exec" ], 10 | "/bin/ash": [ "exec" ], 11 | "/etc/ddns-go/ddns-go-config.yaml": [ "read" ], 12 | "/var/log/ddns-go.log": [ "read" ] 13 | }, 14 | "ubus": { 15 | "service": [ "list" ] 16 | }, 17 | "uci": [ "ddns-go" ,"ddns-go" ] 18 | }, 19 | "write": { 20 | "uci": [ "ddns-go" ,"ddns-go" ] 21 | } 22 | } 23 | } 24 | --------------------------------------------------------------------------------