We've tried a few things that we found around Google for this, but can't seem to get anything to work.
The Problem
We have a server with around 500 Wordpress websites on it. We're trying to lock down all the wp-login.php pages for every instance to the IP address of our office using a global htaccess - but the individual Wordpress htaccess files are overriding this.
The Environment
We're hosted on an AWS Linux server running Plesk to manage each website / Wordpress instance.
The Question
Is there a way we can set one htaccess file on the server to lock down all of the Wordpress login pages without the individual htaccess files overriding this?
any help or suggestions for a good way to do this, would be appreciated.
Thanks in advance
I assume that you have read up on the RewriteOptions directive. As I explain in Tips for debugging .htaccess rewrite rules and as you have found with WP which generates its own .htaccess files, by default the current path is scanned for .htaccess and the rewrite rules in the lowest are applied unless a higher one specifies a RewriteOptions Inherit in which case it's rules are executed after rules specified in the child scope, and this is the catch-22 in that WP access file generates a [L] flag on all its execution paths preventing the parent rules from firing.
So the answer is to do this with an Apache mechanism other than rewrite and you can use the SetEnvIf directive:
SetEnvIf Remote_Addr "!^192\.168\." forbidden
<Files *>
Order allow,deny
Allow from all
Deny from env=forbidden
</Files>
or
SetEnvIf Remote_Addr "!^192\.168\." forbidden
<Directory /var/www/wproot>
Order allow,deny
Allow from all
Deny from env=forbidden
</Directory>
Clearly you'll need to change the Regexp to your local needs but this should do the biz. The Apache docs give other variants on this, but you should be able to find one which works in your case. Just put this in the a per-virtual server context -- within a Directory(Match) directive if necessary -- or in a common parent directory .htaccess file.
I ended up getting this to work with your first suggestion, but actually without the SetEnvIf line being required, so thanks very much! this was my .htaccess in the /var/www/vhosts folder for anyone else needing this:
<files wp-login.php>
order deny,allow
deny from all
Allow from xxx.xxx.xxx.xxx
</files>
Nice and simple and completely different from the previous routes I was trying to take for this.
Related
I am setting up a WordPress site in a subdomain. The subdomain will be in a subdirectory of the main directory.
So http://dl.abc.com will be in the folder /public_html/dl/
Within there is going to be the wp-admin folder when WordPress is installed:
/public_html/dl/wp-admin/
That wp-admin folder we wanted to block anyone trying to access it (or any files/subdirectories contained within) except those users from Australia and Singapore.
Is this the correct way to go about it? (I suspect a caveat is any plugins that make ajax requests by calling admin-ajax.php won't work properly?)
<ifModule mod_geoip.c>
GeoIPEnable On
# Put countries to allow here
SetEnvIf GEOIP_COUNTRY_CODE NZ AllowCountry
SetEnvIf GEOIP_COUNTRY_CODE SG AllowCountry
Deny from all
Allow from env=AllowCountry
</ifModule>
Second question is how can we go about doing the same thing with the wp-login.php file that will be installed within the /public_html/dl/ folder?
Will this work if we put it in the .htaccess file within the /public_html/dl/ directory? Or is there a better way?
<Files "wp-login.php">
<ifModule mod_geoip.c>
GeoIPEnable On
# Put countries to allow here
SetEnvIf GEOIP_COUNTRY_CODE NZ AllowCountry
SetEnvIf GEOIP_COUNTRY_CODE SG AllowCountry
Deny from all
Allow from env=AllowCountry
</ifModule>
</Files>
?
And lastly, I'd like to have a bit of additional "security through obscurity" in that for both examples above I'd rather return the "404 not found" error instead of the denied error.
What's the best way to do that?
Unfortunately we don't have any sort of dev/test server to try things out with first, so want to get this as close to perfect as possible the first time through.
Thank you.
_
htaccess - deny directory based on geolocation
check this url :https://mediatemple.net/community/products/dv/204643270/using-htaccess-rewrite-rules
To answer your second question, according to this page:
https://www.askapache.com/htaccess/using-filesmatch-and-files-in-htaccess/
you can surround other directives with the <Files></Files> or <FilesMatch></FilesMatch> directive:
"The directive limits the scope of the enclosed directives by
filename. It should be matched with a directive. The
directives given within this section will be applied to any object
with a basename (last component of filename) matching the specified
filename. sections are processed in the order they appear in
the configuration file, after the sections and .htaccess
files are read, but before sections. Note that can
be nested inside sections to restrict the portion of the
filesystem they apply to."
So essentially it seems that what you have stated already should work.
So I have a setup that looks as follows:
www.mydomain.com - runs a complex multisite Wordpress install
www.mydomain.com/othersite - for various reasons this needs to run a totally separate install of Wordpress, but the URL must be in this format for historic reasons.
I'd like the "othersite" install of WP not to have to sit in the directory of the main multisite install, eg
/var/www/main-multisite
/var/www/othersite and NOT /var/www/main-multisite/othersite
My understanding is that I couldn't create a separate virtualhost for othersite, so I created an alias in the main virutalhost:
Alias /othersite /var/www/othersite
However when doing that, it seems the .htaccess file in /var/www/othersite is being ignored - I first noticed this as the permalinks in Wordpress don't work. I tried adding other directives into .htaccess but none work...so I then put gibberish into .htaccess to try and induce an error...but that didn't happen. So taht confirms my thinking that .htaccess is being ignored.
However, if I remove the alias from the Virtual host, and move things so we have
/var/www/main-multisite/other
everything works fine, and the .htaccess in the folder works ok! But this is not how I want things.
Can anyone help me shed any light on what I'm missing here?
Thanks in advance.
After you have set the Alias, you should set the group of directives to apply to the directory. You should add the <Directory> directive in apache config. The default config AllowOverride None will completely ignore .htaccess on the directory. You should also check the documentation about the <Directory> directive.
<Directory "/var/www/othersite">
Options FollowSymLinks Includes
AllowOverride All
Order allow,deny
Allow from all
</Directory>
I am no expert on apache conf files, but I am reasonably familiar with them. A security plugin I have installed on one of my wordpress sites (https://ithemes.com/security/) makes edits to an .htaccess files in order to enforce automated IP bans (for example, if you have too many failed login attempts in a short period of time). Here is the block that it generated: (xxx added by me for the IP address)
<IfModule mod_authz_core.c>
<RequireAll>
Require all granted
Require not env DenyAccess
Require not ip xxx.xxx.xxx.xxx
</RequireAll>
</IfModule>
<IfModule !mod_authz_core.c>
Order allow,deny
Deny from env=DenyAccess
Deny from xxx.xxx.xxx.xxx
Allow from all
</IfModule>
Now, this causes the site to bomb out with a 500 error. The error I get in my log is
Expected </RequireAll>> but saw </RequireAll>
(Note the extra trailing >). And, lo and behold, if I add an extra >, the site works again.
What syntax rule is at play here? Why on earth do I need the extra > in a closing tag? Why would the (popular and genreally respected) plugin be generating an invalid .htaccess? Since this looks so wrong to me I'm inclined to believe I have some obscure server setting or an outdated apache or something causing this. Any insight would be much appreciated.
Using Apache/2.0.46
I've tried everything. I read other how to threads here and elsewhere. I have the following in my apache2 site configuration file:
<Directory /var/www/html/site_root/>
AllowOverride All
</Directory>
</VirtualHost>
There is no other occurence of "AllowOverride" in the site conf file so it's not a case of something earlier in the file overriding this (don't even know if that's possible). I also tried '/var/www/html/site_root'.
If I try either of the following (or both) in my /var/www/html/site_root/.htaccess file:
<Files .htaccess>
Order Allow,Deny
Deny from all
</Files>
<Files "xmlrpc.php">
Order Allow,Deny
Deny from all
</Files>
I get 520s and the whole site is crashed. I also tried /xmlrpc.php or "xmlrpc.php" without "" and ./xmlrpc.php etc. No matter what I do my error log is full of:
[Thu Dec 03 18:05:25.628237 2015] [core:alert] [pid 6956] [client 192.168.0.1:56529] /var/www/html/site_root/.htaccess: order not allowed here
How can this be and why is this so difficult to do?
My purpose is to block access to /xmlrpc.php. This is an absolute Achilles heel for WordPress. It is very easy to crash and burn any site by just hitting this over and over and over again. For some reason WordPress leaves it wide open by default and Cloudflare is not able to detect or protect against these attacks. They happen all the time and it brings down the server completely.
Thanks.
The best answer I found is this:
If your server is an Apache, you can block access before WordPress is even reached with one line in your .htaccess:
Redirect 403 /xmlrpc.php
You can add another line to keep the response short:
ErrorDocument 403 "die"
That will send a very minimal response (three bytes plus HTTP headers), and it will save your resources for better traffic.
Source:
https://wordpress.stackexchange.com/questions/156522/restrict-access-to-xmlrpc-php
Please go vote up the answer at the wordpress stack, by user #toscho. I don't have enough reputation. Toscho's answer is is way better than the accepted answer because you can deny access in .htaccess and still burn up server resources loading the 404 in Wordpress. His answer actually saves you one byte over mine.
Well did you restart your server after you made changes to apache2.config? Secondly there is a difference between order allow,deny AND order deny,allow
Try using this
<Files xmlrpc.php>
order deny,allow
deny from all
</Files>
You can also disable the XML-RPC Feature, from the system itself. Just put this in your wp-config
add_filter('xmlrpc_enabled', '__return_false');
Update: Some clarification:
I agree with jason, blocking xmlrpc.php at the htaccess level is always a much better idea because even if you disable it through the filter, the site still goes through the whole request cycle. Here filters is just being used as a safeguard from someone getting in, but the site is still open to DDOS attacks. In short usage of filters is only for people who are using it for some other purposes and not finding an escape from DDOS attacks, for eg if someone doesn't have access to the htaccess file.
I am having problems as some computer from an IP address is trying to access all the files on my server.
How should I change the .htaccess file so that IP address gets NO access at all to any files? And which .htaccess file do I change? It looks like I have one inside each folder.
The basic mod_access module should get you what you need
Order allow,deny
Allow from all
Deny from xxx.xxx.xxx.xxx
Something like that. I dont know the exact syntax. Keep in mind that depending on your exact version of Apache (1.3/2.0/2.2) then the module requirements might be different. I think in 2.2 you need the authz_host module, but in 1.3 its mod_access.
For simple cases, you can try http://wordpress.org/extend/plugins/wp-ban/, which can keep IP or IP range from visiting your blog.
If that's not enough, you can modify .htaccess as follows
Deny from xx.xx.xx.xx/xx
Allow from ALL
Another way, this time using mod_rewrite rules in a .htaccess file.
RewriteEngine on
RewriteCond %{HTTP_HOST} ^123.123.123.123$
RewriteRule ^(.*)$ blocked.html [L,F]
[L,F] means 'stop executing further rules, and return 403 Forbidden as the HTTP status'. blocked.html could contain a message indicating that they've been blocked.