simplyddns

package module
v0.0.0-...-4a8ce9b Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 8, 2024 License: MIT Imports: 11 Imported by: 0

README

Simply DDNS

Build Status

根据指定的 IP 地址,更新对应的 DNS 记录。

思路

其实我看到已经有对应的类似的项目,已经是非常的好用。但是,有几点不符合我个人的期望以及要求:

  1. 我不需要个 UI 界面,对应的我其实更想要的是个全功能的配置文件;
  2. 需要更多的灵活性,而且可以自由的搭配配置;
  3. 作为服务端需要更加详细的日志,并能回传需要的信息。

加上这块其实是强需求(大家都知道建站的时候,其实最后一部就是更改 DNS,非常的麻烦而且容易出错)。

于是就有了这个应用,可能相对而言可能有比较高的配置门槛,但是有更多的灵活性。

概念

将 DDNS 动态注册 DNS 的行为抽象为两种:一种为如何获取 IP 地址、另外一种为如何配置 DNS,简单的将如下图所示:

因此,主要实现了这个两个接口,并且对应上配置就可以灵活的搭配以及运行,详细参见扩展章节。

安装

出于安全方面的考虑暂时不提供二进制可执行文件,如果您需要自己编译生成二进制文件,可以直接参考 Makefile 文件中的配置。

通常而言 make build 是个非常不错的选择,默认情况下运行它以后(当然,需要 Golang 开发环境)就可以在当前目录下生成对应的可执行文件。

docker-compose

推荐您使用容器的方式运行本应用,在本程序中还提供了 docker-compose.yml 以及 Dockerfile 文件,方便构建和运行镜像。

// @TODO

配置

详细的配置文件例子在 example 目录中,具体可以参考详细的 Yaml 文件。下面举个非常简单的例子(来自 basic.yml)文件:

logfile: "/dev/stderr"
debug: Yes

ddns:
  - source:
      type: "lo"
      interval: 60 # 1 minute
    target:
      type: "sleep"

这个配置文件的其中含义就是从 lo 模块中获取 IP 地址后,传给 sleep 的 target 去执行。

因为 sleep 的 target 除了 sleep 几秒以外,其实什么都不干但由此可以看出 SimplyDDNS 的工作机制。

Webhook

扩展

扩展 SimplyDDNS 其实非常的容易,可以分别参考 source 以及 target 中对应的文件即可,比较简单的是 lo.go 以及 target 目录中的 sleep.go 文件,因为它们并不做任何实际的事情。

已实现模块
source

lo

这个模块只返回 Lookup 地址,用于测试使用

static

指定对应的静态地址,通常用于固定 IP 地址的情况

myip

通过访问 ipip.net 得知访问的 IP 地址,推荐的获取 IP 地址方法之一,用于访问主机有公网地址并能直接访问的情况(如 DMZ 主机)。

biturl

另外个能够通过访问对方 Web 地址的 IP 获取服务,原有的 ipsb 服务已经废弃不再使用。

target

sleep

啥都不干,就是 Sleep 暂停几秒,可以作为测试使用。

alidns

使用阿里云 DNS 服务的接口,需要后台先申请 API 的 Key 和 Token。详细使用方式在 target/alidns_test.go 文件中,配置文件例子在 example/alidns.yml 中。

namedotcom

使用 Name.com 作为域名服务的后端。因为 Name.com 有白名单验证,所以如果不是本机访问可以考虑使用代理的方式请求(具体请参见 target/namedotcom_test.go 这个文件)。

FAQ

如果我只有一种请求 IP 地址的方式但是有多个域名,这样子一来重复配置二来看起来配置非常的臃肿,有没有更好的方案?

这是个比较常见的场景,你可以考虑使用 Yaml 的引用特性减少重复的配置,例如:

defaults: &defaults
  type: lo
  interval: 60

首先定义每分钟返回个 lo 的回传本地地址,然后配置对应的域名更新:

ddns:
  - source:
      <<: *defaults
    target:
      type: "sleep"
      domains:
        - a.com
        - b.com
  - source:
      <<: *defaults
    target:
      type: "another"
      domains:
        - c.com
        - d.com

这样子配置后,只需要关心 target 也就是域名的配置即可。

WebHook 的配置

WebHook 可以在任何配置更改的情况下通知到用户,可以参考使用以下的配置:

webhook:
  url: https://<your-webhook-address>

类似这样子配置后,当地址发生改变时,会将结果和更改的域名结果 POST 到对应的地址。结果的格式如下:

{
    "address": "127.0.0.1",
    "domains": "a.com,b.com",
    "now": "2022-07-13T15:00:10.931809+08:00"
}

如果有多个域名的结果,会用逗号分隔。

- eof -

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GetAllSupportSourceFunc

func GetAllSupportSourceFunc() []string

func NewLogger

func NewLogger() *logrus.Logger

func ProxyHttpClient

func ProxyHttpClient(addr string) (*http.Client, error)

ProxyHttpClient to create http client with socks5 proxy

func RegisterSourceFunc

func RegisterSourceFunc(name string, fn SourceFunc) (err error)

func RegisterTargetFunc

func RegisterTargetFunc(name string, fn TargetFunc) (err error)

func ValidateConfig

func ValidateConfig(config *JobConfig) error

ValidateConfig 验证配置对象是否合适

func ValidateRecord

func ValidateRecord(domain string, addr *net.IP) error

ValidateRecord 批量验证 DNS 域名是否已经是对应的 IP 地址

func ValidateRecords

func ValidateRecords(domains []string, addr *net.IP) error

ValidateRecords 批量验证 DNS 域名是否已经是对应的 IP 地址

Types

type Auth

type Auth struct {
	User     string `yaml:"username" mapstructure:"username"`
	Password string `yaml:"password" mapstructure:"password"`
}

type Config

type Config struct {
	LogFile  string      `yaml:"logfile" mapstructure:"logfile"`
	Debug    bool        `yaml:"debug" mapstructure:"debug"`
	LoadUI   bool        `yaml:"ui" mapstructure:"ui"`
	BindAddr string      `yaml:"addr" mapstructure:"addr"`
	Auth     Auth        `yaml:"auth" mapstructure:"auth"`
	Jobs     []JobConfig `yaml:"ddns" mapstructure:"ddns"`
}

type Dispatch

type Dispatch struct {
	Timeout time.Duration
	Configs []JobConfig
	// contains filtered or unexported fields
}

func NewDispatch

func NewDispatch(configs []JobConfig) (*Dispatch, error)

func (*Dispatch) Start

func (d *Dispatch) Start(ctx context.Context)

Start the dispatch

func (*Dispatch) Stop

func (d *Dispatch) Stop()

Stop the dispatch

type Job

type Job struct {
	Config     *JobConfig
	SourceFunc []SourceFunc
	TargetFunc TargetFunc
	// contains filtered or unexported fields
}

func NewJob

func NewJob(config JobConfig) (job *Job, err error)

NewJob for instance a new ddns job

func (*Job) RunWebhook

func (j *Job) RunWebhook(ctx context.Context, addr string, domains []string) (err error)

RunWebhook to run the webhook when ip address has updated

func (Job) Source

func (j Job) Source(ctx context.Context, config *SourceConfig) (*net.IP, error)

Source to execute multi-source function

func (*Job) Start

func (j *Job) Start(ctx context.Context)

Start to start a job

func (*Job) Stop

func (j *Job) Stop()

Stop to stop a job

type JobConfig

type JobConfig struct {
	WebHook WebHook      `yaml:"webhook" mapstructure:"webhook"`
	Source  SourceConfig `yaml:"source,omitempty" mapstructure:"source"`
	Target  TargetConfig `yaml:"target,omitempty" mapstructure:"target"`
}

type SourceConfig

type SourceConfig struct {
	Interval uint   `yaml:"interval,omitempty"`
	Type     string `yaml:"type,omitempty"`
	Path     string `yaml:"path"`
	Content  string `yaml:"content"`
}

type SourceFunc

type SourceFunc func(context.Context, *SourceConfig) (*net.IP, error)

func SourceFuncByName

func SourceFuncByName(name string) (fn SourceFunc, err error)

type TargetConfig

type TargetConfig struct {
	Type    string   `yaml:"type,omitempty"`
	Key     string   `yaml:"key,omitempty"`
	Token   string   `yaml:"token"`
	Proxy   string   `yaml:"proxy"`
	Domains []string `yaml:"domains,omitempty"`
}

type TargetFunc

type TargetFunc func(context.Context, *net.IP, *TargetConfig) error

func TargetFuncByName

func TargetFuncByName(name string) (fn TargetFunc, err error)

type WebHook

type WebHook struct {
	Url      string `yaml:"url" mapstructure:"url"`
	Token    string `yaml:"token" mapstructure:"token"`
	UserName string `yaml:"token" mapstructure:"username"`
	Password string `yaml:"token" mapstructure:"password"`
}

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL