Home > English, OSS Solutions > How to configure HTTPS on Apache 2

How to configure HTTPS on Apache 2

Introduction

Setting up several VirtualHost’s on an Apache2 server is easy.

Setting up several VirtualHost’s on an Apache 2 server, some of them using SSL (HTTPS) is considerably less easy. The main problem is the documentation, not really easy to find, with examples of such configurations.

Here, we will intend to give all the steps to get there, remaining at a minimal level of complexity.

If you want more details, I suggest you have a look at this nice article by Artur Maj. This is where most of the inspiration comes from for the current article, together with real tests on a Debian Etch server. Thanks to his article, We will allow ourselves to skip the HTTPS, SSL and TLS definitions and prerequisites. We will consider that you have already installed SSL on your server installation, but haven’t enabled it with VirtualHost’s just yet.

Generating a key

To get things started, you will need a key. This key will be used by the VirtualHost you will define, only if you ask it to.
To generate the key, create an ssl directory in your /etc/apache2/ directory (on a Debian Etch, that is)
Then move inside that directory (cd ssl) and do the following:

mkdir crt
mkdir key
openssl req -new -x509 -days 365 -keyout key/vhost1.key -out crt/vhost1.crt -nodes -subj  ‘/O=VirtualHost Website Company name/OU=Virtual Host Website department/CN=www.virtualhostdomain.com’

This operation will create two files, crt/vhost1.crt and key/vhost1.key, that you will use in your VirtualHost definition to enable SSL encryption using that key.

Changing the VirtualHost config

Now move on to your Apache sites configuration. In most cases, you should have something like an /etc/apache2/sites-available/ and an /etc/apache2/sites-enabled directory. As sites-enabled should only contain links to sites-available, we are only interested in sites-available. So go there.

Now you should have one default file there, as well as one file that defines the configuration of the VirtualHost you would like to setup to use HTTPS.

Open the default config file. It should start with something like

NameVirtualHost *:80

or

NameVirtualHost *

Either way, change it to:

NameVirtualHost *:80
NameVirtualHost *:443

Now you have just told your webserver to accept both requests on port 443 and 80. *if* you restart your webserver at this point, you should get a warning message saying that no host is using the port 443. This is normal for me: I never really got around how to configure the whole thing correctly to avoid it throwing warnings at reload, but it is definitely not a big problem. Now let’s proceed to the config of the VirtualHost itself.

Open your VirtualHost config file. You should have something along the lines of:

<VirtualHost *>
ServerAdmin webmaster@yourdomain.com
DocumentRoot /var/www/vhost1
ServerName vhost1.yourdomain.com
DirectoryIndex index.php
ErrorLog /var/log/apache2/vhost1-error.log
CustomLog /var/log/apache2/vhost1-access.log combined
<Location />
Options Indexes FollowSymLinks
AllowOverride All
</Location>

</VirtualHost>

Together with the new config, this should look like that:

<VirtualHost *:80>
ServerAdmin webmaster@yourdomain.com
DocumentRoot /var/www/vhost1
ServerName vhost1.yourdomain.com
DirectoryIndex index.php
ErrorLog /var/log/apache2/vhost1-error.log
<Location />
RewriteEngine on
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R]
</Location>
</VirtualHost>
<VirtualHost *:443>
ServerAdmin webmaster@yourdomain.com
DocumentRoot /var/www/vhost1
ServerName vhost1.yourdomain.com
DirectoryIndex index.php
ErrorLog /var/log/apache2/vhost1-error.log
CustomLog /var/log/apache2/vhost1-access.log combined
SSLEngine On
SSLCertificateFile /etc/apache2/ssl/crt/vhost1.crt
SSLCertificateKeyFile /etc/apache2/ssl/key/vhost1.key
<Location />
SSLRequireSSL On
SSLVerifyClient optional
SSLVerifyDepth 1
SSLOptions +StdEnvVars +StrictRequire
</Location>

</VirtualHost>

Now if you restart your web server, you should be able to make it work straight away.

Note that if you do that on a fresh server, you might receive a “Configtest failed” error message. This is most likely to be due to the Rewrite or SSL modules not being enabled. Just enable them:

sudo a2enmod rewrite

sudo a2enmod ssl

sudo /etc/init.d/apache2 restart

 

2012-10-15 edit: as indicated by Gerard H. Pille in the comments to this article, Apache needs to be configured to answer on port 443 as well. This is generally a default setting in Debian/Ubuntu, but if you need to enable it, just locate the “Listen 80” in your Apache configuration directory and add a “Listen 443” on the next line. Restart Apache, and you should be done with it.

Categories: English, OSS Solutions Tags: ,
  1. June 19, 2009 at 9:10 am

    I have my website in a shared hosting server.
    can i enable https in my domain (www.peipians.com) ?
    plz help me!

    Thanks in advance.

    • ywarnier
      June 19, 2009 at 4:56 pm

      Hi. It is very unlikely that you can enable https on a shared hosting if you don’t have that option in your contract. This being said, their is generally a possibility to add the option to the cost of additional services.

  2. Lun Fa
    December 20, 2010 at 6:37 pm

    Thanks for a great article!
    Would you happen to know how this should work for multiple ssl virtual hosts (name based not IP based)?

    • Yannick Warnier
      December 20, 2010 at 6:55 pm

      I think it doesn’t (you have to have at least different virtual public addresses). You *can* have several subdomains of the same domain, using a multiple subdomains SSL feature, but having SSL for multiple domains on the same machine (or same IP) is still a problem, as far as I am aware…
      Now with all the cloud stuff and the virtualization of machines, it is kind of a little less problematic, but that is still kind of a technical headache (afaik)…

  3. Praveen
    May 12, 2011 at 8:45 am

    Hi,

    I am using Apache Tomcat server version 5, i want to change HTTP connection to HTTPS connection. Can any one please suggest me how to do in clear.

    Thanks in Advance..

    Praveen.

  4. May 12, 2011 at 5:00 pm

    Hi,

    Currently i try to setup localhost with https function. I have apache in my pc and and openssl. I using Window Xp But, up till now i still unable to UP the https function. Wish you can help me. Thanks.

    • Yannick Warnier
      May 12, 2011 at 5:27 pm

      Sorry Hasanul, we don’t support non-open technologies stacks (i.e. Windows) for a lot of reasons. You might want to have a look at the microsoft knowledge base for that (I hear they are doing a “big effort” of interoperability these days).
      Good luck!

  5. deconya
    June 17, 2011 at 1:44 pm

    Hi

    Im searching how to use https only in login page. This is because is a web that if not I can’t use mysql cache. Do you know the apache rule?

    Thanks

  6. September 23, 2011 at 12:25 pm

    This looks strange:

    SSLRequireSSL On
    SSLVerifyClient optional
    SSLVerifyDepth 1
    SSLOptions +StdEnvVars +StrictRequire

    You open a location tag and then immediately close it, then some directives and then closing the location tag again – you do this with all location tags

    Is this Apache syntax, or just a typo on your part?

    I tried both as prescribed and with

    SSLRequireSSL On
    SSLVerifyClient optional
    SSLVerifyDepth 1
    SSLOptions +StdEnvVars +StrictRequire

    and no matter what i get:

    SSL received a record that exceeded the maximum permissible length.

    (Error code: ssl_error_rx_record_too_long)

    Any tips on what this could be?

    • Yannick Warnier
      September 24, 2011 at 6:44 pm

      Probably just a typo on my part (for the opening and closing location tags), but I probably left it at the time to remember where to put it (at which level) later if needed. Thanks for pointing it out.

  7. September 23, 2011 at 12:36 pm

    Hmmm … I must’ve bungled it up

    I re-instated the weird tags and now I get what I expected. A warning that the certificate cannot be trusted and access after that

    Gotta say it out loud: APACHE IS WEIRD!

    a convention like: open tag = – closing tag = – openandclosetag = should not be messed with :)

  8. September 23, 2011 at 12:37 pm

    I meant

    open <tag>
    close </tag>
    open and close <tag/>

    should not be messed with

    • A(ncestor) Warnier
      November 28, 2012 at 11:45 am

      You shouldn’t confuse the Apache configuration file syntax with XML. It is not XML.
      In Apache config files,

      actually means “the start of the section regarding location ‘/’ ” (the document root at the top of the pages hierarchy).
      Just like
      means “the start of the section regarding location ‘/abc’ “. And the end of any Location section is indicated by a

      It’s not weird; it’s only that it was invented before XML became popular.

      • A(ncestor) Warnier
        November 28, 2012 at 11:48 am

        I adding some juducious quoting would have helped making this understandable. The missing tags above are ‘, and ‘.

  9. September 23, 2011 at 12:39 pm

    Hmmm – my first post is stripped of location tags which makes it hard to understand

    All the directive blocks in my first post is enclosed like this:

    <location />

    …. directives ….

    </location>

  10. Fabio
    December 30, 2011 at 12:10 pm

    Good job with me.

    Just two small issues: I’ve tested it today on ubuntu desktop 10.04 and I get just a pair of easy-to-solve errors. Both in this step:
    openssl req -new -x509 -days 365 -keyout key/vhost1.key -out crt/vhost1.crt -nodes -subj ‘/O=VirtualHost Website Company name/OU=Virtual Host Website department/CN=www.virtualhostdomain.com’

    The first is “unknown option Website” and I fixed it by changing in this way:
    /etc/apache2/ssl$ sudo openssl req -new -x509 -days 365 -keyout key/vhost1.key -out crt/vhost1.crt -nodes -subj ‘/O=VirtualH/OU=Virtual/CN=www.virtualhostdomain.com’

    Now I get another error “Subject does not start with ‘/’.” and I fixed it by doing this way:
    sudo openssl req -new -x509 -days 365 -keyout key/vhost1.key -out crt/vhost1.crt -nodes -subj /O=VirtualH/OU=Virtual/CN=127.0.0.1’

  11. Chad
    June 4, 2012 at 2:48 pm

    The problem with “Unknown option Webisite” is fixed by replacing the matched single quotes in the openssl command with ordinary single quotes. You probably cut and pasted the code into your console, right? WordPress blogs automatically translate single and double quotes into matched quotes, and it can screw up code.

    Great tutorial Yannick! I’ve generated my keys, but I’m going to have to go to bed before trying the rest tomorrow.

  12. October 14, 2012 at 6:52 pm

    Shouldn’t the “LISTEN 443” appear somewhere in your article?

    • Yannick Warnier
      October 16, 2012 at 1:58 am

      Interesting question. The Listen directive is usually enabled on port 443 on Debian/Ubuntu installations (/etc/apache2/ports.conf), so the process to enable it is not really necessary on that architecture, but yes, technically, there needs to exist a “Listen 443” somewhere so that Apache can tell inetd that it will answer to port 443 (generally it also already answers to port 80). Thanks.

  13. December 7, 2012 at 11:59 pm

    Very very good, all is right

  14. eddy (Guatemala)
    November 22, 2014 at 5:33 am

    Hi, I want to configure apache2 with https
    I have running a virtual box ubuntu 14.04 64-bits machine that running over Windows 7,
    how I can configure apache2 with https if I do not have a domain “ServerAdmin webmaster@yourdomain.com” because is locally,

    by the way
    this is for education purpose

  15. sand
    December 17, 2014 at 9:53 am

    “Open your VirtualHost config file …”
    pl tell me the location of this file.

  16. Almar
    November 3, 2015 at 6:46 pm

    Thanks for everything !
    You’re awesome.

  17. Paul L.
    March 30, 2016 at 10:50 am

    Hello!
    I try to use Apache 2.4.10 on Debian 8.3 as a reverse-proxy server for my Microsoft Remote Desktop Services (on 2012R2). And all seems to be ok, but I can’t to make an RDP connection wich is tunnelling in https session (between Apache & MSRDS )

    And there is a problem in the Apache log:
    “RDG_OUT_DATA /remoteDesktopGateway/ HTTP/1.1” 404 5633 “-” “MS-RDGateway/1.0”
    “RPC_OUT_DATA /rpc/rpcproxy.dll?localhost:3388 HTTP/1.1” 401 506 “-” “MSRPC”
    “RPC_IN_DATA /rpc/rpcproxy.dll?localhost:3388 HTTP/1.1” 400 0 “-” “MSRPC”
    error] (70007)The timeout specified has expired: proxy: prefetch request body failed to x.x.x.x from x.x.x.x

    May be you know is there any way (may be special module) to resolve such trouble or Apache doesn’t support the for Microsoft’s non-standard HTTP behavior still?

    Any comments appreciated. Thanks.

  18. March 30, 2016 at 3:35 pm

    This was the answer I was looking for for over an hour! Thanks! You have saved me from losing my mind!
    My site was displaying when I typed in the address again suddenly it was giving me 403 errors. In fact I had been loading the https version up until then so I hadn’t been aware that the http version was causing errors.

  1. March 17, 2011 at 5:23 am
  2. February 14, 2012 at 6:04 pm
  3. March 21, 2012 at 9:11 pm
  4. September 14, 2012 at 6:10 pm
  5. August 2, 2013 at 1:04 am
  6. November 5, 2013 at 10:40 am
  7. January 7, 2015 at 3:49 pm
  8. January 8, 2015 at 7:44 am
  9. October 11, 2016 at 9:58 pm
  10. September 2, 2017 at 4:57 pm

Leave a comment