使用SSL的Erlang:inets httpd

wi3ka0sx  于 2022-12-08  发布在  Erlang
关注(0)|答案(2)|浏览(190)

这是愚蠢的荒谬,这是多么困难的设置。我已经尝试了3天了。梳理互联网和这个网站的帮助,但没有任何工作。
我想要的概念很简单。我想要一个带有ssl的inets httpd服务器。让服务器启动和运行是没有问题的...反正不是ssl。当ssl被添加进去的时候,它就不工作了。
不要问是什么错误,有很多错误,它们会根据我对配置所做的更改而改变。主要是浏览器错误,说证书没有给予做这个或那个的权限,或者如果做了更改,一系列错误和进程在erlang shell中崩溃。
我只是想知道1)我需要什么ssl证书,2)它们需要什么格式,3)在httpd服务器端,我需要什么ssl配置选项。
没有类似Apache的配置或配置文件。我想要的配置选项,这样做的编程。
如果有人能帮上忙,我洗耳恭听。

8xiog9wr

8xiog9wr1#

Using Erlang R16B03 the following setup works for me:

-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.

The cert (server.crt) and key (server.key) files can be generated with:

$ 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

Taken from https://devcenter.heroku.com/articles/ssl-certificate-self
Assuming a index.html file exists in document_root the url https://localhost:22443/index.html should be accessible.

ubby3x7f

ubby3x7f2#

This worked for me using linux OTP release 22 and windows OTP release 23:
https://127.0.0.1:9999/db/api:get
Of course my cert was not signed (had to add an exception for that in Firefox) and in windows it seems that my connection was just reset.
However curl worked for both cases and it managed to establish a connection

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.

It worked after I used 127.0.0.1 instead of localhost and added the modules part:

{modules,[mod_esi,ssl,crypto]}

After that I got some TLS notice reports from the server and the reason it doesn't seem to work in Windows is that:

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

My small code just increments a counter.

EDIT:

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

Will make it possible to do get commands through the webbrowser, seems it defaults to an old tls version.

相关问题