openwebwork / webwork2

Course management front end for WeBWorK
http://webwork.maa.org/wiki/Main_Page
Other
141 stars 164 forks source link

Add optional certbot renewal routes. #2321

Closed drgrice1 closed 5 months ago

drgrice1 commented 5 months ago

To enable these routes set enable_certbot_renewal_routes: 1 in conf/webwork2.mojolicious.yml.

Then execute

sudo certbot certonly --webroot -w /opt/webwork/webwork2/tmp \
  -d your.domain.edu \
  --post-hook "chown -R www-data:www-data /etc/letsencrypt && systemctl reload webwork2"

to renew certificates without needing to stop the webwork2 app. That command will renew the certificate for the first time, and also set up autorenewal in the future. Obviously your.domain.edu needs to be changed to your actual domain name. Note that /opt/webwork/webwork2/tmp is the default value of $webworkDirs{tmp}. If you customize $webworkDirs{tmp} in localOverrides.conf, then you will need to use what you have that variable set to instead. Be careful since the default value of $webworkDirs{tmp} depends on the value of $webworkDirs{root} (which is /opt/webwork/webwork2 by default). So if you customize $webworkDirs{root}, then you will need to adjust the path accordingly. Also, change www-data:www-data in the command to be server_user:server_group where server_user and server_group are the values of those settings above. The post hook in the command will run every time that certificates are automatically renewed, and will fix permissions on the new certificates so that the webwork2 app can read them, and will hot reload the webwork2 app to load the new certificates (with zero downtime).

Edit: Note that for this to work http://*:80 needs to be included in the hypnotoad listen list in addition to https://*:443?.... I added a comment about this in webwork2.mojolicious.dist.yml.

sean-fitzpatrick commented 5 months ago

I might be able to test this next week -- we have a break from classes.

It looks like there's a typo in your initial description (but not in the changed file): you have routs instead of routes.

I was about to suggest that documentation changes be included but then remembered that that's the wiki, which is completely separate.

drgrice1 commented 5 months ago

The wiki will need something, but this will go into the release manual on the wiki for the 2.19 release.

sean-fitzpatrick commented 5 months ago

Is a dry run sufficient for testing? I'll be able to test in a week.

I seem to recall that LetsEncrypt doesn't like to see too many certificate requests from the same user in a short period of time.

If someone remembers how to trigger the auto renewal process without waiting 3 months, I could do with a reminder.

drgrice1 commented 5 months ago

A dry run is sufficient to test.

LetsEncrypt does limit the number of certificate requests, but the limit is 50 per week. That is usually sufficient to do some renewal testing without going over. I did several in the process of testing this pull request, but I am not concerned.

With this pull request certificate renewal is automatic. Once you run the given command once, then automatic renewal is set up, and you don't need to do anything after that. When you run that command, certbot will update the file /etc/letsencrypt/renewal/your.domain.edu.conf with the parameters for the command, and will use them to perform the autorenewal. So there is no need for a reminder.

sean-fitzpatrick commented 5 months ago

Ok, that's fantastic.

We've only recently switched to using CertBot. IT policy used to require enterprise certificates from Entrust that they would issue once per year.

But now that some browsers want renewal every 6 months (or even 3!) they've realized that manually issuing and installing certificates for every server on campus is too big of a nuisance...

sean-fitzpatrick commented 5 months ago

I made the two edits in this PR and then ran CertBot with the webroot option, and renewed the certificate successfully.

The dry run failed. But this was due to an oversight on my part: if you were previously using the standalone option, it is now necessary to go back into webwork2.mojolicious.yml, and uncomment the line to have it listen on port 80. (It is then also a good idea to change the redirect_http-to_https value from 0 to 1.

With those changes and a restart of the webwork2 service, the dry run succeeds. As far as I can test, this works as expected.

(The Active Calculus people who are using my server as the backend for their book on Runestone will be pleased to learn that their students will no longer temporarily lose access every 3 months.)

drgrice1 commented 5 months ago

Ahh, I knew that, but I forgot to mention it. I will add a comment in the webwork2.mojolicious.dist.yml file. The redirect_http_to_https is not required for the certificate renewal to work, but probably is a good idea in that case.

drgrice1 commented 5 months ago

I also mention that this new option should only be used when serving directly with hypnotoad (presumably what you meant by the standalone option). This won't work if proxying via apache2 or nginx (and it also isn't needed in that case).