64

I have a long and intricate list of <VirtualHost> directives, and I have to duplicate them into separate <VirtualHost> groups for ports 80 and 443 because I'm using SSL. Whenever I update my mod_rewrite rules I have to remember to do it in both places or else I'll break my app... this duplication is asking for trouble. Is there a way to combine or alias these -- the only difference between the two is that the port 443 version contains the SSLEngine, SSLCertificateFile and the like.

My <Virtualhost> contains many mod_rewrite rules, LocationMatch rules, CGI directives, etc.

Also, I can't use .htaccess files.

scotts
  • 4,027
  • 3
  • 29
  • 26

6 Answers6

53

Can't you use an include directive to include the common rules. here

article

eg.:

<VirtualHost _default_:80>
    ...
    include conf/common_rule.conf
</VirtualHost>

<VirtualHost _default_:*>
    ...
    include conf/common_rule.conf
</VirtualHost> 

<VirtualHost _default_:443>
    ... #SSL rules
    include conf/common_rule.conf
</VirtualHost>  
sfossen
  • 4,774
  • 24
  • 18
  • thanks for this; btw, [here's an updated version](http://httpd.apache.org/docs/2.4/mod/core.html#include) of the apache `include` directive, which is the first linked-to resource in your answer – ILMostro_7 Feb 04 '14 at 11:46
  • 1
    A simpler solution for me was to rename *:80 to *:443 and then setup a very tiny *:80 VirtualHost that redirects. I realize this doesn't directly answer the original question, but if there's interest I'm happy to share my config. – Jonathan Berger May 01 '19 at 23:29
36

You can use any # of hosts and ports in a single Virtualhost directive.

<VirtualHost addr[:port] [addr[:port]] ...> ... </VirtualHost> 

In My case I used.

<VirtualHost *:80 *:443>
  ServerName loop.lk

 ....
SSLEngine on
SSLCertificateFile /etc/apache2/ssl/local.crt

</VirtualHost>
Dumindu Perera
  • 1,571
  • 15
  • 13
  • 10
    SSLEngine on seems to be applied even when the site is accessed via http, resulting in an error page. – Jacob Rigby Oct 09 '13 at 07:05
  • 2
    If you have a `` block, I'm assuming you can then have a separate block for `` that only includes the SSL stuff. Is that correct? – iconoclast Nov 26 '13 at 16:42
  • 3
    @iconoclast No you can't have another directive. You can use .... OR ... – Dumindu Perera Jan 27 '14 at 09:08
  • @SampathPerera it does return an error message for me too: "Bad Request Your browser sent a request that this server could not understand. Reason: You're speaking plain HTTP to an SSL-enabled server port. Instead use the HTTPS scheme to access this URL, please." – Greg Dubicki Jun 24 '15 at 14:37
  • ..and it does in fact use HTTPS on both 80 and 443 ports, which can be proven by using URL like https://yourhost.yourdomain.com:80 in your browser. – Greg Dubicki Jun 24 '15 at 14:38
  • Can you share more of your config, @SampathPerera? How did you make it work? – Greg Dubicki Jun 24 '15 at 14:38
  • I think the syntax would only work with Apache >=2.4. – contrebis Aug 28 '15 at 13:56
  • Hi @GregDubicki , here is a complete example: ServerName loop.lk DocumentRoot /var/www/loop/web Order allow,deny Allow from All AllowOverride None SSLEngine on SSLCertificateFile /etc/apache2/ssl/apache.crt SSLCertificateKeyFile /etc/apache2/ssl/apache.key – Dumindu Perera Aug 29 '15 at 15:10
  • Thanks @SampathPerera, and what Apache HTTPD version are you using? – Greg Dubicki Aug 29 '15 at 16:54
  • As noted above, `SSLEngine On` won't work, but most SSL settings are inherited from global config. You can put `SSLEngine optional` if you need per-vhost different settings of the key/certificate pair, for example. Also, in my experience, this needs the `_default_:443` Vhost as the first in the config, and that needs an explicit `SSLEngine on`. – Ulrich Schwarz Jun 25 '17 at 07:07
10

Sorry to bump up an old post like this, but in order to help other Googlers out there I wanted to share how I dealt with it:

I have a couple of vhosts on my localhost, say: localhost, foo.com, bar.com

This being a localhost site on my laptop (macosx) I could get away with self-signed certificates and thus the ssl-part is the same for all the vhosts...

What I did is this:

I created the directory /etc/apache2/extra/vhosts/.

I created a /etc/apache2/extra/vhosts/localhost.conf:

ServerName localhost
DocumentRoot "/www/localhost"
<Directory /www/localhost>
  Require all granted
</Directory>
ErrorLog "/var/log/apache2/localhost.error_log"
CustomLog "/var/log/apache2/localhost.access_log" common

A /etc/apache2/extra/vhosts/foo.conf:

ServerName foo.com
DocumentRoot "/www/foo.com"
<Directory /www/foo.com>
  Require all granted
</Directory>
ErrorLog "/var/log/apache2/foo.com.error_log"
CustomLog "/var/log/apache2/foo.com.access_log" common

A /etc/apache2/extra/vhosts/bar.conf:

ServerName bar.com
DocumentRoot "/www/bar.com"
<Directory /www/bar.com>
  Require all granted
</Directory>
ErrorLog "/var/log/apache2/bar.com.error_log"
CustomLog "/var/log/apache2/bar.com.access_log" common

And finally a /etc/apache2/extra/vhosts/ssl.conf:

SSLEngine on
SSLCertificateFile "/etc/apache2/ssl/server.crt"
SSLCertificateKeyFile "/etc/apache2/ssl/server.key"

And in my /etc/apache2/extra/httpd-vhosts.conf:

<VirtualHost *:80>
  Include /etc/apache2/extra/vhosts/localhost.conf
</VirtualHost>
<VirtualHost *:443>
  Include /etc/apache2/extra/vhosts/localhost.conf
  Include /etc/apache2/extra/vhosts/ssl.conf
</VirtualHost>

<VirtualHost *:80>
  Include /etc/apache2/extra/vhosts/foo.conf
</VirtualHost>
<VirtualHost *:443>
  Include /etc/apache2/extra/vhosts/foo.conf
  Include /etc/apache2/extra/vhosts/ssl.conf
</VirtualHost>

<VirtualHost *:80>
  Include /etc/apache2/extra/vhosts/bar.conf
</VirtualHost>
<VirtualHost *:443>
  Include /etc/apache2/extra/vhosts/bar.conf
  Include /etc/apache2/extra/vhosts/ssl.conf
</VirtualHost>
reformed
  • 4,505
  • 11
  • 62
  • 88
RemyNL
  • 576
  • 3
  • 8
  • Also went with this solution. Works great – Aaron Ransley Nov 06 '15 at 18:35
  • No need to apologize for "bumping". StackOverflow's point is to collect the best answers, not to be a chat room. The idea of needing to have a different thread based on time is a holdover from the days of dial-up Bulletin Board Systems. – hackerb9 Sep 02 '22 at 23:09
7

Another option instead of using Include is using Macro (so you can keep it all in one file).

First enable the macro module:

a2enmod macro

Then put your shared stuff in a macro and use it from your virtualhosts:

<Macro SharedStuff>
   ServerName example.com
   ServerAdmin example@example.com
   <DocumentRoot /var/www/example>
      ...
   </DocumentRoot>
</Macro>

<VirtualHost *:80>
  Use SharedStuff
</VirtualHost>

<VirtualHost *:443>
  Use SharedStuff

  SSLEngine On
  SSLProtocol All -SSLv2 -SSLv3
  ...
</VirtualHost>

Macros can also take parameters, and be defined in other files that are included; so you can use them a bit like Functions, and save a lot of duplication across your Apache config files.

See here for more details:

https://httpd.apache.org/docs/2.4/mod/mod_macro.html

Seb
  • 6,507
  • 2
  • 19
  • 23
  • Great answer, but this isn't in 2.2 in case anyone wanted to know. – poolnoodl Feb 11 '19 at 01:14
  • No, this is a 2.4 onward feature; however, 2.2 went EOL with the final release in July 2017 so really everyone should be on 2.4 by now :) – Seb Feb 19 '19 at 13:54
2

You could put the common configuration into a separate file and include it in both VirtualHost segments. For example:

<VirtualHost 192.168.1.2:80>
  Include conf/common.conf
</VirtualHost>

<VirtualHost 192.168.1.2:443>
  Include conf/common.conf
  (put your ssl specific cofiguration stuff here ...)
</VirtualHost>
Uwe Kleine-König
  • 3,426
  • 1
  • 24
  • 20
sme
  • 5,673
  • 7
  • 32
  • 30
0

You could also specify the common directives within a container instead of within the itself. That's what I do, mostly because I prefer mod_rewrite rules at the directory level instead of at the server level, but it should work equally well for you too.

Matt Jacob
  • 6,503
  • 2
  • 24
  • 27
  • 5
    You're missing a critically important word. Can you add that? And if you could give an example that would also be helpful. – iconoclast Nov 26 '13 at 16:43