2

I have had a lot of attacks on my server. Most start with a vulnerability scan, followed by waves of POST requests.

I will soon be implementing Cloudflare (WAF and DDos). This means that a DNS lookup on my domain will show the IP address of Cloudflare, rather than my server. So my server's IP address will be hidden in that regard.

However, attacks can still come in by going one-by-one through all the possible IPs in the world. When I look at my server logs, I can see this happens A LOT. (I have 3 IPs tied to my 1 server and the exact same attacks happen on XXX.XXX.XXX.XX1 then XXX.XXX.XXX.XX2 then XXX.XXX.XXX.XX3)

My top-level .htaccess looks like this:

# deny all POST requests
<IfModule mod_rewrite.c>
    RewriteCond %{REQUEST_METHOD} POST
    RewriteRule .* - [F,L]
</IfModule>


# deny unused request types
<IfModule mod_rewrite.c>
    RewriteCond %{REQUEST_METHOD} ^(delete|head|trace|track) [NC]
    RewriteRule .* - [F,L]
</IfModule>


# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress

Questions:

  1. What should I add so that [if HTTP_HOST=XXX.XXX.XXX.XX1 OR HTTP_HOST=XXX.XXX.XXX.XX2 OR HTTP_HOST=XXX.XXX.XXX.XX3] then the traffic is immediately blocked?

  2. Can I put this new code at the top of the .htaccess? Will it break what's currently there?

Ryan B
  • 21
  • 1
  • 2

1 Answers1

1

You don't need to check the Host header for specific IPs, just check for any Host that starts with a digit. For example, at the top of your .htaccess file:

RewriteCond %{HTTP_HOST} ^\d
RewriteRule .* - [F]

You don't need the L flag with F - it is implied.

You also don't need the additional <IfModule mod_rewrite.c> wrappers. Just leave the WordPress one as it is. (Although that isn't strictly required either.)

However, these type of blocks should ideally be performed at the server/vitualhost level, not in .htaccess. Configure a default <VirtualHost> that traps these undesirable IP requests.

For example, assuming you are only using name-based VirtualHosts then you can configure a default VirtualHost (that must occur before all other VirtualHosts) of the form:

# Catch all other requests for non-specific hosts. eg IP address access
<VirtualHost _default_>
  ServerName default.example.com
  <Location />
  Require all denied
  </Location>
</VirtualHost>

This catches all requests that do not map to any other "named" Virtual Host. _default_ is simply an alias for *. As noted above, this <VirtualHost> container must occur before all other <VirtualHost> containers in your server config. The fact that it is defined first is what makes it the "default".

The ServerName directive should be defined as anything other than a real server name on your system. It can be omitted, but the server will only attempt to calculate it, which could prove unreliable.

This prevents your actual Virtual Hosts (that serve your website) from having to deal with these other requests.


# deny all POST requests

That seems a little extreme! I'm surprised your site still works?

MrWhite
  • 12,647
  • 4
  • 29
  • 41
  • "However, these type of blocks should ideally be performed at the server/vitualhost level, not in .htaccess" ----> why is that? "Configure a default that traps these undesirable IP requests." ----> how would I write that? I know where to put it in Plesk, just not how to write it. – Ryan B May 31 '18 at 20:49
  • Using the server config is more efficient and harder to circumvent (either accidentally by a script error, or maliciously via a site hack). By asking this question on ServerFault it is assumed that you have full access to the server config - in which case it is often considered preferable to use the server config for everything and disable `.htaccess` altogether. I have updated my answer with an example of a default `` to block these requests. – MrWhite Jun 01 '18 at 22:26