Multiple apache2 Virtual host sitses - All work except one - apache

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.

Related

Apache2 fails to find the requested URL when accessed via a domain name, but functions perfectly via an IP address?

I've recently been migrating a small website on a VPS from a rudimentary and static one to the Flask framework, via WSGI/Apache2. However, while access to the website is functional when accessing from a browser using the IP address, use of the domain name brings the standard and nonspecific Apache2 message "The requested URL was not found on this server." My VHost is as follows:
<VirtualHost *:443>
ServerName slow.estate
ServerAlias www.slow.estate
ServerAdmin my.email#gmail.com
WSGIScriptAlias / /var/www/se/se.wsgi
<Directory /var/www/se/se/>
Order allow,deny
Require all granted
</Directory>
Alias /static /var/www/se/se/static
<Directory /var/www/se/se/static/>
Order allow,deny
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
I've tried this both with the VHost set to port 80 (and, of course, with SSLify disabled) and with SSL and port 443, with no difference. The problem also persists no matter if I use Apache's older Allow from all or the newer Require all granted in my VHost. In the VHost above, the website will not work at all. If I modify the ServerName to be the IP address, then it works exclusively when that IP address is entered into the browser. Each time I try and fail to use the website in the above manner, a relevant entry is made in access.log, and no entry is made in error.log.
I've only found one other person out there with a similar problem to me, and that seemed just to be that their nonstandard TLD was being misinterpreted by their browser, which is why I mention that my TLD is .estate. I doubt, surely, that this could be the issue, especially when this issue, unlike the other person's, plagues me across browsers?

Configuring mod_ssl in Apche2

I want users to be able to navigate to https://cloud.xxx.de, which works totally fine with the following configuration file. But besides the working (and correct) url, every url points to /var/www/cloud. Shouldn't ServerName cloud.xxx.de tell Apache to only point requests with this specific server name to the directory?
ServerName cloud.xxx.de
DocumentRoot /var/www/cloud
SSLEngine on
SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
<Directory /var/www/cloud>
...
</Directory>
Alright, I found out myself. From the Apache2 documentation:
Unless a NameVirtualHost directive is used for the exact IP address and port pair in the VirtualHost directive, Apache selects the best match only on the basis of the IP address (or wildcard) and port number. If there are multiple identical best matches, the first VirtualHost appearing in the configuration file will be selected.
So basically I just had to put
NameVirtualHost *:443
in front of my first evaluated virtual host listening on port 443.

Override single setting in default Apache <VirtualHost> block

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.

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