Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to redirect to 404 when url is pointing to an existing folder (no trailing slash). HAproxy or mod-rewrite related

I am using HAProxy listening on 80 to send requests to a node server (port:3000) or php server (4000); I also have CSF installed which have ports 3000 and 80 available.

It works okay when I browse a page at http://example.com/forum/1/page.php, but sometimes when I accidentally enter example.com/forum/1 (no trailing slash), it keeps loading and eventually leads to an error page ERR_CONNECTION_TIMED_OUT. The address bar shows that it has redirected to http://example.com:4000/forum/1/.

Since I don't have the 4000 port open, when I keep going to example.com/forum/1 a multiple times, it would trigger a block by CSF. My question is, can I redirect all the requests that are pointing to an actual folder example.com/forum/1 (no trailing slash) to an 404 page? I have tried adding a rewrite rule to append a trailing slash to every request, but that would break all of my relative paths (see my issue at this post).

So what I want to know is, why was I redirected to http://example.com:4000/forum/1/ from http://example.com/forum/1? Was it caused by HAproxy?

Some HAproxy config:

frontend all 0.0.0.0:80
    timeout client 1h
    # use apache2 as default webserver for incoming traffic
    default_backend apache2

backend apache2
    balance roundrobin

    option forwardfor
    server apache2 myIpAddress:4000 weight 1 maxconn 1024 check 

    # server must be contacted within 5 seconds
    timeout connect 5s
    # all headers must arrive within 3 seconds
    timeout http-request 3s
    # server must respond within 25 seconds. should equal client timeout
    timeout server 25s

Here's my rewrite rules:

RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -l
RewriteRule ^ - [L]

RewriteCond %{REQUEST_URI} !^.*\.(jpg|css|js|gif|png)$ [NC]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule !.*\.php$ %{REQUEST_FILENAME}.php [QSA,L]

RewriteCond %{THE_REQUEST} /index\.php [NC]
RewriteRule ^([^\.]+)$ $1.php [NC,L]
like image 657
RedGiant Avatar asked Jun 02 '15 11:06

RedGiant


2 Answers

Since /forum/1 is a valid physical directory you get redirected to /forum/1/ due to this setting:

DirectorySlash On

which is used by a module called mod_dir that adds a trailing slash after directories if it is missing.

You can of course turn this flag off by using:

DirectorySlash Off

but be aware of security implications.

To be more secure you also need:

Options -Indexes

to turn off directory listing.

Security Warning (copied from linked manual)

Turning off the trailing slash redirect may result in an information disclosure. Consider a situation where mod_autoindex is active (Options +Indexes) and DirectoryIndex is set to a valid resource (say, index.html) and there's no other special handler defined for that URL. In this case a request with a trailing slash would show the index.html file. But a request without trailing slash would list the directory contents.


Update: To answer this part of the question:

My question is, can I redirect all the requests that are pointing to an actual folder example.com/forum/1 (no trailing slash) to an 404 page?

You can use this code in /forum/1/.htaccess:

DirectorySlash On
RewriteEngine On

RewriteRule ^$ - [L,R=404]

This will force a trailing slash so that rewrite rule can used to send 404 error.

like image 144
anubhava Avatar answered Sep 27 '22 16:09

anubhava


In your .htaccess file add the following code. Replace /404.php with any file you want.

ErrorDocument 404 /404.php
like image 40
kayleighsdaddy Avatar answered Sep 27 '22 18:09

kayleighsdaddy