I keep refining the way I lock down external access to the Drupal 7 admin site and user login page. Lots of attempts come in using “?q=user” which I’d had some success blocking but just added a new check that seems to be doing good work.
I already had a check in place in a file.. a whole list of IP checks to set an environment variable if the user is internal:
SetEnvIf Remote_Addr "^123\.123\.123\.123" Test_Internal=Internal
Then there’s two checks
First a Location match for a bunch of stuff no one should be accessing off network:
<LocationMatch "^/(admin|user|(node/\d+/edit|add|delete|translations|revisions)|update.php|cron.php)">
Order deny,allow
Deny from all
Allow from env=Test_Internal
Allow from 127.0.0.1
Allow from ::1
</LocationMatch>
And then a rewrite for those queries:
RewriteCond "%{ENV:Test_Internal}" "!=Internal"
RewriteCond %{QUERY_STRING} ^q=(node/add|user|user/register)$
RewriteRule ^ - [F,L]
Previously I’d added a patch to core that checked for that but it meant bootstrapping drupal just to throw a 403.
Lastly there’s a handfull of quick checks to 404 users hitting the common WordPress strings:
RedirectMatch 404 ^/wp-admin.*$
RedirectMatch 404 ^/(.*)/wp-login.*$
All these work in my RHEL 8, Apache 2.4 environment.