Ssl.conf <VirtualHost _default_:443> collides with vhosts

I’m attempting to learn and implement some best practices for Apache configuration that will also be compatible with letsencrypt certbot. Some configuration in ssl.conf is getting in my way so to speak…

Versions
Centos 7.4
Apache 2.4.6
certbot 0.20.0

Question
Inspection of the output from apachectl -S shows that the <VirtualHost _default_:443> configuration line in ssl.conf is being interpreted as default server. Can I delete that configuration while preserving the configuration in ssl.conf?

The virtual hosts for the other non jhalbrecht.net hosts are working well. Content for ‘www.dediserve1.jhalbrecht.net’ is being served by the ssl.conf. Consequently it is using the main server DocumentRoot of /var/www/html for that defaul host matching on dediserve1.jhalbrecht.net rather than /var/www/dediserve1… DocumentRoot.

_ponders a bit…_then configuration change

I renamed ssl.conf to ssl.conf.nope so it wouldn’t be loaded and placed a Listen 443 https in the 000-dediserve1.jhalbrecht.net-le-ssl.conf vhost file. That seems to work. All combinations of http and https www.deiserve1.jhalbrecht.net and dediserve1.jhalbrecht.net are serving from the desired directory.

I’m probably missing important SSL configuration directives that were in the ssl.conf perhaps I could copy them and paste into the /etc/letsencrypt/options-ssl-apache.conf that is included into each vhost file? Or does the /etc/letsencrypt/options-ssl-apache.conf file already contain sufficient configuration? Umm… Wow I just put dediserve1.jhalbrecht.net through the Qualys SSL Labs test and received an A where with the ssl.conf intact I was receiving a C. The other vhosts also received A ratings.

I wonder if a yum update could reinstall the ssl.conf file harming my configuration?

Notes:
I’m working of the Apache document Name-based Virtual Host Support See the secion; “Main host goes away” In this document it is suggested that there be a vhost file for the FQDN of the main server.

Main host goes away

Any request that doesn’t match an existing is handled by the global server configuration, regardless of the hostname or ServerName.

When you add a name-based virtual host to an existing server, and the virtual host arguments match preexisting IP and port combinations, requests will now be handled by an explicit virtual host. In this case, it’s usually wise to create a default virtual host with a ServerName matching that of the base server. New domains on the same interface and port, but requiring separate configurations, can then be added as subsequent (non-default) virtual hosts.

See also my previous letsencrypt issue; CNAME secure A record not secure I fixed the mismatch in the distribution self signed certificate however subsequent runs of certbot have not updated ssl.conf with new cert names when an unfortunate -0001 was append to the cert name causing me some organizational displeasure. and cert mismatch. I suppose that should be addressed in a separate issue?

Action item?
So many blog posts and HowTo’s have not addressed this issue of the FQDN host configuration as to default server vs: vhost configuration of the FQDN (and CNAMEs). Perhaps the best practices from the Apache document and my solution, or a more elagent one?, could be rolled into a paragraph in a letsncrypt FAQ and/or certbot apache documentation?

apachectl -S (before removal of ssl.conf)

[root@dediserve1 sites.d]# apachectl -S
    VirtualHost configuration:
    *:443                  is a NameVirtualHost
             default server dediserve1.jhalbrecht.net (/etc/httpd/conf.d/ssl.conf:56)
             port 443 namevhost dediserve1.jhalbrecht.net (/etc/httpd/conf.d/ssl.conf:56)
             port 443 namevhost dediserve1.jhalbrecht.net (/etc/httpd/sites.d/000-dediserve1.jhalbrecht.net-le-ssl.conf:2)
                     alias www.dediserve1.jhalbrecht.net
             port 443 namevhost recoveryworking.com (/etc/httpd/sites.d/recoveryworking.com-le-ssl.conf:2)
                     alias www.recoveryworking.com
             port 443 namevhost rodaw.info (/etc/httpd/sites.d/rodaw.info-le-ssl.conf:2)
                     alias www.rodaw.info
             port 443 namevhost rodaw.net (/etc/httpd/sites.d/rodaw.net-le-ssl.conf:2)
                     alias www.rodaw.net
             port 443 namevhost wiki.rodaw.com (/etc/httpd/sites.d/wiki.rodaw.com-le-ssl.conf:2)
             port 443 namevhost wiki.theretrowagon.com (/etc/httpd/sites.d/wiki.theretrowagon.com-le-ssl.conf:2)
    *:80                   is a NameVirtualHost
             default server dediserve1.jhalbrecht.net (/etc/httpd/sites.d/000-dediserve1.jhalbrecht.net.conf:1)
             port 80 namevhost dediserve1.jhalbrecht.net (/etc/httpd/sites.d/000-dediserve1.jhalbrecht.net.conf:1)
                     alias www.dediserve1.jhalbrecht.net
             port 80 namevhost recoveryworking.com (/etc/httpd/sites.d/recoveryworking.com.conf:1)
                     alias www.recoveryworking.com
             port 80 namevhost rodaw.info (/etc/httpd/sites.d/rodaw.info.conf:1)
                     alias www.rodaw.info
             port 80 namevhost rodaw.net (/etc/httpd/sites.d/rodaw.net.conf:1)
                     alias www.rodaw.net
             port 80 namevhost wiki.rodaw.com (/etc/httpd/sites.d/wiki.rodaw.com.conf:1)
             port 80 namevhost wiki.theretrowagon.com (/etc/httpd/sites.d/wiki.theretrowagon.com.conf:1)
    ServerRoot: "/etc/httpd"
    Main DocumentRoot: "/var/www/html"
    Main ErrorLog: "/etc/httpd/logs/error_log"
    Mutex authdigest-opaque: using_defaults
    Mutex proxy-balancer-shm: using_defaults
    Mutex rewrite-map: using_defaults
    Mutex authdigest-client: using_defaults
    Mutex ssl-stapling: using_defaults
    Mutex proxy: using_defaults
    Mutex authn-socache: using_defaults
    Mutex ssl-cache: using_defaults
    Mutex default: dir="/run/httpd/" mechanism=default
    Mutex mpm-accept: using_defaults
    PidFile: "/run/httpd/httpd.pid"
    Define: _RH_HAS_HTTPPROTOCOLOPTIONS
    Define: DUMP_VHOSTS
    Define: DUMP_RUN_CFG
    User: name="apache" id=48
    Group: name="apache" id=48
    [root@dediserve1 sites.d]#

certbot invocation

    certbot --authenticator standalone --installer apache \
            -d dediserve1.jhalbrecht.net \
                    -d www.dediserve1.jhalbrecht.net \
            -d rodaw.info -d www.rodaw.info \
            -d rodaw.net -d www.rodaw.net \
            -d wiki.theretrowagon.com \
            -d wiki.rodaw.com \
            -d recoveryworking.com -d www.recoveryworking.com \
            --pre-hook "systemctl stop httpd" --post-hook "systemctl start httpd"

I further modified my configuration to be more self explanatory as well as neat and tidy…

I renamed my FQDN vhost from 000-dediserve1.jhalbrecht.net.conf to dediserve1.jhalbrecht.net.conf then created a 000-default.conf vhost with, so far, a single line Listen 443 https I removed the Listen from dediserve1.jhalbrecht.net.conf or there will be an ip already bound error message. This has the same effect but looks better and can be expanded. Perhaps the Include /etc/letsencrypt/options-ssl-apache.conf could go here.

I think it’s worth mentioning there are less “magical”/intrusive Let’s Encrypt clients available if you find yourself fighting with Certbot over configuration idioms.

For instance I like to just use acmetool (which does nothing but issue certificates) and manually configure my web server with config generated from the Mozilla SSL Configuration Generator. You can also use Certbot’s certonly command and opt to do the SSL configuration yourself.

This will depend on how Apache was packaged, but you can also just comment out the contents of the file (rather than deleting or renaming it) and leave it in place, and it shouldn’t get replaced on upgrade.

1 Like

I setup acmetool and configured a cert fairly easily. I like that it's not going to muck with my config. Can you comment on cert syntax for Apache 2.4.6? Following is what I'm using. Commented out for history while tuning previous syntax.

Include /etc/letsencrypt/options-ssl-apache.conf
# certbot
# SSLCertificateFile /etc/letsencrypt/live/dediserve1.jhalbrecht.net-0001/cert.pem
# SSLCertificateKeyFile /etc/letsencrypt/live/dediserve1.jhalbrecht.net-0001/privkey.pem
# SSLCertificateChainFile /etc/letsencrypt/live/dediserve1.jhalbrecht.net-0001/chain.pem
#
# jha 2/2/2018 acmetool httpd -v 2.4.6
# SSLCertificateFile /var/lib/acme/live/rodaw.net/cert
SSLCertificateFile /var/lib/acme/live/rodaw.net/fullchain
SSLCertificateKeyFile /var/lib/acme/live/rodaw.net/privkey
# SSLCertificateChainFile /var/lib/acme/live/rodaw.net/fullchain

To be fair to Certbot you can also use certonly to do achieve the same thing (not messing with your config).

I think because you use Apache 2.4.6, you still need to use a separate SSLCertificateChainFile directive. The “combined” certificate format was introduced to Apache in 2.4.8.

SSLCertificateFile /var/lib/acme/live/rodaw.net/cert
SSLCertificateChainFile /var/lib/acme/live/rodaw.net/chain

If you go the self-managed path, the Mozilla SSL generator will give you a standalone configuration for whatever webserver and webserver version you ask it, so you don’t even need to include /etc/letsencrypt/options-ssl-apache.conf.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.