You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Elixir与Erlang :ssl模块获取SSL证书时连接报错如何解决

问题原因

你遇到的报错是因为tls_certificate_check.options(host)返回的配置列表中包含了socket_options嵌套字段,而Erlang的:ssl.connect/4的第三个参数仅接受平层的TLS专属配置,不识别嵌套的socket_options这类底层TCP socket配置,因此抛出了选项格式错误。

修复方案

你需要先拆分tls_certificate_check返回的配置,把socket_options下的内容提取到平层,再传入:ssl.connect即可。修正后的代码如下:

defmodule ElixirSslCheck do
  def check do
    host = "www.lawlorbagcal.org"
    all_opts = :tls_certificate_check.options(host)
    # 拆分socket配置和TLS配置
    socket_opts = Keyword.get(all_opts, :socket_options, [])
    tls_opts = Keyword.delete(all_opts, :socket_options)
    # 拼接为平层配置传入连接方法
    :ssl.connect(host, 443, socket_opts ++ tls_opts, 5000)
  end

  # 补充:连接成功后获取证书到期时间的实现
  def get_cert_expiry do
    case check() do
      {:ok, socket} ->
        # 获取对端证书
        {:ok, der_cert} = :ssl.peercert(socket)
        # 解码DER格式证书为OTP结构化数据
        {:OTPCertificate, tbs_cert, _, _} = :public_key.pkix_decode_cert(der_cert, :OTPCertificate)
        # 提取有效期字段
        {:Validity, _not_before, not_after} = elem(tbs_cert, 1) |> elem(4)
        # 转换ASN.1时间格式为可读字符串
        expiry_str = not_after |> elem(1) |> List.to_string()
        :ssl.close(socket)
        {:ok, expiry_str}

      error ->
        error
    end
  end
end

额外调试建议

  • 先确认你的Erlang/OTP版本和tls_certificate_check版本兼容,OTP 25及以上版本建议使用tls_certificate_check 1.20.0以上版本,避免版本不兼容导致的选项错误。
  • 如果连接依然失败,可以临时在tls_opts中添加verify: :verify_none测试网络连通性,确认是否是证书验证逻辑导致的问题,该配置仅用于调试,生产环境必须删除。

内容的提问来源于stack exchange,提问作者wgwz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 21:24:03