在 ejabberd 中安装 TLS 证书以进行 STARTTLS 协商

TLS certificate installation in ejabberd for STARTTLS negotiation

我读到 ejabberd 建议使用 STARTTLS 协商来实现通信实体之间的安全连接。当我安装 ejabberd 时,默认情况下它带有 TLS 证书。

那我为什么要买证书安装呢?既然我们有默认证书,那么从 Certificate Authoririty 购买新证书的目的是什么?

当我在机器上部署 ejabberd 时,默认证书将如何用于我的域?客户端如何验证默认证书?

您可以通过提供的 TLS 证书将 ejabberd 与 SSL/STARTTLS 结合使用。但是,该证书只是一个自签名证书。这意味着:

  1. 您仍然可以加密客户端和服务器之间的流量。
  2. 您的客户端将无法检查服务器是否是它伪装的域。为了能够知道证书是可信的,客户端需要以某种方式引用信任机构。

在第二种情况下,这意味着如果中间网络设备(即 Wifi 接入点)试图冒充您的服务器,它可以向用户出示任何自签名证书,伪装成您的域。

所以,你当然可以使用自签名证书来加密流量,但是为了保护你的用户免受中间人类型的攻击,你需要找到一种方法让客户端现在可以信任证书。

这可以通过从受信任的机构(将证明您的证书域)购买证书或使客户端支持定义明确的证书列表来完成。这称为证书锁定,但是它需要在您的客户端中构建可接受的证书列表,这可能是不可能的。

你的情况可能没问题,所以购买证书不是强制性的。 但是,不要使用默认的 ejabberd 自签名证书,即使您计划使用自签名证书。 ejabberd 提供的证书与您自己的域不匹配。您至少应该生成与您的实际 XMPP 域匹配的自签名证书:How to create a self-signed certificate with openssl?

客户端将验证证书是否为Jabber ID (JID) 的域名颁发,即'@'后面的部分。 (还有其他选项,但它们与浏览器供应商针对 CA 强制执行的策略不兼容,因此不实用。)

除非您已经与证书颁发机构 (CA) 建立业务关系,否则我会建议任何人使用 Let's Encrypt 并远离自签名证书。

可以在 here 和链接的 wiki 页面中找到一些自动执行此操作并对 Let's Encrypt 服务器友好的说明。

总结(假设你是 运行ning Ubuntu 16.04 LTS,想 运行 它在域 example.org并且只将证书用于 ejabberd):

使用以下内容创建 /usr/local/sbin/auto-renew-letsencrypt

#!/bin/bash
# Renew all Let's Encrypt certificates which are due for renewal
t=`mktemp`
# Try to be quiet unless an error is returned
letsencrypt renew > $t || cat $t
# Hooks are not yet supported by `letsencrypt` shipping with Ubuntu 16.04 LTE
# Crudely emulate --renew-hook; breaks if diagnostic messages change
if grep -q "The following certs have been renewed" $t; then
  cat /etc/letsencrypt/live/example.org/{privkey,fullchain}.pem > /etc/ejabberd/ejabberd.pem
  service ejabberd reload
fi
rm $t

运行以下命令创建和激活证书并自动更新

apt install letsencrypt
letsencrypt certonly --standalone --domain example.org
cat /etc/letsencrypt/live/example.org/{privkey,fullchain}.pem > /etc/ejabberd/ejabberd.pem
chown ejabberd:ejabberd /etc/ejabberd/ejabberd.pem
chmod 640 /etc/ejabberd/ejabberd.pem
chmod 755 /usr/local/sbin/auto-renew-letsencrypt
echo $(($RANDOM % 60)) $((RANDOM % 6)) "* * * root /usr/local/sbin/auto-renew-letsencrypt" > /etc/cron.d/auto-renew-letsencrypt