Override single setting in default Apache <VirtualHost> block - apache

In debian's default apache2 configuration, /etc/apache2/sites-enabled/000-default contains a lot of settings for the default VirtualHost:
<VirtualHost *:80>
# Many good settings here, among them:
CustomLog ${APACHE_LOG_DIR}/access.log combined
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
</VirtualHost>
In another configuration file, I'd like to override a single one of them, the CustomLog setting, so that logs go somewhere else. I don't want to copy or mess with all the other settings, e.g. ScriptAlias. But I still want it to apply to <VirtualHost *:80>.
Is that possible?
What I tried
I tried putting this in
/etc/apache2/sites-enabled/001-mylog:
<VirtualHost *:80>
CustomLog ${APACHE_LOG_DIR}/my.log combined
</VirtualHost>
That has no effect, presumably because apache only looks at the first <VirtualHost> section, and /etc/apache2/sites-enabled/000-default gets loaded before /etc/apache2/sites-enabled/001-mylog.
Instead I tried putting the same snippet in /etc/apache2/conf.d/mylog, that gets loaded before /etc/apache2/sites-enabled/000-default because /etc/apache2/apache2.conf has an Include conf.d/ before Include sites-enabled/. That does override the CustomLog value as I wanted. But now the ScriptAlias from /etc/apache2/sites-enabled/000-default doesn't take effect.
I'd like to avoid duplicating everything from /etc/apache2/sites-enabled/000-default effectively creating a fork of the default debian apache configuration file.
Documentation
Apache HTTP Server - core documentation has this rather vague:
When a request is received, the server first maps it to the best matching
based on the local IP address and port combination only.
Non-wildcards have a higher precedence. If no match based on IP and port occurs
at all, the "main" server configuration is used.
If multiple virtual hosts contain the best matching IP address and port, the
server selects from these virtual hosts the best match based on the requested
hostname. If no matching name-based virtual host is found, then the first
listed virtual host that matched the IP address will be used. As a consequence,
the first listed virtual host for a given IP address and port combination is
default virtual host for that IP and port combination.
<VirtualHost> doesn't behave like <Directory>
Very confusingly, it looks to me as if for <VirtualHost> directives, only a single matching instance is considered. But for e.g. <Directory> directives, they are added/combined, so that:
<Directory "/some/dir">
Options Indexes MultiViews FollowSymLinks
</Directory>
<Directory "/some/dir">
AllowOverride None
Order deny,allow
Allow from all
</Directory>
is equivalent to:
<Directory "/some/dir">
Options Indexes MultiViews FollowSymLinks
AllowOverride None
Order deny,allow
Allow from all
</Directory>
But that this mechanism doesn't work for <VirtualHost> :-(
Edit: This is not the same as Sharing configuration between several VHosts, because debian's default VirtualHost doesn't use any of those solutions. But perhaps others can find inspiration in that answer.

I get the same puzzle for the multiple vhosts'(virtual hosts') definition. Do they override(redefine), overlap? Or there are other veiled details inside?
I find some links for this puzzle as following:
https://www.thegeekstuff.com/2011/07/apache-virtual-host/
https://httpd.apache.org/docs/2.4/vhosts/examples.html
With cautions to these examples inside, I could say the vhosts' definitions are not the same (even they look like the same). The difference mainly lays on the SeverName inside definition. Apache httpd server distinguishes the different vhost definitions based on ServerName inside(each vhost definition), not the IP Address or Port Number as listed in the <VirtualHost> header.
This puzzle keeps coming and going since there lacks explicit explanation for this topic(in the web). I hope this post can help to relieve this mindboggler in a way.

Related

Multiple apache2 Virtual host sitses - All work except one

I have a problem with apache2 and Virtual Hosts. I run a server with multiple sites. I have subdomains setup that point to my server IP. My customers, those that choose to have their own domain names point their domain/sub-domain to one of my subdomains. I've done this with multiple sites and it's always worked, except for now, and I cant figure out why.
This is the virtual host that doesnt seem to work, it always points to my default site when i try to access it.
The domain redirecting goes like this. customer.domain.com -> customer.mydomain.com -> server IP
<VirtualHost customer.domain.com:443>
ServerName customer.domain.com
ServerAlias *customer.domain.com *customer.mydomain.com
DocumentRoot /var/www/page
<Directory />
Order Deny,Allow
Deny from all
</Directory>
<Directory /var/www/page>
Options -Indexes +FollowSymLinks +MultiViews
AllowOverride All
Order allow,deny
Allow from all
</Directory>
ErrorLog /var/log/apache2/customer/logs/error.log
LogLevel warn
CustomLog /var/log/apache2/customer/logs/access.log combined
SSLEngine on
SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
BrowserMatch ".*MSIE.*" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
</VirtualHost>
This format is used for all other sites, and they are directed to the correct folder and site. But with this particular site it always gets directed to the default site.
I've noticed that when i run apache2ctl -S I get two IPs. One is my servers IP with all of the virtual hosts, and the second IP seems connected to the new virtual host, the one that doesnt work.
52.52.52.52:443 customer.domain.com (/etc/apache2/sites-enabled/006-customer.domain.com.conf:1)
12.12.12.12:443 is a NameVirtualHost
default server default.mydomain.com (/etc/apache2/sites-enabled/001-default.mydomain.com.conf:1)
port 443 namevhost default.mydomain.com (/etc/apache2/sites-enabled/001-default.mydomain.com.conf:1)
alias www.default.mydomain.com
port 443 namevhost customer2.domain.com (/etc/apache2/sites-enabled/002-customer2.domain.com.conf:1)
alias www.customer2.domain.com
wild alias *subdomain.mydomain.com
*:80 default.mydomain.com (/etc/apache2/sites-enabled/000-default.conf:1) ..... more
I'm not really sure what to look for, the logs don't seem to tell me anything useful.
Any ideas on what I might be doing wrong? Thank you.
You should avoid putting hostnames inside of <virtualhost> at all costs. On a typical system, *:port in each vhost is sufficient.
If you really care about what local interface a connection is related to BEFORE checking the hostname used, put a local interface address name and not a hostname. But most people simply do not care what interface was used.
The particular risk of using a hostname is that it might not resolve to any local interface, in which case Apache will never map a connection to it. The per-request hostname matching only kicks in from the best matching connection-level info.

Apache: <Directory> directive with no path specified

I have a local server environment running on my OS X machine using MAMP, and I am currently setting up a few virtual hosts. I found that, in order for one of my virtual hosts to recognize my site's .htaccess file, I needed to add a <Directory> directive within the <VirtualHost> directive.
Here is an example of what I am using to configure one of my virtual hosts:
<VirtualHost *>
DocumentRoot "/path/to/mysite"
ServerName mysite.local
<Directory "/path/to/mysite">
AllowOverride All
Order Allow,Deny
Allow from all
</Directory>
</VirtualHost>
Now, I would like to avoid redundancy by removing the path from that <Directory> directive. I tried doing so and it seems to work, although I am not familiar with Apache enough to know the potential consequences of doing this. Furthermore, I could not find an explanation of this case in the Apache Documentation.
This is what I would like to do:
<VirtualHost *>
DocumentRoot "/path/to/mysite"
ServerName mysite.local
<Directory>
AllowOverride All
Order Allow,Deny
Allow from all
</Directory>
</VirtualHost>
Therefore, my question is this: what happens when I omit the path from the <Directory> directive (in this case)?
Directory is a directive targeting a file system directory, and should always have a path (waildcards allowed).
Using some instructions targetd to no directory may be discarded silently, or maybe with an error (you could test it), but is would certainly be useless.
Why would you write some configuration instructions targeted to no directory at all?
But there's maybe more things in your question.
Ususally a Virtualhost should contains at least one Directory instruction, the DocumentRoot directory, and usually we also add one targeting the root of the filesystem, this way:
<Directory />
(instructions to deny access and avoid .htaccess reads)
</Directory>
<Directory /my/document/root/>
(instructions to allow access and still avoid .htaccess reads or to allow them if you are lazy and feel over confident that .htaccess are useful in any way and you do not need speed)
</Directory>
And you could add more, especially to avoid usage of .htaccess files as such file stored in /path/to/somewhere is the same thing as a <Directory /path/to/somewhere> section, but slower.
Now you do not like to repeat yourself in your VH configuration, so you coud maybe use .htaccess files or global level instructions for things that are usually set there. And you could also use another magical keyword, which is Location.
You can use a lot of Apache instruction in a <Location /foo> directive. Locations works on url, not on filesystem paths.
So <Location /> is your documentRoot, and <Location /foo> is maybe the subdirectory 'foo' under you DocumentRoot. This could help you write things in your VH without reusing the documentroot prefix everywhere. But be careful, urls are not file-system paths. Any protection applied on the url level may be weaker or stronger compared to a protection applied on a directory level. It depends on your alias, the way you use urls, etc.
Update:
If you use the new Apache 2.4 version you can now use mod_macro or even easier, built-in variables support:
Define docroot "/path/to/mysite"
DocumentRoot ${docroot}
<Directory ${docroot}>
(...)

Apache - Hyphen in ServerName breaks VirtualHost

I can't get Apache's configuration to return the correct page, if there is a hyphen in the ServerName. I found a page here titled, "Dashes not allowed in virtual host entry?", but it was dealing with hyphens in the DocumentRoot, not with ServerName. In any case, it did not solve my problem, and I've been unable to find any other references to this problem.
I'm setting up multiple virtual hosts (VH) on a recently acquired Ubuntu 12.04 server, running Apache. Ubuntu's configuration for this is organized so that you have folders for sites-available and sites-enabled. A separate file, placed in sites-availabe is used for each individual VH. Enabling the VH is just a matter of making a symlink from the file in the sites-available folder to the sites-enabled folder, and restarting Apache.
I have several working VHs already. It's an easy recipe, since it's just a matter of copying a working file to a new filename, and changing a few variables.
All of my correctly-working entries do NOT have any hyphen in the ServerName, or ServerAlias. The one entry which does have a hyphen, does not work. Instead of returning the proper page, Apache returns the host's base page (which tells me DNS is fine).
I've tried enclosing ServerName and ServerAlias in quotes, with and without. No change.
Lots of domains use hyphens, I can't be the only one with this problem. Has anyone found a workaround? Here's my config:
<VirtualHost *:80>
ServerAdmin webmaster#localhost
ServerName datacore-inc.com
ServerAlias www.datacore-inc.com
DocumentRoot /home/web/datacore/www
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /home/web/datacore/www/>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
I had the same issue and thought the problem came from the hyphen character in the ServerName. But actually I had declared the VirtualHost twice. I've removed one of them and that resolved the problem.

Apache accepts all websites that point to server

I only have two websites pointed to my server IP, Asite.com and Bsite.com. I tried adding a website, so I pointed Csite.com to my server IP (but I haven't registered a virtualhost for site3.com yet). How come when I access Csite.com apache recognizes it as Asite.com even if I haven't registered a virtualhost for Csite.com?
httpd.conf
Listen 8080
NameVirtualHost *:8080
Asite.com
<VirtualHost *:8080>
ServerAdmin webmaster#localhost
ServerName asite.com
ServerAlias asite.com *.asite.com
DocumentRoot /var/www/asite.com/public
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /var/www/asite.com/>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>
ErrorLog /var/log/httpd/error_log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
</VirtualHost>
^The same goes for Bsite.com
The first virtualhost is also the default:
"The asterisks match all addresses, so the main server serves no requests. Due to the fact that www.example1.com is first in the configuration file, it has the highest priority and can be seen as the default or primary server. That means that if a request is received that does not match one of the specified ServerName directives, it will be served by this first VirtualHost."
See 'Running several name-based web sites on a single IP address.' http://httpd.apache.org/docs/2.0/vhosts/examples.html
It uses the first-listed one, when it has no ServerName match.
You'll find you can also use the raw IP address to access Asite.com.
If you feel uncomfortable with that, you could create a different virtual host as the first one listed for <VirtualHost *:8080>, and configure so it just Redirects somewhere else. Or gives a 404 message, etc.
This is happening because you pointed the csite.com to your local host and the first virtual host is recognized as local host so if you switch around siteA and siteB so it would be virtual host for sure b first and type in your browser "localhost" or sitec.com it will show siteb.com
Don't worry; this isn't a problem. It is supposed to happen.
You didn't actually point sitec.com to localhost but I if you created it in your hosts file our pointed it to your domain it will take you to the first specified file!

Setup Dynamic Virtual Host (Apache2 on Ubuntu)

I want to set up a single virtual host that can dynamically handle all requests based on the hostname used to access it. If %{HTTP_HOST} could be used in a DocumentRoot, this is probably exactly what I want:
<VirtualHost *:80>
ServerAdmin me#example.com
DocumentRoot /var/www/live/%{HTTP_HOST}/public
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /var/www/live/%{HTTP_HOST}/public>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
# Possible values include: debug, info, notice, warn, error, crit, alert, emerg.
LogLevel warn
ErrorLog /var/www/live/%{HTTP_HOST}/logs/error.log
CustomLog /var/www/live/%{HTTP_HOST}/logs/access.log combined
</VirtualHost>
...unfortunately, %{HTTP_HOST} is not allowed in the DocumentRoot (Warning: DocumentRoot [/var/www/live/%{HTTP_HOST}/public] does not exist). How else can I achieve my goal?
Update: I thought of pointing a catch-all vhost to a single directory and having a .htaccess use mod_rewrite to dynamically select the path but (honestly) I'm exhausted. I'll try at it again in the morning, but in the meantime, if anyone has good ideas, I'd love to hear them! Thank you!
Maybe you can try the following solution from this article: Apache: Dynamic Virtual Hosts
A few months back I looked for a solution to overcome the problem of
creating individual Virtual Hosts in Apache every time I wanted to
configure a new site on a development machine (something that is a big
issue in work where we have a lot of websites). Apache is able to
support this functionality relatively easy using a module and a few
lines in the configuration file. I set this up on Fedora 14, so
results may be slightly different for other OS's (different paths,
configuration file setup, etc)
Open up the main Apache conf (/etc/httpd/conf/httpd.conf), and ensure
the module mod_vhost_alias is enabled. There should be a line in the
configuration like
LoadModule vhost_alias_module modules/mod_vhost_alias.so
Next, add the
following lines to the bottom of this file. You'll need to edit the
file with sudo privileges.
NameVirtualHost *:80
UseCanonicalName Off
<VirtualHost *:80>
VirtualDocumentRoot /var/www/html/domains/%0
</VirtualHost>
This sets up a catch all for any domain coming in over port 80 (the
default port for http traffic, if your using https you will need to
use 443 - alternatively you could remove the port restriction). The
important line here is the VirtualDocumentRoot. The tells Apache where
your files will reside on disk. The %0 part takes the whole domain
name and inserts it into the path. To illustrate this if we went to a
domain testing.com.dev the VirtualDocumentRoot would be:
/var/www/html/domains/testing.com.dev
This type of configuration might
be suitable for most situations, however I didn't want to have the
.dev part of the domain in my folders on disk. I was able to achieve
this by setting the VirtualDocumentRoot to:
VirtualDocumentRoot /var/www/html/domains/%-2+
The above example of testing.com.dev would now point to:
/var/www/html/domains/testing.com
Remember to add the domain to your
hosts file (/etc/hosts)
For a full list of options see the mod_vhost_alias documentation.
Additional documentation can be found here.
The official methods for achieving dynamic virtual hosts are explained in the Apache documentation:
http://httpd.apache.org/docs/2.0/vhosts/mass.html