apache virtual host and "Dynamic" Domains - apache

I have a java application responding multiple domains and uses, for each domain, a specific apache virtual host. This because Apache is faster than tomcat, to serve static resources.
The need is to do that at runtime, without restart apache configuration.
To perform this action I'm using VirtualDocumentRoot directive, as described below:
AddType text/html .html .shtml
AddOutputFilter INCLUDES .html .shtml
NameVirtualHost *:80
UseCanonicalName Off
<VirtualHost *:80>
ServerName domain.com
ServerAlias *
# Define virtual host directory, using entire domain
VirtualDocumentRoot /path/to/whosts/%0
# Define directory access
<Directory "/path/to/whosts/">
Options -Indexes MultiViews +Includes
Order allow,deny
Allow from all
</Directory>
# Define Java Proxies
<Proxy *>
AddDefaultCharset Off
Order deny,allow
Allow from all
</Proxy>
# Allow Libs (static resources) to access apache directly
ProxyPass /libs !
ProxyPass / ajp://localhost:8009/
ProxyPassReverse / ajp://localhost:8009/
</VirtualHost>
This does not work well, because if I try to access to www.domain.com, is different than access to domain.com.
Do you think is a good idea to register a symbolic link from www.domain.comto domain.com???
Exists another way to do that? I'm really poor in apache managing...
Thank's a lot!
Ciao, Davide.

I regularly use symlinks to link multiple domains to the same webroot when doing configurations similar to this, there is no explicit harm in that solution so definitely no reason to shy away from it.

A good way would be to decide which type of URL should be the canonical one, and use mod_rewrite to redirect URLs to it - for instance, match requests to domain.com and redirect them to www.domain.com. There's plenty of tutorials on how to do this available on the web which you should be able to find easily.
Off the top of my head, you could use something like:
RewriteEngine on
RewriteCond %{HTTP_HOST} !^www\.$ [NC]
RewriteRule ^(.*) http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
That would cause problems if you're using SSL, though, due to the hardcoded http://. I think you could change the RewriteRule line to the following to avoid that:
RewriteRule ^(.*) %{SERVER_PROTOCOL}://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

Related

How can i use parts of the Referrer Header in an Apache Rewrite Rule

I'm writing a generic proxy of sorts - so I can access a single host in the form of http://<proxy-host>/<host-to-proxy-to>/<port>/<path>/ which currently uses rewrites to Proxy requests to https://<host-to-proxy-to>:<port>/<path>
I've got that part working and it seems to do what I want it to. However in some scenarios I'm using it with a stubborn sites that are forcing root relative urls. The application in question is not particularly easy (and in some cases impossible) to change.
My problem is how to identify the root relative URLs that are hitting apache, and proxy them to the correct host. I have identified that the correct host details are still in the path of the referrer header, so I'm trying to break apart and use the referrer path in a rewrite rule.
Updated Code Below:
<VirtualHost *:80>
ServerName wtf.devbox-cole.orion.internal
ServerAlias wtf.devbox-cole
RewriteEngine On
<LocationMatch "^/$">
Header always set X-CRAP-BASE "Its working kinda"
Redirect 410 /
</LocationMatch>
<Location /web/>
Header always set X-CRAP-BASE "Hardly Working"
RewriteCond %{HTTP_REFERER} "http://%{HTTP_HOST}/([a-zA-Z0-9_\.]*)/([0-9]*)/.*"
RewriteRule (.*) https://%1:%2/$1 [P]
</Location>
<LocationMatch "^/(?<host>[a-zA-Z0-9_\.]*)/(?<port>[0-9]*)/(?<path>.*)">
RewriteRule ".*" https://%{env:MATCH_HOST}:%{env:MATCH_PORT}/%{env:MATCH_PATH} [P]
ProxyPassReverse "https://%{env:MATCH_HOST}:%{env:MATCH_PORT}/%{env:MATCH_PATH}"
</LocationMatch>
# Enable proxying to https://
SSLProxyEngine On
# Allow Proxying to https without valid cert
SSLProxyVerify none
# Disable Domain Nmae checking on the Certs
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
# disbaled cert expiryt Check
SSLProxyCheckPeerExpire off
LogLevel debug rewrite:trace8
CustomLog "/var/log/apache2/wtf_log" "%h"
ErrorLog "/var/log/apache2/wtf_error
</VirtualHost>
The above code still isn't quite working. Still trying to track down why..
So after many attempts and reading as much documentation as I can find - I managed to solve my initial question. The following VHost block will Proxy http://domain.com/<host>/<port>/<path> to https://<host>:<port>/<path> AND it will map any requests to /web/* originating from that domain, back to the proper place.
<VirtualHost *:80>
ServerName domain.com
RewriteEngine On
<LocationMatch "^/$">
Header always set X-CRAP-BASE "Its working kinda"
Redirect 410 /
</LocationMatch>
<Location /web/>
Header always set X-CRAP-BASE "Hardly Working"
</Location>
RewriteCond %{REQUEST_URI} "^/web/.*"
RewriteCond %{HTTP_REFERER} "http://.*/([a-zA-Z0-9_\.\-]*)/([0-9]*)/.*"
RewriteRule (.*) https://%1:%2/$1 [P]
RewriteCond %{REQUEST_URI} "^/([a-zA-Z0-9_\.\-]*)/([0-9]*)/(.*)"
RewriteRule ".*" https://%1:%2/%3 [P]
<LocationMatch "^/(?<host>[a-zA-Z0-9_\.\-]*)/(?<port>[0-9]*)/(?<path>.*)">
ProxyPassReverse "https://%{env:MATCH_HOST}:%{env:MATCH_PORT}/%{env:MATCH_PATH}"
</LocationMatch>
# Enable proxying to https://
SSLProxyEngine On
# Allow Proxying to https without valid cert
SSLProxyVerify none
# Disable CN Checking on the Certs
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
# Disable Cert Expiry Check
SSLProxyCheckPeerExpire off
# Extra Logging
#LogLevel debug rewrite:trace8
CustomLog "/var/log/apache2/domain.com_log" "%h"
ErrorLog "/var/log/apache2/domain.com_error
</VirtualHost>
And then i remembered how silly Referrer headers are, in that if a CSS file requests another CSS file, or an image for example, then the Referrer isnt set as expected :facepalm:

apache add trailing slash redirects to different ServerName

In apache 2.2.22, I have multiple local servers setup such that localhostN refers to a server which I can access via local.myserver.com (for different "myserver"s). The problem is that one such server is doing a strange redirect when adding the automatic slash (I'm guessing via mod_dir), where accessing:
http://local.myserver.com/noslashdir
sends me to
http://localhost5/noslashdir/
instead of to
http://local.myserver.com/noslashdir/
I have not been able to override this behavior in the .htaccess file. Here are the relevant details:
/noslashdir/.htaccess:
DirectoryIndex index.html
/.htaccess:
SetEnvIf HTTPS on http_proto=s
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^noslashdir/(.*)$ /noslashdir/$1.html [L]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^noslashdir/(.+)\.html$ http%{http_proto}://%{HTTP_HOST}/noslashdir/$1 [L,R=302]
/etc/httpd/httpd.conf
<VirtualHost 127.0.0.5>
ServerName localhost5
DocumentRoot /var/www/myserver.com/
DirectoryIndex index.php index.html index.htm index.shtml
<Directory "/var/www/myserver.com">
Options Indexes +Includes FollowSymLinks
AllowOverride All
Allow from all
Order allow,deny
</Directory>
ScriptAlias /cgi-bin/ "/var/www/myserver.com/cgi-bin/"
</VirtualHost>
/etc/hosts
127.0.0.5 local.myserver.com localhost5
I have tried RewriteRules, DirectorySlash Off, etc, but nothing has worked so far. All other desired redirects work fine.
Apache is using the ServerName you have set for your VirtualHost when creating “self-referential URLs”.
http://httpd.apache.org/docs/2.2/en/mod/core.html#servername:
“The ServerName directive sets the request scheme, hostname and port that the server uses to identify itself. This is used when creating redirection URLs.”
You should set UseCanonicalName to Off:
“In many situations Apache must construct a self-referential URL -- that is, a URL that refers back to the same server. With UseCanonicalName On Apache will use the hostname and port specified in the ServerName directive to construct the canonical name for the server. This name is used in all self-referential URLs, […]
With UseCanonicalName Off Apache will form self-referential URLs using the hostname and port supplied by the client if any are supplied […]”

URL rewriting for cakephp on local OSX apache

I have set up apache on OSX for local web dev use and made a dynamic vhost using dnsmasq such that visiting foo.dev will point to the /foo directory in my ~/Sites/sites folder.
This is what the vhost rule looks like:
<Virtualhost *:80>
VirtualDocumentRoot "/Users/harryg/Sites/sites/%1"
<Directory "/Users/harryg/Sites/sites">
Order allow,deny
Allow from all
Options Indexes FollowSymLinks Includes ExecCGI
# New directive needed in Apache 2.4.3:
Require all granted
AllowOverride All
Satisfy Any
</Directory>
ErrorLog "/Users/harryg/Sites/logs/sites/error.log"
CustomLog "/Users/harryg/Sites/logs/sites/access.log" common
ServerName sites.dev
ServerAlias *.dev
UseCanonicalName Off
</Virtualhost>
This all works great but I donwloaded a copy of cakephp and put it in a directory ~/Sites/sites/cake. When I visit http://cake.dev I get taken to the cakephp default app page which is expected but there is a warning about url rewriting not being properly configured and stylesheets etc do not load. I followed the guide and tried placing the following in the .htaccess for the cake directory:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^$ app/webroot/ [L]
RewriteRule (.*) app/webroot/$1 [L]
</IfModule>
But I then get a 500 Internal Server Error. Error log says:
Request exceeded the limit of 10 internal redirects due to probable
configuration error. Use 'LimitInternalRecursion' to increase the
limit if necessary. Use 'LogLevel debug' to get a backtrace.
Suggesting the rewriting rules are conflicting somehow. Any idea how to solve this?
Solved. The answer was to simply add the following line to my .htaccess files:
RewriteBase /
Not sure why it's necessary but it worked!

File not found with VirtualHost and mod_rewrite

I'm bulding a RESTful api based on Tonic.
On my developer machine and our stage server we use virtual hosts.
Tonic uses a .htaccess file to translate the incomming calls to it's dispatcher.php file. This works fine on servers without VirtualHosts enabled.
However if i enable VirtualHosts i get a file not found even thought the path and name to the file is correct.
Here is the VirtualHost setup on my developer machine.
<VirtualHost *:80>
ServerAdmin admin#xxxxxxxxxxxx
ServerAlias *.dev.xxxxx
VirtualDocumentRoot /home/xxxxxxxx/workspace/%1
<Directory /home/xxxxxxxx/workspace/>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>
</VirtualHost>
And Tonic's .htacces located in a folder called rest in the project root:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI} !dispatch\.php$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* dispatch.php [L,QSA]
</IfModule>
A call to http://project.dev.xxxxx/rest/ gives:
Not Found
The requested URL /home/xxxxxxxx/workspace/project/rest/dispatch.php was
not found on this server.
Apache/2.2.22 (Ubuntu) Server at xxxxxxx Port 80
It appears as though you're misusing VirtualDocumentRoot. Try changing it to:
DocumentRoot /home/xxxxxxxx/workspace/project/rest
Also, here's a good explanation on the VirtualDynamicRoot: Dynamically configured mass virtual hosting
Hope that helps.

Apache - Can no longer use mod_rewrite after adding virtual directory

My apache server is set up with a very basic configuration. I used to serve just one website from apache, let's call it example.com. Within the httpd.conf file, I had some code to force the website to always show www in the url.
I recently added a subdomain for the site, blog.example.com. In order to do this I needed to create 2 virtual directory directives within my httpd.conf file.
NameVirtualHost *:80
<VirtualHost *:80>
ServerName example.com
DocumentRoot /var/www/html
</VirtualHost>
<VirtualHost *:80>
ServerName blog.example.com
DocumentRoot /var/www/blog
</VirtualHost>
Immediately after this, I kept my rewrite code:
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\.example\.com [NC]
RewriteCond %{HTTP_HOST} !^$
RewriteRule ^/(.*) http://www.example.com/$1 [L,R]
The problem is that this after adding the Virtual Directory code, the rewrite code is no longer working. I tried creating the following Directory directive, which doesn't seem to work at all.
<Directory "/var/www/html">
Options Indexes MultiViews FollowSymLinks
Order Deny,Allow
Allow from all
AllowOverride All
</Directory>
Additionally, I tried creating a .htaccess file in the html folder of the website and restarting apache, but nothing that I put in there is getting noticed at all.
Any help is greatly appreciated. Thanks!
Answer from comment by original poster:
Ok, I figured it out. I just needed to move the rewrite logic within the start and end Directives. Thanks for the help #animuson. – Henry Wrinkler