htaccess deny from http - apache

I know how to use the apache rewrite engine to redirect http requests to https
However, for the task at hand (an app exchanging data with the server via https) what we actually want is for http requests to simply be denied. I have tried the following but it does not work
​Deny from %{HTTPS}=off
Is there a way to do this?

You cannot simply take parts of directives and scrumble them together somehow. You need to obey the syntax of those directives, otherwise the engine cannot make sense of them. And will throw an internal syntax error.
Two things you need to do:
You need to start monitoring your http server's error log file. That is where you can see those errors. You cannot implement web logic without monitoring that file in your development environment . And you definitely should look into it in your production environment too from time to time.
You should start to read the documentation of the tools you are using. The apache http server project is a good example for the high quality of open your products: it offers an excellent documentation that is precise and comes with lots of great examples. Start with the documentation of the rewriting module: https://httpd.apache.org/docs/current/mod/mod_rewrite.html
This would be a suggestion to implement the logic you have in mind:
RewriteEngine on
RewriteCond %{HTTPS} !=on
RewriteRule ^ - [F]
Other variants are possible, for example:
RewriteEngine on
RewriteCond %{SERVER_PORT} !^443$
RewriteRule ^ - [F]

Related

htaccess RewriteRule creates only root-url, not the expected one

here are some possible URL's i need to rewrite:
https://www.example.org/products/rubbers/1234-super-special-rubber
https://www.example.org/forum/2345-hello-world
https://www.example.org/3456-very-special-article
I want to remove all numbers and the - sticking to the number from the URL:
https://www.example.org/products/rubbers/super-special-rubber
https://www.example.org/forum/hello-world
https://www.example.org/very-special-article
What i tried so far (4 digits and -):
RewriteCond %{REQUEST_URI} ^.*[/][0-9][0-9][0-9][0-9]-.*$
RewriteRule ^.*[/][0-9][0-9][0-9][0-9]-.*$ /$1 [R=301,L]
The redirect works not as expected, it only takes me to:
https://www.example.org/
I also tried
RewriteEngine On
RewriteBase /
RewriteRule (\d+)-([^/]*) $2 [R=301,L]
this should work, but it cuts '/products/rubbers' away :(
https://www.example.org/super-special-rubber
How do i tell the RewriteRule to cut out the numbers and the first - ?
Thank you :)
The $1 reference you use in your rule references the first captured group from your matching pattern, but you did not define any such group. That is why it is empty and you rewrite to what you call the "root URL".
Take a look at this instead:
RewriteEngine on
RewriteRule ^/?(.*)/\d{4}-(.+)$ /$1/$2 [R=301,END]
It is a good idea to start out with a 302 temporary redirection and only change that to a 301 permanent redirection later, once you are certain everything is correctly set up. That prevents caching issues while trying things out...
In case you receive an internal server error (http status 500) using the rule above then chances are that you operate a very old version of the apache http server. You will see a definite hint to an unsupported [END] flag in your http servers error log file in that case. You can either try to upgrade or use the older [L] flag, it probably will work the same in this situation, though that depends a bit on your setup.
This implementation will work likewise in the http servers host configuration or inside a distributed configuration file (".htaccess" file). Obviously the rewriting module needs to be loaded inside the http server and enabled in the http host. In case you use a distributed configuration file you need to take care that it's interpretation is enabled at all in the host configuration and that it is located in the host's DOCUMENT_ROOT folder.
And a general remark: you should always prefer to place such rules in the http servers host configuration instead of using distributed configuration files (".htaccess"). Those distributed configuration files add complexity, are often a cause of unexpected behavior, hard to debug and they really slow down the http server. They are only provided as a last option for situations where you do not have access to the real http servers host configuration (read: really cheap service providers) or for applications insisting on writing their own rules (which is an obvious security nightmare).

Redirect all subdomains to file

I have a server to which many domains points. So I need a generic .htaccess rule. I need to create a .htaccess file which redirects all subdomains to their correspondent subdomain folder.
Is that possible? Thanks.
For example:
http(s)://apple.domain1.com -> https://domain1.com/redir/apple/index..html
http(s)://orange.2domain.co.uk -> https://2domain.co.uk/redir/orange/index.asp
http(s)://banana.doma3n.org -> https://doma3n.org/redir/banana/index.php
OK, so now it suddenly are three questions in one :-)
I don't really understand why you need separate folders for this. Why not one script that handles those requests, regardless on what host ("subdomain") is called? The script knows about what host has been called, so it can act accordingly.
Anyway, your question is how to rewrite to separate folders, so that is what I will answer to...
In addition to rewriting hosts acting as landing pages you also want to configure your default host (the fallback host) such that it delivers something that does make sense.
Anyway, this should point you into the right direction:
First you need to configure your DirectoryIndex:
DirectoryIndex index.html
DirectoryIndex index.php
DirectoryIndex index.asp
Consult the documentation for more details and where to place those directives:
https://httpd.apache.org/docs/2.4/mod/mod_dir.html
Second you need to rewrite the incoming requests to internal directories:
RewriteEngine on
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteCond %{REMOTE_ADDR} ^10\.
RewriteRule ^ /redir_internal [END]
RewriteCond %{HTTP_HOST} ^([^.]+)\.
RewriteCond -d %1
RewriteRule ^ /%1 [END]
RewriteRule ^ /something_that_acts_as_a_fallback
Consult the documentation for more details:
https://httpd.apache.org/docs/current/mod/mod_rewrite.html
It is a good idea to start out with a 302 temporary redirection and only change that to a 301 permanent redirection later, once you are certain everything is correctly set up. That prevents caching issues while trying things out...
In case you receive an internal server error (http status 500) using the rule above then chances are that you operate a very old version of the apache http server. You will see a definite hint to an unsupported [END] flag in your http servers error log file in that case. You can either try to upgrade or use the older [L] flag, it probably will work the same in this situation, though that depends a bit on your setup.
This implementation will work likewise in the http servers host configuration or inside a distributed configuration file (".htaccess" file). Obviously the rewriting module needs to be loaded inside the http server and enabled in the http host. In case you use a distributed configuration file you need to take care that it's interpretation is enabled at all in the host configuration and that it is located in the host's DOCUMENT_ROOT folder.
And a general remark: you should always prefer to place such rules in the http servers host configuration instead of using distributed configuration files (".htaccess"). Those distributed configuration files add complexity, are often a cause of unexpected behavior, hard to debug and they really slow down the http server. They are only provided as a last option for situations where you do not have access to the real http servers host configuration (read: really cheap service providers) or for applications insisting on writing their own rules (which is an obvious security nightmare).

Exception for rewriting every php file

RewriteCond %{REQUEST_FILENAME} !\.(png|jpg|jpeg|gif|svg|zip|xml|json|html|txt)$
RewriteRule ^(.*)$ index.php [L,QSA]
This works perfectly, but I want to except the one file I use as a GET endpoint.
I tried:
RewriteRule /assets/get_endpoint\.php - [L,QSA]
But that didn't work... I'm still getting rerouted to the "index.php".
AND the php file will definitely consist of GET parameters as well.
e.g.
www.example.com/assets/get_endpoint.php?date=2019-12-21&location=Paris
The .htaccess only consists of those two lines ( and the third ).
This should be really easy but I can't figure it out. Thanks so much for your help!
This probably is what you are looking for:
RewriteEngine on
RewriteRule ^/?assets/get_endpoint\.php$ - [END]
RewriteCond %{REQUEST_URI} !\.(png|jpg|jpeg|gif|svg|zip|xml|json|html|txt)$
RewriteRule ^/?(.*)$ /index.php [END]
I also made a few other optimizations once on it :-)
In case you receive an internal server error (http status 500) using the rule above then chances are that you operate a very old version of the apache http server. You will see a definite hint to an unsupported [END] flag in your http servers error log file in that case. You can either try to upgrade or use the older [L] flag, it probably will work the same in this situation, though that depends a bit on your setup.
This implementation will work likewise in the http servers host configuration or inside a dynamic configuration file (".htaccess" file). Obviously the rewriting module needs to be loaded inside the http server and enabled in the http host. In case you use a dynamic configuration file you need to take care that it's interpretation is enabled at all in the host configuration and that it is located in the host's DOCUMENT_ROOT folder.
And a general remark: you should always prefer to place such rules in the http servers host configuration instead of using dynamic configuration files (".htaccess"). Those dynamic configuration files add complexity, are often a cause of unexpected behavior, hard to debug and they really slow down the http server. They are only provided as a last option for situations where you do not have access to the real http servers host configuration (read: really cheap service providers) or for applications insisting on writing their own rules (which is an obvious security nightmare).

.htaccess redirects if the condition doe not match/ negative condition

I am modifying the .htaccess file of a legacy PHP web application. I am not familiar with apache .htaccess syntax. I found this tutorial. What I am trying to do is that I am trying to redirect all the requests to a URL/ path if the request URL is not a specific URL/ path. For example, all the requests to the website will be redirected to localhost/my-custom-page unless the request URL is localhost/my-custom-page.
I know how to redirect mapping 1 to 1 as follows:
RewriteEngine on
RewriteRule ^my-old-url.html$ /my-new-url.html [R=301,L]
But, what I am trying to do is that redirecting all the requests to the specific page unless the request is to that page. Even the home page will be redirected to that page. How can I do that?
When I tried the following solution
RewriteEngine on
RewriteCond %{REQUEST_URI} !/my-new-url\.html
RewriteRule ^ /my-new-url.html [R=301]
I get the error
I want to check using OR condition as well. For example, if the path is not path-one or path-two, redirect all the requests to path-one.
Your question is a bit vague, due to your wording. But I assume this is what you are actually looking for:
RewriteEngine on
RewriteCond %{REQUEST_URI} !/my-new-url\.html
RewriteRule ^ /my-new-url.html [R=301]
In case you receive an internal server error (http status 500) using the rule above then chances are that you operate a very old version of the apache http server. You will see a definite hint to an unsupported [END] flag in your http servers error log file in that case. You can either try to upgrade or use the older [L] flag, it probably will work the same in this situation, though that depends a bit on your setup.
It is a good idea to start out with a 302 temporary redirection and only change that to a 301 permanent redirection later, once you are certain everything is correctly set up. That prevents caching issues while trying things out...
This rule will work likewise in the http servers host configuration or inside a dynamic configuration file (".htaccess" file). Obviously the rewriting module needs to be loaded inside the http server and enabled in the http host. In case you use a dynamic configuration file you need to take care that it's interpretation is enabled at all in the host configuration and that it is located in the host's DOCUMENT_ROOT folder.
And a general remark: you should always prefer to place such rules in the http servers host configuration instead of using dynamic configuration files (".htaccess"). Those dynamic configuration files add complexity, are often a cause of unexpected behavior, hard to debug and they really slow down the http server. They are only provided as a last option for situations where you do not have access to the real http servers host configuration (read: really cheap service providers) or for applications insisting on writing their own rules (which is an obvious security nightmare).
RewriteCond %{REQUEST_URI} !/my-new-url\.html
RewriteRule ^ /my-new-url.html [R=301]
There are a few potential issues with this, particularly since you hint in a comment that you are perhaps using a front-controller to "route" the URL.
This redirect satisfies the conditions outlined in the question, but does assume that you have no other rewrites, have an essentially "static site" and are not linking to any static resources.
You are missing an L (last) flag, so processing will continue through the file and possibly be rewritten if you have later rewrites.
If you are rewriting the URL to a front-controller in order to route the URL (as you suggest in comments) then this redirect will break, as it will redirect away from the front-controller. You need to only redirect direct requests, ie. when the REDIRECT_STATUS environment variable is empty.
If you are linking to any static resources in the same file space then these will also be redirected. You need to create an exception for any static resources you are using, either by file extension (eg. (css|js|jpg|png)) or by location (eg. /static).
So, try the following instead:
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_URI} !\.(js|css|jpg|png)$
RewriteRule !^my-custom-url$ /my-custom-url [R=302,L]
You don't need a separate condition to implement the exception for the URL you are redirecting to. It is more efficient to do this directly in the RewriteRule pattern.
The first condition ensures we are only redirecting direct requests and not rewritten requests to your front-controller.
The second condition avoids any static resources also being redirected. You could alternatively check the filesystem path if all your resources are stored under a common root. Or, as a last resort, implement filesystem checks (ie. RewriteCond %{REQUEST_FILENAME} !-f) if your static resources are too varied - but note that this is less efficient.
You will need to clear your browser cache before testing, since any earlier (erroneous) 301s are cached persistently by the browser.

How to make files only accessible to scripts? / Innacessable Directly?

I've spent all day looking for a solution on how to make files inaccessible directly, but still accessible to scripts.
All answers I've found lead me in round about loops.
This may be useful to someone.
If anyone has a better solution,
Please Post.
Here is the one I have found.
How to make files only accessible to scripts ( Including Client Side Scripts? ) / Innacessable Directly (IE: Through URL)?
Turn on mod_rewrite
in .htaccess file:
RewriteEngine on
RewriteCond %{HTTP_REFERER} !http://*************
RewriteCond %{HTTP_REFERER} !http://*************
RewriteRule ^ - [L,F]
Type in your domain in the ******
Use Https if needed.
If by "direct" you mean file access from a browser, then you can require that an HTTP client presents a custom header, e.g. X-Access: authorized_script so it can't be easily sent from a browser.
This answer discusses how it's done with Apache.