Moodlebox: Support HTTPS

Created on 1 Sep 2017  ·  33Comments  ·  Source: moodlebox/moodlebox

MoodleBox is now http only. Find a way to enable https.

doc needed tests passed enhancement

Most helpful comment

Yes, it works with https! Very nice!

All 33 comments

Bonjour Nicolas,
Je n'ai encore jamais joué à la MoodleBox, et n'ai pas encore configuré mes serveurs Apache pour servir du HTTPS, mais je ne comprends pas où serait la difficulté à installer un serveur et un certificat SSL . La MoodelBox ne tourne-t-elle pas sous une distribution Linux ?
Il semble assez facile à configurer du HTTPS sur une machine Linux, en tout cas sous Debian par exemple, à ce que j'ai pu lire.
Je suis peut-être complètement à côté de la plaque pour ce qui concerne la MoodleBox, et le système d'exploitation installé est peut-être très différent. En tout cas j'ai noté les références suivantes pour conduire ma procédure de mise ne place du HTTPS sur mes installations :
How To Secure Apache with Let's Encrypt on Ubuntu 16.04 | DigitalOcean
Mise en place d’un serveur HTTPS sous Debian

PG

Ce n'est pas une question de difficulté d'installation. Le problème est double :

  1. il est compliqué d'obtenir un certificat quand le serveur n'est atteignable qu'en intranet, car l'instance fournissant le certificat doit vérifier que le serveur est bien légitime, et comme il ne peut pas l'atteindre, la vérification échoue. Ceci pourrait être contourné d'après les liens ci-dessus (c'est ce que je dois tester avant implémentation ;
  2. il faut un nom de domaine root (TLD) public enregistré à l'IANA, et le domaine actuel ".home" ne l'est pas. Donc potentiellement, il faudra changer l'URL standard par lequel on accède à la MoodleBox, ce qui est ennuyeux.

Bonjour Nicolas,

Merci pour ta réponse. Ce sont là deux points dont j'avais eu effectivement l'intuition. Cependant, en vadrouillant un peu pour en connaître davantage sur les certificats SSL et HTTPS, j'ai plutôt fini par penser qu'on trouverait une solution :

  1. Auto-certification en local (je ne doute pas que tu sauras tester avant implémentation)
  2. L'enregistrement à l'ICANN du nom de domaine root ne me semble en fait pas obligatoire...

Il me semble que ta réponse confirme ma vision : rien d'insurmontable pour une personne de ton niveau en informatique !
Le mieux, c'est que c'est peut-être aussi surmontable pour une personne de mon modeste niveau (à plus ou moins long terme) ! J'ai en tout cas l'intention de braver le challenge : réaliser mon propre serveur HTTPS, sans pointage de nom de domaine enregistré (uniquement sur une adresse IP). Je ne manquerai pas de revenir vers toi si je réussis le premier. (attention, cela risque de prendre un peu de temps pour moi... Il ne faut pas m'attendre !)

Nota : je crains cependant que nous garderons toujours des avertissements sur la qualité du certificat auto-attribué. Chaque client devra accepter et enregistrer une clef privée lors de la première connexion.

A bientôt,
PG

je crains cependant que nous garderons toujours des avertissements sur la qualité du certificat auto-attribué. Chaque client devra accepter et enregistrer une clef privée lors de la première connexion.

C'est pour cela que je vais tenter de faire un "vrai" certificat avec Let's encrypt.

As expected, non-public root domain isn't allowed by Letsencrypt.

$ sudo certbot certonly -d moodlebox.home --manual --register-unsafely-without-email --preferred-challenges dns

(several lines omitted)
Obtaining a new certificate
An unexpected error occurred:
The request message was malformed :: Error creating new authz :: Name does not end in a public suffix
Please see the logfiles in /var/log/letsencrypt for more details.

Explanation here: https://www.reddit.com/r/sysadmin/comments/3vyjd9/letsencrypt_non_public_domain/

In case you would get a cert for lets say intranet.lan, everyone else can do also! So ... bad guys knowing your internal domains, would have no problem to redirect your users to a "intranet looking phishing site" and to them everything would be "green", as the cert is trusted. Even to YOU it would not be suspicous directly, as the cert is valid, and it's signed by LE. With a "private" corporate CA they usually won't be able to issue another one.

Steps required:

  • [x] Change FQDN to a real existing domain name
  • [x] Generate certificate with certbot of Let's Encrypt
  • [x] Configure nginx for HTTPS
  • [x] Configure Moodle to use HTTPS
  • [ ] Configure automatic renewal of certificate

Last point of checklist (Configure automatic renewal of certificate) seems unfortunately no doable: the owner of the domain has to modify the TXT record for each renewal, which is impractical for all the MoodleBoxes in the field, unless it has its own unique domain name.

I'm afraid I can't add this feature in the standard image.

Hi Nicolas,
I read that someone browsers will mark a web site as insecure in near future when the web site doesn‘t use a ssl certificate. This would be a bad thing when the MoodleBox comes in mind as an insecure device.

Therefore I was searching for some ideas to get a ssl certificate into the Raspberry Pi. What do you think about these ideas?

Best regards, Ralf

I don‘t know of the ssl certificate of a local web server must be updateted online? Therefore the certificate update process should run only when the MoodleBox is connected and online via ethernet. This would be the same condition as needed for time synchronisation or for an updated DNS entry.

What will happen when the ssl certificate gets invalid and the MoodleBox is not connected to the internet? You wrote that the users must modify a text record for each renewal. There should be a script for the renewal process. An the url is the same for every MoodleBox.

Hi Ralf,
If you look at the checklist above, I've already done all of this (via the excellent LetsEncrypt).

However, I've gotten in a dead end. First of all, as noted here, it is not possible to get a SSL certificate with a non-public root domain. So this will need to change the moodlebox.home FQDN to something like a public one, say moodlebox.me. This is not a problem (except that all the user will have to change their habits, which is bad), I've done it.

Secondly, unfortunately though, I've not found any solution the renewal of certificate, since any MoodleBox installation will need a unique certificate, so we are in the situation where we'll have to ask LetsEncrypt different certificates each time for the same FQDN (see explanation here).

If you have a solution, I'll be glad to hear you.

Okay ... the problem can not be fixed with thousands of dynamic DNS entries for the MoodleBoxes all over the world.

What do you think about a selfsigned certificate on the MoodleBox. The certificate can be installed with an installation script. The admin could start this script in the terminal or it can be started automatically. Yes, I know that every user will get a warning that a selfsigned certificate is not secure. But if every user will trust this certificate the connection should be secure.

The web server could provide a download link for the certificate in a profile so every user is able to download it to his devices. A lot of working areas, universities and schools are using selfsigned certificates for their internal server communication and proxy servers.

Every MoodleBox will generate its own cerificate. But what will happen when a user has more than only one MoodleBox? He can change the Wi-Fi from MoodleBox1 to Moodlebox4 and then he opens the url https://moodlebox.home. The Wi-Fi is different, but the url is the same. Would it be possible to accept a second profile for a second Wi-Fi but the same url?

I'm afraid that the warning for a unknown (self-signed certificate) will not reassure much more than the one saying that the connection is not secure ;-)

I understand that in a big institution, installing a certificate on managed devices is OK. But this is not doable in institutions where devices aren't managed. So I'm not so keen to add such complexity to all users, at least not until it's really blocking.

Maybe I'll add some documentation about how to enable HTTPS on the MoodleBox and how to get oneself a self-signed certificate. What do you think?

Yes. I think we should try a Moodlebox version with a selfsigned certificate.

To make it a little bit easier for the admin all needed software should be installed and all directory folders should exist. I found some instructions which are showing a lot of installation steps ... no, this should be very easy with the MoodleBox.

Good idea. I'll think I'll publish MoodleBox with an already generated a self-signed certificate, and with a configuration file for nginx prepared with commented out instructions (and documentation).

With this done, one could make it with just editing 2 files (nginx and moodle config files).

Tested: it works 👍

@ralf-krause: if you want to test yourself: login via SSH then

  1. Get root privileges: sudo -s
  2. Create folder: mkdir /etc/nginx/ssl
  3. Generate certificate and key with this command (one line, no new lines): openssl req -new -x509 -sha256 -nodes -newkey rsa:4096 -keyout /etc/nginx/ssl/moodlebox.key -out /etc/nginx/ssl/moodlebox.crt -days 3650 -extensions v3_ca -extensions SAN -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:*.moodlebox.home")) -subj "/C=CH/O=MoodleBox/CN=moodlebox.home"
  4. Add following 3 lines to file /etc/nginx/sites-available/default, just after line listen [::]:80 default_server;:
listen 443 ssl;

ssl_certificate /etc/nginx/ssl/moodlebox.crt;

ssl_certificate_key /etc/nginx/ssl/moodlebox.key;
  1. In file /var/www/moodle/config.php, line beginning with $CFG->wwwroot, change http with https.
  2. Restart nginx: systemctl restart nginx
  3. Exit root: exit.

Yes, it works with https! Very nice!

Hi Nicolas,
the MoodleBox works fine with https but it's not easy to use! I installed the certificate in the key chain on my Mac and I set it as "Always trusted". I thought that everything would work.

  • The Safari browser shows the MoodleBox web site without any problem.
  • The Chrome browser opens the MoodleBox but it shows a big sign "Not Secure". :-(
  • The Firefox browser uses its own certification folder and the users must verify the web site again. :-(

To have an easy access to the MoodleBox we should use it without https.

Additional I found a blocker for the self signed certificate ... the Moodle Mobile app does not connect to the MoodleBox with this certificate even if the certificate is installed within a profile (.mobileconfig) and can be used by any app.

Thanks for your feedback. In this case, I'm afraid we're out of luck.

Seems there's no good solution for this. I'll leave this open for the moment, if someone have a genius idea.

Will need documentation when (if?) feature is implemented.

Hello @martignoni

I just read through this case and think that the solution with Let's Encrypt and real public domains is not the right way. MoodleBox is mostly used in an intranet environment, isn't it?

I think what we need to do is create a root certificate on each MoodleBox (i.e. host a own CA), which the user can then add to his "Trusted Certificates" on his client. With this solution it should be possible to generate a self-signed certificate for Moodle from this CA. After that, when the user accesses the platform, the verification chain should be verified as secure, as the root certificate is stored on the client side.

So out of the box nginx is listening on port 80/443 but the Moodle wwwroot is per default https. And all traffic accessing Moodle is redirected to 443. Just the landing page providing the root certificate download is accessible by port 80. Like that is a user decision, if they want avoid the unsecure message.

Let me know what you think about that? I can give it a try. 😙

Overview

  • [x] Chrome (70.0.3538.77 - Win10)
  • [x] FF (Quantum 63.0.1 -Win10)
  • [x] Edge (42.17134.1.0 - Win10)
  • [ ] Android (6.0) with Moodle Mobile App (3.5.2)
  • [x] [Moodle Mobile Browser App](https://mobileapp.moodledemo.net) (3.5.2)

Results

Chrome

I just made a straigtforward test and it seems to work with Chrome:


Click to expand

image

image


You must only add the root certificate as trusted certificate authority on the client-side and the MoodleBox is then trusted:


Click to expand

image


FireFox

With FF you must import it directly in the browsers certificates storeage:


Click to expand

image

image


Edge

Edge is working fine (doing the cert import on client, see above):


Click to expand

image


Safari

With Safari I can't do a test... I don't own a Apple device.


Moodle Mobile

It should work with the Moodle Mobile App if the rootCA is present. I just don't figure out how to add this to my android device. But there's a Moodle Mobile Browser App for testing purposes with the same behaviour:


Click to expand

image

Thanks. This is very interesting and could be a solution. Main issue then is the diversity of ways to add the root CA to the various browsers, which is unfortunately a mess in term of usability.

Could you please point me to a "How to" creating such a root CA and the a SSL cert based on it?

On my Win10 client it's only the FF which doesn't take the root certificate from the OS. I think most users uses Chrome.

I used this as guide: https://medium.freecodecamp.org/how-to-get-https-working-on-your-local-development-environment-in-5-minutes-7af615770eec

Update

Last point of checklist (Configure automatic renewal of certificate) seems unfortunately no doable: the owner of the domain has to modify the TXT record for each renewal, which is impractical for all the MoodleBoxes in the field, unless it has its own unique domain name.

I'm afraid I can't add this feature in the standard image.

What about a solution with ngrok?

Hi Adrian,
during my test in February 2018 I found that every browser on macOS wanted to get its own certificate verification. The blocker was that the Moodle Mobile app on iOS did not accept the self signed certificate from the MoodleBox.
Best regards, Ralf

@ralf-krause: the situation is not the same, because at this time we didn't thought to add a root CA to the browser.

Maybe MoodleBox should have this HTTPS as experimental option? Per default is HTTP and HTTPS is for advanced users who are aware where are the limits. It will be hard with a not official certificate to satisfy all needs.

Do you know ngrok @martignoni? But for a static domain it's a paid subscription... 😏

I think what we need to do is create a root certificate on each MoodleBox (i.e. host a own CA), which the user can then add to his "Trusted Certificates" on his client. With this solution it should be possible to generate a self-signed certificate for Moodle from this CA. After that, when the user accesses the platform, the verification chain should be verified as secure, as the root certificate is stored on the client side.

So out of the box nginx is listening on port 80/443 but the Moodle wwwroot is per default https. And all traffic accessing Moodle is redirected to 443. Just the landing page providing the root certificate download is accessible by port 80. Like that is a user decision, if they want avoid the unsecure message.

I worked a bit on this, and will try to implement it in a next version. However, I'll keep port 80 as default port, so that the UX won't change for most people.

Note to self: implementation instructions

Preparation

sudo -s
mkdir /root/CA
mkdir /etc/nginx/ssl

Certificate authority

# Generate our CA private key.
openssl genrsa -out /root/CA/moodlebox.CA.key 2048
# Generate a CA root certificate.
openssl req -x509 -new -extensions v3_ca -nodes -key /root/CA/moodleboxCA.key -sha256 -days 3652 -out /root/CA/moodleboxCA.pem -subj "/C=CH/O=MoodleBoxCA/CN=net.moodlebox.ca"

Create SSL certificate signed with above CA root certificate

# Generate our website private key.
openssl genrsa -out /etc/nginx/ssl/moodlebox.key 2048
# Create a CSR.
openssl req -new -key /etc/nginx/ssl/moodlebox.key -out /etc/nginx/ssl/moodlebox.csr -subj "/C=CH/O=MoodleBox/CN=moodlebox.home"
# Create the signed SSL certificate.
openssl x509 -req -in /etc/nginx/ssl/moodlebox.csr -CA /root/CA/moodleboxCA.pem -CAkey /root/CA/moodleboxCA.key -CAcreateserial -out /etc/nginx/ssl/moodlebox.pem -days 3652 -sha256
# Delete CSR.
rm /etc/nginx/ssl/moodlebox.csr

Configure __nginx__

Add following 3 lines to file /etc/nginx/sites-available/default, just after line listen [::]:80 default_server;.

listen 443 ssl;

ssl_certificate /etc/nginx/ssl/moodlebox.crt;

ssl_certificate_key /etc/nginx/ssl/moodlebox.key;

And reload __nginx__

sudo systemctl reload nginx.service

Note

This is a cool documentation: https://gist.github.com/Soarez/9688998

Hi @martignoni

Cool that you are working on this issue. Thumbs up! 👍

Greets
Adrian

Documentation published. Closing :-)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

martignoni picture martignoni  ·  6Comments

martignoni picture martignoni  ·  19Comments

martignoni picture martignoni  ·  8Comments

spipau picture spipau  ·  9Comments

nicolaibaralmueller picture nicolaibaralmueller  ·  4Comments