Blocking subdomain with htaccess. But only access from main domain - .htaccess

I have a domain (example.com) and I want to load a page from this subdomain (subdomain.example.com) within an iframe. But I want to block direct access to the subdomain with .htaccess. So I have edited the .htaccess in the subdomain with the code below.
There I have added access only to the localhost, but it doesn't work. It gives me page error. How can I solve this?
RewriteEngine On
#RewriteCond %{HTTP_HOST} ^(www\.)?subdomain.myurl.com$
#--allowed ip(s)--#
#RewriteCond %{REMOTE_ADDR} !^(127.0.0.1)$
#RewriteRule ^ - [F,L]

You can't reliably do this with .htaccess. The problem here is that when the browser requests the subdomain's URL in the IFRAME, this is also essentially a "direct request" - a direct request from the client. So, from the server's perspective, it's difficult to determine whether the request is from within the iframe or not.
The closest you can get is to check the HTTP Referer request header (as sent by the browser), which should be set to example.com when the document in the IFRAME is requested. However, this is unreliable, can be easily faked and will block indexing - if that is a concern. If a user types the URL directly in the browser's address bar then there is no HTTP Referer, but likewise,
the Googlebot also does not send a Referer header.
For example, in the root of the subdomain:
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^https?://(subdomain\.)example\.com
RewriteRule ^ - [F]
If the HTTP Referer is not start http://example.com or http://subdomain.example.com (HTTP or HTTPS) then block the request (403 Forbidden).
The L flag is not required when using the F flag - it is implied.
Alternatively, you could perhaps use JavaScript to detect whether the document is contained in a frame or not and if not, redirect to the framed document. However, this would only work if you have a single "master" document that contains the IFRAME.
There I have added access only to the localhost
The IP address from which the request originates has nothing to do with whether the subdomain is being requested from within an IFRAME on the main domain.

Related

Redirect all traffic if referrer is external

My old website is located in public_html. I have a new version of the site, which i installed in public_html/new/ .
I want to redirect all traffic from https://example.com to https:/example.com/new but i want to allow users to browse the old version (https://example.com) if they click a link from my new site.
Tried using:
RewriteCond %{HTTP_REFERER} !^https://example.com/.*
to match the referrer, but it doesn't seem to work.
Any help would be much appreciated.
RewriteEngine On RewriteCond %{HTTP_REFERER} !^https://example.com/.*
​RewriteRule ^$ https://example.com/new/? [R=301,L]
You've implemented this as a 301 (permanent) redirect (as it would need to be for SEO if you are migrating from an old to new site). However, the 301 redirect will be cached persistently by the browser. And redirect the user back to /new (from cache) without making a request to the server.
(This redirect also only redirects the old homepage. Inner pages are not redirected. Is that the intention?)
This would need to be a 302 (temporary) redirect - to avoid the redirect being cached, but that's not so good for SEO.
You could include a ?noredirect=1 parameter on URLs back to the old site (in the root) - a different URL - and only redirect when this param is not present. However, you would need to persist this URL param across all URLs having navigated from the new to old site. (And would allow anyone to access the old site by simply appending this URL param.)
However, #CBroe's suggestion in comments would be preferable. To move the old site to an /old subdirectory and the new site replaces the old site in the root. This would be better for SEO and users. Optionally, you could then simply block access to /old if the Referer is not the same domain (which would allow links from the new to old). And would prevent (most) bots from accessing /old (although you would still implement a X-Robots-Tag: noindex HTTP response header). Note, however, the Referer is unreliable and might not be set at all by some browsers (user's settings).

.htaccess rewrite rule to external domain - client IP and HTTP referer

let's say i'm running a web site at www.domain1.com
in ".htaccess" i do a redirect to an external "domain2" as follows:
RewriteEngine On
RewriteBase /
RewriteRule ^mydirectory/(.*)$ http://www.domain2.com/mydirectory/$1 [NC,L]
note that in the RewriteRule i'm not passing the flags [R] or [R=301].
and now i'm opening http://www.domain1.com/mydirectory/ from a web browser.
in the logs of that external "domain2", what exactly will show up as:
client IP
HTTP referrer (referer)
will the client IP be from the actual client web browser, or from my web server running at "domain1"?
will there be any hints that it got "redirected" from my "domain1"? in the "referer" field, for example?
and will the web client will be notified about any "redirection" status code?
will the client IP be from the actual client web browser, or from my web server running at "domain"?
The "actual client web browser". (Or, whatever IP would normally be reported when that client makes a request to domain2.com, as they could be connecting through a proxy server, VPN, etc.)
A redirect response from domain1.com is an instruction for the client to make an entirely new request to domain2.com.
will there be any hints that it got "redirected" from my "domain1"? in the "referer" field, for example?
Not if you make the redirect as soon as the user first arrives at domain1.com. Generally, the browser preserves the Referer header from the previous "non-redirected" request. The redirect itself does not generate a Referer.
So, if you make a direct request to domain1.com (ie. no Referer) then no Referer will be passed in the redirected request to domain2.com.
However, if a user followed a link from another-domain.com to domain1.com (ie. another-domain.com is the Referer) and you issue a "redirect" from domain1.com to domain2.com then the browser would pass another-domain.com as the Referer (by default).
And if you allowed the user to browse domain1.com for a while (navigating from page to page - which will naturally generate a Referer) before issuing a redirect to domain2.com then domain1.com will likely be seen as the Referer when the client makes the request to domain2.com. At least, by default, this can be overridden by setting a Referrer-Policy (in modern browsers) on the referring site.
Of course, the user may have configured their browser to suppress the Referer and the originating website (eg. another-domain.com, or domain1.com) can also suppress the Referer being sent by setting a Referrer-Policy in modern browsers. Old browsers (such as IE11) do not support this, so you are at the mercy of whatever defaults the browser uses.
and will the web client will be notified about any "redirection" status code?
Yes, that's what a redirect is.
If domain1.com redirects to domain2.com then...
domain1.com sends a 3xx redirect response back to the client with a Location HTTP response header telling the client of the URL to make a request to.
The client's browser then makes a new request to the URL stated in the Location header.
RewriteEngine On
RewriteBase /
RewriteRule ^mydirectory/(.*)$ http://www.domain2.com/mydirectory/$1 [NC,L]
Note that this generates a 302 (temporary) redirect, even though the status code (R or R=301) is not explicitly stated. (The RewriteBase directive is entirely superfluous here.)

How to block access to a website if its directly accessed with it's IP address using a .htaccess file?

I would like to know how to prevent visitors of my website to access it using the website's IP address. I want to do this through a .htaccess file. I just want it to say "Forbidden" when they try it. But if they visit the website using it's domain name they have access.
There may be a better way, but this will work:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^$
RewriteRule ^ - [F,L]
If there is nothing in the host header, it returns forbidden. There would be an empty host header for access by IP.
A better way is to put a default <VirtualHost> in the config for that IP, so requests by IP never get served by the site. I guess this may not be an option for you since you requested a .htaccess solution. The above method blocks HTTP 1.0 clients but that's really not much of a concern these days.

Render symbolic link without redirecting

I want /rss-2/ to be reached at /rss/news.php (this file does not exist) /rss-2/ currently shows the feed (generated by a wp plugin), I want to show it on the other page as well.
I tried
RewriteCond %{REQUEST_URI} /rss/news.php
RewriteRule ^(.*)$ /rss-2/ [R]
but I couldn't find an appropriate flag that renders the destination instead of redirecting to it.
Wordpress looks at the url in the address bar, not how you rewrite the url. You can use the [P] flag to proxy the request, but I heard this is quite expensive since you are doing an additional request to your own server with that url. The second request will see rss-2 and will handle it accordingly, which will pass it on to request 1 which will show it to the user. Additionally, the proxy connection has to be set up for each request.
See this page for more information.

Blocking direct access to an URL (not a file)

A drupal site is pushing International traffic over quota on my (Plesk 10.4) server, and it looks as though much of that of that (~250,000 visits/month) is direct access to the URL /user/register. We are already using the botcha module to filter out spambot registrations, but that approach is resulting in two full pages being served to each bot. And while Drupal
I'm thinking that a .htaccess rule which returns a 403 response to that URL unless the referer is from the site might be the way to go, but my .htaccess-fu is not strong, and I can only find examples for blocking hot-linking of images.
What do I need to add and where?
Thanks,
Richard
You'd be checking against the HTTP referer. It's not a guarantee way to block incoming traffic linked from a site other than yours, since the field can be easily forged. But you can try adding this to the htaccess file (above any rules that are already there):
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^https?://(www\.)?your-domain\com/ [NC]
RewriteRule ^user/register - [L,F]

Resources