End user can accidentally prevent Apache restart by deleting or corrupting ssl.cert

Two facts interact to make it possible for an end user to accidentally (or deliberately) prevent Apache from restarting.

  1. Apache does not check the validity of SSL certificates when it is asked to check its configuration with 'httpd -t'.
  2. An end user can delete or corrupt his own ssl certificate, since it resides in ~/ssl.cert and is owned by him.

So a user could, via the shell or file manager, install an invalid SSL certificate into ~/ssl.cert. Or perhaps an invalid key into ~/ssl.key.

On the next attempted restart, Apache will fail to restart and all websites on the server will be down.

To prevent this problem, Apache should not directly use the SSL certificate and key files in the user's home directory. Instead, the UI should check these files for validity by calling the openssl command (which I think it already does), and then make a root-owned copy of the files elsewhere, for use by Apache.

If a user uploads a fresh SSL certificate into his ssl.cert file, Apache should not use it until the user goes to the UI and "registers" the new SSL certificate, which will cause it to be checked for validity and then installed as the root-owned copy.

See also: https://www.virtualmin.com/node/39546.

Status: 
Active

Comments

There is a solution for this which you can configure in Virtualmin - just go to System Settings -> Virtualmin Configuration -> SSL settings, and change the "Template for private key path" to something like /etc/sslcerts/${DOM}.key (and similar for the cert file).

Thanks, I tried that and also tried something more ambitious: Having my script relocate the certificate and key to root-owned files any time the user's virtual server is created or modified. But Virtualmin expects the certificate and key to be owned by the user. Root ownership causes error messages on the SSL certificate screens.

So long as the user owns those files, and their pathnames are printed on the Virtualmin screen (or available to the user by searching around), we are not eliminating the problem, only making it a little less likely to occur. Curious/adventurous/malicious users will still directly access the files and corrupt them at some point.

Virtualmin should be OK as long as it can read the cert files.

You are right in general though that the current default setup of putting certs in user home dirs is unsafe. I'll update this ticket once we have a better solution..

Virtualmin reading the files is exactly where I ran into problems. If I want to have the key readable by the user that owns it but not by other users on the same machine, then protections become a mess, requiring the use of a new group for each user. I also considered doing chattr +i on each file to make it immutable, while leaving it owned by the user so the user can read it. That can work, but Virtualmin would need to do a chattr -i (as root) before updating it.

Yeah, we will need to make some fairly large changed to Virtualmin to prevent changes to the key file without validation. I'll update this ticket once they have been implemented.

This should be done also for some other files like fcgi-bin directory. If it is deleted Apache refuse to start. Also it will be good to recreate public_html if it is accidentally deleted. This prevents graceful restarts.

I have tested your suggestion Jamie but appears another bug: First I tried to set the path for the certs to /etc/sslcerts/${USER}/${DOM}.key (ca, cert) but when I try to enable "SSL website" for one website It gave me error:

=======================================

Changing IP address of virtual website .. .. done Creating SSL certificate and private key .. .. SSL website failed! : Failed to open /etc/sslcerts/fsdagfsd/domain-test.com.cert.webmintmp.20618 : No such file or directory at /usr/libexec/webmin/web-lib-funcs.pl line 1397, line 1.

Saving server details .. .. done

Applying web server configuration .. .. done

=======================================

Then tried exactly what you suggest /etc/sslcerts/${DOM}.key

But the error reminds exactly the same including the path /etc/sslcerts/fsdagfsd/domain-test.com.cert... which i have changed to the above

Then turn settings to the default values and the error is exactly the same. Nothing changed. Restart webmin -- nothing changed still the same error.

So if you change these settings once they can't be reverted.

Ok I managed to fix it manually in the domains configuration file. The issue is that virtualmin adds the path to the domain's config file but did not add the ssl=1 and other related entries. So it ends up with wrong path to the cert but with no enabled ssl. After deleting the paths the SSL website was added correctly. Also tested to make sslcert directory with permissions 700 with owner root and it is working. Also that way it will be secure.

Now the big question is is there a way to automatically move all existing certs from the domains home to the new location.

No, there's no automation in Virtualmin currently that can move all the certs.

Unfortunately after couple of days after setting these settings (moved ssl files described above). I tried to enable SSL website i get error

Creating SSL certificate and private key ..

.. SSL website failed! : Failed to open /etc/sslcerts/domain-test.com.cert.webmintmp.10047 : Permission denied at /usr/libexec/webmin/web-lib-funcs.pl line 1397, line 1.

Saving server details .. .. done

Applying web server configuration .. .. done

Nothing is changed since then. After this I see file

domain-test.com.cert.lock

in directory /etc/sslcerts/ which contain pid number which do not exist in the process list.
setting /etc/sslcerts/ permissions to 770 and root:root does not help.

This is probably because the SSL certificate writes are done always with the permissions of the domain owner.

So there is no solution on that issue. Because if we make that directory readable all users theoretically will be able to see and/or read them. It will be better if we can make the structure there like: /etc/sslcerts/username/domain/ssl.cert with permissions /etc/sslcerts (770 [root:root])/username (700 [username:username])/domain (whotever [username:username])/ssl.cert (whotever [username:username])

That way no one except the user will have rights to see these files.

For now we are lucky that users do not often touch these files. Otherwise our web server will be constantly down.

Sorry, no .. there's no perfect solution that you can implement in the current Virtualmin version. We plan to fix this in future though.

In the short term, having certs in directories under /etc is probably a little safer, as users are less likely to see them.

Do you had time to work on this? It is very frustrating users to have ability to take server down.

Not yet, but it is planned.

just my 2 cents, Could virtualmin create the certificate with root user under home directory of the domain owner. and configure apache in a way to then use this info for considering the certificate.. do you think that might work?

Even if the cert file is owned by root, the user could still delete it because they own the directory.