请问怎样实现不同的客户端使用不同认证方式(用户名/密码、证书)

EMQ版本 4.4
目前使用的是MySQL插件完成认证和ACL。
具体需求如下

  1. 不同的客户端,需要不同的认证方式,账号/密码和证书认证。
  2. 认证所用的证书非固定,会变更,且数量有若干个
  3. 证书认证通过的客户端使用MySQL的ACL控制访问
    请问一下可以实现这样的功能么,目前看到EMQ配置文件中的证书应该是单个的。

感谢~

1 个赞

账号密码认证的需求很正常,现在 MySQL 插件应该能完全满足要求。现在的问题只是想让客户端用不同的证书登录吗?

  • 做 TLS 双向认证,用同一个 CA 签发不同的 client 证书。
  • 每一个 emqx listener 只能使用一个证书,可以启用多个 listener。比如在 1883 端口之外,再启动一个 2883 端口,用另外的证书。

是的,MySQL方式的认证和ACL已经对接好了,目前的问题是证书认证这方面的,大概是以下三个。

  • 我试了一下开启证书,但好像同时还是需要账号密码,请问怎么设置可以使得客户端连接的时候只用证书或只用账号密码。
  • 使用多个listener实现多个证书认证时,如果证书有变更,指增加或删除,那emq是否需要重启才能生效,
  • 证书认证是否可以在认证后使用MySQL的ACL信息控制访问呢
    感谢解答

问题二已解决,多个证书的情况下,实现方法是在 listener.ssl.external.cacertfile 所配置的 ca 文件中同时保存多个ca证书文件,目前已尝试 pem 格式的ca文件可行,暂未尝试其他格式。
有相同需求的可做参考。

找到了一种方案来实现多个客户端是用不同认证方式,有类似需求的可以参考。

  1. emq_auth_mysql 的认证和ACL控制插件保持不变。
  2. 打开 emq_auth_http 认证插件,在自己的服务中写一个接口,供插件调用,只需要认证的接口,acl和超级用户不用配置

原理如下:

  1. emqx的认证和acl是链式的,所有启用的认证插件和acl控制插件会链式的调用,直到产生通过或不通过的结果。
  2. 需要通过用户名/密码认证的客户端,认证信息保存在mysql中,且不存储需要证书认证的客户端认证信息
  3. 当需要通过证书认证的客户端建立连接时,会依次通过mysql和http认证插件进行认证(顺序不清楚,但不影响),mysql插件因为库中没有查询到认证信息,会忽略,进入下一个认证插件,即http插件,此时插件会调用你提供的接口,只要在这个接口中返回认证通过,或认证失败,或忽略即可,若忽略,最后则根据配置文件中的配置判断是否允许连接。

我这边最终完整的效果大概是:

  1. ssl端口配置证书文件,包括服务端证书和ca证书,其中ca证书用pem格式,内容可包含若干个客户端使用的ca证书。
  2. 客户端通过1883端口连接时,使用用户名/密码连接,进行认证,通过mysql插件认证(实际也会调用http插件认证,只要提供的接口此时返回忽略即可),通过mysql插件判断acl信息。
  3. 客户端通过8883端口连接时,使用用户名,ca证书,客户端证书和客户端密钥,连接时会先进行emqx的证书验证,证书验证通过后,才会调用http插件认证,此时调用我提供的接口,我自行通过用户名和连接的证书信息,判断是否通过认证(实际此时也会调用mysql认证,但没查询到信息会忽略)。
  4. 8883端口ca证书连接若认证通过,则会判断acl信息,此时因为http插件没有配置acl的接口,所以只会执行mysql插件的acl控制,与之前逻辑一致即可。
1 个赞