Issue with RewriteCond - apache

Ive got an issue with apache's rewrite module. This is what im trying to do:
Ive got confluence(tomcat) running on a server with apache as reverse proxy in front.
Also, im using authentification in apache (form auth). So if ure trying to access [server]/confluence, you get redirected to a file login.php containing the authentification routine. If login succeeds, proxy lets u access tomcat.
Every other request is blocked. This works easily for every request except for [server]/login.php as this file exists indeed in htdocs. Every other request is handled with
FallbackResource wrong_url.shtml
Now i want to block direct access to login.php as you would get stuck in a dead end.
I tried to do this by using a RewriteCond with ${REQUEST_URI} as phpinfo() gave me this:
<server>/confluence (you automatically get redirected to login.php by apache): php says REQUEST_URI = /confluence
<server>/login.php: php says REQUEST_URI = /login.php
makes sense, though. Now what i did is:
<VirtualHost *:80>
ServerName 192.168.2.237
RewriteEngine on
RewriteCond %{REQUEST_URI} ^/login.php$
RewriteRule ^/login.php$ wrong_url.shtml [L]
</VirtualHost>
But this doesnt work properly. It either wont work at all or it crashes everything.
Pls forgive me if this is obvious, but im quite a beginner to rewriting. Can anybody tell me wheres my fault oder provide me a way to do this (propably, this is really easy)?

Have you checked the server logs ? Enable and set RewriteLogLevel (to 9) and debug the request flow.
Although you don't really need mod_rewrite for such a basic task, use mod_alias instead.
<VirtualHost *:80>
ServerName 192.168.2.237
Alias /login.php /wrong_url.shtml
</VirtualHost>

Related

I can't pass URL Parameters with Vue-Router and Apache2?

I am deploying an Vue3 Applikation with Vue-Router 4 on an Apache2 Server.
I observed some obstacles while doing it.
So my main problem is, that I can't pass Url Params to Vue via the Apache2 Server.
While developing the app and debugging it at localhost, everything worked perfectly.
e.g localhost:8080/myParam
Matches and redirects me to the index.html and passes the myParam to vue-router and the correct view is displayed.
So far so good.
Now I am deploying on an apache2 server and exactly that redirecting doesnt work.
I have read the docu and found this description:
https://router.vuejs.org/guide/essentials/history-mode.html#apache
The redirect works. But when I type in example.org/browse/myParam it redirects me to example.org/browse/index.html and my myParam is gone.
My Setup:
Apache 2.4, Vue3, Vue-Router4
The App is a Subapplication of a bigger project (thatswhy the app is not served in the root folder).
At the moment my App is running in a docker-container on the Server at port 8895, so I needed to create a proxypass in the apache.conf.
Because the files were not actually accessible at the server I also couldnt just use {REQUEST_FILE} (as shown in the vue-router example), so I solved it kind of hacky via the request uri and a pattern matching. But in my view that shouldn't be the problem, right?
#------------#
# BROWSER #
#------------#
ProxyPass /browse/ http://localhost:8895/
ProxyPassReverse /browse/ http://localhost:8895/
RewriteEngine On
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
<IfModule mod_rewrite.c>
RewriteRule ^/browse/index\.html$ - [L]
RewriteCond %{REQUEST_URI} !/browse/js/.*.js(.map)?$
RewriteCond %{REQUEST_URI} !/browse/css/.*.css$
RewriteRule ^/browse/ https://example.org/browse/index.html [L]
</IfModule>
Conclusion: I can visit my website, but only the homepage. I can't visit https://example.org/browse/Person/Sebastian directly. I can only go to https://example.org/browse/index.html and the click myself through the application.
I can't imagine that there are not many other people who had a similar problem, but I couldn't find any.

apache mod_rewrite user URLs to index.php

I've always had a fairly standard apache configuration. Right now we're introducing a new concept, user session specific URLs that's going to change things. Basically we have a DocumentRoot and anything such as:
http://example.com/ would hit index.html in the DocumentRoot directive.
But now I'd like to be able to do something like
http://example.com/uid/5/
http://example.com/uid/2
Those should still hit index.html in the DocumentRoot that has been set. The URL is mostly for server-side and client-side scripts to be able to carry out their own tasks.
What's the best way to handle this in Apache? Is mod_rewrite even necessary here?
I also need to be able to support existing paths such as say the following:
http://example.com/foo/bar/something.php will be rewritten to http://example.com/uid/3/foo/bar/something.php but will still hit the same place on the filesystem as before.
You could use mod_rewrite by putting this code in your htaccess
RewriteEngine On
RewriteRule ^uid/([1-9][0-9]*)/(.+)$ /$2?uid=$1 [L]
Example:
http://example.com/foo/bar/something.php -> unchanged
http://example.com/uid/3/foo/bar/something.php -> rewritten to /foo/bar/something.php?uid=3
EDIT: without uid appended
RewriteEngine On
RewriteRule ^uid/[1-9][0-9]*/(.+)$ /$1 [L]

Correctly setup Tomcat behind Apache with mod_proxy_ajp

I've been tinkering with Apache + Tomcat so that I can serve multiple tomcat apps (in different machines) through apache (clean & crisp urls rock). I've succesfully configured mod_proxy_ajp & mod_rewrite to the point where I can serve two tomcat apps in different machines with almost no troubles.
The only issue I've found is that one of the apps (which I'm developing in Struts2) has a lot of links and forms, which are generated with <s:a />, <s:url /> and <s:form /> tags. The urls generated by these tags generally are like this:
/WebApp/path/to/some.action
Thanks to the magic of ModRewrite, this is generally not a big issue and hyperlinks poiting to such urls are quickly rewriten & redirected to /app/path/to/some.action (although I do get tons of 302 responses).
The real problem occurs when performing POST requests. As you all might know, I cannot redirect POST requests with mod_rewrite... so in the end... all of my POST requests don't work because mod_rewrite redirects to the correct url but as a GET request.
I have already read a bit about mod_proxy_html and how it can help me rewrite the urls returned by the Tomcat web application... but it feels troublesome.
This is my current apache configuration:
## HACKING BEGINS RIGHT HERE
# cookies
ProxyPassReverseCookiePath /WebApp /app
# this is for CSS, IMGs, JS and redirecting urls with /WebApp*
RewriteRule ^/WebApp(.*)$ /app$1 [R,L]
<Location /app>
ProxyPass ajp://localhost:8009/WebApp
ProxyPassReverse ajp://localhost:8009/WebApp
Order allow,deny
Allow from all
</Location>
# the other app
ProxyPassReverseCookiePath /WebApp2 /other
<Location /other>
ProxyPass ajp://200.9.4.6:8009/WebApp2
ProxyPassReverse ajp://200.9.4.6:8009/WebApp2
Order allow,deny
Allow from all
</Location>
There must be a solution to my POST requests problem... Any ideas? Can I somehow configure something that will allow Struts2 to output correct urls?
Thanks for your help.
There may be a couple ways to go about this.
If you are able to deploy your app to Tomcat under the same name that you are using in the URL, that would be the easiest. So your application app would be /webapps/app[.war] instead of /webapps/WebApp, this would avoid the rewrite altogether.
Otherwise, the following should work, and should go before your current rewrite rule. The [PT] should allow Apache to still proxy the request (this works when using mod_jk, not sure I've used/tested it with mod_proxy_ajp):
RewriteCond %{REQUEST_METHOD} POST
RewriteRule ^/WebApp(.*)$ /app$1 [PT,L]
Once your bean has processed the POST request, you could then send the request to a URL that would be redirected. In the end, the POST URL doesn't matter to the user, so it doesn't have to be a pretty URL.
Edits Below:
I saw on the Apache mod_proxy, that ProxyPassReverse should work with the [PT] flag. And I was able to replicate the issue you're having, and the below config worked for me with a basic JSP page with a form that posted to another JSP page.
<VirtualHost *:80>
ServerName localhost
RewriteEngine On
RewriteCond %{REQUEST_METHOD} !POST
RewriteRule /WebApp/(.*) /app/$1 [R,L]
RewriteCond %{REQUEST_METHOD} POST
RewriteRule /WebApp/(.*) /app/$1 [PT,L]
<Location /app>
ProxyPass ajp://localhost:8109/WebApp
ProxyPassReverse ajp://localhost:8109/WebApp
</Location>
</VirtualHost>
This is a problem with the webapp setup; there may be a way to work around it in httpd config, but it's cleaner to fix the original inconsistency vs. hacking around it.
Also worth mentioning that Struts is trying to help you by giving you context-aware, non-relative URLs; if you just make the paths match, you can rely on that (instead of fighting it...).
So, just deploy the Struts webapp to /app and /other, instead of /WebApp and /WebApp2. (There might be some reason this isn't possible -- like if you don't actually control those other servers -- but it sounds like that doesn't apply).
I would avoid URL rewriting. It just opens cans of worms like this, makes you look into mod_proxy_html, etc, which of course are just yet more worms. Instead just deploy your apps in Tomcat with real URLs you can live with as being visible externally.

RewriteRule for mapping x.domain.com to y.domain.com

Is it possible to redirect all requests to x.domain.com/.* to y.domain.com/.* WITHOUT letting this redirection be visible in the url?
I have unsuccessfully tried several things in .htaccess. Just specifying the [L] flag still shows this redirection in the url (as it does when I use the [R] flag additionally).
EDIT: as somebody claimed there being no reason for this, let me give some more information :)
I have one nice url: x.domain.com , which is well known.
Then there are a number of other domains: spring.domain.com , summer.domain.com , autumn.domain.com, winter.domain.com .
Depending on the time of the year, a specific y.domain.com becomes the current one. The x.domain.com should always map to the current one.
EDIT2:
I'll write here, as the code isn't nicely rendered in the comments...
I tried what Arjan suggested:
RewriteCond %{HTTP_HOST} ^x.domain.com$
RewriteRule ^(.*)$ /path/to/y.domain.folder/$1
Unfortunatly though this keeps redirecting forever. :(
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.
Putting the [R] flag behind, I see in the url something like:
http://x.domain.com/path/to/y.domain.folder/path/to/y.domain.folder/path/to/y.domain.folder/ ...
Any suggestions?
Now that I can read the errorlogs, I can give a direct response, as what a possible 500 error refers to.
Assuming you have access to the Apache configuration, create the following virtual host for domain x.domain.com. Then simply update y to whatever you need each season.
<VirtualHost ...:80>
ServerName x.domain.com
UseCanonicalName Off
ProxyRequests Off
<Proxy *>
Order Allow,Deny
Allow from all
</Proxy>
ProxyPreserveHost Off
RewriteEngine On
RewriteRule ^$ http://y.domain.com/ [P,NC]
RewriteRule ^/(.*)$ http://y.domain.com/$1 [P,NC]
ProxyPassReverse / http://y.domain.com/
</VirtualHost>
Also to pick up the Alias suggestions, if you have multiple virtual hosts (one for each season) then you could put a server alias into the current domain. E.g.
<VirtualHost ...:80>
ServerName summer.domain.com
ServerAlias x.domain.com
...
</VirtualHost>
<VirtualHost ...:80>
ServerName spring.domain.com
...
</VirtualHost>
...
This would make Apache deliver the summer.domain.com pages if you go to x.domain.com. If your seasonal subdomains depend on the HOST header line to be set correctly (i.e. to season.domain.com) you would need to use the first suggestion above, though.
If these are not hosted on the same server, then you'd need the Proxy flag. This also requires the proxy module to be running. Not tested:
RewriteCond %{HTTP_HOST} ^x.domain.com$
RewriteRule ^(.*)$ http://y.domain.com/$1 [P]
EDIT: Given the edits to your question they're probably just on the same server. So then indeed, as jetru suggested an Alias might do. Or:
# No RewriteCond required; serve all content from other folder:
RewriteRule ^(.*)$ /path/to/y.domain.folder/$1
EDIT: The above would not change the HTTP_HOST header that was sent by the browser (maybe that can be done as well). This implies that it would only work if the subdomains are represented on the file system as separate directories. So, as the .htaccess would then be placed in the directory holding the website for x.domain.com, the RewriteCond wouldn't even be required. Also, the directory for this x.domain.com subdomain would in fact not need any HTML content then; in the end all content would be served from the directory of another subdomain.
EDIT: As the above does not seem to work either, and yields endless rewrite loops even when adding [NS], maybe simply adding [L] helps here:
RewriteRule ^(.*)$ /path/to/y.domain.folder/$1 [NS,L]
Or maybe one can set an environment variable to stop the loop:
RewriteCond %{ENV:MY_VAR} !=1
RewriteRule ^(.*)$ /path/to/y.domain.folder/$1 [E=MY_VAR:1]
But, for both [L] and [E]: I'm just guessing; I've never made mod_rewrite jump into the directory of another virtual host. I am not sure it can be done to start with.
Unfortunately, it's unclear how one would add a new subdomain. If one would just need to create a new directory with the name of the subdomain (without any use of some administrative tool) then the provider might be be using system wide rewriting as well. In fact, even without subdomains the provider might be doing some Mass Virtual Hosting as described in the URL Rewrite Guide.
I guess the best solution would be to change the value of HTTP_HOST on the fly, to solve issues with any system wide rewriting. Maybe the following is allowed to achieve that:
RewriteCond %{HTTP_HOST} ^x.domain.com$
RewriteRule ^(.*)$ /path/to/y.domain.folder/$1 [E=HTTP_HOST:y.domain.com]
Again, as the above would only be present in the .htaccess in the x.domain.folder, the RewriteCond is probably not needed at all.
Have you tried
Alias /dir/file.html /full/path/to/other/file.html
??
To my knowledge and testing with firebug a redirect via .htaccess is always announced to the client and it's up to him how to proceed. It is therefore not an alternative to some sort of SSI functionality. To prevent a "fake" address modern browser should always make the REAL address visible to the user, however I think I have seen some misbehavior in programs like "feeddemon" where IE is embedded. If you - for whatever reason - really want to show content from one subdomain on another you can try using Javascript or (i)frames on the user side or some include functionality on the server site (eg. file_get_contents with php). However, I don't recommend this.

Problems redirecting old domain to new with Apache and htaccess

My homepage is located at www.nazgulled.net and I bought a new domain which is www.ricardoamaral.net. Both these domains point to the same exact server.
I'm having two problems with the redirection, my current code is this:
RewriteCond %{HTTP_HOST} ^(www\.)?nazgulled\.net [NC]
RewriteRule ^(.*)$ http://www.ricardoamaral.net/$1 [L]
For now I'm just testing but the idea is to replace [L] with [L,R=301] when I'm ready to move the whole thing, just so you know.
Anyway...
1) This is not working, when I try it, I can't access "nazgulled.net", it gives me a "server internal error" and I don't understand why... I don't understand why because if replace "ricardoamaral.net" by "google.com", the redirect works just fine :/
2) I have a few subdomains and I would like to redirect everything in those too. My first choice is to add different rewrite conditions/rules for each of the subdomains but that takes a lot of manual code and if the user types some subdomain that doesn't exist, they don't be redirect it and I also want that.
I think for your situation creating separate vhosts would be the ideal fit. What I do often is place domains that are being redirected on the same server but in a different folder to keep the www folder clean, for instance. My main site would be here:
/var/www/example.com/public
For all my redirects I would place them like so:
/var/www/redirects/example-2.com/public
Within each public folder of the redirected sites you would add this line to your .htaccess file
RedirectMatch permanent /.* http://example.com/
For 1, you can use something like this instead:
<VirtualHost *:80>
ServerAdmin webmaster#nazgulled.net
ServerName nazgulled.net
ServerAlias www.nazgulled.net
Redirect permanent / http://www.ricardoamaral.net/
</VirtualHost>
I use a similar configuration and it works perfectly, keeping query parameters, paths, etc.
Regarding your own rewrite rule, I want to note that you may lose your query params if you don't include QSA.
To diagnose internal server errors, just have a look at the log file provided by your ErrorLog directive within your vhost, or a global one, depending on your configuration. It should give you the exact reason for the error.
This is best solutions. Create a notepad file and save it as .htaccess if you do not already have an existing one.
Update the .htaccess file with the following code and save
Options +FollowSymLinks
RewriteEngine on
RewriteRule (.*) http://new-domain.com/$1 [R=301,L]