Let some routes access on IP blocked Apache server - .htaccess

I have an apache 2.4 server, hosting a Symfony website. Server is accessible only from some IPs via .htaccess:
<RequireAny>
Require all denied
Require ip x.xx.xxx.xx
</RequireAny>
That is working fine. Problem is that now I want to let requests access from any IP to some routes only. For example /login. I "know" that in Symfony, internally, the route is like app.php/login but I tried these unsuccessfully:
Require expr %{REQUEST_URI} = "/app_dev\.php/login"
Require expr %{REQUEST_URI} = "/app\.php/login"
Require expr %{REQUEST_URI} = "/login"
Require expr %{REQUEST_URI} = "login"
if I create a login.php file, this works fine, but of course I can't do that for all routes:
Require expr %{REQUEST_URI} = "/login\.php"
The error is always the same:
"GET /login HTTP/1.1" 403

Related

SyntaxError: Unexpected token < in JSON at position 0 with run NodeJs (express)

I deployed my NodeJS (express server) code as backend on remote server, and I add Rewrite Rule to .htaccess.
This is rule
RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
RewriteRule ^ /index.html
But when I try to make API call to my express server I get status 200 and error SyntaxError: Unexpected token < in JSON at position 0.
If I delete this rule from .htaccess, everything works properly.
With this .htaccess file, you are telling your web server (Apache) to return index.html whenever you request a page it cannot find. So you get a 200 response with a HTML document, which is not a JSON document.
This .htaccess file is used to configure the web server that hosts your Angular application.
Your NodeJS Express web service does not require a web server as it provides it's own web server. You can however use the Apache web server as a reverse proxy for your web service, but this requires a different configuration.

Simple apache mod_rewrite just not working

What I wanted is really simple, but it's just not working.
First the application is running on Node.js, i.e., localhost:8080
And I use Apache mod_rewrite to route the requests to Node.js, like this
<VirtualHost *:443>
RequestHeader set X-Forwarded-Proto "https"
ProxyPreserveHost On
ServerName shopecific.com
RewriteEngine On
RewriteRule /(.*) http://localhost:8080/$1 [P,L]
...
</VirtaulHost>
Which works perfectly. Then I want to redirect one request to a static page, which is from https://shopecific.com/amzvar to https://shopecific.com/amzvar.html
But I tried the following rewrite rules, but none of those works:
# RewriteRule ^/amzvar$, /amzvar.html [R,L]
# RewriteRule ^/amzvar$, https://shopecific.com/amzvar.html [R,L]
# RedirectMatch 301 ^/amzvar$ https://shopecific.com/amzvar.html
Somehow those rules are just got ignored, and I always got the not found page. Note that "amzvar" is not a defined route on the Node.js. I understand that by the following rule in routers.js, it could be redirected to "not found".
<Route path="*" component={NotFound} status={404} />
However, the Apache Rule should be matched first, right?
What am I missing here?
Looks like this is related to Service Worker. Somehow React-Router V3 and Service Worker does not work together to handle undefined router (i.e., it will redirect to default route () regardless other rules even in the Apache config.

Mod_rewrite for single.php

I'd like to use mod_rewrite to show pretty urls in my urls:
Instead of
.../juegos/plants-vs-zombies/?play=jugar
change to
.../juegos/plants-vs-zombies/jugar/
And
.../juegos/ddtank/?play=full
change to
.../juegos/ddtank/full/
I use the file "single.php" with this code:
$url = (isset($_SERVER['HTTPS']) ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
$parts = parse_url($url);
parse_str($parts['query'], $query);
$parametro = $query['play'];
if ($parametro == 'jugar')
{
include( get_template_directory() . '/single-play.php');
}
else if ($parametro == 'full')
{
include( get_template_directory() . '/single-full.php');
}
And in .htaccess I have this:
RewriteEngine On
RewriteCond %{QUERY_STRING} (^|&)play=jugar($|&)
RewriteRule ^(.*)/$ /jugar/?&%{QUERY_STRING}
But when I try to get the url with /jugar/ and /full/ at the end of the url, it displays an 404 error.
I don't know what else to do. I hope you can help me.
Sounds pretty straight forward to me:
RewriteEngine on
RewriteRule ^/?juegos/plants-vs-zombies/jugar/?$ /juegos/plants-vs-zombies/?play=1 [END]
For that to work the rewriting module has to be installed and enabled, obviously. The rule will work likewise in the http servers host configuration and in a dynamic configuration file (.htaccess). If you decide to use a dynamic configuration file, then you need to place that in the http hosts document root folder and enable its interpretation using the AllowOverride directive in the host configuration.
If you receive a http status 500 using the above rule ("server internal error") chances are that you operate a very old version of the apache http server. In that case try replacing the [END] flag with the [L] flag.
And a general hint: you should always prefer to place such rules inside the http servers (virtual) host configuration instead of using dynamic configuration files (.htaccess style files). Those files are notoriously error prone, hard to debug and they really slow down the server. They are only supported as a last option for situations where you do not have control over the host configuration (read: really cheap hosting service providers) or if you have an application that relies on writing its own rewrite rules (which is an obvious security nightmare).
what the browser sees /juegos/plants-vs-zombies/jugar/,
what the server sees ?play=juegos/plants-vs-zombies/jugar
after explode it changes to an Array ( [0] => juegos [1] => plants-vs-zombies/ [1] => jugar)
Options +FollowSymlinks
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ ?play=$1 [NC]
This to change$_GET['play'] to an array
$play = explode("/", $_GET['play']);
if(isset($_GET['play'])){
$play = explode("/", $_GET['play']);
//if you want to add `/` at the end
if(end($play) == ""){
array_pop($page);
}
}
Passing Query String Parameters in WordPress URL

Masking sub domain with a new domain while preserving the paths

I own a domain since long, just masking the names:
http://mydomain.com
Later I started using a subdomain on this domain for some project.
http://subdomain.mydomain.com
Those projects grew and now I have a structure like
http://subdomain.mydomain.com/project1
http://subdomain.mydomain.com/project2
http://subdomain.mydomain.com/project3/subproject1
http://subdomain.mydomain.com/project3/subproject2
http://subdomain.mydomain.com/project3/subproject3
http://subdomain.mydomain.com/project4
....
etc.
now I bought a new domain (shortdomain.com) where I plan not to move anything but everything should be accessible via redirects so everything looks like:
http://shortdomain.com
http://shortdomain.com/project1
http://shortdomain.com/project2
http://shortdomain.com/project3/subproject1
http://shortdomain.com/project3/subproject2
http://shortdomain.com/project3/subproject3
http://shortdomain.com/project4
...
etc.
So basically I need to do two things:
1. if anyone visits my old domain, redirect them the new naming structure. i.e. if someone loads http://subdomain.mydomain.com/project2 they should be redirected to http://shortdomain.com/project2
when a user loads/redirected to http://shortdomain.com/project2 this should actually load the content present at http://subdomain.mydomain.com/project2
So I will not manually migrate projects,codes and GBs of other data. I think this might be acievable by smart redirection only.
Just FYI:
1. I have full DNS control of both the domains
2. I am hosted on hostgator
3. I use cloudflare on the first domain and would like to continue using it
I think this might be acievable by smart redirection only.
No, redirection changes what's in the browser's location bar. If you redirect to shortdomain.com then the request will get sent to shortdomain.com, and have nothing to do with subdomain.mydomain.com anymore. If you redirect back to subdomain.mydomain.com, then the location bar in the browser will change as well.
What you really want to do is point shortdomain.com to the same server and document root that subdomain.mydomain.com is on. Then use this to redirect (either in htaccess file or server config):
RewriteEngine On
RewriteCond %{HTTP_HOST} ^subdomain\.mydomain\.com$ [NC]
RewriteRule ^(.*)$ http://shortdomain.com/$1 [L,R=301]
If, for whatever absurd reason you can't point the shortdomain.com DNS to the same webserver that serves subdomain.mydomain.com, or can't setup that webserver to accept requests for the shortdomain.com host, you need to setup a proxy server. And it'll work something like this:
2 Webservers, server A (hosts subdomain.domain.com) and server B (hosts shortdomain.com)
Someone requests http://subdomain.mydomain.com/project3/subproject1
server A gets the request and redirects the browser to http://shortdomain.com/project3/subproject1
browser's location bar changes to new location
server B gets the request and reverse proxies the request back to server A
server A gets the request again but must recognize that it is a proxy and then serve the page instead of redirecting
As you can see, this is a horrendously ineffecient solution. It's also a high possibility that your hosting service won't allow you to setup proxy servers.
I have full DNS control of both the domains
With full control I assume you can enable mod_proxy as well on Apache web-server of shortdomain.com. Once that is done set it all up this way.
On subdomain.mydomain.com enable mod_rewrite and place this rule in Apache config OR DOCUMENT_ROOT/.htaccess:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^subdomain\.mydomain\.com$ [NC]
RewriteRule ^ http://shortdomain.com%{REQUEST_URI} [L,R=301]
On shortdomain.com enable mod_proxy, mod_rewrite and place this rule in Apache config OR DOCUMENT_ROOT/.htaccess:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^shortdomain\.com$ [NC]
RewriteRule ^ http://subdomain.mydomain.com%{REQUEST_URI} [L,P]

Detect if server is redirecting via a .htaccess file

I've created a .htaccess file to redirect a specific IP address to another file:
# Allow rewriting of htaccess
RewriteEngine On
RewriteBase /
# Get remote address/block of addresses to redirect
RewriteCond %{REMOTE_ADDR} 127\.0\.0\.1
# Define the file being accessed
RewriteCond %{REQUEST_URI} /index\.php$
# When the remote address(es) try to access the file above redirect them to the file below
RewriteRule .* /other-index\.php [R,L]
This works well and the above redirects localhost to other-index.php if it tries to access index.php but allows all other remote hosts to access index.php.
The remote host is calling: http://www.example.com/index.php
My question is can the remote host (in this case localhost) find out that it is being redirected by the server?
My question is can the remote host (in this case localhost) find out that it is being redirected by the server?
Yes because the client (at 127.0.0.1) makes a request for /index.php to the server. The server responds with a 302 redirecting the client to a different location /other-index.php.
Normally this all happens seemlessly, like if you are using a browser. The browser gets the new location (/other-index.php) and simply makes a new request to the server for the new location and gets it. It happens instantly. But the remote host (the client) knows it's being redirected because the first request it made (for /index.php) resulted in a 302 with a new location (/other-index.php).
If the R flag in the square brackets of your RewriteRule was omitted, there wouldn't be a redirect and the URI would be internally re-written by the server, and the client (the remote host) would be oblivious to the fact that was served the content at other-index.php when it requested other.php.

Resources