Caddy2 与 Cloudflare 不完美结合方案

  |   1 评论   |   0 浏览

本文的大多数信息来源于社区的lizhongyue248帮助以及官方文档,我这边只是将相关内容整理出来。

感谢lizhongyue248!🙏🙏🙏

01. cloudflare相关设置

1.环境变量设置的方式无效了,需要在配置文件里面设置 token

2.不需要设置邮箱,不能使用全局 token,要单独创建一个具有如下权限的 token

Zone / Zone / Read
Zone / DNS / Edit

进入cloudflare管理端,点击右下角的“获取您的API令牌“

image.png

进入编辑页面

image.png

修改如下配置,区域资源那边选择自己的网站。

image.png

全部处理完成之后,会出现一个api_token,值得注意的一点是这个token和大多数网站一样,只显示一次,注意⚠️找个地方记录下。

02. 编译caddy添加tls.dns.cloudflare模块

可以使用golang的docker镜像来构建,你运行的环境是什么os,你就选择什么环境的golang

$ mkdir -p caddy && cd caddy
$ wget https://raw.githubusercontent.com/caddyserver/caddy/v2/cmd/caddy/main.go

然后编辑 main.go,在 import 代码块里面添加你需要的模块:



package main

import (
	caddycmd "github.com/caddyserver/caddy/v2/cmd"

	// plug in Caddy modules here
	_ "github.com/caddyserver/caddy/v2/modules/standard"
	_ "github.com/caddyserver/tls.dns/providers/cloudflare"
)

func main() {
	caddycmd.Main()
}

然后构建就可以了,我当时构建的是 beta.15 版本

$ go mod init caddy
$ go get github.com/caddyserver/caddy/[email protected]
$ go build

构建完成用会在当前目录生成一个 caddy 二进制文件

./caddy list-modules

结果会包含 tls.dns.cloudflare,我之前用caddy的caddy-builder镜像一直没改成功

03. caddy相关配置

Caddy1 可以直接从 get caddy 里面选择插件进行下载

目前 caddy2 只有手动编译,get caddy相关页面还在开发过程中

Caddyfile 里面没有配置dns选项,由于go不是很熟悉

https://github.com/caddyserver/dnsproviders/blob/master/cloudflare/cloudflare.go

这个仓库中有一个 credentials,不知道如何配置

// Package cloudflare adapts the lego Cloudflare DNS
// provider for Caddy. Importing this package plugs it in.
package cloudflare

import (
	"errors"

	"github.com/caddyserver/caddy/caddytls"
	"github.com/go-acme/lego/v3/providers/dns/cloudflare"
)

func init() {
	caddytls.RegisterDNSProvider("cloudflare", NewDNSProvider)
}

// NewDNSProvider returns a new Cloudflare DNS challenge provider.
// The credentials are interpreted as follows:
//
// len(0): use credentials from environment
// len(2): credentials[0] = Email address
//         credentials[1] = API key
func NewDNSProvider(credentials ...string) (caddytls.ChallengeProvider, error) {
	switch len(credentials) {
	case 0:
		return cloudflare.NewDNSProvider()
	case 2:
		config := cloudflare.NewDefaultConfig()
		config.AuthEmail = credentials[0]
		config.AuthKey = credentials[1]
		return cloudflare.NewDNSProviderConfig(config)
	default:
		return nil, errors.New("invalid credentials length")
	}
}

代码的大概意思是可以通过环境变量获取apikey和mail,也可以通过 credentials这个来获取对应的值

熟悉go的小伙伴可以去深入的研究下,原先是想caddy1的Caddyfile中配完tls,然后用caddy2的adapt来自适应,目前发现不可行

caddy2的那部分代码发生变化,可以看出来完全使用的json中key


package cloudflare

import (
	"time"

	"github.com/caddyserver/caddy/v2"
	"github.com/caddyserver/caddy/v2/modules/caddytls"
	tlsdns "github.com/caddyserver/tls.dns"
	"github.com/go-acme/lego/v3/challenge"
	"github.com/go-acme/lego/v3/providers/dns/cloudflare"
)

func init() {
	caddy.RegisterModule(Cloudflare{})
}

// CaddyModule returns the Caddy module information.
func (Cloudflare) CaddyModule() caddy.ModuleInfo {
	return caddy.ModuleInfo{
		ID:  "tls.dns.cloudflare",
		New: func() caddy.Module { return new(Cloudflare) },
	}
}

// Cloudflare configures a solver for the ACME DNS challenge.
//
// Please see the following documentation about which credentials
// to supply: https://go-acme.github.io/lego/dns/cloudflare/#api-tokens.
type Cloudflare struct {
	// An API token with the scoped to all applicable domains with the
	// following permissions:
	//
	// - Zone / Zone / Read
	// - Zone / DNS / Edit
	//
	// Or, if you prefer a more strict set of privileges: give this token
	// only the `Zone / DNS / Edit` permission, scoped only to the domains
	// you want to manage certificates for, then provide a ZoneAPIToken
	// scoped to all your zones with the `Zone / Zone / Read` permission.
	APIToken string `json:"api_token,omitempty"`

	// An optional API token used in conjunction with APIToken, only
	// needed if you prefer a stricter set of privileges. If used, this
	// API token must have the `Zone / Zone / Read` for all zones.
	ZoneAPIToken string `json:"zone_api_token,omitempty"`

	tlsdns.CommonConfig
}

// NewDNSProvider returns a DNS challenge solver.
func (wrapper Cloudflare) NewDNSProvider() (challenge.Provider, error) {
	cfg := cloudflare.NewDefaultConfig()
	if wrapper.APIToken != "" {
		cfg.AuthToken = wrapper.APIToken
	}
	if wrapper.ZoneAPIToken != "" {
		cfg.ZoneToken = wrapper.ZoneAPIToken
	}
	if wrapper.CommonConfig.TTL != 0 {
		cfg.TTL = wrapper.CommonConfig.TTL
	}
	if wrapper.CommonConfig.PropagationTimeout != 0 {
		cfg.PropagationTimeout = time.Duration(wrapper.CommonConfig.PropagationTimeout)
	}
	if wrapper.CommonConfig.PollingInterval != 0 {
		cfg.PollingInterval = time.Duration(wrapper.CommonConfig.PollingInterval)
	}
	if wrapper.CommonConfig.HTTPClient != nil {
		cfg.HTTPClient = wrapper.CommonConfig.HTTPClient.HTTPClient()
	}
	return cloudflare.NewDNSProviderConfig(cfg)
}

// Interface guard
var _ caddytls.DNSProviderMaker = (*Cloudflare)(nil)

我的caddyfile转成json,tls部分如下

"tls": {
      "automation": {
        "policies": [{
          "hosts": ["solo.mufengs.com"],
          "management": {
            "challenges": {
              "dns": {
                "provider": "cloudflare",
                "api_token": "pSSnFQj",
                "base_url": "mufengs.com"
              }
            },
            "module": "acme"
          }
        }]
      }
    }

可以将上面部分直接拷到你的josn中apps那一层中

启动caddy

caddy run --config /path/to/caddy.json

搞定收工,再次感谢lizhongyue248

---------------------------------------------------------------
>> 博客地址:https://blog.mufengs.com
>> 邮箱地址:[email protected]
>> 微信帐号:Do8080
>> Github : https://github.com/mufengcoding
---------------------------------------------------------------

评论

发表评论