Do I have to duplicate the Virtualhost directives

2019-03-07 23:00发布

问题:

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.

回答1:

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>  


回答2:

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>


回答3:

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>


回答4:

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>


回答5:

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.



回答6:

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