让我们加密失败的 DVSNI 挑战

Let's Encrypt Failing DVSNI Challenge

我正在尝试在可公开访问的服务器上配置 Let's Encrypt certificates。本来服务器是躲在路由器后面的,后来我转发了80和443端口

证书似乎已完成大部分安装过程,但失败并显示消息:Failed to connect to host for DVSNI challenge

完整堆栈跟踪:

Updating letsencrypt and virtual environment dependencies......
    Requesting root privileges to run with virtualenv: sudo /bin/letsencrypt certonly --standalone -d example.net -d www.example.net
    Failed authorization procedure. example.net (tls-sni-01): urn:acme:error:connection :: The server could not connect to the client to verify the domain :: Failed to connect to host for DVSNI challenge

IMPORTANT NOTES:
 - The following 'urn:acme:error:connection' errors were reported by
   the server:

   Domains: example.net
   Error: The server could not connect to the client to verify the
   domain

如有任何支持,我们将不胜感激!

我四处寻找解决方案,但运气不佳。大多数其他类似情况都通过转发端口 443 解决了,但我确定此端口已经转发并打开,尽管目前 运行 上没有服务。

应该没什么区别,但我正在尝试配置此证书以在 Raspberry Pi.

上与 Node JS 一起使用

我终于明白是怎么回事了。我发现 --manual 标志以交互方式逐步完成身份验证过程。

过程中的每个阶段都会显示类似如下的提示:

Make sure your web server displays the following content at
http://www.example.net/.well-known/acme-challenge/twJCKQm9SbPEapgHpyU5TdAR1ErRaiCyxEB5zhhw0w8 before continuing:

twJCKQm9SbPEapgHpyU5TdAR1ErRaiCyxEB5zhhw0w8.t7J7DDTbktMGCCu2KREoIHv1zwkvwGfJTAkJrnELb4U

If you don't have HTTP server configured, you can run the following
command on the target server (as root):

mkdir -p /tmp/letsencrypt/public_html/.well-known/acme-challenge
cd /tmp/letsencrypt/public_html
printf "%s" twJCKQm9SbPEapgHpyU5TdAR1ErRaiCyxEB5zhhw0w8.t7J7DDTbktMGCCu2KREoIHv1zwkvwGfJTAkJrnELb4U > .well-known/acme-challenge/twJCKQm9SbPEapgHpyU5TdAR1ErRaiCyxEB5zhhw0w8
# run only once per server:
$(command -v python2 || command -v python2.7 || command -v python2.6) -c \
"import BaseHTTPServer, SimpleHTTPServer; \
s = BaseHTTPServer.HTTPServer(('', 80), SimpleHTTPServer.SimpleHTTPRequestHandler); \
s.serve_forever()"

Press ENTER to continue

正如我所发现的,尽管该进程本身是 运行 root,但它本身没有启动挑战服务器的权限。当然,这可能是 API.

中的错误

运行提示中的脚本直接产生如下错误:

$(command -v python2 || command -v python2.7 || command -v python2.6) -c \
> "import BaseHTTPServer, SimpleHTTPServer; \
> s = BaseHTTPServer.HTTPServer(('', 80), SimpleHTTPServer.SimpleHTTPRequestHandler); \
> s.serve_forever()"

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/lib/python2.7/SocketServer.py", line 419, in __init__
    self.server_bind()
  File "/usr/lib/python2.7/BaseHTTPServer.py", line 108, in server_bind
    SocketServer.TCPServer.server_bind(self)
  File "/usr/lib/python2.7/SocketServer.py", line 430, in server_bind
    self.socket.bind(self.server_address)
  File "/usr/lib/python2.7/socket.py", line 224, in meth
    return getattr(self._sock,name)(*args)
socket.error: [Errno 13] Permission denied

但是运行将它设置为 root(如提示本身所述)正确启动了服务器,并且可以在外部服务器查询它以完成挑战时被监控:

sudo $(command -v python2 || command -v python2.7 || command -v python2.6) -c "import BaseHTTPServer, SimpleHTTPServer; \
s = BaseHTTPServer.HTTPServer(('', 80), SimpleHTTPServer.SimpleHTTPRequestHandler); \
s.serve_forever()"

66.133.109.36 - - [08/Jan/2016 21:25:10] "GET /.well-known/acme-challenge/SZ88SorxBGXBtSZCTn4FX2g7u5XjnPFOOV3f5S5DuXB HTTP/1.1" 200 -
66.133.109.36 - - [08/Jan/2016 21:25:10] "GET /.well-known/acme-challenge/twJCKQm9SbPEapgHpyU5TdAR1ErRaiCyxEB5zhhw0w8 HTTP/1.1" 200 -

这个错误需要一段时间才能诊断出来,因为有很多事情可以防止挑战失败,并且产生的服务器在后台静默失败。

如果您在站点前使用 Cloudflare DNS,请记住让 DNS A、AAAA 记录直接指向您的站点,直到续订完成为止。

我想你们都已经检查过了。在续订过程中向我提出了同样的错误。我已将流量从 443 重定向到 8443(使用 iptables)。解决方案是从 iptables 中删除条目,停止 tomcat,然后执行更新过程就像一个魅力。脚本看起来像这样。

/etc/init.d/tomcat7 stop
iptables -t nat -D PREROUTING -i eth0 -p tcp -m tcp --dport 443 -j REDIRECT --to-ports 8443

$letsencryptdir/letsencrypt-auto renew --standalone --standalone-supported-challenges tls-sni-01 --renew-by-default --email <my_email> --verbose --text  --agree-tos

iptables -t nat -I PREROUTING -i eth0 -p tcp -m tcp --dport 443 -j REDIRECT --to-ports 8443
/etc/init.d/tomcat7 start

我尝试时遇到了同样的错误:

./letsencrypt-auto --apache  -d example.com -d www.example.com

但它适用于:

./letsencrypt-auto certonly --webroot -w /var/www/html -d example.com -d www.example.com

之后您需要更改 apache.conf 文件中的证书路径(默认-ssl.conf)并重新启动 apache。

我通过在 Apache 2.4 的 Ubuntu 14.04 机器上禁用 IPv6 解决了这个问题,因为我的服务器没有真正的 IPv6 地址。 (https://community.letsencrypt.org/t/how-to-resolve-the-correct-zname-not-found-for-tls-sni-challenge-error-when-i-try-renew-certificate/9405/43 上的原创 post)

为此,我在 /etc/apache2/ports.conf:

中明确设置了 IP 地址
Listen <IP>:80
Listen <IP>:443

在所有虚拟主机中:

<VirtualHost <IP>:80>

而不是:

<VirtualHost *:80>

进行这些更改后,netstat -lnp | egrep ":443|:80" 在第一列中显示 tcp 而不是 tcp6

然后,cerbot renew 就像一个魅力。

我为此奋斗了几个小时,在我的日志中完成了相同的输出。我什至跟进了此页面上的所有建议。我只是偶然发现了我的答案。我从另一个 webconfig 粘贴了一些代码,其中已经有一个 <virtual host _._._._:443> 部分。删除 443 部分后,sudo certbot-auto --apache -d example.com 运行 没有错误,我有了一个工作站点。

我只是根据我的经验得出结论:确保你只有 80 端口的虚拟主机。我阅读的文档中没有任何地方提到这个问题,但 certbot 似乎不能很好地处理站点可用的 conf已包含 443 虚拟主机部分的文件。