Letsencrypt virtual host vs htaccess on apache - apache

I have a site that I was working to move to use the virtualhost configuration over an .htaccess. Figuring if I have the access I should.
The rewrite I have was for php slim framework to remove index.php
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [QSA,L]
When I made the changes of moving from .htaccess to the production server routes were failing. I realized that the rewrites were not being followed on the :80 virtualhost but rather what was specified in the :443 letsencrpyt virtualhost.
In a pinch I just moved the above re-write into the letsencrpyt and voila working.
It seems that certbot uses the :80 port to create the :443 so I cannot remove that and just go with the generated one. Right now I am just duplicating the logic between the two.
Question I have at this point for this type of re-write should I just leave it in the .htaccess? Or is there a way to update the ssl vhost with certbot when I make changes to the default port 80 one?

Considering your comments to the question I now see that your actual question is:
"How is it possible to share configuration directives between different hosts in an apache http server? "
This is easily possible using the Include statement:
<VirtualHost *:80>
# include the rules common for http and https
Include sites-includes/shared-config.inc
</VirtualHost>
<IfModule mod_ssl.c>
<VirtualHost *:443>
# include the rules common for http and https
Include sites-includes/shared-config.inc
</VirtualHost>
</IfModule>
Using that you can now define common configuration directives in the file sites-includes/shared-config.inc (or wherever you want to place it).

Related

Apache Configuration: redirecting to www in .htaccess

I have read a number of formulas for redirecting example.com to www.example.com and this appears to apply to .htaccess. However, I am confused about how this might work.
I want to assume that I have no access to the Apache vhosts configuration, and that I need to do it with .htaccess.
Suppose the configuration contains something like this:
<VirtualHost *:80>
ServerName www.example.com:80
ServerAlias www.example.com
VirtualDocumentRoot /whatever/example.com/www
</VirtualHost>
One such formula is something like this"
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ www\.%{HTTP_HOST}/$1 [R=301,L]
However, I don’t see how one root directory can respond to both requests.
The question is: Is it even possible to redirect example.com to www.example.com using .htaccess only, without tweaking the Virtual Host file?
The way I see it, the original request
I run my own server, and I can do anything I like. However, I am asking this because many of my clients and students have no access to tehe configuration, and can only fiddle with .htaccess.

Apache dynamic wildcard host rewrite with dynamic subdomains

I'm currently in the process of converting an old apache vhost, where one is currently created for each new release, to a dynamic host that can handle all the subdomains so we don't have to create a new one all the time. I need some help! We're using apache v2.2.
The Goal
Dynamic all the things. To have a single virtual host that handles all redirects for a specific set of subdomains. The url is below, note that sub1 and branch are dynamic and could be anything.
sub1.branch.sandbox.domain.com
The directory structure for this is as follows:
/var/www/vhosts/branch/sub1.branch.sandbox.domain.com
As you can see above, the directory structure has the branch as a sub-directory before the full url is the name of another sub-directory.
Also, /images/ in the url needs to forward to shared-httpdocs/images for each domain.
The vhost I have so far
<VirtualHost *:80>
ServerName branch.sandbox.domain.com
ServerAlias *.branch.sandbox.domain.com
VirtualDocumentRoot /var/www/vhosts/branch/%0
Options Indexes FollowSymLinks
# Rewrite Engine Stuff Here
RewriteEngine On
DirectoryIndex index.php
# Assets needs to be forwarded - currently not working
RewriteCond %{REQUEST_URI} ^/(css|js|images)/.*
RewriteRule .*$ /var/www/vhosts/%0/shared-httpdocs/%1$ [L]
# The HTTP dispatcher - currently not working
RewriteCond %{HTTP_HOST} ^(.*)\.branch\.sandbox\.domain\.com [NC]
RewriteRule ^(.*)$ /var/www/vhosts/%1/applications/portal/dispatchers/http.php [L,QSA,NS,NE,NC]
</VirtualHost>
The old host I'm trying to copy
This is the old vhost I'm trying to convert from. It's horrible, messy, and our ops has to create a new DNS entry every time. What a joke! I need to sort this out...
<VirtualHost *:80>
# Notice how the stupid convention below will require a new DNS entry each time?
ServerName sandbox.branch.domain.com
ServerAlias sandbox.api.branch.domain.com
DocumentRoot /var/www/vhosts/sandbox.branch.domain.com/applications/portal/httpdocs
<Directory "/var/www/vhosts/sandbox.branch.domain.com/applications/portal/httpdocs">
allow from all
order allow,deny
# Enables .htaccess files for this site
#AllowOverride All
RewriteEngine On
# Rewrite all non-static requests to go through the webapp
RewriteCond %{REQUEST_URI} ^/(css|js|images)/.*
RewriteRule .* - [L]
# Rewrite everything else to go through the webapp
RewriteRule ^(.*)$ /dispatchers/http.php [QSA,L]
</Directory>
<Directory "/var/www/vhosts/sandbox.branch.domain.com/applications/portal/dispatchers">
allow from all
</Directory>
# Allow us to rewrite to the webapp without it being in the webroot
Alias /dispatchers /var/www/vhosts/sandbox.branch.domain.com/applications/portal/dispatchers
# Get shared/ to point to the shared static resources
Alias /shared /var/www/vhosts/sandbox.branch.domain.com/shared-httpdocs
</VirtualHost>
A new DNS entry is required each time we have a new branch, so I'm trying to mitigate this by providing a dynamic subdomain vhost (see the vhost I have so far). I've gone from not even being able to match /images/ in the url to a permanent redirect loop.
How can I achieve my goal? I know it's a little complex. If I can't do it, I'll just have to write a script that will generate a new vhost each time but a dynamic one that 'just works' would be fantastic. I've put two days into this so far, I'm no sysadmin. Your help would be greatly appreciated.
Resources I have been using:
mod_rewrite official docs - Shows the basics like things on conditions with REWRITE_COND
Sub domain rewriting - A question on subdomain rewriting
Asset rewriting - Another question on rewriting things like images / css / js, which doesn't seem to work for me
It's not a complete answer, but is too long for comment.
The %0 (%0 to %9) in a rewrite rule are back references to captures in the last RewriteCond. It seems to me you wanted instead the host name. Also it seems you miss the "branch" part of the path. In the Asset's rewrite you also throw away the filename part.
# Assets needs to be forwarded - currently not working
RewriteCond %{REQUEST_URI} ^/(css|js|images)/(.*)
RewriteRule .*$ /var/www/vhosts/branch/%{HTTP_HOST}/shared-httpdocs/%1/%2$ [L]
# The HTTP dispatcher - currently not working
RewriteCond %{HTTP_HOST} ^(.*)\.branch\.sandbox\.domain\.com [NC]
RewriteRule ^(.*)$ /var/www/vhosts/branch/%{HTTP_HOST}/applications/portal/dispatchers/http.php [L,QSA,NS,NE,NC]
You can get debugging help also from mod_rewrite dedicated logging with RewriteLog and RewriteLogLevel directives.
Hope this will bring you further.

Apache Virtualhost Directory conditional redirect

I just created a website with two environments as virtualservers - testing and production. As production server is open to everyone but I allowed only my IP to access testing environment:
<VirtualHost *:80>
DocumentRoot /home/xxx/www
ServerName testing.xxx.com
<Directory /home/xxx/www>
Order deny, allow
Deny from all
Allow from xxx.xxx.xxx.xxx
</Directory>
</VirtualHost>
The problem is that google has already indexed some of my testing environment pages and they are available in google results. I would like any IP but mine to be redirected to production server (xxx.com) while accessing testing.xxx.com. I would rather do it with apache.conf than .htaccess(because of git repositories conflicts). Is it possible to add a conditional redirect to apache config?
You can use mod_rewrite features in your httpd.conf Apache config file:
<IfModule mod_rewrite.c>
Options +FollowSymLinks
RewriteEngine on
RewriteCond %{REMOTE_HOST} !^123\.456\.788 [OR] # exclude your first IP
RewriteCond %{REMOTE_HOST} !^123\.456\.789 # exclude your second IP
RewriteRule ^(.*)$ http://production-env.com/$1 [R=301,L] # redirection to production site
</IfModule>
Or you can put these declarations into <Directory> section of your vhosts config file.
Generally you can take advantage of mod_rewrite module to manage URL routing policies for your web server. Before using it make sure that this module is installed and activated in your Apache.

Configuring mod_rewrite and mod_jk for Apache 2.2 and JBoss 4.2.3

My problem is as follows: I have JBoss 4.2.3 application server with AJP 1.3 connector running on one host under Windows (192.168.1.2 for my test environment) and Apache 2.2.14 running on another FreeBSD box (192.168.1.10). Apache acts as a "front gate" for all requests and sends them to JBoss via mod_jk. Everything was working fine until I had to do some SEO optimizations. These optimizations include SEF urls, so i decided to use mod_rewrite for Apache to alter requests before they are sent to JBoss. Basically, I nedd to implement 2 rules:
Redirect old rules like "http://hostname/directory/" to "http://hostname/" with permanent redirect
Forward urls like "http://hostname/wtf/123/" to "http://hostname/wtf/view.htm?id=123" so that end user doesn't see the "ugly" URL (the actual rewrite).
Here is my Apache config for test virtual host:
<VirtualHost *:80>
ServerAdmin webmaster#dummy-host.example.com
DocumentRoot "/usr/local/www/dummy"
ServerName 192.168.1.10
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule /directory/(.*) /$1 [R=permanent,L]
RewriteRule ^/([^/]+)/([0-9]+)/?$ /$1/view.htm?id=$2
</IfModule>
JkMount /* jsp-hostname
ErrorLog "/var/log/dummy-host.example.com-error_log"
CustomLog "/var/log/dummy-host.example.com-access_log" common
</VirtualHost>
The problem is that second rewrite rule doesn't work. Requests slip through to JBoss unchanged, so I get Tomcat 404 error. But if I add redirect flag to the second rule like
RewriteRule ^/([^/]+)/([0-9]+)/?$ /$1/view.htm?id=$2 [R,L]
it works like a charm. But redirect is not what I need here :) . I suspect that the problem is that requests are forwarded to the another host (192.168.1.2), but I really don't have any idea on how to make it work. Any help would be appreciated :)
The reason your second rewrite rule doesn't work is that you use the '?' in your URI definition and the URI definition never contains the separator '?'.
So simply use the rewrite rules without it. eg.
RewriteRule ^/([^/]+)/([0-9]+)/$ /$1/view.htm?id=$2 [R,L]
Simply, doesn't works because the first RewriteRule has the [L] at the end, which means is the last rule to process.

How can I implement a global RewriteCond / RewriteRule in Apache that applies to all virtual hosts?

The title pretty much says it all. :-) I have lots of virtual hosts and I want to put a single rewriting block at the top of the httpd.conf file that rewrites URLs no matter which virtual host the request might be directed to. How the heck do I do this?
I found this but my question is the same: how can I do this without resorting to .htaccess files and performing some other action for each virtual host?
OMGTIA!
Specify RewriteOptions InheritDown in the parent scope (such as httpd.conf) to get your rules applied in child Virtual Hosts without modifing them.
This will only work on Virtual Hosts where the RewriteEngine directive is set to on:
Note that rewrite configurations are not inherited by virtual hosts. This means that you need to have a RewriteEngine on directive for each virtual host in which you wish to use rewrite rules.
(source)
Apache supports this since 2.4.8 (not available at the time of the original question).
From documentation for RewriteOptions:
InheritDown
If this option is enabled, all child configurations will inherit the configuration of the current configuration. It is equivalent to specifying RewriteOptions Inherit in all child configurations. See the Inherit option for more details on how the parent-child relationships are handled.
Available in Apache HTTP Server 2.4.8 and later.
InheritDownBefore
Like InheritDown above, but the rules from the current scope are applied before rules specified in any child's scope.
Available in Apache HTTP Server 2.4.8 and later.
IgnoreInherit
This option forces the current and child configurations to ignore all rules that would be inherited from a parent specifying InheritDown or InheritDownBefore.
Available in Apache HTTP Server 2.4.8 and later.
(http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewriteoptions)
By default, mod_rewrite configuration settings from the main server context are not inherited by virtual hosts. To make the main server settings apply to virtual hosts, you must place the following directives in each <VirtualHost> section:
RewriteEngine On
RewriteOptions Inherit
click http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html to find more information
Looks like the simplest possible solution is to add
RewriteOptions inherit
to each VirtualHost directive. This is at least a lot simpler than messing with .htaccess files. Apache is pretty clear on the fact that
by default, rewrite configurations are
not inherited. This means that you
need to have a RewriteEngine on
directive for each virtual host in
which you wish to use it.
(http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html)
and apparently the way to change the default is via RewriteOptions in the child (vhost or director), so you have to do something in each child.
I've never tested it, so it might not work, but I would try adding an include directive in all of the virtual host blocks to a single file. You would have to change each virtual host configuration block once, but after that, you should have a central place from which to make changes. YMMV.
If you're only trying to rewrite something in the domain part of the name, e.g. to fix a common misspelling, you don't even need the 'inherit' option. I setup a no-name virtual host to catch all invalid host names and respell them correctly before redirecting them.
Since this uses redirects, the appropriate virtual host will be found after the rewrites have been applied.
Options +Indexes +FollowSymLinks
RewriteEngine on
# If it begins with only domain.com, prepend www and send to www.domain.com
RewriteCond %{HTTP_HOST} ^domain [NC]
RewriteRule ^(.*) http://www.domain.com$1 [L,R=301]
# Correct misspelling in the domain name, applies to any VirtualHost in the domain
# Requires a subdomain, i.e. (serviceXXX.)domain.com, or the prepended www. from above
RewriteCond %{HTTP_HOST} ^([^.]+\.)dommmmmain\.com\.?(:[0-9]*)?$ [NC]
RewriteRule ^(.*) %{HTTP_HOST}$1 [C]
RewriteRule ^([^.]+\.)?domain.com(.*) http://$1domain.com$2 [L,R=301]
# No-name virtual host to catch all invalid hostnames and mod_rewrite and redirect them
<VirtualHost *>
RewriteEngine on
RewriteOptions inherit
</VirtualHost>
You may want to use InheritDownBefore to avoid having to add more junk to your vhosts.
An example of a global letsencrypt alias:
# letsencrypt
<IfModule alias_module>
Alias /.well-known/ /var/www/html/.well-known/
</IfModule>
<IfModule mod_rewrite.c>
# prevent vhost rewrites from killing the alias
RewriteEngine On
RewriteOptions InheritDownBefore
RewriteCond %{REQUEST_URI} ^/\.well\-known
RewriteRule . - [L,PT]
</IfModule>
Then you can do this in each of your vhosts, with no other directives:
<VirtualHost *:80>
....
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^/.* /index.php [L,PT]
</IfModule>
</VirtualHost>
Thanks to everyone to answered above. It helped me find my answer.
Question has been answered already, I just wanted to add an example in case you are using Google Compute Engine. It says it requires Apache HTTP Server 2.4.8 BUT it works with Apache/2.4.25 (Debian). Even when I try to upgrade, I cannot go past Apache/2.4.25. It says this version is the latest version.
Here's an example of how to implement.
RewriteOptions InheritDown
RewriteCond %{HTTP_HOST} ^www\. [NC,OR]
RewriteCond %{HTTP_HOST} !\.co$ [NC]
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)\.[^.]+$ [NC]
RewriteRule ^ https://%1.co%{REQUEST_URI} [L,NE,R=301]
<VirtualHost *:80>
RewriteEngine On
ServerAlias *.*
</VirtualHost>
ALSO OF NOTE (For Testing):
When you are testing your rewrite engine. It is really easy to get confused about if it is working or not because of cache and cookies. If you got it to work once on a browser, it will continue to work even if you delete the rewrite code. Testing rewrite is really annoying sometimes. You might think it works but then it stops or starts.
Best way to test rewrite code is to open an incognito tab in your browser, clear or cookies and cache. Open developer mode just in case. DO NOT JUST REFRESH. You need to click into the URL and refresh. Or open new tab. Or copy/paste URL into new window. If you use same window with refresh, it might be just redoing results from the past instead of renewing the new code.
I've always used a "catch-all" VHost for directives I wanted across the board, like......
Listen 80
NameVirtualHost *:80
<VirtualHost *:80>
ErrorLog "/var/log/apache2/error_log"
</VirtualHost>
<VirtualHost *:80>
ServerName alloftherestoftheVHosts.com
DocumentRoot "/ServiceData/.........
............
And it's always seemed to work... error logs were getting combined properly, etc...... but it IS possible that this was the result of an earlier / conflicting / like-minded directive.
Personal note.. Whoever dreamed up the Apache configuration schema and syntax was a dingbat, or a group of dingbats, who spent too much time in their cave.... The whole thing should be exorcised and XMLized, or something! Although they are both wildly different... the Hello-Kitty setup process of Cherokee.. to the viciously succinct NGinx config.... are both so much more logical..