Do I have to duplicate the Virtualhost directives for port 80 and 443?

ApacheVirtualhost

Apache Problem Overview


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.

Apache Solutions


Solution 1 - Apache

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>  

Solution 2 - Apache

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>

Solution 3 - Apache

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>

Solution 4 - Apache

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 [email protected]
   <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

Solution 5 - Apache

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>

Solution 6 - Apache

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionscottsView Question on Stackoverflow
Solution 1 - ApachesfossenView Answer on Stackoverflow
Solution 2 - ApacheDumindu PereraView Answer on Stackoverflow
Solution 3 - ApacheRemyNLView Answer on Stackoverflow
Solution 4 - ApacheSebView Answer on Stackoverflow
Solution 5 - ApachesmeView Answer on Stackoverflow
Solution 6 - ApacheMatt JacobView Answer on Stackoverflow