2

设置起来有多么困难,真是太荒谬了。我已经尝试了3天了。梳理互联网和这个网站寻求帮助,但没有任何效果。

我想要的在概念上很简单。我想要一个带有 ssl 的 inets httpd 服务器。让服务器启动并运行没有问题......无论如何都不是ssl。当添加 ssl 时,它就不起作用了。

不要问什么错误,有多个错误,它们会根据我对配置所做的更改而变化。主要是浏览器错误说证书没有授予执行此或那个的权限,或者如果进行了更改,则在 erlang shell 中出现了一堆错误和进程崩溃。

我只是想知道 1)我需要什么 ssl 证书,2)它们需要采用什么格式,以及 3)在 httpd 服务器端,我需要哪些 ssl 配置选项。

没有类似 Apache 的配置或配置文件。我想要以编程方式执行此操作的配置选项。

如果有人可以提供帮助,我会全力以赴。

4

2 回答 2

3

使用 Erlang R16B03,以下设置适用于我:

-module(inets_ssl).

-export([start/0]).

start() ->
  inets:start(),
  {ok, Pid} = inets:start(httpd, [
                                  {port, 22443},
                                  {server_name,"localhost"},
                                  {server_root,"./"},
                                  {document_root,"./"},
                                  {bind_address, any},
                                  {socket_type, {ssl, [{certfile, "./server.crt"}, 
                                                {keyfile, "./server.key"}]}},
                                  {mimetypes, [
                                               {"html", "text/html"}
                                              ]}
                                 ]),
  Pid.

( certserver.crt) 和key(server.key) 文件可以通过以下方式生成:

$ openssl genrsa -des3 -passout pass:x -out server.pass.key 2048
$ openssl rsa -passin pass:x -in server.pass.key -out server.key
$ openssl req -new -key server.key -out server.csr
$ openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

取自https://devcenter.heroku.com/articles/ssl-certificate-self

假设urlindex.html中存在文件应该是可访问的。document_roothttps://localhost:22443/index.html

于 2014-03-28T20:02:45.373 回答
0

这对我使用 linux OTP 版本 22 和 Windows OTP 版本 23 有效:

https://127.0.0.1:9999/db/api:get

当然,我的证书没有签名(必须在 Firefox 中添加一个例外),在 Windows 中,我的连接似乎刚刚被重置。

然而 curl 对这两种情况都有效,它设法建立了连接

curl -v -k https://127.0.0.1:9999/db/api:get

-module(api).
-export([start/0, get/3, main_handler/1]).

start() -> 
    try 
        inets:start(),
        ssl:start()
    catch 
        _ -> erlang:exit("Failed to start inets")
    end,

    case lists:member(main_handler_pid, registered()) of
        false -> 
            MainPid = spawn_link(api, main_handler, [0]),
            register(main_handler_pid, MainPid);
        _ -> ok
    end,
    try start_api_response() of 
        {State,Pid} -> erlang:display({State,Pid}),
        case State of 
        ok ->
            ok;
        _ -> 
            erlang:display(State)
        end
    catch 
         _:_ -> {"Error starting server"}
    end.


start_api_response() ->
    {State,Pid} = inets:start(httpd, [{port, 9999}, 
        {server_name, "localhost"}, 
        {socket_type, {ssl,[{certfile, "./cert.pem"}, {keyfile, "./key.pem"}]}},
        {document_root, "./"}, 
        {modules,[mod_esi,ssl,crypto]},
        {server_root, "./"}, 
        {bind_address, any},
         {mimetypes, [
                                               {"html", "text/html"}
                                              ]},
        {erl_script_alias, {"/db", [api,io]}}]),
    {State,Pid}.


main_handler(N) ->
    receive
        Pid -> 
            erlang:display("ping main: " ++ integer_to_list(N)),
            Pid ! N
    end,
    main_handler(N+1).

get(Sid, _Env, Input) ->
    main_handler_pid ! self(),
    erlang:display(Input),
    receive
        N -> 
            mod_esi:deliver(Sid, integer_to_list(N))
    end.

在我使用 127.0.0.1 而不是 localhost 并添加了模块部分之后,它起作用了:

{modules,[mod_esi,ssl,crypto]}

之后,我从服务器收到了一些 TLS 通知报告,它似乎在 Windows 中不起作用的原因是:

TLS server: In state hello at tls_record.erl:539 generated SERVER ALERT: Fatal - Unexpected Message
 - {unsupported_record_type,71}

我的小代码只是增加一个计数器。

编辑:

ssl:cipher_suites(all,'tlsv1.3).

将使通过网络浏览器获取命令成为可能,似乎它默认为旧的 tls 版本。

于 2021-02-22T13:54:06.953 回答