How to test in htaccess if there is proxy? - .htaccess

I've a htaccess that filters and redirects to a API a Moodle referer. "moodle.mysite.com"; works well with:
**RewriteRule ^. * $ /****/******.php [NC, L]**
With "http (s): //mysite.com/moodle" , I get this:
*The proxy server received an invalid response from an upstream server.
The proxy server could not handle the request GET/proxy8080/****/******.php.
Reason: DNS lookup failure for: nodomainamen: 8080http:*
But it works with
'**RewriteRule ^. * $ /****/******.php?requete=%{REQUEST_URI}? [P]**'
That's why I would like to test the presence of a proxy with a code like this:
"**RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]**"
# if no proxy
"**RewriteRule ^.*$ /index.php [NC,L]**"
#elseif there is proxy
"**RewriteRule ^.*$ /index.php?request=%{REQUEST_URI}? [P,QSA,NC]**"
I want to verify if the referer needs the proxy server and if it is, use [P] with trasferring %{REQUEST_URI} or not.
Thanks for help

Related

Crontab being blocked by htaccess even Whitelisted

I'm trying to block all access except my own and my server to my two scripts, but when I try to make a crontab to run my scripts, I get the error 403 forbidden even with my server IP being whitelisted in my htaccess.
This is my .htaccess
Options +FollowSymlinks
RewriteEngine on
#the urls that should be checked
RewriteCond %{REQUEST_URI} ^(/script.php|/script2.php).*$
RewriteCond %{REMOTE_ADDR} !=194.1....(My server Ip)
RewriteCond %{REMOTE_ADDR} !=0.0.0.0
RewriteCond %{REMOTE_ADDR} !=127.0.0.1
RewriteCond %{REMOTE_ADDR} !=172......(My Ip)
RewriteRule ^.*$ / [F]
this is my crontab (i'm using hostinger panel)
wget -O /dev/null mydomain.com/script.php/
This is the error
--2022-07-15 09:30:02-- mydomain.com/script.php
Resolving mydomain.com (mydomain.com)... 2a02:4780:b....., 194.1....(my server ip)
Connecting to mydomain.com(mydomain.com)|2a02:4780:b:....|:80... connected.
HTTP request sent, awaiting response... 403 Forbidden
2022-07-15 09:30:02 ERROR 403: Forbidden.
and if i run manually from my ip , it works fine.
So is there a way i can make my script run as a crontab and not accessible by url by others. only by me and by my server
I think i Got it , I just added this line before the RewriteCond %{REMOTE_ADDR} and is working now , no one can access via url , and the server can access normaly
RewriteCond %{HTTP_USER_AGENT} !^Wget [NC]

Rewrite url to pretty after redirect to folder - htaccess laravel

Hello I have a "protected" folder on my server. In its .htaccess file for conditional redirect of some users I use the following rules:
RewriteCond %{REMOTE_ADDR} ^1\.2\.3\.4*
RewriteCond %{REQUEST_URI} !^/special
RewriteRule ^$ /special [R,NE,NC]
In the /special folder I have a .htaccess file with the following rules:
RewriteCond %{REMOTE_ADDR} !^1\.2\.3\.4$
RewriteRule ^(.*)$ / [R=301,NE,NC,L]
The application in the folder will be laravel based so my content will have to be served from index.php file residing in /special/laravel/public/index.php
I want the URL to look like /special/.
What rules should I put and where for this to happen?
This is a follow up to my previous question:
https://stackoverflow.com/questions/24487012/redirecting-specific-ip-to-special-content-htaccess-vs-php
Simply rewrite the URL with .htaccess: (goes in /)
DirectoryIndex index.php
#Redirect to /special/laravel/public if you haven't already and the IP is okay
RewriteCond %{REMOTE_ADDR} ^1\.2\.3\.4*
RewriteCond %{REQUEST_URI} !^/special/laravel/public
RewriteRule ^(/special)(/laravel)?(.+) /special/laravel/public$2 [L]
#if IP does not match and you ARE in the folder, then Redirect to root
RewriteCond %{REMOTE_ADDR} !^1\.2\.3\.4*
RewriteCond %{REQUEST_URI} ^/special/laravel/public
RewriteRule .? / [R=301,L]
I think that'll work. I didn't test it though. I can add to it if you need me to. And of course for your use case you may need to add some more RewriteConds in there for validating the REMOTE_ADDR.
The way I handle it:
.htaccess:
RewriteCond %{REQUEST_URI} !^/load_page.php$
RewriteRule ^(.+)$ /load_page.php [QSA, L]
That causes the server to redirect internally to load_page.php if the requested URL is not load_page. Without the RewriteCond, I believe it would cause an infinite redirect. This should work, but I didn't test it because it's different from my implementation, since mine also handles rewriting URLS to have trailing slashes and never show .php which makes it a bit more complex and quite different.
load_page.php:
$SITE_ROOT = $_SERVER['DOCUMENT_ROOT'];
$URL = $_SERVER['REQUEST_URI'];
ob_start();
if (conditionOne){
//change $URL here if you need to or do nothing
} else if (conditionTwo){ //check the IP or whatever you want to here
if (aCondition){//if $URL starts with '/special'
$URL = str_ireplace('/special/','/special/laravel/public/',$URL,1);
}
if (is_dir($SITE_ROOT.$URL))$URL .='index.php';
}
if (!file_exists($SITE_ROOT.$URL))$URL = '/error/404.php';
include($SITE_ROOT.$URL);
$content = ob_get_clean();
echo $content;
It's something to that affect. The user doesn't see load_page.php and they don't see that you changed the URL to special/laravel/public, but you include the correct file.

Why isn't RewriteCond %{HTTPS} returning the correct value?

I am working on a Drupal site for which the client has requested that we remove the 'www.' from the URL. This is super easy and I've done it before; I simply comment out the suggested lines in the Drupal-generated .htaccess file like so:
# To redirect all users to access the site WITHOUT the 'www.' prefix,
# (http://www.example.com/... will be redirected to http://example.com/...)
# uncomment the following:
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ http%{ENV:protossl}://%1%{REQUEST_URI} [L,R=301]
Those of you familiar with Drupal's .htaccess will know that the environment variable protossl is set towards the top of the file like so:
# Set "protossl" to "s" if we were accessed via https://. This is used later
# if you enable "www." stripping or enforcement, in order to ensure that
# you don't bounce between http and https.
RewriteRule ^ - [E=protossl]
RewriteCond %{HTTPS} on
RewriteRule ^ - [E=protossl:s]
This is working perfectly on my local environment, but when I deployed the change to the production site it breaks. www.mysite.com redirects to mysite.com as expected, but https://www.mysite.com also redirects to mysite.com instead of https://mysite.com. It seems that the %{HTTPS} variable is returning 'off' even when it should be 'on'.
I can go directly to https://mysite.com and it works perfectly. The site's Apache access logs show 'https://' where I expect it to be, as do all of my HTTP requests. The site is running on a RackSpace server using a load balancer (only one node in the balancer). The SSL certificate is on the RackSpace load balancer. I have tried the following steps and none have had any results:
Replace RewriteCond with RewriteCond %{ENV:HTTPS} on [NC]
Replace RewriteCond with RewriteCond %{SERVER_PORT} ^443$
Multiple variations and combinations of the above RewriteCond's
Added $conf['https'] = TRUE; to settings.php
This is driving my coworkers and I crazy. Can anyone help?
anubhava has saved the day! The solution was to use the %{HTTP:X-Forwarded-Proto} variable just as he suggested. I updated the protocol detection bit of my .htaccess to look like this:
# Set "protossl" to "s" if we were accessed via https://. This is used later
# if you enable "www." stripping or enforcement, in order to ensure that
# you don't bounce between http and https.
RewriteRule ^ - [E=protossl]
# The default proto detection provided by Drupal does not work on our
# production server because it sits behind a load-balancing server.
# This additional RewriteCond makes sure we can detect the forwarded proto
RewriteCond %{HTTP:X-Forwarded-Proto} https [OR]
RewriteCond %{HTTPS} on
RewriteRule ^ - [E=protossl:s]
I'm gonna call this a crunchwrap supreme, 'cause it is good to go!

AWS Elasticbeanstalk single instance Force SSL Redirect loop

I'm having issues by forcing ssl. I'm using codeigniter and deployed it in AWS single instance with elasticbeanstalk. My htaccess rules below:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule !/status https://%{SERVER_NAME}%{REQUEST_URI} [L,R]
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]
But browser gets in a redirect loop. Whatever i tried didnt solve this problem.
As I mentioned in my comment:
in the ssl.conf every call from port 443 is "proxyed" to port 80, so you never get https = on.
I did some tests and I found out that the ProxyPass directive in ssl.conf does not simply redirect every request from port 443 to localhost:80, but basically repeats the request to Apache from scratch, through the port 80 (at least, that's what I understood).
I checked the value of $_SERVER and found out that HTTP_X_FORWARDED_FOR, HTTP_X_FORWARDED_HOST and HTTP_X_FORWARDED_SERVER are set during a HTTPS request (but they are NOT set during a HTTP request), meanwhile SERVER_ADDR and REMOTE_ADDR are set to 127.0.0.1 during a HTTPS request (but they are set to different values for HTTP requests).
I assume you can easily check if your request was plain HTTP with something like this (check the syntax, I'm rubbish with Apache):
RewriteCond %{ENV:HTTP_X_FORWARDED_SERVER} !^$
or
RewriteCond %{ENV:SERVER_ADDR} !^127\.0\.0\.1
BEWARE: I couldn't find any reference in AWS documentation, it's just an empiric result... they can easily change this behavior!
Happy coding! :)
I run into the same problem. Here is what worked for me:
RewriteCond %{SERVER_PORT} !=443
RewriteCond %{SERVER_ADDR} !^127\.0\.0\.1
RewriteRule (.*) https://%{SERVER_NAME}/$1 [L]
Here is the official way. Found in AWS docs.
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteCond %{HTTP_USER_AGENT} !ELB-HealthChecker
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
Sources
https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/configuring-https-httpredirect.html
https://github.com/awsdocs/elastic-beanstalk-samples/blob/master/configuration-files/aws-provided/security-configuration/https-redirect/php/https-redirect-php.config
I believe (give your exception for /status) that you are using the "Load-balancing, Autoscaling Environment" which means you have an Elastic Load Balancer in the middle.
If you setup your environment with Elastic Load Balancing, than what may be happening is if the Elastic Load Balancer (ELB) is using (serving) secure content (HTTPS).
However, if the traffic between the ELB and the EC2 Instances is unsecure, your code will always detect an unsecure connection because the EC2 client is actually the ELB, not the end user (think of the ELB as a proxy).
Side note, I'm not sure how the SERVER_NAME variable will work with an ELB in the middle.
That said, if your intention was for a single-instance, non-load balanced environment, you can "turn off" the load balancer (possible since July 2013). (see ref #3)
Reference: http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/using-features.managing.elb.html
http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/using-features-managing-env-types.html
Elastic Beanstalk without Elastic Load Balancer
This is the right way:
RewriteEngine on
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

.htaccess rewrite with url masking

I need to do a url rewrite maintaining following condition:
rewrite http://domain.net (or http://www.domain.net) to http:// ip:port/folder
redirect any other request like http://domain.net/logout?query=1 to http:// ip:port/folder/logout?query=1 (preserve query string and all)
mask the rewrite so that novice users cannot detect the ip (the address where they are redirected to) from the browser url bar
as for masking, a visible redirection like http:// domain.net:port/folder is also acceptable.
What I tried so far: The following results in 500 error.
RewriteCond %{HTTP_HOST} ^(*.)?domain\.net$
RewriteRule ^(/)?$ http:// ip:port/folder/$1 [L,R,QSA]
The following works without the masking:
RewriteCond %{HTTP_HOST} !^www\.domain\.net [NC]
RewriteCond %{HTTP_HOST} !^$
RewriteRule ^/(.*) http:// ip:port/folder/$1 [L,R,QSA]
You can do this only if ip:port and domain.net refers to the same server. Otherwise you have to use some script that pulls the remote content from ip:port for a request to domain.net, if you want to hide ip:port.
Otherwise you can proxy the request to another server using the [P] flag.
See: http://httpd.apache.org/docs/current/rewrite/flags.html#flag_p

Resources