1

I have a yaws webserver. I'm trying to connect via https in local network. When I setup my server in yaws.conf for http, as follows, all works fine when I connect via http://0.0.0.0:80/myappmod in browser

<server *:80>
    port = 80
    listen = 0.0.0.0
    docroot = /home/anyuser/anydir/
    auth_log = true
    appmods = </, myappmod>
</server>

But the following config (with ssl) does not: (I connect via https://0.0.0.0:443/myappmod)

<server mydomain.com>
    port = 443
    docroot = /home/anyuser/anydir/
    listen = 0.0.0.0
    dir_listings = true
    auth_log = true
    appmods = </, myappmod> 
    <ssl>  
        keyfile = /home/anyuser/private-key.pem
        certfile = /home/anyuser/cert_by_ca.pem
        depth = 0
    </ssl>
</server>

The certificate is officially issued by certificate authority and generally works for other webservers under "mydomain.com". private-key format is this

-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC7WBJR0YV9bq4P
...
CAy+LaJpyW/b2vQ+He7t/rg=
-----END PRIVATE KEY-----

And .crt file is of this format:

-----BEGIN CERTIFICATE-----
MIIGgjCCBWqgAwIBAgIIZiCEI/Q/x7gwDQYJKoZIhvcNAQELBQAwgbQxCzAJBgNV
...
1CtNn+5v4lBpgzWS0ZSv5xkeskHjzXnRbjl7jzbkwUdseCZHwXc=
-----END CERTIFICATE-----

When I'm trying to connect, I get ERR_CONNECTION_RESET in Chrome and PR_END_OF_FILE_ERROR in firefox. What am I doing wrong? I can't find any more infos on the config in the official yaws docs. Can someone help please?

EDIT:

trace.log output from curl -v -k --trace-ascii trace.log https://0.0.0.0:443/:

== Info:   Trying 0.0.0.0:443...
== Info: Connected to 0.0.0.0 (127.0.0.1) port 443 (#0)
== Info: ALPN, offering h2
== Info: ALPN, offering http/1.1
== Info: TLSv1.0 (OUT), TLS header, Certificate Status (22):
=> Send SSL data, 5 bytes (0x5)
0000: .....
== Info: TLSv1.3 (OUT), TLS handshake, Client hello (1):
=> Send SSL data, 512 bytes (0x200)
0000: .......w.`0V;k.z;7...}1..Y..5.;..WjO.. .4.,30.....L.......3.../.
0040: ..Y.....>.......,.0.........+./...$.(.k.#.'.g.....9.....3.....=.
0080: <.5./.....u..................................3t.........h2.http/
00c0: 1.1.........1.....*.(.........................................+.
0100: .......-.....3.&.$... ....d>..xlz#..H.V...|.R.s.k.t..r..........
0140: ................................................................
0180: ................................................................
01c0: ................................................................
== Info: OpenSSL SSL_connect: Die Verbindung wurde vom Kommunikationspartner zurückgesetzt in connection to 0.0.0.0:443 
== Info: Closing connection 0
== Info: TLSv1.3 (OUT), TLS alert, decode error (562):
=> Send SSL data, 2 bytes (0x2)
0000: .2

EDIT2: Die Verbindung wurde vom Kommunikationspartner zurückgesetzt means: The connection was reset by the communication partner in English.

Is the decode error (562) due to invalid cert-file encoding? I must admid, that I got 2 files from godaddy.com: One .pem and one .crt file. Their contents looked identically to me. Content is as posted above.(I used the .pem file in yaws.conf). The key-file I am using is the output I copied from the cert sign request on godaddy.com. (Just copied it from their Web-TextBox and pasted it into a .txt file on ubuntu).

EDIT3:

openssl s_client -connect mydomain.com:443 (dns works for http//mydomain.de:80) gives me:

CONNECTED(00000003)
write:errno=104
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 310 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---

EDIT4:

So I produced some more output. First I verified, that my certificate is ok. Therefore I made an openssl-client and server the following way:

openssl s_server -accept 8443 -cert /etc/mydomain.pem -key /etc/mydomain.key -CAfile /etc/gd_bundle-g2-g1.crt

openssl s_client -connect localhost:8443 -cert /etc/mydomain.pem -key /etc/mydomain.key -CAfile /etc/gd_bundle-g2-g1.crt -verify 8 -verify_hostname mydomain.de

Which results in a successful handshake:

... Certificate and other data I do not want to post and:

SSL handshake has read 5658 bytes and written 373 bytes
Verification: OK
Verified peername: mydomain.de

... more data

Then I setup one http and one http server using the following config file. I further assured .pem and .key file can be accessible by yaws with chmod +777 (I know this is bad but I just wanted to be sure). Then I started the yaws server (with root priviliges, which I know is evil too, but until I figured out how to bind to priviliged ports as non-root, I go with that just for testing)

logdir = /var/log/yaws
ebin_dir = /usr/local/lib/yaws-appmods/ebin
include_dir = /usr/local/lib/yaws-appmods/include
max_connections = nolimit
keepalive_maxuses = nolimit
process_options = "[]"
acceptor_pool_size = 8
trace = false
use_old_ssl = false
copy_error_log = true
log_wrap_size = 0
log_resolve_hostname = false
fail_on_bind_err = true
pick_first_virthost_on_nomatch = false
keepalive_timeout = 30000
sni = enable

<server mydomain.de>
    port = 80
    listen = 192.168.178.75
    docroot = /home/my_non_root_user/my_appmod/
    auth_log = true
    appmods = </, my_appmod>
</server>


<server mydomain.de>
    port = 443
    docroot = /home/my_non_root_user/my_appmod/
    listen = 192.168.178.75
    dir_listings = true
    auth_log = true
    appmods = </, my_appmod>    
    <ssl>  
        keyfile = /etc/mydomain.key
        certfile = /etc/mydomain.pem
        depth = 0
    </ssl>
</server>

I also tried providing the ca-bundle, setting higher depths, and played with some other parameters, but all to no success. I got the same error as described above. In the following yaws output, one only can see that http is working. When I try to connect via https, there is no output produced. No worker, etc. I am very new to yaws and webservers in general. I like erlang very much, and just wanted to have a small webserver for my own. No production ready, sophisticated solution. I guess I did something wrong in my config file or have just incomplete knowledge about the whole webserver concept.

1> =INFO REPORT==== 30-Jan-2022::21:16:55.826108 ===
Yaws: Using config file /etc/yaws/yaws.conf

=ERROR REPORT==== 30-Jan-2022::21:16:55.839289 ===
use_old_ssl in yaws.conf is no longer supported - ignoring

=INFO REPORT==== 30-Jan-2022::21:16:55.904479 ===
yaws debug:Add path "/usr/local/lib/yaws-appmods/ebin"

=INFO REPORT==== 30-Jan-2022::21:16:55.906202 ===
yaws debug:Add path "/usr/lib/yaws/examples/ebin"

=INFO REPORT==== 30-Jan-2022::21:16:55.906272 ===
yaws debug:Running with id="default" 
Running with debug checks turned on (slower server) 
Logging to directory "/var/log/yaws"

=INFO REPORT==== 30-Jan-2022::21:16:55.911016 ===
Ctlfile : /root/.yaws/yaws/default/CTL

=INFO REPORT==== 30-Jan-2022::21:16:55.911698 ===
sync call startup:start 

ENSURE SSL: {ok,[]}

=INFO REPORT==== 30-Jan-2022::21:16:56.045817 ===
Trace directory "/var/log/yaws/trace_20220130_211656" created

=INFO REPORT==== 30-Jan-2022::21:16:56.055200 ===
Yaws: Listening to 192.168.178.75:443 for <1> virtual servers:
 - https://mydomain.de under /home/my_non_root_user/my_appmod

=INFO REPORT==== 30-Jan-2022::21:16:56.055388 ===
Yaws: Listening to 192.168.178.75:80 for <1> virtual servers:
 - http://mydomain.de under /home/my_non_root_user/my_appmod

Worker: <0.194.0> 
[2022-01-30 21:17:15.987] ===== CLI -> SRV =====
New (nossl) connection from 80.*.*.*:57260                // * are manually hidden numbers for stackoverflow post

Worker: <0.200.0> 
[2022-01-30 21:17:15.987] ===== CLI -> SRV =====
New (nossl) connection from 80.*.*.*:57262                // here too

Worker: <0.200.0> 
[2022-01-30 21:17:15.994] ===== CLI -> SRV =====
GET / HTTP/1.1
Connection: keep-alive
Accept: text/html, application/xhtml+xml, application/xml;q=0.9, image/avif, image/webp, image/apng, */*;q=0.8, application/signed-exchange;v=b3;q=0.9
Host: mydomain.de
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36
Cookie: pvisitor=cc2529f0-abf8-4e78-80d2-85908b25f227
Accept-Language: en-US,en;q=0.9,de-DE;q=0.8,de;q=0.7
Accept-Encoding: gzip, deflate
Upgrade-Insecure-Requests: 1


Worker: <0.200.0> 
[2022-01-30 21:17:15.996] ===== SRV -> CLI =====
HTTP/1.1 200 OK
Server: Yaws 2.1.0
Date: Sun, 30 Jan 2022 20:17:15 GMT
Content-Length: 46
Content-Type: text/html


Worker: <0.200.0> 
[2022-01-30 21:17:16.203] ===== CLI -> SRV =====
Connection: keep-alive
Accept: image/avif, image/webp, image/apng, image/svg+xml, image/*, */*;q=0.8
Host: mydomain.de
Referer: http://mydomain.de/
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36
Cookie: pvisitor=cc2529f0-abf8-4e78-80d2-85908b25f227
Accept-Language: en-US,en;q=0.9,de-DE;q=0.8,de;q=0.7
Accept-Encoding: gzip, deflate


Worker: <0.200.0> 
[2022-01-30 21:17:16.203] ===== SRV -> CLI =====
HTTP/1.1 405 Method Not Allowed
Server: Yaws 2.1.0
Date: Sun, 30 Jan 2022 20:17:16 GMT
Content-Length: 0
Content-Type: text/html
  • 1
    Perhaps running `curl -v -k --trace-ascii trace.log https://0.0.0.0:443/` and then checking `trace.log` will help identify what's going wrong. You can also run Yaws interactively from a shell command line via `yaws -i --tracetraf --tracehttp --traceout` and it will emit trace info to stdout that might also help. – Steve Vinoski Jan 28 '22 at 11:45
  • @SteveVinoski: Thank you very much for your help! I posted the output of trace.log as edit to the above question, together with a guess of mine about the ocurring `decode error (562)`. I googled it but I'm not wiser now though :/ – Sebastian Hölzl Jan 28 '22 at 13:31
  • 1
    What version of Yaws are you using, and what version of Erlang/OTP? Also, are you seeing any errors or crashes logged by Yaws? – Steve Vinoski Jan 28 '22 at 14:53
  • @SteveVinoski: `erlang:system_info(otp_release). = "24"` with `Yaws 2.1.0`. There is no error output from `yaws -i --tracetraf --tracehttp --traout` stdoutput is all okay. Just the normal Reports. When I do https request acutally nothing happens in yaws. No output. Yaws reports `=INFO REPORT==== 28-Jan-2022::18:33:20.991754 === Trace directory "/var/log/yaws/trace_20220128_183320" created` but the directory has only empty file of pattern: `'trace.\<0.*.0\.http'`in it. – Sebastian Hölzl Jan 28 '22 at 17:41
  • @SteveVinoski: Does this output of `openssl s_client -connect mydomain.com:443` (EDIT3 above) help? There seems to be no cert at all. – Sebastian Hölzl Jan 28 '22 at 18:53
  • 1
    I set up Yaws with a sample configuration with trace enabled as I specified earlier, then ran `openssl s_client -connect localhost:8443` against it and it showed correct certificate details. Yaws trace output showed `Worker` messages for new SSL connections and the closing of those connections. Do you see similar `Worker` trace messages? Does your `yaws.conf` file specify a setting for `pick_first_virthost_on_nomatch` ? If not, please try setting `pick_first_virthost_on_nomatch = false` in the global section, not in a server block. – Steve Vinoski Jan 29 '22 at 14:24
  • @SteveVinoski: I provided some more information (EDIT4 forward). I hope this helps understanding my problem a litte bit better. And thanks a lot for your patience btw – Sebastian Hölzl Jan 30 '22 at 20:55
  • 1
    Interesting that you're getting a 405 status code. What does your appmod do? Can you either try running without an appmod, or try replacing your appmod with a really simple one that just returns `{status, 200}`? Also feel free to email me if it would be faster than going through these comments. – Steve Vinoski Jan 30 '22 at 22:36
  • @SteveVinoski: I think the 405 is due to the favicon.ico request made by chrome which I do not handle right at the moment. I wrote you an email to your IEEE adress. Hope this is the correct one – Sebastian Hölzl Jan 31 '22 at 18:01

1 Answers1

1

In your yaws.conf file, your keyfile parameter in the <ssl> block refers to a file with a .key suffix. According to the Erlang ssl module man page, that file should instead be in PEM format (i.e., a .pem file).

  • The ssl man page says if you leave out the keyfile parameter, it defaults to the same as certfile, so you could try dropping keyfile from your yaws.conf file to see if that helps.
  • If that doesn't work, you likely need to convert the .key file to a .pem file; this answer describes how to do it.
Steve Vinoski
  • 19,847
  • 3
  • 31
  • 46
  • Thank you very much. I can accept your answer put I do not have enough reputation to give it an upvote. Hope someone else does it for me. – Sebastian Hölzl Feb 01 '22 at 18:24