# Howto: Apache2 ssl and vhosts

## revresxunil

I've run into this, and i've seen others run into this.  You want to setup vhosts, and you want ssl to work too, but once you allow vhosts.conf to be included in the apache configs, ssl stops working or you get errors about the port already being defined, or stuff like that.

The truth of this matter, is the ssl VHOST is already defined in /etc/apache/conf/modules.d/41_mod_ssl.default-vhost.conf.  Thats why there is errors when you try to make your own vhost for ssl.  Here's what you need to do:

1)  move 41_mod_ssl.default-vhost.conf to 41_mod_ssl.default-vhost.conf.bak so that it is not loaded as a config.

2) create /etc/apache/conf/modules.d/ssl.conf and add the following:

```

<IfDefine SSL> 

  <IfModule !mod_ssl.c> 

    LoadModule ssl_module    extramodules/mod_ssl.so 

  </IfModule> 

</IfDefine> 

```

That will tell apache that it can load the ssl module if the -D SSL flag is present in /etc/conf.d/apache2.

3) If you have not already uncommented the vhost.conf include from /etc/apache2/conf/apache2.conf do so now.

```

###

### Virtual Hosts

###

# We include different templates for Virtual Hosting. Have a look in the

# vhosts directory and modify to suit your needs.

Include conf/vhosts/vhosts.conf

#Include conf/vhosts/dynamic-vhosts.conf

#Include conf/vhosts/virtual-homepages.conf

```

4) Everything that was in the default ssl.conf file should now be placed in vhost.conf with a little modifications so that it will work flawlessly.  If you follow my sample /etc/apache2/conf/vhosts/vhost.conf file, you should be on the track to getting vhosts, ssl, and apache2 working like good friends.

```

NameVirtualHost *:80 

<VirtualHost *:80> 

    ServerName revresxunil.cmforums.net 

    ServerPath /htdocs 

    DocumentRoot /home/httpd/htdocs 

    ServerAdmin root@localhost 

</VirtualHost> 

<VirtualHost *:80> 

    ServerName forums.cmforums.net

    ServerPath /forums 

    DocumentRoot /home/httpd/forums 

    ServerAdmin root@localhost 

</VirtualHost> 

<IfModule mod_ssl.c> 

<VirtualHost *:443> 

    DocumentRoot "/home/httpd/secure" 

    #ServerName localhost:443 

    #ServerAdmin root@localhost 

    ErrorLog logs/ssl_error_log 

    <IfModule mod_log_config.c> 

      TransferLog logs/ssl_access_log 

    </IfModule> 

    SSLEngine on 

    SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL 

    SSLCertificateFile conf/ssl/server.crt 

    SSLCertificateKeyFile conf/ssl/server.key 

    <Files ~ "\.(cgi|shtml|phtml|php?)$"> 

      SSLOptions +StdEnvVars 

    </Files> 

    <Directory "/home/httpd/cgi-bin"> 

      SSLOptions +StdEnvVars 

    </Directory> 

    <IfModule mod_setenvif.c> 

      SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown \ 

      downgrade-1.0 force-response-1.0 

    </IfModule> 

    <IfModule mod_log_config.c> 

      CustomLog logs/ssl_request_log \ 

      "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b" 

    </IfModule> 

    <IfModule mod_rewrite.c> 

      RewriteEngine On 

      RewriteOptions inherit 

    </IfModule> 

</VirtualHost> 

</IfModule> 

```

As always, make sure to add some <directory>'s to your commonapache.conf that match the newly created vhost.  (ill post a specific example of directory when I get my webserver back up... Im in a transition from apartment to dorm room right now.

----------

## h0rntuckin

hi.

thanks for this howto.  it seems to make so much sense, yet i've followed it to the letter and apache2 still will not start.

```
root@mythbox conf # /etc/init.d/apache2 restart

 * Starting apache2...                                                                        [ !! ]
```

is all i get.  here's my setup:

 - apache2 compiled w/ ssl

 - APACHE_OPTS=-D SSL in /etc/conf.d/apache2

 - the stock apache2.conf file, vhosts uncommented, and the vhosts file looking exactly like yours below (w/ my domain-specific stuff of course)

 - an ssl.conf defined exactly as above

 - 41...ssl...conf renamed .bak so it doesn't load

here's some diagnostics which may be informative:

```
root@mythbox conf # apache2ctl -S

VirtualHost configuration:

wildcard NameVirtualHosts and _default_ servers:

*:443                  mail.nudz.org (/etc/apache2/conf/vhosts/nudz.conf:56)

*:80                   is a NameVirtualHost

         default server www.nudz.org (/etc/apache2/conf/vhosts/nudz.conf:37)

         port 80 namevhost www.nudz.org (/etc/apache2/conf/vhosts/nudz.conf:37)

         port 80 namevhost gallery.nudz.org (/etc/apache2/conf/vhosts/nudz.conf:49)

Syntax OK
```

anybody out there got an idea as to why apache2 won't start for me using this configuration?

----------

## rizzo

Is it still the case that you can only have ONE ssl host?  That is you can NOT have multiple virtual ssl hosts using their own certificates?  I can get multiple https hosts, but they all use the same certificate so I get a warning when the domains don't match.

I read in another post from splooge that this was, indeed, impossible, but there must be something that can be done.

----------

## El_Presidente_Pufferfish

```

    <IfModule mod_log_config.c>

      TransferLog logs/ssl_access_log

    </IfModule>

    SSLEngine on

    SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL

    SSLCertificateFile conf/ssl/server.crt

    SSLCertificateKeyFile conf/ssl/server.key

    <Files ~ "\.(cgi|shtml|phtml|php?)$">

      SSLOptions +StdEnvVars

    </Files>

    <Directory "/home/httpd/cgi-bin">

      SSLOptions +StdEnvVars

    </Directory>

    <IfModule mod_setenvif.c>

      SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown \

      downgrade-1.0 force-response-1.0

    </IfModule>

    <IfModule mod_log_config.c>

      CustomLog logs/ssl_request_log \

      "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"

    </IfModule>

    <IfModule mod_rewrite.c>

      RewriteEngine On

      RewriteOptions inherit

    </IfModule>
```

Do you need all that?

i'm not quite sure what all of it does, so if you could tell me, or point me towards the proper documentation that would be great

----------

## vdboor

 *revresxunil wrote:*   

> 1)  move 41_mod_ssl.default-vhost.conf to 41_mod_ssl.default-vhost.conf.bak so that it is not loaded as a config.
> 
> 

 

there is something I'd like to add here.. I've just re-merged apache, and the file was created again.. It took quite a while before I noticed this. (and why my server wasn't working  .. because I did an 'emerge -e system')

I'd recommend everyone to clear the file, and keep a notice there (why you removed it). This prevents 'emerge' from overwriting your file, and you remember this when you run etc-update.  :Wink: 

----------

## Hideki

About having multiple certificates, I have run into the same questions and did a search and I found it was not possible.

When https protocol is requested, client and server does some handshake authentication, at that time only IP is known to the server and no host name is passed from the client. http gives Host: header and is a must on HTTP/1.1 protocol, so the apache knows which directory to show, but when handshaking(giving out certificates) there is no way the server can know by which host name the client wants, and I heard it's some kind of security stuff not to include Host: header like http protocol in ssl handshaking.

That's all I know and I just use one default certificate for multiple ssl vhosts.

But it's funny even not recognizing the second certificate in ssl.conf, if the certificate configuration is missing the apache won't work, so you have to either put the default one or some fake configuration line.

Though it works if you make it access on different port. Like https://abc.somehost.org:443 and https://def.somehost.org:1443

can give out 2 different certificates. You have to get around it with your own tweak like redirecting etc to get multiple vhost certificates.

----------

## tuxable

I believe you can have multiple secure certificates, but you have to have an IP address associated with each one.  You can have multiple IP addresses for one network connection.

----------

## BoBoeBoe

This sounds like what I want to do, could anyone post an example of a vhost.conf file with multiple vhosts with their own certificates? It seems a more tricky than I expected it to be.

And could anyone explain the different sections in the vhost.conf because I don't understand it completely

Thanks

----------

## Wilhelm

I was reading the Apache2.0 docs and if you want SSL you'll have to do IP-based virtual hosting and not Name-Based.

http://httpd.apache.org/docs-2.0/vhosts/

I'm planning on using my DNS to route a full 10.*.*.* subnet of domains.

Ok it will cost me some more time to configure and script but i'm not limited in any way. I can also do per site logging and bandwidth throttling if i wish according to apache.

[EDIT] Hrmm this is hard and unknown territory but i'll have to alias the whole C-Class onto my single interface and hope it goes well.

----------

## starachna

Yes, Apache "can" only have one ssl host on port 443, but you can tell apache to listen on port 1443 and 2443 and 3443, that way you can have multiple certs on one ip ...

----------

## ElForesto

Great how-to! This was precise and very easy to follow.

As a side note, anyone needing a free certificate from a certificate authority (CA) should really take a look at http://www.cacert.org/ I got freebies for my server and all of my e-mail addresses.

----------

## postop

Just to make sure what I'm doing is right, I wanted to have http and https support for the two virtual hosts that I created.

I took your sample file (thanks by the way, I didn't move the modules file to a .bak, just commented out everything in it). I created two vhosts in the IfModule section, both listening on :443 and with the same configuration as the :80s. 

I needed to at a NameVirtualHost *:443 also. This makes both sites come up fine with just the certificate warning. There's some mod_jk stuff in there too which also finally works. You'll need to duplicate the workers along with the docroot, servername, and serveralias.

```

<Directory "/var/www/localhost/websites">

  Options Indexes

  AllowOverride None

  Order allow,deny

  Allow from all

</Directory>

<Directory "/var/www/localhost/applications">

  Options Indexes

  AllowOverride None

  Order allow,deny

  Allow from all

</Directory>

NameVirtualHost *:80

<VirtualHost *:80>

  ServerName joel.sol

  ServerAlias joel

  DocumentRoot /var/www/localhost/websites/joel.sol/htdocs

  CustomLog /var/log/apache2/joel.sol.access_log combined

  ErrorLog /var/log/apache2/joel.sol.error_log

  <Location "/webapp">

    JkUriSet worker ajp13:localhost:8009

  </Location>

</VirtualHost>

<VirtualHost *:80>

  ServerName alt.joel.sol

  ServerAlias alt.joel

  DocumentRoot /var/www/localhost/websites/alt.joel.sol/htdocs

  CustomLog /var/log/apache2/alt.joel.sol.access_log combined

  ErrorLog /var/log/apache2/alt.joel.sol.error_log

  <Location "/webapp">

    JkUriSet worker ajp13:localhost:8009

  </Location>

</VirtualHost>

<IfModule mod_ssl.c>

NameVirtualHost *:443

  <VirtualHost *:443>

    DocumentRoot /var/www/localhost/websites/joel.sol/htdocs

    ServerName joel.sol

    ServerAlias joel

    ErrorLog logs/ssl_error_log

    <IfModule mod_log_config.c>

      TransferLog logs/ssl_access_log

    </IfModule>

    <Location "/webapp">

      JkUriSet worker ajp13:localhost:8009

    </Location>

    ... ssl junk ...

  <VirtualHost *:443>

    DocumentRoot /var/www/localhost/websites/alt.joel.sol/htdocs

    ServerName alt.joel.sol

    ServerAlias alt.joel

    ErrorLog logs/ssl_error_log

    <IfModule mod_log_config.c>

      TransferLog logs/ssl_access_log

    </IfModule>

    <Location "/webapp">

      JkUriSet worker ajp13:localhost:8009

    </Location>

    ... ssl junk ...

  </VirtualHost>

</IfModule>

```

----------

## kezzla

Would just like to say THANKS to POSTOP !!!

 *Quote:*   

> I needed to add a NameVirtualHost *:443 also. This makes both sites come up fine with just the certificate warning.

 

Works awesomely !

----------

## Corona688

Just wanted to say, Thanks!  I've been wrestling with this all day, but this thread told me all I needed to know.

----------

## biatch0

Just thought this might help someone, since I got stuck for a couple of hours here.

You MUST add this to commonapache2.conf to match the vhosts... In my case, all vhosts are in /www/directoryname, which is why I use <Directory "/www/*">. If this entry is missing, you end up with 403's for all your vhosts...

```
<Directory "/www/*"> 

  Options Indexes 

  AllowOverride None 

  Order allow,deny 

  Allow from all 

</Directory> 

```

Peace.

----------

## indynet

 *biatch0 wrote:*   

> Just thought this might help someone, since I got stuck for a couple of hours here.
> 
> You MUST add this to commonapache2.conf to match the vhosts... In my case, all vhosts are in /www/directoryname, which is why I use <Directory "/www/*">. If this entry is missing, you end up with 403's for all your vhosts...
> 
> 

 

You should setup directoryindex instead of show all files by your configuration.

----------

## kevev

It worked. I will post my config files for anyone having issues with the latest apache2 config file layout.

----------

## seemant

post them, kevev

----------

## kevev

Yikes forgot to. Now I am having trouble so I dont want to post them yet. I just upgraded to php4 and php5 using SUPHP. I will post if I get it working.......

----------

## lyallp

I note these posts are 15 years old.

I thought I would setup ssl for my local pages on my local apache server.

Any chance of an update, for example, the initial post has config files in the wrong place, which immediately made me suspicious of the rest of the article, excellent though it may be, at the time.

Or, if the article is still relevant, just posting a ping that it is still relevant  :Smile: 

----------

## szatox

I use use this config for apache vhost. The document root is /var/www/<hostname>.

The stuff that's commented out is something I use (because reasons) but is not strictly required to make things work.

```
/etc/apache2/vhosts.d # cat vhost.conf 

Listen ::1:8080 # could be 127.0.0.1:8080 just as well

<VirtualHost *:8080>

   VirtualDocumentRoot "/var/www/%0"

   <Directory /var/www/*/>

#      Options -Indexes

#      AllowOverride All

      Require all granted

      DirectorySlash On

   </Directory>

#   <Directory "/var/www/*/.git/">

#      Require all denied

#   </Directory>

#      <Directory "/var/www/*/cgi-bin/">

#      Options ExecCGI

#      SetHandler cgi-script

#   </Directory>

#

#   LogFormat "%t %v:%p %{X-Forwarded-For}i %{Host}i %l %u \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" proxy

#   ErrorLog  /var/log/apache2/error.log

#   CustomLog /var/log/apache2/access.log proxy

#   SetEnvIf X-Forwarded-Proto https HTTPS=on

   UseCanonicalName Off

</VirtualHost>

```

Something's missing, you say?

Well.... I just do ssl termination on haproxy in front of apache:

```
frontend www-https

    bind *:443 ssl crt-list /etc/haproxy/cert.list ciphers ECDH+AESGCM256:DH+AESGCM256:ECDH+AES256:SH+AES256:RSA+AESGCM256:RSA+AES256:!aNULL:!MD5:!kEDH no-sslv3

#    acl acl_xff_exists req.hdr(X-Forwarded-For) -m found

#    http-request set-header X-Forwarded-Proto https

#    http-request set-header X-Forwarded-For %[hdr(X-Forwarded-For)],\ %[src] if acl_xff_exists

#    http-request set-header X-Forwarded-For %[src] if ! acl_xff_exists

    default_backend servers

```

Cert list /etc/haproxy/cert.list ciphers  is automagicaly generated by a script triggerd via letsencrypt hook which checks out what certificates are available, compiles a list, and then then triggers a config reload. This happens upon renewal.

It  does use additional tools to do the same job, but splitting ssl from vhosts makes the configuration cleaner and more manageable, since every tool does what it can do well.

Like in: I don't have to touch that vhost config _ever_ again, and cert-list updates are trivial to automate, so I can add a new site by simply creating a new directory under /var/www and optionally generating a certificate (which will update haproxy's cert-list and trigger a reload).

I think that apache alone would require me to create a new vhost configuration for every certificate I have instead of one dynamic vhost to serve all sorts of contents.

----------

## alamahant

The mod_ssl is already enabled in httpd.conf

```

<IfDefine SSL>

LoadModule socache_shmcb_module modules/mod_socache_shmcb.so

</IfDefine>

LoadModule speling_module modules/mod_speling.so

<IfDefine SSL>

LoadModule ssl_module modules/mod_ssl.so

</IfDefine>

```

You can have as many ssl vhosts as you wish provided they have different ServerName directives.

Use this format

```

<VirtualHost *:443>

...

</VirtualHost>

```

The "NameVirtualHost" directive is somewhat obsolete.

You can keep both the default_ssl_vhost and all your other ssl vhosts at the same time provided you do not redeclare "Listen 443"

----------

## guitou

Hi.

If having a local webserver is only for serving on your local network, setting up https is almost useless but for testing purpose, otherwise here (last example) is a minimal sample...

```

  SSLProtocol all -SSLv2

  SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5

```

Could not tell how relevant this is (most probably enough for a local net and a self signed certificate), but if using certbot and a letsencrypt certificate, you may have to replace them with a file include.

And last, just make a 301 (permanent) redirect from standard port vhost (or default) config, if you want to force https.

++

Gi)

----------

## lyallp

Just to provide a little background on why I would like to setup ssl on my local machine.

I serve http://olde-distfiles.is.remotely-helpful.info from my home PC, 250G+ is a bit to much for my shared hosting plan.

I have domain is.remotely-helpful.info with SSL but olde-distfiles (host) redirects to my home IP address, which is fixed.

My modem re-routes requests for this redirection to my home PC which serves up the info via Gentoo/apache.

So, given the internet is heading towards ssl, by default, I figured I would setup my apache to serve up https://olde-distfiles.is.remotely-helpful.info

I have rate-limited this particular URL to 1024/512 with mod_ratelimit, so that my home internet is not consumed entirely by remote accesses, so the page may take  a little time to load, as there are over 70k files in portage distfiles layout.

I also have fail2ban running on everything else my apache server serves up, with olde-distfiles being the only directory which does not require authentication.

It's quite interesting seeing the hack attempts that arrive.

olde-distfiles may be used as a portage source, if required, hence the existence of a self referring symlink to distfiles in the tree.

----------

