【问题标题】:Connection closed - strange error, unable to connect from erlang VM to certain host连接关闭 - 奇怪的错误,无法从 erlang VM 连接到某些主机
【发布时间】:2016-12-01 21:16:14
【问题描述】:

重要提示已证明从 18.3 迁移到 18.3.4 会导致此问题,迁移回 18.3 可消除此问题。

一切都起作用了,直到某一刻。然后它就停止工作了。

  def work do
    HTTPotion.get("https://ssl-third-party.com",
    ibrowse: [
      is_ssl: true,
      ssl_options: [
        certfile: Path.join(File.cwd!, "cert_dev.pem"),
        password: "pass" |> to_charlist,
      ]
      ])
  end

回应:

%HTTPotion.ErrorResponse{message: "closed"}

我从 iex shell 尝试了几个没有 elixir 包装的 erlang 库(hackney + ibrowse):

iex(5)> url = <<"https://ssl-third-party.com">>
iex(6)> headers = []
[]
iex(8)> payload = <<>>
""
iex(9)> options=[:insecure]
[:insecure]
iex(10)> :hackney.request(m, url, headers, payload, options)
{:error, :closed}
###
iex(1)> a = "https://ssl-third-party.com" |> to_char_list
iex(2)> :ibrowse.send_req(a, [], :get)
{:error, {:conn_failed, {:error, :closed}}}

虽然我可以连接到其他主机。

应用程序已启动,我可以从同一个会话中发出请求。

连接适用于简单的 curl 请求。

Erlang 测试 - 18.3.4/19.0.2

OS X El Capitan。

UPD1 我在重新安装所有与 erlang 相关的软件包时也注意到了这个报告:

20:25:01.535 [error] Failed updating session: 
   ProfileName: :httpc_mix
   SessionId:   {{'repo.hex.pm', 443}, #PID<0.163.0>}
   Pos:         7
   Value:       0
when
   Session (db) info: :undefined
   Session (db):      {:session, {{'repo.hex.pm', 443}, #PID<0.163.0>}, false, :https,
 {:sslsocket, {:gen_tcp, #Port<0.5536>, :tls_connection, :undefined},
  #PID<0.164.0>}, {:essl, []}, 1, :keep_alive, true}
   Session (record):  {:EXIT,
 {:badarg,
  [{:ets, :lookup,
    [:httpc_mix__session_db, {{'repo.hex.pm', 443}, #PID<0.163.0>}], []},
   {:httpc_manager, :lookup_session, 2, [file: 'httpc_manager.erl', line: 189]},
   {:httpc_handler, :update_session, 4,
    [file: 'httpc_handler.erl', line: 1909]},
   {:httpc_handler, :handle_empty_queue, 4,
    [file: 'httpc_handler.erl', line: 1368]},
   {:httpc_handler, :handle_info, 2, [file: 'httpc_handler.erl', line: 471]},
   {:gen_server, :try_dispatch, 4, [file: 'gen_server.erl', line: 601]},
   {:gen_server, :handle_msg, 5, [file: 'gen_server.erl', line: 667]},
   {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 247]}]}}
   T: :error
   E: :badarg

20:25:01.536 [error] Failed updating session: 
   ProfileName: :httpc_mix
   SessionId:   {{'repo.hex.pm', 443}, #PID<0.163.0>}
   Pos:         9
   Value:       true
when
   Session (db) info: :undefined
   Session (db):      {:session, {{'repo.hex.pm', 443}, #PID<0.163.0>}, false, :https,
 {:sslsocket, {:gen_tcp, #Port<0.5536>, :tls_connection, :undefined},
  #PID<0.164.0>}, {:essl, []}, 1, :keep_alive, false}
   Session (record):  {:EXIT,
 {:badarg,
  [{:ets, :lookup,
    [:httpc_mix__session_db, {{'repo.hex.pm', 443}, #PID<0.163.0>}], []},
   {:httpc_manager, :lookup_session, 2, [file: 'httpc_manager.erl', line: 189]},
   {:httpc_handler, :update_session, 4,
    [file: 'httpc_handler.erl', line: 1909]},
   {:httpc_handler, :maybe_make_session_available, 2,
    [file: 'httpc_handler.erl', line: 1516]},
   {:httpc_handler, :answer_request, 3,
    [file: 'httpc_handler.erl', line: 1507]},
   {:httpc_handler, :terminate, 2, [file: 'httpc_handler.erl', line: 759]},
   {:gen_server, :try_terminate, 3, [file: 'gen_server.erl', line: 629]},
   {:gen_server, :terminate, 7, [file: 'gen_server.erl', line: 795]}]}}
   T: :error
   E: :badarg

20:25:01.541 [error] GenServer #PID<0.163.0> terminating
** (stop) {:failed_updating_session, [profile: :httpc_mix, session_id: {{'repo.hex.pm', 443}, #PID<0.163.0>}, pos: 9, value: true, etype: :error, error: :badarg, stacktrace: [{:ets, :update_element, [:httpc_mix__session_db, {{'repo.hex.pm', 443}, #PID<0.163.0>}, {9, true}], []}, {:httpc_manager, :update_session, 4, [file: 'httpc_manager.erl', line: 210]}, {:httpc_handler, :update_session, 4, [file: 'httpc_handler.erl', line: 1887]}, {:httpc_handler, :maybe_make_session_available, 2, [file: 'httpc_handler.erl', line: 1516]}, {:httpc_handler, :answer_request, 3, [file: 'httpc_handler.erl', line: 1507]}, {:httpc_handler, :terminate, 2, [file: 'httpc_handler.erl', line: 759]}, {:gen_server, :try_terminate, 3, [file: 'gen_server.erl', line: 629]}, {:gen_server, :terminate, 7, [file: 'gen_server.erl', line: 795]}]]}
    (inets) httpc_handler.erl:1911: :httpc_handler.update_session/4
    (inets) httpc_handler.erl:1516: :httpc_handler.maybe_make_session_available/2
    (inets) httpc_handler.erl:1507: :httpc_handler.answer_request/3
    (inets) httpc_handler.erl:759: :httpc_handler.terminate/2
    (stdlib) gen_server.erl:629: :gen_server.try_terminate/3
    (stdlib) gen_server.erl:795: :gen_server.terminate/7
    (stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3
Last message: {:ssl, {:sslsocket, {:gen_tcp, #Port<0.5536>, :tls_connection, :undefined}, #PID<0.164.0>}, "HTTP/1.1 200 OK\r\nx-amz-id-2: FGpS/bqXLPTNYV4oMTTIvqekRgbExlvO83ZoTR6deiB02Hsm4uqtctPYvP5lqryk/ZYK12/DCuM=\r\nx-amz-request-id: 346087C27C829E83\r\nx-amz-replication-status: COMPLETED\r\nCache-Control: public, max-age=604800\r\nx-amz-meta-surrogate-key: installs\r\nx-amz-version-id: IzHO194FIe8NSS4oev.5dtp2BgBltonw\r\nLast-Modified: Wed, 29 Jun 2016 00:00:27 GMT\r\nETag: \"e8a325a6ca33736d137e5b6f57fe4259\"\r\nContent-Type: binary/octet-stream\r\nServer: AmazonS3\r\nVia: 1.1 varnish\r\nFastly-Debug-Digest: 864530c58fa2f5e6f7b455ba1b8a8fd668c94f688c98b6cdc85319515ff6f6b1\r\nContent-Length: 350\r\nAccept-Ranges: bytes\r\nDate: Fri, 29 Jul 2016 17:25:01 GMT\r\nVia: 1.1 varnish\r\nAge: 235183\r\nConnection: keep-alive\r\nX-Served-By: cache-iad2144-IAD, cache-bma7023-BMA\r\nX-Cache: HIT, HIT\r\nX-Cache-Hits: 1, 1\r\nX-Timer: S1469813101.087231,VS0,VE0\r\n\r\njM3an/yCuclmNcCX0wzS9QhCHsJl+Xf6/FS5bAaQ5O9AAFMlkCnJt4vW08LNU6eL\nkfOsK+mVZ1n8Dk/+I8ThzpO1NZlH3UNYt/8OgK+ZfhFlrT0D1UZ/QEIR1/8TIC4v\nC25ibCcvxTK9zG93mAdrLLCLA6/o4NXeaMV6DOOZ31ZcMWjpCNjDLU1B20UsVSBN\nKzsLkI4QfgrtSt5Iquhs0wovJlpz/lZh7jEf58BTMWa/Z9Yl2EmEVsyO8Fie5RiF\np+KTkDILxY/QkKwSPE+0AcS5BR3dpJSsp8m5RVLUb/44b0KUKko+uPBmN8g6TSYP\nGSIG5Ay9BjXE0uAi2RTFEw==\n"}
State: {:state, {:request, #Reference<0.0.3.498>, #PID<0.70.0>, 0, :https, {'repo.hex.pm', 443}, '/installs/rebar3-1.x.csv.signed', [], :get, {:http_request_h, :undefined, 'keep-alive', :undefined, :undefined, :undefined, :undefined, :undefined, :undefined, :undefined, :undefined, :undefined, :undefined, :undefined, :undefined, :undefined, :undefined, 'repo.hex.pm', :undefined, :undefined, :undefined, :undefined, :undefined, :undefined, :undefined, :undefined, :undefined, [], 'Mix/1.3.2', :undefined, :undefined, :undefined, '0', :undefined, :undefined, :undefined, :undefined, :undefined, ...}, {[], []}, {:http_options, 'HTTP/1.1', :infinity, true, {:essl, []}, :undefined, true, :infinity, false}, 'https://repo.hex.pm/installs/rebar3-1.x.csv.signed', [], :none, [], 1469813101026, :undefined, :undefined, false}, {:session, {{'repo.hex.pm', 443}, #PID<0.163.0>}, false, :https, {:sslsocket, {:gen_tcp, #Port<0.5536>, :tls_connection, :undefined}, #PID<0.164.0>}, {:essl, []}, 1, :keep_alive, false}, :undefined, :undefined, :undefined, {:httpc_response, :parse, [:nolimit, true]}, {[], []}, {[], []}, :new, [], :nolimit, :nolimit, {:options, {:undefined, []}, {:undefined, []}, 0, 2, 5, 120000, 2, :disabled, false, :inet, :default, :default, []}, {:timers, [], :undefined}, :httpc_mix, :inactive}

UPD2

可能必须是 OSX 或 >18.3 OTP 错误:刚刚在另一台 ubuntu 计算机 Erlang 版本 18.3 上制作它,它工作正常,这个返回(Erlang shell):

httpc:request(get, {"https://ssl-third-party.com", []}, [], []).
{error,{failed_connect,[{to_address,{"https://ssl-third-party.com",
                                     443}},
                        {inet,[inet],closed}]}}

【问题讨论】:

  • 你能用curl做同样的事情吗?好像连接被关闭了,可能是服务器宕机了?
  • @PawełObrok,是的,它适用于 curl。它工作正常,直到我的系统中的某个点,然后突然停止
  • 18.3.4 测试过了,18.3.4.2 没有测试?这两者之间有一些与 SSL 相关的更改:“SSL 服务器的 TLS/SSL 协议版本选择已更正以遵循 RFC 5246 附录 E.1,尤其是在支持的版本列表存在差距的情况下。现在服务器选择它支持的最高协议版本不高于客户端支持的版本。”

标签: erlang elixir


【解决方案1】:

听起来您最近遇到了this erlang-questions 邮件线程中讨论的相同问题。 显然,SSL 应用程序在 18.3 补丁版本之间更改了密码套件配置,这可能导致此问题。

在我引用的邮件线程中,解决方案是将 SSL 配置为使用 TLS 1.2,即设置

{versions, ['tlsv1.2']}

用于 SSL 应用程序。

【讨论】:

  • 这对我不起作用...引发错误选项的错误。
  • {{{:badmatch, %HTTPotion.ErrorResponse{message: "{:options, {'tlsv1.2', {:versions, ['tlsv1.2']}}}"}} 如果有人帮我解决这个不受欢迎的答案
  • 在 Erlang 中使用 ibrowse 对我有用:ibrowse:send_req("https://aws.amazon.com", [], get, [], [{is_ssl, true}, {ssl_options, [{versions, ['tlsv1.2']}]}]). 注意ssl_options 键。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-25
  • 2014-12-15
  • 2021-09-22
  • 2021-03-20
  • 1970-01-01
  • 1970-01-01
  • 2014-01-16
相关资源
最近更新 更多