How to Rewrite Rule for folder permission error? - linux

I have assets[/admin/assets] directory which I restricted access from browser.
So whenever user requested on [/admin/assets] , I want to rewrite rule to [admin/index.html].
I tried with below setting , but this doesn't rewrite to expected path but show permission access error with 403.
RewriteRule /assets /index.html [L]
I have one solution for that by handling ErrorDocument. But I don't prefer it that way, I want to handle by RewriteRule .

This can be achieved using the mod_rewrite module in Apache web server. You can add the following code in your .htaccess file or server configuration file to rewrite the URL:
RewriteEngine on
RewriteCond %{REQUEST_URI} /assets
RewriteRule ^assets/(.*)$ /admin/index.html [L]
The RewriteEngine directive turns on the rewriting engine.
The RewriteCond directive specifies a condition that must be met before the RewriteRule is applied. In this case, the condition checks if the requested URL starts with "/assets".
The RewriteRule directive specifies the actual URL rewriting. The pattern "^assets/(.)$" matches any URL that starts with "/assets/", and captures the rest of the URL into a group (.). The URL is then rewritten to "/admin/index.html". The [L] flag specifies that this is the last rule to be applied, so no further rewriting should take place.

I set by Directory module with Require All Denied
You can't block access and rewrite the request. The <Directory> container will take priority. (But there's no point blocking the request when you want to rewrite it. You are essentially blocking it by rewriting.)
Remove the <Directory> block and directly inside the <VirtualHost> container (outside of any <Directory> section) use mod_rewrite:
RewriteEngine On
RewriteRule ^/admin/assets($|/) /admin/index.html [L]
Any requests to /admin/assets or /admin/assets/<anything> are internally rewritten to /admin/index.html.

Related

Restrict access to TYPO3 backend via .htaccess

I'm trying to restrict access to the TYPO3 backend and the install tool. Beacause of that, the IPMaskList isn't the best thing to do so. I tried an .htaccess file in the /typo3 directory and it worked quite well to certain point. The following code was used to accomplish that:
RewriteEngine On
RewriteCond %{REMOTE_ADDR} !=<my_ip>
RewriteRule ^(.*)$ https://example.com [R=301]
Only the computer with the listed ip can access the index.php or install.php, which is very good. But as soon as I click the login button, and the URL changes to https://example.com/typo3/login?loginProvider=1433416747, it throws a 404 error. First, I thought it was the configured IP, as the server is requesting a page, and not my computer, but I don't know how to implement that.
The problem might just be that you are missing the L flag on the RewriteRule. The missing L flag will cause processing to continue through the remaining directives which probably includes a front-controller pattern. Typo3 then generates a 404 because https://example.com is not a valid "Typo3" URL.
But also...
First, I thought it was the configured ip, as the server is requesting a page, and not my computer,
If the server itself is also making an HTTP request (although not sure why) then you will also need to permit the server's IP address in your rule. For example:
RewriteCond %{REMOTE_ADDR} !=<my_ip>
RewriteCond %{REMOTE_ADDR} !=<server_ip>
RewriteRule ^ https://example.com/ [R=301,L]
Additional changes:
Missing L flag. (Mentioned above)
Missing trailing slash after the hostname (the browser "corrects" it).
No point capturing the URL-path in the RewriteRule pattern.
Although if you simply ant to restrict access then why not serve a "403 Forbidden" instead. Change the RewriteRule accordingly:
:
RewriteRule ^ - [F]
(L flag not required here.)
UPDATE:
No, by default there's no .htaccess in that dir, only the one in the root dir. Only with a .htaccess in the typo3 dir it's resulting in a 404. That's my only content in this particular .htaccess.
By enabling the rewrite engine in the subdirectory then it's going to completely override any mod_rewrite directives in the parent .htaccess file (by default), regardless of whether you are accessing the site by your IP or not. It would seem there are mod_rewrite directives in the parent/root .htaccess file that are required for your Typo3 installation to function (a front-controller pattern perhaps). (I had assumed these were all in the /typo3/.htaccess file.)
There are two solutions:
Move the above rule to the top of the root .htaccess file, adjusting accordingly. And delete the /typo3/.htaccess file. For example:
# In the root ".htaccess" file
RewriteCond %{REMOTE_ADDR} !=<my_ip>
RewriteRule ^typo3(/|$) - [F]
OR
Don't use mod_rewrite to block the request. For example, use an Apache expression with mod_authz_core instead. For example:
# In the "/typo3/.htaccess" file
<If "! -R '<my_ip>'">
Require all denied
</If>

Redirect all URLS to new URL EXCEPT for /backend/ with .htaccess

I want to redirect all incoming queries to a new domain, except for /backend
I have this in my .htaccess, everything works, except for the /backend. I tried a few combinations, it just doesnt work.
I fear /backend is a virtual address....
what can i do?
HERE IS THE CODE:
RewriteCond %{HTTP_HOST} ^example.de$ [OR]
RewriteCond %{HTTP_HOST} ^www.example.de$
RewriteCond %{REQUEST_URI} !^/backend/$
RewriteRule (.*)$ https://www.bing.de/ [R=302,L]
PLEASE HELP. Thank you. Patrick
I fear /backend is a virtual address....
In which case you most probably have other mod_rewrite directives that rewrite the request to a front-controller (such as index.php) - and that's the problem. Whilst your existing rule includes an exception for /backend/ (the originally requested URL), so the rule is skipped on the first pass by the rewrite engine, once the request is rewritten to the front-controller (eg. index.php) the rewrite engine begins a 2nd pass which results in the rule being successfully executed since the URL is now /index.php (or whatever your front-controller is) and not /backend/.
You either need to:
modify the other directives that rewrite the request to the front-controller, so as not to trigger a 2nd pass through the rewrite engine. (You've not included your complete .htaccess file, so I'll discount this approach for now.)
OR, make sure you only examine the originally requested URL and not the rewritten URL. (The REQUEST_URI server variable is modified as the request is rewritten.)
However, I would assume that your /backend/ page also links to static assets (such as images, CSS, JS)? In which case, you also need to make exceptions for any additional static assets that are used by the page, otherwise these will also be redirected. For the sake of this example, I will assume all you static assets are located in an /assets subdirectory.
Try the following instead, near the top of your root .htaccess file:
RewriteCond %{HTTP_HOST} ^(www\.)?example\.de [NC]
RewriteCond %{THE_REQUEST} !\s/backend/\s
RewriteRule !^assets/ https://www.bing.de/ [R=302,L]
Note that this rule must go before the rewrite to the front-controller.
The THE_REQUEST server variable contains the first line of the HTTP request headers and importantly, does not change as the request is rewritten. This contains a string of the form GET /backend/ HTTP/1.1 (containing the request method, URL and protocol).
If there are no external assets then change the RewriteRule pattern from !^assets/ to simply ^, to match everything.

Redirect internally to higher directory

I have example.org and foo.example.org pointing to the same directory, /var/www/html/, and want foo.example.org to internally redirect to /var/www/foo/ using only mod_rewrite.
This is what I have so far, but no joy:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_HOST} ^foo [NC]
RewriteRule ^(.*)$ ../foo/$1 [L]
</IfModule>
This gets me 500s due to hitting the limit of 10 internal redirects, but I don't understand why.
The reason for the internal redirect loop is that your only RewriteCond is the host name check. The host name won't change after the internal redirect, and alas, will get triggered when the rules are parsed for the new request. You can solve this by adding a RewriteCond to check if the path already is set to the expected value (i.e. only rewrite requests with the path set to /var/www/html, and skip any other rewrite - as it has already been rewritten).
I'm going to suggest that it might be cleaner to do something like this through mod_vhost_alias, depending on your use case.

Redirect to fallback file if first attempt fails

I have this in my .htaccess:
RewriteRule ^images/([^/\.]+)/(.+)$ themes/current/images/$1/$2 [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^images/([^/\.]+)/(.+)$ modules/$1/images/$2 [L,NC]
The idea is that it does the following:
// Rewrite this...
images/calendar/gear.png
// ... to this
themes/current/images/calendar/gear.png
// HOWEVER, if that rewritten path doesn't exist, rewrite the original URL to this:
modules/calendar/images/gear.png
The only things that change here are calendar and gear.png, the first of which could be any other single word and the latter the file name (possibly with path) to an image file.
I can rewrite the original URL to the first rewrite as shown in the example just fine, but what I cannot do is get my .htaccess to serve up the file from the other, fallback location if the first location 404s. I was under the impression that not using [L] in my first RewriteRule would rewrite the URL for RewriteCond.
The problem I'm having is that instead of serving the fallback file, the browser just shows a 404 to the first rewritten path (themes/current/calendar/gear.png), instead of falling back to modules/calendar/gear.png. What am I doing wrong?
Please note that my regex isn't perfect, but I can refine that later. Right now I'm concerning myself with the rewrite logic itself.
Fallthrough rules are fraught with bugs. My general recommendation is than any rule with a replacement string other than - should trigger an internal redirect to restart the .htaccess parse. This avoids the subrequest and URI_PATH bugs.
Next once you go to 404, again in my experience this is unrecoverable. I have a fragment which does something similar to what you are trying to do:
# For HTML cacheable blog URIs (a GET to a specific list, with no query params,
# guest user and the HTML cache file exists) then use it instead of executing PHP
RewriteCond %{HTTP_COOKIE} !blog_user
RewriteCond %{REQUEST_METHOD}%{QUERY_STRING} =GET [NC]
RewriteCond %{ENV:DOCUMENT_ROOT_REAL}/blog/html_cache/$1.html -f
RewriteRule ^(article-\d+|index|sitemap.xml|search-\w+|rss-[0-9a-z]*)$ \
blog/html_cache/$1.html [L,E=END:1]
Note that I do the conditional test in filesystem space and not URI (Location) space. So this would map in your case to
RewriteCond %{DOCUMENT_ROOT}/themes/current/images/$1/$2l -f
RewriteRule ^images/(.+?)/(.+)$ themes/current/images/$1/$2 [L]
Though do a phpinfo() to check to see if your hosting provider uses an alternative to DOCUMENT_ROOT if it is a shared hosting offering e.g an alternative environment variable as mine uses DOCUMENT_ROOT_REAL.
The second rule will be picked up on the second processing past after the internal redirect.

htaccess - Redirect loop

Why is this causing a redirect loop?
Options +FollowSymlinks
RewriteEngine on
RewriteBase /summary/1/document/
RewriteRule !^[a-z]{2}/ /summary/1/document/en/ [L,R]
RewriteRule ^([a-z]{2})/ ../index.php?lang=$1&type=document
What I am trying to achieve is:
If there's no language specified, redirect to english:
Example:
website.com/summary/1/document --> website.com/summary/1/document/en/
website.com/summary/1/document/fr/ [no redirect]
And when a language is specified, rewrite internally to ../index.php with lang and type parameters.
From Flag L: Apache Docs: flag_l :
If you are using RewriteRule in either .htaccess files or in <Directory> sections, it is important to have some understanding of how the rules are processed. The simplified form of this is that once the rules have been processed, the rewritten request is handed back to the URL parsing engine to do what it may with it. It is possible that as the rewritten request is handled, the .htaccess file or section may be encountered again, and thus the ruleset may be run again from the start. Most commonly this will happen if one of the rules causes a redirect - either internal or external - causing the request process to start over.
Since, rewritten request is handed back to the URL parsing engine, after redirect from the first rewrite rule,
Try this:
Options +FollowSymlinks
RewriteEngine on
RewriteBase /summary/1/document/
RewriteRule ![a-z]{2}/$ /summary/1/document/en/ [NC,L,R]
RewriteRule ^([a-z]{2})/$ ../index.php?lang=$1&type=document [L,QSA]

Resources