Why it fails ?
The instructions you apparently followed are partly incorrect.
$ openssl req -new -key server.key -x509 -days 3653 -out server.crt
// enter fields... (may all be empty when cert is only used privately)
The fields that
req -new -x509 prompts for (at least with the 'standard' upstream config file) are used as the subject name in the created certificate (or the CSR without
-x509). (For a selfsigned cert the issuer name is the same as the subject name so the same data also appears there.)
For HTTPS server, to establish that a connection reached the valid server and not an impostor, the server's cert must be valid per rfc5280 (signed by a trusted CA etc) AND the cert must be issued to the server named in the URL: either the Common Name field in the subject name in the cert must match the desired server, or the Subject Alternative Name extension (commonly abbreviated SAN and also called UCC by Microsoft or people influenced by Microsoft) must be present and contain an entry that does so. See rfc2818. That's why OpenSSL prompts for this field as:
Common Name (e.g. server FQDN or YOUR name) :
because mostly people use URLs that identify the server by FQDN, although there are exceptions. So you need to answer that prompt with
localhost. Officially SAN is preferred, and implemented by all 'real' CAs (
Verisign Symantec Digicert, GoDaddy, etc) since about 2000, but doing SAN with OpenSSL is a little bit more work. There are many Qs already on Stack about SAN in OpenSSL; if you need and can't find them I'll dig some up from my notes. An exception is if you want to use Chrome/chromium: as of a few months ago it requires the cert have SAN (with the correct server name) and no longer accepts subject.CN. There are also Qs on this; ditto.
Note SSL/TLS based protocols other than HTTPS may differ, and an empty subject name may indeed be okay, e.g. FTPS SNMPS LDAPS.
Why do we need to transfer the client certificate to the server ? This does not happen while I browse the net, or does it ?
Do you really mean the net, or the web? Although the SSL/TLS protocol supports client authentication via client certificate, very few web servers on the secure (HTTPS) part of the web use this. Most web servers that need to authenticate their clients use HTTP-level methods -- as for example the options offered by Stack. This allows them to control the UI and make it consistent across all browsers, and provide instructions and help and support accordingly, while the UI for client certs is implemented by each browser or platform differently, and often requires some technical skill or at least intelligence and patience to use correctly, which most websites assume most users can't or at least won't do.
The few web servers that
do use client cert generally require certs issued by a public CA and/or a trusted third-party (such as a government, or bank), or sometimes a CA run or controlled by the server itself. Using selfsigned client certs would indeed require users to provide their certs in advance -- and that provision process would have to be very secure, because anyone who could get a bogus cert accepted once would then be able to make fraudulent connections for years.
OTOH when you 'own' both ends, the server admin has an easy job identifying and trusting the client admin, and vice versa. AIUI OpenVPN key exchange uses this (SSL/TLS with selfsigned or maybe adhoc-CA certs).
Bonus answer: the above change should make the TLS layer of the connection work, but your setup still won't work as an HTTPS server, because the output of
uptime is not a valid HTTP response. You need something that generates HTTP headers and content, in roughly the same way CGI 'pages' do under a real web server (for either HTTP or HTTPS).