Setting up https with a self-signed certificate on Apache

9,680

Solution 1

Well, since the user Jure1873 hasn't written up an answer, I cannot give him the credit deserved. Here is his solution:

what if you replace <VirtualHost mail.craimer.org:443> with <virtualhost *:443>?

And that was the solution. It turns out that (as of this writing) httpd cannot support multiple virtual hosts for HTTPS, so any connections to 443 must be directed to a single host. So I guess httpd was just silently rejecting the configuration that attempting to run a virtual host for HTTPS.

Oh, and don't rail against apache for this "missing feature". It's not their fault! The HTTPS protocol doesn't support virtual hosts.

Boring Explaination:

You see, when you connect to port 443, and start an HTTPS session, all that's happening is security negotiation. HTTPS is all about setting up a secure tunnel between two points, and has nothing to do with HTTP. Only once the tunnel is set up, will data flow through. That data is the HTTP stream.

This means that the Host: directive (which is part of HTTP, not HTTPS) will only get sent after the secure tunnel has been constructed. It is the Host: header which tells HTTP server which virtual host is being accessed. But in HTTPS, we get this information far too late: it arrives after we had to choose encryption keys.

Bottom line: HTTPS cannot choose encryption keys based on the HTTP hostname.

Solution 2

The issue is more likely to lie with your vhost configuration.

The ssl_error_rx_record_too_long error can be produced by initiating an HTTPS session against an HTTP resource. Such as - https://host.name:80.

Solution 3

The approach I've used in the past is slightly different to the one you detailed. The instructions below were originally detailed in this post I found whilst looking how to set up ssl: Step by Step Installation Of Subversion Over Apache/SSL Authenticating through Active Directory (SSPI)

To summarise:

  1. Under apache\bin create openssl.conf and set its contents as follows:

    [ v3_ca ] 
    subjectKeyIdentifier = hash 
    authorityKeyIdentifier = keyid:always,issuer:always 
    basicConstraints = CA:true 
    [ req ] 
    default_bits  = 1024 
    default_keyfile  = server.key 
    distinguished_name = req_distinguished_name 
    attributes  = req_attributes 
    x509_extensions = v3_ca  
    string_mask  = nombstr 
    [ req_distinguished_name ]  
    commonName  = Common Name 
    commonName_default = My Server Name 
    [ req_attributes ]
  2. Open a command prompt up, navigate to apache\bin and run the following command:

    openssl req -config openssl.conf -new -out server.csr

  3. When prompted enter a pass phrase and then a second time to verify.

  4. You will then be prompted to enter a Common Name [My Server Name]. Enter the name of the machine

  5. Next remove the passphrase from the private key with the following command (note this may give a warning about not being able to find openssl.conf - this can be ignored):

    openssl rsa -in server.key -out server.key

  6. Enter the previously used passphrase when prompted

  7. Next create the self signed certificate with the following command

    `openssl x509 -in server.csr -out server.cert -req -signkey server.key -days 365

  8. Delete the server.csr file from the apache\bin folder.

  9. Copy the server.key and server.cert files from the apache\bin folder to the apache\conf folder.

  10. Open apache\conf\httpd.conf in a text editor.

  11. Change the listen port directive (which will probably either be Listen 80 or Listen 8080) to port 443:

    Listen 443

  12. Change the ServerName directive to include port 443 (note this may be commented out so remove the # at the start of the line if it is and replace server with your server name):

    ServerName server:443

  13. Uncomment or add the load module directive for mod_ssl (this should be present and commented so remove the # at the start of the line):

    LoadModule ssl_module modules/mod_ssl.so

  14. Add an IfModule section for mod_ssl (this shouldn't already be there, but if it is overwrite it):

    <IfModule mod_ssl.c>
        SSLEngine on
        SSLRandomSeed startup   builtin
        SSLRandomSeed connect   builtin
        SSLPassPhraseDialog     builtin
        SSLSessionCache         dbm:logs/ssl_scache
        SSLSessionCacheTimeout  300
        SSLMutex                default
        SSLCertificateFile      conf\server.cert
        SSLCertificateKeyFile   conf\server.key
    </IfModule>
  15. Restart the Apache service. Test configuration by attempting (and failing) to connect via http, and attempting (and succeeding) to connect via https.

Share:
9,680

Related videos on Youtube

Shalom Craimer
Author by

Shalom Craimer

Just another coder. (Programming is fun!) Currently in HFT (high frequency trading) which makes it fun using C++ to push the limits what can be done on an Intel off-the-shelf chip. And I paid to do it! My area of expertise shifts according to the job I'm working in: Video (MPEG), Embedded (PIC32, MSP's of various flavors), Full-Stack (Linux, PHP, SQL)

Updated on September 17, 2022

Comments

  • Shalom Craimer
    Shalom Craimer almost 2 years

    I'm trying to set up HTTPS on Apache, using a self-signed certificate. But instead of displaying the page, I get a bunch of weird errors. An a different error from each browser!

    From Chrome:

    Error 2 (net::ERR_FAILED): Unknown error.

    From Firefox:

    SSL received a record that exceeded the maximum permissible length. (Error code: ssl_error_rx_record_too_long)

    I followed the steps detailed on http://slacksite.com/apache/certificate.php, as well as about 4 other guides. They are all about the same, but all give the same result. So I must be doing something wrong.

    Briefly, here's what I did:

    • Generate the server key:

      openssl genrsa -des3 -out server.key 1024

    • Generate CSR:

      openssl req -new -key server.key -out server.csr

    [while generating the request, I was careful to enter my actual hostname as the "Common Name (eg, your name or your server's hostname)"]

    • remove password from key:

      cp server.key server.key.org
      openssl rsa -in server.key.org -out server.key

    • Self-sign the certificate:

      openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

    • Configured apache to point at those files, and use those certificates.

    Any ideas?

    UPDATE: Here's my virtual host configuration:

    LoadModule ssl_module modules/mod_ssl.so
    Listen 443
    #   Some MIME-types for downloading Certificates and CRLs
    #
    AddType application/x-x509-ca-cert .crt
    AddType application/x-pkcs7-crl    .crl
    SSLSessionCache         shmcb:/var/cache/mod_ssl/scache(512000)
    SSLSessionCacheTimeout  300
    SSLMutex default
    SSLRandomSeed startup file:/dev/urandom  256
    SSLRandomSeed connect builtin
    SSLCryptoDevice builtin
    
    ## Virtual host to redirect to HTTPS
    <VirtualHost *:80>
        ServerName mail.craimer.org
        Redirect permanent / https://mail.craimer.org:443
    </VirtualHost>
    
    ##
    ## SSL Virtual Host Context
    ##
    
    <VirtualHost mail.craimer.org:443>
        ServerName mail.craimer.org
        DocumentRoot "/usr/share/roundcubemail/trunk/roundcubemail/"
    
             ErrorLog logs/ssl_error_log
             TransferLog logs/ssl_access_log
             LogLevel warn
    
             SSLEngine on
    
             SSLProtocol all -SSLv2
    
             SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW
    
             SSLCertificateFile /etc/httpd/conf/ssl/server.crt
             SSLCertificateKeyFile /etc/httpd/conf/ssl/server.key
    
             <Files ~ "\.(cgi|shtml|phtml|php3?)$">
                                    SSLOptions +StdEnvVars
             </Files>
             <Directory "/var/www/cgi-bin">
                                    SSLOptions +StdEnvVars
             </Directory>
    
        # Deal with broken MSIE
             SetEnvIf User-Agent ".*MSIE.*" \
             nokeepalive ssl-unclean-shutdown \
             downgrade-1.0 force-response-1.0
    
        CustomLog logs/ssl_request_log \
              "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
    </VirtualHost>
    
    • Admin
      Admin almost 15 years
      Could you paste you apache/vhost configuration?
    • Admin
      Admin over 13 years
      Was this solved? What was the solution?
  • Admin
    Admin almost 15 years
    Didn't have those in my config...
  • Shalom Craimer
    Shalom Craimer almost 15 years
    All I'm doing is typing in "mail.craimer.org" into my web browser. You'd think that would work, no?
  • Shalom Craimer
    Shalom Craimer almost 15 years
    ugh. it mulched the url. it was https : // mail.craimer.org
  • Shalom Craimer
    Shalom Craimer almost 15 years
    @Jure1873 Wow! That worked! - write is up as an answer, and I'll make it the accepted one, k?
  • Dan Carley
    Dan Carley almost 15 years
    The likely reason is that it was being caught by a <VirtualHost *> directive further up the chain/config.