Lets-encrypt Error: Failed HTTP-01 Pre-Flight / Dry Run

Lets-encrypt Error: Failed HTTP-01 Pre-Flight / Dry Run

我已经在 README file examples 之后设置了一个基于 redbird 的代理。

到目前为止,我已经为 http 和 https 配置了单个域,并且运行良好(https 仍在使用自签名证书)。

但现在我正在尝试将其配置为使用 letsencrypt 自动获取有效的 ssl 证书,但我遇到了以下错误:

 {"level":30,"time":1578681102208,"pid":21320,"hostname":"nigul","name":"redbird","0":false,"1":"setChallenge called for 'exposito.bitifet.net'","msg":"Lets encrypt debugger","v":1}
[acme-v2] handled(?) rejection as errback:
Error: Error: Failed HTTP-01 Pre-Flight / Dry Run.
curl 'http://exposito.bitifet.net/.well-known/acme-challenge/test-cf55199519d859042f695e620cca8dbb-0'
Expected: 'test-cf55199519d859042f695e620cca8dbb-0.MgLl7GIS59DPtPMejuUcXfddzNt8YxfLVo5op670u8M'
Got: '<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
  <title>404 - Not Found</title>
 </head>
 <body>
  <h1>404 - Not Found</h1>
 </body>
</html>
'
See https://git.coolaj86.com/coolaj86/acme-v2.js/issues/4
    at /home/joanmi/SERVICES/redbird_domains/node_modules/acme-v2/index.js:49:10
    at process._tickCallback (internal/process/next_tick.js:68:7)

据我了解,这告诉我 Lets Encrypt 正在尝试使用以下命令访问 url http://exposito.bitifet.net/.well-known/acme-challenge/test-cf55199519d859042f695e620cca8dbb-0

curl 'http://exposito.bitifet.net/.well-known/acme-challenge/test-cf55199519d859042f695e620cca8dbb-0'

...它似乎是一个 404 HTML 错误页面,我不知道它会出现在哪里。

而且,事实上,执行那个 curl 命令或者只是在我的浏览器中粘贴 that url(你可以试试:我离开了服务器运行ning),我得到了给定的 Expected 字符串,因此,从我的角度来看,我的配置似乎是正确的,但由于某种原因,Lets Encrypt 的服务器正在到达另一台服务器(由于错误的路由或 DNS)。

但另一方面,我想更有可能是我的配置有问题。

这里我粘贴了我的整个脚本(端口 80 和 443 分别通过 iptables 重定向到 1080 和 1443,因为脚本是 运行 非特权用户):

const Redbird = require("redbird");

const proxy = Redbird({
    port: 1080,
    xfwd: false, // Disable the X-Forwarded-For header
    letsencrypt: {
    path: __dirname + '/certs',
    port: 9999
            // LetsEncrypt minimal web server port for handling challenges.
            // Routed 80->9999, no need to open 9999 in firewall. Default 3000
            // if not defined.
    },
    ssl: {
        http2: true,
        port: 1443, // SSL port used to serve registered https routes with LetsEncrypt certificate.
    }

});


proxy.register('exposito.bitifet.net:9999', 'http://localhost:8001', {
  ssl: {
    letsencrypt: {
      email: 'xxxxxx@gmail.com', // Domain owner/admin email
      production: false,
                // WARNING: Only use this flag when the proxy is verified to
                // work correctly to avoid being banned!
    }
  }
});

proxy.register("exposito.bitifet.net", "http://localhost:8001");

欢迎提供任何线索。

谢谢。

已解决!!

同时涉及许多问题(尽管我缺乏使用 redbird 和 letsencrypt 的经验。

  1. magic 404/未找到页面: 我猜它来自 lighttpd服务器似乎已预装在我的 VPS.

端口 80 已通过 iptables 重定向,但我想在一个或其他配置调整中我可以将传入请求重定向到 localhost 的端口 80(未重定向)。

  1. 我对 redbird 的误解: 查看其 README 文件中的示例,我认为 redbird 有点像“multi- reverse_proxy " 在某种意义上,您可以使用单个 redbird 实例重定向 http 和 https 请求。

但我终于意识到 port 选项(可能不是很好命名)实际上是一个 http 端口,仅用于配置内置的无条件 http ->https 重定向器(我已经读过,但我认为它是可选的)。

  1. 实际的潜在问题: 如果您的 DNS 激活了 DNSSEC,您应该在其中定义一个 CAA 注册指向 letsencrypt.org.

目前我禁用了 DNSSEC,因为我的提供商的控制面板不允许我创建这样的注册。

我在尝试通过 certbot 获取证书时发现了它(sudo apt-get install certbot 我必须说,如果我之前知道它,我就不会关心尝试 redbird 的 letsencrypt 集成。

它更冗长(而当出现错误时 redbird 更像是一个黑框)并指出我需要 CAA 注册。

这是我做的笔记(以防有人感兴趣):

Free SSL Certificates with Certbot
    Install certbot:
        sudo apt-get install certbot
    Create:
        sudo certbot certonly --manual --preferred-challenges http -d <domain>
    Renew:
        sudo certbot renew
    Caveats:
        DNSSEC
            If your DNS server has DNSSEC enabled, you will need to add a CAA
            register pointing to letsencrypt.org.
            ...and your DNS provider my not allow to create it (at least I
            couldn't with CDMON. Also not -yet- complained).
  1. production = false 用于其他类型的测试: 我读到如果你在测试时输入 true,你如果您执行太多请求,可能会被禁止使用 letsencrypt。

将它设置为 false 你可以测试重定向,但是你仍然会看到关于 letsencrypt 的错误,即使你可以在 没有 安全证书的情况下导航(我认为有点自签名提供给允许测试)。所以不要指望有效。

  1. ssl 端口用于重定向: 不是(大)问题,但如果您指定 443 以外的 ssl 端口,内置重定向器将无条件地将您重定向到该端口。

运行 redbird 作为 root 并使用标准(80 和 443)端口工作正常。但是,如果您像我一样,想要使用替代端口以使用非特权用户执行 redbird,您将被重定向到该替代端口而不是 443(即使通过 iptables 重定向)。


这是我的(几乎*)最终的 redbird 脚本:

const Redbird = require("redbird");

const proxy = Redbird({
    port: 1080,
    xfwd: false, // Disable the X-Forwarded-For header
    ssl: {
        port: 1443,
    },
    letsencrypt: {
        path: __dirname + '/certs',
        port: 9999,
                // LetsEncrypt minimal web server port for handling challenges.
                // Routed 80->9999, no need to open 9999 in firewall. Default 3000
                // if not defined.
    },

});

proxy.register('exposito.bitifet.net', 'http://exposito.bitifet.net:8001', {
    ssl: {
        http2: true,
        letsencrypt: {
          email: 'xxxxxx@gmail.com', // Domain owner/admin email
          production: true,
                    // WARNING: Only use this flag when the proxy is verified to
                    // work correctly to avoid being banned!

        },
    }
});

(*) 我仍然需要修复显式端口重定向问题 (5),因为我不想 运行 redbird 作为 root。但我知道可以允许用户监听给定的端口。即使我可能会更好地尝试修补 redbird 以允许分别指定侦听和重定向端口。

编辑: 它已经使用 ssl[中的(可选)选项 redirectPort 实现(并记录)节。刚刚添加 redirectPort: 443 并完成工作!!

编辑 2:为了完成,还有另一个问题让我苦恼。

为了让事情正常进行,我最终配置了重定向到 http 端口而不是 https 端口。

即:传入的 https 请求被重定向到我的应用程序 http 端口。

这看起来很奇怪,但确实有效。至少如果你不需要任何专有的 https 功能,比如推送通知(我计划在未来使用)。

但这意味着在本地主机上至少 打开一个 http 服务器。现在这不是主要问题(这只是一个游乐场服务器)但我计划在工作中使用 redbird 将多个域代理到不同的服务器,这样会迫使我们至少在我们的 DMZ vlan(这是一个最好避免的额外风险...)。

当我尝试重定向到 https 时出现 DEPTH_ZERO_SELF_SIGNED_CERT 错误。

好的:这告诉我 redbird(或节点)不信任我的原始(自签名)证书。我知道有一个选项可以告诉节点接受这些证书。但也许这不是要走的路...

所以我将我的应用程序配置为使用 redbird 通过 letsencrypt 获得的相同证书。

但后来我得到了另一个错误:

UNABLE_TO_VERIFY_LEAF_SIGNATURE

稍微研究了一下,我发现 this Whosebug answer 解释了如何获取 Mozilla 信任的所有根证书和中间证书 并使节点信任它们。

所以,最后,我做的是:

  1. 已安装 node_extra_ca_certs_mozilla_bundle 软件包:

    npm install --save node_extra_ca_certs_mozilla_bundle
    
  2. package.jsonstart 命令前加上 NODE_EXTRA_CA_CERTS=node_modules/node_extra_ca_certs_mozilla_bundle/ca_bundle/ca_intermediate_root_bundle.pem 脚本部分。

  3. 更新了我的 redbird 脚本以再次指向 https(协议和)端口:

    proxy.register('exposito.bitifet.net', 'https://localhost:4301', {...]);
    

这是我最终的红鸟配置:

const Redbird = require("redbird");

const proxy = Redbird({
    port: 1080,
    xfwd: false, // Disable the X-Forwarded-For header
    ssl: {
        port: 1443,
        redirectPort: 443
        // key: "/etc/bitifet/exposito/ssl/private.key",
        // cert: "/etc/bitifet/exposito/ssl/public.cert",
    },
    letsencrypt: {
        path: __dirname + '/certs',
        port: 9999,
                // LetsEncrypt minimal web server port for handling challenges.
                // Routed 80->9999, no need to open 9999 in firewall. Default 3000
                // if not defined.
    },

});

proxy.register('exposito.bitifet.net', 'https://localhost:4301', {
    ssl: {
        http2: true,
        letsencrypt: {
          email: 'xxxxxx@gmail.com', // Domain owner/admin email
          production: true,
                    // WARNING: Only use this flag when the proxy is verified to
                    // work correctly to avoid being banned!

        },
    }
});

这是我的 package.json 文件内容:

{
  "name": "redbird_domains",
  "version": "0.0.1",
  "description": "Local Domains Handling",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "NODE_EXTRA_CA_CERTS=node_modules/node_extra_ca_certs_mozilla_bundle/ca_bundle/ca_intermediate_root_bundle.pem node ./index.js"
  },
  "author": "Joanmi",
  "license": "GPL-3.0",
  "dependencies": {
    "node_extra_ca_certs_mozilla_bundle": "^1.0.4",
    "redbird": "^0.10.0"
  }
}