Let Virtualmin configuration check pass if SSL management is delegated to proxy server

I requested an option to compose custom directives for Apache SSL on https://www.virtualmin.com/node/53436, but then marked it as works as designed with the following comment:

Let's concentrate on more important issues as we will use custom post creation script to remove directives for SSL version. So Jamie, please disregard this feature until hopefully one day, more people are interested in this, and instead could you please elaborate on https://www.virtualmin.com/node/53448.

because we decided to just remove all the 443 related lines in Apache configuration every time a virtual server is created with SSL option on executing the following code in post creation script:

if [ "$VIRTUALSERVER_ACTION" = "MODIFY_DOMAIN" ]; then
  if [ "$VIRTUALSERVER_OLDSERVER_SSL" = "0" ] && [ "$VIRTUALSERVER_SSL" = "1" ]; then
    sed -ie '\#<VirtualHost .*:443>#,\#</VirtualHost>#d' /etc/httpd/conf/httpd.conf
    systemctl restart httpd
  fi

fi

and everything works perfectly well: (1) Let's Encrypt certificates are created and renewed by Virtualmin and (2) Apache is stripped off all 443 records, because another proxy server manages the SSL certificates.

One big problem is remaining though - when we check Virtualmin configuration, then it gives:

The Apache configuration on your system does not appear to be listening on port 443, which is needed to host SSL websites. If you do not plan to host SSL sites, this feature should be disabled in Virtualmins's module configuration page.

because the line Listen 443 https in the /etc/httpd/conf.d/ssl.conf file is commented out.

As explained in https://www.virtualmin.com/node/53436 our proxy server, not Apache, listens to port 443, however because this association between Apache and SSL configuration is hardcoded in Virtualmin configuration check it fails. So I'd like to file a request to de-couple this hard-coded connection between Apache and SSL configuration as nowadays with SSL everywhere philosophy more and more software like proxy servers are coming up and I do believe Virtualmin has to grow further to start supporting them.

In essence this issue is about Virtualmin treating Apache and SSL configuration together, when in fact SSL configuration could be done via lot's of other proxy servers.

Thanks for consideration!

Status: 
Fixed (pending)

Comments

For now, we are proceeding to our setup by removing the following lines in the /usr/libexec/webmin/virtual-server/virtual-server-lib-funcs.pl file:

        $haslisten ||
            return &text('index_emodssl2', $default_web_sslport, $clink);
        &$second_print($text{'check_sslok'});

as in our case a proxy server listens to port 443.

However, ideally Virtualmin needs to be told which server or proxy software listens to port 443 and then the following whole block has to be rewritten avoiding hard-binding this feature only to Apache:

if ($config{'ssl'}) {
        # Make sure openssl is installed, that Apache supports mod_ssl,
        # and that port 443 is in use
        $config{'web'} || return &text('check_edepssl', $clink);
        &has_command("openssl") ||
            return &text('index_eopenssl', "<tt>openssl</tt>", $clink);

        &require_apache();
        local $conf = &apache::get_config();
        local @loads = &apache::find_directive_struct("LoadModule", $conf);
        local ($l, $hasmod);
        foreach $l (@loads) {
                $hasmod++ if ($l->{'words'}->[1] =~ /mod_ssl/);
                }
        local ($aver, $amods) = &apache::httpd_info(&apache::find_httpd());
        $hasmod++ if (&indexof("mod_ssl", @$amods) >= 0);
        $hasmod++ if ($apache::httpd_modules{'mod_ssl'});
        $hasmod ||
            return &text('index_emodssl', "<tt>mod_ssl</tt>", $clink);

        local @listens = &apache::find_directive_struct("Listen", $conf);
        local $haslisten;
        foreach $l (@listens) {
                $haslisten++ if ($l->{'words'}->[0] =~ /^(\S+:)?$default_web_sslport$/);
                }
        local @ports = &apache::find_directive_struct("Port", $conf);
        foreach $l (@ports) {
                $haslisten++ if ($l->{'words'}->[0] == $default_web_sslport);
                }
        $haslisten ||
            return &text('index_emodssl2', $default_web_sslport, $clink);
        &$second_print($text{'check_sslok'});
        }

But then probably the whole option Apache SSL website enabled? should be rewritten as just SSL website enabled? and respect SSL termination method, which can be done through other proxy servers like Nginx, Pound, HAProxy, etc.

I think that SSL port must be only an option on each webserver, not separate virtualserver feature. So implement separate feature "SSL certificate" in virtualserver features for manage it, and small separate options "Enable SSL with virtualserver ceritificate" in each webserver configuration (Apache, Nginx and others).

Jamie, any thoughts on this request?

So, is that you're really looking for is a way to generate the SSL cert for a domain independently of setting up any webserver (apache or nginx) to use it?

So, is that you're really looking for is a way to generate the SSL cert for a domain independently of setting up any webserver (apache or nginx) to use it?

Yes, because if a proxy server (not necessarily nginx as it could be any other proxy server) is set to listen to port 443, then Virtualmin configuration check fails, because the line Listen 443 https in the /etc/httpd/conf.d/ssl.conf is commented out.

Ideally, management of SSL certs should be totally de-coupled from Apache, because we see more and more proxy server implementations on LAMP, but if that is not easy to do at this stage, then at least make it possible Virtualmin to pass configuration check. And in order to do so the above lines in /usr/libexec/webmin/virtual-server/virtual-server-lib-funcs.pl should be either modified or removed.

That's a good suggestion. Are you also interested in the case where a domain doesn't even have a non-SSL website though?

That's a good suggestion. Are you also interested in the case where a domain doesn't even have a non-SSL website though?

Well, we are currently building "SSL everywhere" platform, so in our case no, we are not interested. However, I understand Virtualmin needs to cover all the possible use cases, but then non-SSL is easy: if SSL is not selected then no port 443 manipulation is involved, so no code change is required. I am asking only minimal code modification when Virtualmin de-couples SSL from hard-linking to Apache and so it passes configuration check if another proxy server is listening to port 443.

Ok, I'll put this on our TODO list for implementation.

Ok, I'll put this on our TODO list for implementation.

Thanks. Any rough ETA, so we could plan the full switch? We'll be hacking the code for now to work around the issue.

Likely several weeks until we actually implement and release it.

I finally finally got around to implementing this - in the next Virtualmin release, it will be possible to have a domain with an SSL cert, but without the SSL feature enabled.