Forum OpenACS Q&A: Trying to get https working with letsencrypt certs...

Hi,

And yes, I did see the letsencrypt module in the naviserv-4.99.17-modules tarball, but I wanted to use certbot to get the initial cert. I got the stack all built with the proper upgrades that I didn't have yet, and put up the instance. Using that, I got a cert from letsencrypt, but I can't use it for one reason or another,, so my first question is,

What parts do the certs consist of, that are needed by nsssl? Also, how do I give it the private key?
nsssl has no special requirements on the certificate. all keys should be provided in PEM format. All documentation of OpenSSL applies.
Collapse
Posted by Jim Lynch on
Hi Gustaf and everyone,

I'm given to understand that web servers need the cert and the private key... do they need the fullchain (combo of chain and cert) or just the cert? Also, I don't see a way to provide the private key, would I have two certificate lines, one for the private key and one for the cert itself? Or, is there a specific attribute name for the private key? Or, would I create a new pem file with openssl, containing the cert and the key? Also, the nsssl documentation shows it needs the component parts of the cert in some sorted order... How can I accomplish that?

-Jim

Collapse
Posted by Jim Lynch on
Also... I'm getting this error after I entered my domain name to letsencrypt.tcl and it tried to reach

can't connect to acme-v01.api.letsencrypt.org port 443: network is unreachable
while executing
"ns_http queue $url"
(procedure ":getAPIurls" line 7)
invoked from within
":getAPIurls $config"
(procedure "getCertificate" line 39)
invoked from within
"$c getCertificate"
("uplevel" body line 756)
invoked from within
"uplevel {
#
# letsencrypt.tcl --
#
# A small Let's Encrypt client for NaviServer implemented in Tcl.
# To use it, set enabled to 1 and drop it..."
(procedure "code::tcl::/web/mu-main//packages/acs-subsite/www/admin/lets..." line 2)
invoked from within
"code::tcl::$__adp_stub"
("uplevel" body line 12)
invoked from within
"uplevel {

if { [file exists $__adp_stub.tcl] } {

# ensure that data source preparation procedure exists and is up-to-date
..."
(procedure "adp_prepare" line 2)
invoked from within
"adp_prepare"
invoked from within
"template::adp_parse $themed_template {}"
(procedure "adp_parse_ad_conn_file" line 14)
invoked from within
"$handler"
("::try" body line 3)
invoked from within
"rp_serve_concrete_file [ad_conn file]"
(procedure "::nsf::procs::rp_serve_abstract_file" line 60)
invoked from within
"rp_serve_abstract_file "$root/$extra_url""
("::try" body line 2)
invoked from within
"ad_try {
rp_serve_abstract_file "$root/$extra_url"
set ::tcl_url2file([ad_conn url]) [ad_conn file]
set ::tcl_url2..."
(procedure "rp_handle_request" line 45)
invoked from within
"rp_handle_request"
("::try" body line 2)
and as you can see, ns_http is having an issue connecting to the letsencrypt server.

Could it be, that for ns_http to be able to connect using https: on port 443, that it needs an additional module or part of one?

-Jim

Collapse
Posted by Jim Lynch on
also, since I was able to ping acme-v01.api.letsencrypt.org from the machine the web server and the letsencrypt.tcl script is running on, the message "network is unreachable" is actually false, so there's a bug in that code, or at least it's throwing one message meaning something else.

-Jim

Collapse
Posted by Jim Lynch on
hi...

and that was the production API of letsencrypt.tcl, so I tried to switch it to the staging api. This time, it tried to reach acme-staging.api.letsencrypt.org and pinging it from that machine is also successful, so again the network is -not- unreachable.

-Jim

This looks indeed strange. Just now, i have refreshed the certificate on openacs.org via letsencrypt,tcl, and everything went as expected (see log below). Maybe, your were unlucky, and the service was down at this time. One can check the availability of the API with https://letsencrypt.status.io/.

Concerning the error message: The only place in NaviServer to return a "can't' connect" error message is the following statement:

        Ns_TclPrintfResult(interp, "can't connect to %s port %hu: %s",
                           host, portNr,
                           (Tcl_GetErrno() != 0) ?  Tcl_PosixError(interp) : "reason unknown");
You see, it gets its error information from Tcl. so far, i had no indication that this is unreliable.

-gn
Output from letsencrypt.tcl:

Obtaining a certificate from Let's Encrypt using the Production API:

Let's Encrypt URLs:

   https://acme-v01.api.letsencrypt.org/acme/key-change
   https://acme-v01.api.letsencrypt.org/acme/new-authz
   https://acme-v01.api.letsencrypt.org/acme/new-cert
   https://acme-v01.api.letsencrypt.org/acme/new-reg
   https://acme-v01.api.letsencrypt.org/acme/revoke-cert

Reuse existing account registration at Let's Encrypt

Authorizing account for domain openacs.org... returned HTTP status 201
... getting HTTP challenge... returned HTTP status 202
... validating the challenge... status: pending
... retry after one second... status: pending
... retry after one second... status: valid

...
Collapse
Posted by Jim Lynch on
Pausing on that for a moment, I have another question, I've been getting permission denied when trying to use various combinations of the cert file...
Full chain then private key, private key then full chain, cert, then chain, then private key, etc etc, and I keep getting permission denied... I'm not sure where that message is coming from, or what function call is throwing that error.

I had a thought: when I start up naviserver, if I want to use port 80 (given it's below port 1024), I have to use -b IP:80... what do I do about port 443 which is -also- below 1024? Another -b? like this: -b IP:80 -b IP:443?

-Jim

When someone starts NaviServer/AOLserver on a privileged port (less than 1024), one has to use the prebind options (see e.g. the systemd example file in [1]).

[1] https://naviserver.sourceforge.io/n/manual/files/admin-maintenance.html

Collapse
Posted by Jim Lynch on
Hi...

OK, I think I finally did it... I saw my site and at the same time the address bar said https:, so I'm pretty sure that's it. Thanks so much for the assistance!

Details:

It was the bind phrase that I had wrong... originally, I had: -b IP:80 -b IP:443, which didn't work. When I changed it to -b IP:80,IP:443 and tried starting it, then it worked.

-Jim, who is now trying to get daemontools working from a systemd unit.

Collapse
Posted by Jim Lynch on
Got https working :)

I had to make sure I started it with a bind phrase that looks like: -b IP:80,IP:443

-Jim