ClearChain

Solving the Apache SSL error “Oops, no RSA or DSA server certificate found for ‘www.somedomain.com:0’?!”

Recently a colleague of mine came to me with a problem he was having with SSL certificates and the web server Apache 2.2. Put simply Apache (httpd) would not start. It was an unusual situation as this server had been running flawlessly for almost 2 years and it was only a recent power outage that had caused the error to occur. Running apachectl configtest revealed no problems with the setup but when running apachectl start, whilst there was no errors reported on the command line, apache would instantly die/crash. Checking the log files we found:

[Thu Jan 20 14:15:16 2011] [error] Oops, no RSA or DSA server certificate found for 'www.somedomain.com:0'?!

Whilst somedomain.com isn’t the official domain name reported (I can’t reveal the client), this error was being printed for every SSL host except the default SSL host. Ironically the default SSL host was simply a redirect to one of the others. A quick check and indeed the problem lied with the SSL hosts – we removed every ssl host and the webserver would start fine – obviously without any ssl.

My colleague and I were  perplexed. He’d tried a quite few things to fix this all without luck. A so call Server Admin told him it was due to not using ip based virtual hosts for ssl, he claimed you can’t use Name Base Virtual hosts with SSL. No doubt this was obtained from a quick google search for the error. The problems is you can run NamedBasedVirtual hosts with SSL on port 443 provided you have a wildcard SSL certificate. A wild is required for NamedBaseVirtual hosts as the SSL connection is established first before the headers are sent. A wildcard will allow any subdomain to use the SSL connection then apache will see the host header and respond with the appropriate vhost. If on only have a single certificate this does not work and you’ll need a separate IP per certificate.

Anyway, we began trying to debug the issue. First we checked the certificate files were at the specified locations – they were. Next we checked the certificates were actually valid. You can use the openssl command below to do this:

openssl x509 -noout -text -in YOURCERTIFICATE.crt

The certificate, key, and certificate authority (CA) were all valid and in date.
Next we tried putting each Vhost in to the config one by one to see if one host had errors over another. Turns out it didn’t matter what order each host was in the config file or which ssl hosts were included, they all had issues – except for the default ssl vhost.

At this point we were a little lost. So we decided to go back to basics and work out what the error really meant. We search to see what apache module the error came from. A simple grep later we’d narrowed down the error to mod_ssl. A search of the mod_ssl source code found the following instance of the message:

# grep Oops *
ssl_engine_init.c:                         "Init: Oops, you want to request client "
ssl_engine_init.c:                "Oops, no RSA or DSA server certificate found "
ssl_engine_init.c:                "Oops, no RSA or DSA server private key found?!");
ssl_engine_io.c:                    (argp != NULL ? "(BIO dump follows)" : "(Oops, no memory buffer?)"));

Looking in ssl_engine_init.c we found the error came from the following function

static void ssl_init_server_certs(server_rec *s,
                                  apr_pool_t *p,
                                  apr_pool_t *ptemp,
                                  modssl_ctx_t *mctx)
{
    const char *rsa_id, *dsa_id;
    const char *vhost_id = mctx->sc->vhost_id;
    int i;
    int have_rsa, have_dsa;

    rsa_id = ssl_asn1_table_keyfmt(ptemp, vhost_id, SSL_AIDX_RSA);
    dsa_id = ssl_asn1_table_keyfmt(ptemp, vhost_id, SSL_AIDX_DSA);

    have_rsa = ssl_server_import_cert(s, mctx, rsa_id, SSL_AIDX_RSA);
    have_dsa = ssl_server_import_cert(s, mctx, dsa_id, SSL_AIDX_DSA);

    if (!(have_rsa || have_dsa)) {
        ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
                "Oops, no RSA or DSA server certificate found "
                "for '%s:%d'?!", s->server_hostname, s->port);
        ssl_die();
    }

    for (i = 0; i < SSL_AIDX_MAX; i++) {         ssl_check_public_cert(s, ptemp, mctx->pks->certs[i], i);
    }

    have_rsa = ssl_server_import_key(s, mctx, rsa_id, SSL_AIDX_RSA);
    have_dsa = ssl_server_import_key(s, mctx, dsa_id, SSL_AIDX_DSA);

    if (!(have_rsa || have_dsa)) {
        ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
                "Oops, no RSA or DSA server private key found?!");
        ssl_die();
    }
}

Hence  the error was caused by the certificates not being able to be imported. Once again we checked paths to make sure the certificates/keys were correct. Alas they were. So we began to wonder why the certificates couldn’t be found. We’d specified the correct files, confirmed they were correct. It occurred to me that perhaps the openSSL context had not been setup correctly. But why not? I took a look at the default SSL vhost which did work and noticed a single line that were not in any of the other ssl vhosts.

SSLEngine on

The comment above this line read:

#   SSL Engine Switch:
#   Enable/Disable SSL for this virtual host.

I added “SSLEngine On” to the other ssl vhosts and it worked! So it turns out you can have an vhost setup on port 443 without SSL hence for each vhost you want SSL working in you must add the above line. My colleague was extremely thankful – why it happened in the  first place, we still don’t know. We suspect previously the option may have been enabled globally. However the fix allows apache to run again and works after a clean shutdown and startup.

Exit mobile version