Deny access to all content except content from one folder - apache

I want to allow access to only one folder of my site in a given subdomain, and have another subdomain pointing to same documentRoot with full access. I want this to avoid duplicated urls (for SEO purposes).
In the restricted virtualHost I have this configuration ...
<Directory /var/www/secundary.mysite.com/web>
Options -Includes +ExecCGI
AllowOverride All
RewriteEngine On
RewriteCond %{QUERY_STRING} !/bundles.*$ [NC]
RewriteRule ^.*$ - [F]
</Directory>
So I expect that navigation to mysite.com give a forbidden response, but www.mysite.com/bundles/js/script.js returns a normal response.
The result is that every request to secundary.mysite.com returns a normal response. Am I missing something, or ...?

I have been using a wrong variable. I wrote %{QUERY_STRING} instead %{REQUEST_URI} that was the variable that I wanted to match again the regular expression. The correct syntax for my purpose was:
<Directory /var/www/secundary.mysite.com/web>
Options -Includes +ExecCGI
AllowOverride All
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/bundles(.*)$ [NC]
RewriteRule ^.*$ - [F]
</Directory>

Related

How to search and replace GET parameters with mod_rewrite

I try write a rewrite rule on an apache webserver configuration in the httpd.conf file, which should replace every GET parameter key which contains &foo= to &poo= but shouldn't change any other GET parameter.
For example:
https://test.com/imb/rs/search?test=abc&foo=123&test2=def&foo=456
Should be changed to:
https://test.com/imb/rs/search?test=abc&poo=123&test2=def&poo=456
I tried it with:
RewriteCond %{QUERY_STRING} ^(.*)&foo=(.*)$
RewriteRule ^(.*)$ $1?%1?&poo=%2 [NC]
But it only changed the last occurrence of foo to poo.
My httpd.conf file is structured as follows:
<Directory ~ "^/imb/rs/*">
Options Indexes FollowSymLinks
AllowOverride All
Order allow,deny
Allow from all
RewriteEngine on
RewriteCond %{QUERY_STRING} ^(.*)&foo=(.*)$
RewriteRule ^(.*)$ $1?%1&poo=%2 [NC]
</Directory>
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{QUERY_STRING} ^(.*)&foo=(.*)$
RewriteRule ^(.*)$ $1?%1&poo=%2 [NC]
</IfModule>
The /imb/rs/ part is written because the url starts with https://test.com/imb/rs/ and continues after that. I thought that would match my case.
Does anyone have an idea how I could solve this?
<Directory ~ "^/imb/rs/*">
Options Indexes FollowSymLinks
AllowOverride All
Order allow,deny
Allow from all
RewriteEngine on
RewriteCond %{QUERY_STRING} ^(.*)&foo=(.*)$
RewriteRule ^(.*)$ $1?%1&poo=%2 [NC]
</Directory>
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{QUERY_STRING} ^(.*)&foo=(.*)$
RewriteRule ^(.*)$ $1?%1&poo=%2 [NC]
</IfModule>
There are a few issues here. The <Directory> container is not going to match the request, so the mod_rewrite directives inside this container are not processed. Only the mod_rewrite directives outside the <Directory> container are processed, but this will only replace the last instance of &foo= in the query string (since the regex is greedy and the rewrite engine makes just a single pass in a vHost/server context).
<Directory ~ "^/imb/rs/*">
You are mixing regex and wildcard syntax. However, this should be an absolute filesystem path, not a URL-path, as this appears to be ("url starts with https://test.com/imb/rs/"). But you do not need to use the regex version of the <Directory> directive here anyway. I'm assuming /imb/rs is a physical directory and not simply a virtual URL-path?
AllowOverride All
You are explicitly enabling .htaccess overrides. If you do have a .htaccess file that contains mod_rewrite directives in this directory then this will completely override the <Directory> container in the server config. You should probably be disabling .htaccess overrides altogether.
Order allow,deny
Allow from all
These are Apache 2.2 directives and are formerly deprecated on Apache 2.4 (which I would assume you are using). You should be using the equivalent Require all granted instead. (But you do need to make sure you are using Apache 2.4 directives throughout - do not mix the two.)
Options Indexes FollowSymLinks
Aside: Are you intentionally allowing mod_autoindex to generate directory listings of your content? Generally, this should be disabled (ie. remove Indexes from this rule).
Try the following instead:
<Directory "/absolute/file/path/to/imb/rs">
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
RewriteEngine On
RewriteCond %{QUERY_STRING} (.*)&foo=(.*)
RewriteRule (.*) $1?%1&poo=%2 [L]
</Directory>
And remove the rule from outside the <Directory> container.
So, the rule you had in the beginning was basically OK. The start-of-string and end-of-string anchors are not required here, since the regex is greedy. The NC flag is not required. The L flag is not strictly required, but would be if you add any more rules later.
I found this solution which works only with 1 occurrence, not with multiple.
This one takes only the first occurrence:
RewriteCond %{QUERY_STRING} (.*?)foo(.*) [NC]
RewriteRule ^ %{REQUEST_URI}?%1poo%2 [NC]
This one takes only the last occurrence:
RewriteCond %{QUERY_STRING} (.*)foo(.*) [NC]
RewriteRule ^ %{REQUEST_URI}?%1poo%2 [NC]
But I couldn't find a way to replace all of them.

Rewrite from subdomain to file in .htaccess

this htaccess code work genially on old server, but on new is work perfectly without last RewriteRule. After put adress in web explorer for example sub.domain.com it load index.php. It may be by wrong setting of Apache? Or other?
Thanks a lot
RewriteEngine on
RewriteBase /
RewriteCond %{HTTP_HOST} ^domain\.com
RewriteRule ^hra/([0-9]+)/?$ /game2.php?id=$1 [L,QSA]
RewriteCond %{HTTP_HOST} ^sub\.domain\.com [NC]
RewriteRule ^$ /nacitanie.php [L]
in file 000-default.conf on new server in sites-enabled is part of enabling htaccess:
<Directory /home/juraj/WWW>
Options FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>
in apache.conf on new server is part about htaccess too:
<Directory /home/juraj/WWW>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
The error was in condition of last RewriteRule, where in regular condition on new server must be added option with index.php
RewriteCond %{HTTP_HOST} "^sub\.domain\.com"
RewriteRule "^(index\.php|\?)$" "/nacitanie.php" [L,QSA]

Apache rewrite 1 file globally to new file URL

I have a file with an identical name that exists in 15 subdirectories. Let's say it's called blah.txt.
I'm looking to do a global rewrite within httpd.conf to match any subdirectory's blah.txt and Rewrite it to a singular http://myserver/blah.txt.
If I add the following to an .htaccess, it works great. I hit the subdirectory's txt file, and I'm 301 forwarded. However doing this means I need to manage 15 .htaccess's. I'm trying to avoid that.
RewriteEngine On
RewriteRule ^(blah)\.txt http://myserver/blah.txt [L,R=301]
If I put this same text into httpd.conf under the <Directory /> section, I get a 404 on the subdirectory's blah.txt.
<Directory />
Options All Indexes FollowSymLinks
AllowOverride All
Allow from all
RewriteEngine On
RewriteRule ^(blah)\.txt http://myserver/blah.txt [L,R=301]
</Directory>
How can I have this global match within httpd.conf?
Edit: If I change the httpd.conf rewrite to the below, it seems like it wants to work, however I get stuck in an infinite loop because it's constantly matching the same file name.
RewriteEngine On
RewriteRule blah.txt http://myserver/blah.txt [L,R=301]
Still looking for a way to have it match in subdirectories and redirect to the same filename.
Edit 2: I think I got this working - but would love confirmation!
I added a RewriteCond to my rule. Basically, I think, this means that if the URI does not contain "firmware", then rewrite.
<Directory />
Options All Indexes FollowSymLinks
AllowOverride All
Allow from all
RewriteEngine On
RewriteCond %{REQUEST_URI} !(firmware) [NC]
RewriteRule blah.txt firmware/series/version/blah.txt [R=301,L]
</Directory>
It seems to be working without looping
As per my Edit 2: I think I got this working.
I added a RewriteCond to my rule. Basically, I think, this means that if the URI does not contain "firmware", then rewrite.
<Directory />
Options All Indexes FollowSymLinks
AllowOverride All
Allow from all
RewriteEngine On
RewriteCond %{REQUEST_URI} !(firmware) [NC]
RewriteRule blah.txt firmware/series/version/blah.txt [R=301,L]
</Directory>
After quite a bit of testing, it seems to be working without looping

How to add www in front of my wesite

I have a website say www.abcd.com. Its working fine if i access it using url http://abcd.com. But what i want is that if user go with url http://abcd.com, then web server should be able to convert it into url www.abcd.com.
%LOCATION_CONTAINS_HTACCESS_FILE% = Some Path
Some important changes in httpd.config are:
1. DocumentRoot "/var/www/html"
2. <Directory />
Options FollowSymLinks
AllowOverride All #changed to All
</Directory>
3. <Directory "%LOCATION_CONTAINS_HTACCESS_FILE%">
AllowOverride All
</Directory>
4. AccessFileName .htaccess #default
5. %LOCATION_CONTAINS_HTACCESS_FILE%/.htaccess # I added
6. <Files ~ "^\.ht">
Order allow,deny
Deny from all
</Files>
My .htaccess
RewriteCond %{HTTP_HOST} !^$
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTPS}s ^on(s)|
RewriteRule ^ http%1://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
With these changes I am getting error in line 5(from above, i think) when executing "service httpd restart":
Starting httpd: Syntax error on line 415 of /etc/httpd/conf/httpd.conf:
Invalid command '%LOCATION_CONTAINS_HTACCESS_FILE%/.htaccess', perhaps misspelled or defined by a module not included in the server configuration
I went through most of links on web, but couldn't get any specific solution to this.
I don't have much knowledge about Web services. But waiting for a simpler solution.
Hoping you guys have faced this issue & surely solved.
I always use the snippet below:
RewriteEngine On
RewriteBase /
# Redirect non-canonical domains
RewriteCond %{HTTP_HOST} !^www.yourdomain.com$ [NC]
RewriteRule ^(.*)$ http://www.yourdomain.com/$1 [L,R=301]
# Redirect non-www to www version
RewriteRule %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTP_HOST} ^([^.]+\.[a-z]{2,6})$ [NC]
RewriteRule ^(.*)$ http://www.%1/$1 [R=301,L]
It does two things:
The first snippet (below "Redirect non-canoncial domains") redirects visitors who come in from an alias (eg. my-domain-alias.com) to the main domain (yourdomain.com). It uses a 301 redirect (permanent) to let search engines know this is the right address (and not some duplicate content).
It checks if the www prefix is used. If not, it redirects, and also redirects using the 301 status code.
Note: the NC flag tells apache to check ignoring the case.
-- Edit:
I'd change the order directive to:
# Protect hidden files from being viewed
<Files .*>
Order Deny,Allow
Deny From All
</Files>
This will deny access to ALL hidden files (eg. your php .user.ini file, if present), not only .htaccess/.htpasswd files etc.

mod_rewrite: multiple domains on one server, mod_rewrite refuses to work on one

I have a server that serves several domains from a single IP address using Apache's Virtual Host shenanigans. Three of the sites are required to redirect to www if it's omitted from the URL.
I have the following rule in the .htaccess file of each domain:
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP_HOST} !^www\..+$ [NC]
RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
This works for two of the three, but the third completely fails to comply. I know that the .htaccess is being hit because the framework requires all hits to be routed through index.php... and that is happening correctly. So, it's not permissions, and the .htaccess is identical (more or less) on each domain. I even looked into caching (even though that doesn't make any sense... desperation gives way to insanity!)
Please help me if you have any clue what is going on.
As requested, here's the complete vhost config, and .htaccess file...
vhost configuration:
<VirtualHost *:80>
ServerAdmin me#gmail.com
DocumentRoot /var/www/example.com
ServerName www.example.com
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /var/www/example.com>
Options FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
.htaccess file:
# BEGIN example.com
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP_HOST} !^www\..+$ [NC]
RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteBase /
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [S=40]
####################################################
# If requested URL-path plus ".php" exists as a file
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
# Rewrite to append ".php" to extensionless URL-path
RewriteRule ^(([^/]+/)*[^.]+)$ /$1.php [L]
####################################################
# redirect to RoutingHandler
RewriteRule ^.*$ /index.php [NC,L]
</IfModule>
# END example.com
Bear in mind, there are two other domains set up in an identical manner... and they both work with zero issues.
I know this is an old question, but google brought me here while looking for answers on the same problem.
After searching through apache's documentation I found:
AllowOverride Directive
When this directive is set to None, then .htaccess files are completely ignored. In this case, the server will not even attempt to read .htaccess files in the filesystem.
So I changed "AllowOverride None" to "AllowOverride All" in the <Directory /var/www/example.com> section and it worked.