27

I need to setup my VirtualHost on Apache to serve on both http and https (using standard ports)

If I enable the SSL Engine (as per below) - I get an error when on port 80.

The reason is, parts of the site need to be SSL but other parts don't. How can I go about serving both http + https on the site?

Here is my virtual host file....

NameVirtualHost *

<VirtualHost *>
        ServerAdmin webmaster@localhost
        ServerName mysite.co.uk
        DocumentRoot /var/www/mysite/public
        <Directory />
                Options FollowSymLinks
                AllowOverride None
        </Directory>
        <Directory /var/www/mysite/public>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride All
                Order allow,deny
                allow from all
        </Directory>

        ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
        <Directory "/usr/lib/cgi-bin">
                AllowOverride None
                Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
                Order allow,deny
                Allow from all
        </Directory>

        ErrorLog /var/log/apache2/error.log

        # Possible values include: debug, info, notice, warn, error, crit,
        # alert, emerg.
        LogLevel warn

        CustomLog /var/log/apache2/access.log combined
        ServerSignature On

    Alias /doc/ "/usr/share/doc/"
    <Directory "/usr/share/doc/">
        Options Indexes MultiViews FollowSymLinks
        AllowOverride None
        Order deny,allow
        Deny from all
        Allow from 127.0.0.0/255.0.0.0 ::1/128
    </Directory>

     #SSL STUFF...
      SSLEngine on
      SSLCertificateFile /etc/apache2/crts/mysite.crt
      SSLCertificateKeyFile /etc/apache2/crts/mysite.key
      SSLCertificateChainFile /etc/apache2/crts/DigiCertCA.crt


</VirtualHost>
41

You can't do this in one virtual host, because Apache needs to know which one's going to talk SSL and which one isn't (sidenote: nginx doesn't have this problem, you can tell it which listen directives relate to SSL; one of the many reasons I love it).

The way I manage this in Apache is to put all my non-SSL-related configuration into a separate file, and then have the two vhosts configured next to each other, each including the site-specific configuration file inside the vhost stanza, like this:

<VirtualHost 192.0.2.12:80>
    Include /etc/apache2/sites/example.com
</VirtualHost>

<VirtualHost 192.0.2.12:443>
    SSLEngine On
    # etc
    Include /etc/apache2/sites/example.com
</VirtualHost>
6

It seems like an issue in Apache vHost, but it does the job without having to repeat configuration.

SSLCertificateFile /srv/.ssl/self/server.crt
SSLCertificateKeyFile /srv/.ssl/self/server.pem

# REQUIRED
<VirtualHost *:80>
    DocumentRoot /srv/www/badhost
</VirtualHost>

<VirtualHost *:80 *:443>
    SSLEngine On
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /srv/www/example.www
</VirtualHost>
  • That's really weird, but exists! – user77376 Mar 24 '16 at 11:01
  • 1
    This worked as well as you might expect from such a kludge — almost, but not quite! I found that Apache 2.4.10 sets the SERVER_PORT environment variable to 443 instead of using the port on which the request came in (80 or 443 depending). <IMAGINARY_PARAGRAPH_BREAK> Pity, as I was hoping to be able to use this, as I really wanted to keep one file per virtual host. <IMAGINARY_PARAGRAPH_BREAK> Also, you will need a ServerName directive inside the top <VirtualHost> otherwise it will gobble up requests by mistake. Set it to ServerName badhost.bad or something. – Daniel Beardsmore Oct 17 '16 at 17:40
  • 1
    @DanielBeardsmore: I've just tested this with 2.4.18 from RH Software collections, and that seems to be due to the default of UseCanonicalPhysicalPort Off. If you set that to on, you seem to get the actual port used. (Funnily enough, I had to leave off the SSLEngine On in my doubly-used vhost and got port 80 as the default.) – Ulrich Schwarz Jan 6 '17 at 6:54
  • 1
    @DanielBeardsmore: FWIW, %{HTTPS} will also be set correctly, but %{REQUEST_SCHEME} isn't (always http). I'd feel silly putting in a feature request for a UseCanonicalRequestScheme directive, though. – Ulrich Schwarz Jan 6 '17 at 7:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.