实现 caddy 非 80/443 端口访问 以及泛域名证书

2022年10月18日 7664点热度 4人点赞 0条评论
内容纲要

背景

最近要将域名跟家庭宽带的公网 IP 打通,出现了一系列的问题。

注意:国内未经备案的机器,不能对外提供服务!

http://www.gov.cn/gongbao/content/2005/content_93018.htm
非经营性互联网信息服务备案管理办法

在中华人民共和国境内提供非经营性互联网信息服务,应当依法履行备案手续。
未经备案,不得在中华人民共和国境内从事非经营性互联网信息服务。

在国内的家庭宽带中,80/443 端口是不开放的,但是 caddy 需要使用这两个端口才能访问,如果设置其他端口,会导致 tls 证书服务商颁发证书失败,依然无法访问。
另外公网泛域名证书,需要配置 DNS, 否则不能颁发泛域名证书。

{
    http_port 1080
    https_port 1443
}

如果需要了解原理,可以看这篇:

https://ssine.ink/posts/caddy-non-443-port-https/

修改端口导致不能访问的原因是 tls 服务商验证域名的方式不能通过 80/443 访问。

域名验证过程有:

  • HTTP-01
  • DNS-01
  • TLS-SNI-01 (已禁用)
  • TLS-ALPN-01

由于修改了端口,第一种方式就行不通了,需要使用第二种方式,使用 DNS 插件,其要求在域名服务商那里增加 TXT 记录,以证明其域名所有权,但是这个过程需要动态。

caddy 支持的 dns 创建可以到这里看:

https://caddyserver.com/docs/modules/

file

笔者使用的是腾讯云 DNSPOD。

caddy 本身里面没有包含这些非标准模块,即 NON-STANDARD 模块,因此需要以插件的形式安装这些模块,但是 caddy 是 go 语言写的,没有动态加载程序集的方式,因此需要手动重新编译才行。

打包构建新的模块

下载 caddy 的源码:

git clone https://github.com/caddyserver/caddy.git

下载 xcaddy,此工具用于加载模块到 caddy 源码中,重新编译 caddy;下载的版本与当前机器有关,跟要运行的环境无关。

例如,要在 Windows 下编译给 Linux 用,那么就要下载 Windows 版本的。

https://github.com/caddyserver/xcaddy/releases

file

将下载的压缩包解压,取出 xcaddy.exe,将所在的目录添加到环境变量,以便可以使用此命令(不加也行)。

添加插件

我们要添加的插件其源码在:

https://github.com/caddy-dns/dnspod

因为我们需要在 Windows 下编译出 Linux 的程序,因此需要先设置环境变量。

全局设置:

go env -w CGO_ENABLED=0 GOOS=linux GOARCH=amd64   

打开 caddy 源码目录,执行:

xcaddy build --with github.com/caddy-dns/dnspod

file

其实这个是 Linux 的软件,只是名称保留了 .exe,修改名称为 caddy ,然后上传到 Linux 中即可。

获取 DNSPOD Token

因为要使用 Dnspod ,因此需要先获取 token,以便插件可以动态修改 TXT 记录。

打开:

https://console.dnspod.cn/account/token/token

创建一个 Dnspod token

然后复制 token。

配置 Caddyfile

首先创建一个环境变量文件,与 Caddyfile 文件分开存放。

dnspod.env

DNSPOD_TOKEN=1111

替换 1111 为你的 token。

然后配置全局端口以及对网站配置 tls 使用 dns 验证。

{
    http_port 1080
    https_port 1443
}

test.local.你的域名.com {
    respond "Hello, world!"
    tls {
        dns dnspod {env.DNSPOD_TOKEN}
    }
}

启动 caddy

启动命令:

caddy run --config Caddyfile --envfile dnspod.env

如果报 token 错误,是正常的,这是因为官方的库有问题。

2022/10/18 00:22:52.389 ERROR   tls.obtain  will retry  {"error": "[test.local.nativet.cn] Obtain: [test.local.***.cn] solving challenges: presenting for challenge: adding temporary record for zone \"nativet.cn.\": Create record err.Zone:*.cn., Name: _acme-challenge.test.local, Value: 11-1, Error:could not get domains: The login token ID is invalid, { TXT _acme-challenge.test.local -** 0s 0} (order=https://acme.zerossl.com/v2/DV90/order/*-cWPoG4azrA) (ca=https://acme.zerossl.com/v2/DV90)", "attempt": 1, "retrying_in": 60, "elapsed": 14.129376688, "max_duration": 2592000}

dns dnspod {env.DNSPOD_TOKEN} 替换为 dns dnspod tokenId,token 即可,例如:

dns dnspod 124,xxxxxx

file

然后启动:

caddy run

痴者工良

高级程序员劝退师

文章评论