Trying to go from older allow, deny, order syntax to the new one to secure WordPress admin section, but I can't get it to recognize my IP.
This is what my .htaccess file contains in /wp-admin folder.
ErrorDocument 401 default
ErrorDocument 403 default
# Disallow access for everyone except these IPs
<RequireAny>
Require ip 50.153.218.4
</RequireAny>
# Allow plugin access to admin-ajax.php around password protection
<Files admin-ajax.php>
<RequireAll>
Require all granted
</RequireAll>
</Files>
And this is what I have in .htaccess in the root under the WordPress mod rewrite info.
# Protect WordPress
ErrorDocument 401 default
ErrorDocument 403 default
<Files wp-login.php>
<RequireAny>
Require ip 50.153.218.4
</RequireAny>
</Files>
But I just keep getting 403 Forbidden error. When I add Require All Granted under the IP, it works fine, but that opens it up to every user. It seems like apache is just not reading my ip correctly? Anyone have any idea what I'm doing wrong?
Your syntax looks perfectly fine to me.
The only reason I can think that apache might not be reading the user's IP correctly is if you're behind a proxy or load balancer. If that is the case you would use X-Forwarded-For instead of ip. In PHP, you can confirm if you're behind a proxy by comparing $_SERVER['REMOTE_ADDR'] and $_SERVER['HTTP_X_FORWARDED_FOR'].
If that is not the issue so you might have better luck finding an answer at ServerFault.
I can offer you some workarounds though. The easiest solution may be to use one of several WordPress security plugins that allow you to restrict access to the backend by IP address.
Alternatively, in your theme or in a plugin you can implement this same sort of authentication logic:
add_action('init', function() {
$allowed_ips = array('50.153.218.4');
if(is_admin() || $GLOBALS['pagenow'] == 'wp-login.php') {
if( !DOING_AJAX && !in_array($_SERVER['REMOTE_ADDR'], $allowed_ips) ) {
wp_die('', 'Forbidden' array(
'response' => 403
));
}
}
});
Update: From the comments it looks like there is a proxy involved. This should work:
ErrorDocument 401 default
ErrorDocument 403 default
SetEnvIF X-Forwarded-For "50.153.218.4" AllowIP
# Disallow access for everyone except these IPs
<RequireAny>
Require env AllowIP
</RequireAny>
# Allow plugin access to admin-ajax.php around password protection
<Files admin-ajax.php>
<RequireAll>
Require all granted
</RequireAll>
</Files>
and
# Protect WordPress
ErrorDocument 401 default
ErrorDocument 403 default
SetEnvIF X-Forwarded-For "50.153.218.4" AllowIP
<Files wp-login.php>
<RequireAny>
Require env AllowIP
</RequireAny>
</Files>
You should also be able to use a similar method using the "Allow, Deny" syntax.
Related
Im trying to restrict WordPress Login by IP but for any reason does not work the "allow from",
I have been restarted my server and seems do not work. any ideas? (my IP is static). Always I get 403 error.
<Files wp-login.php>
Order deny,allow
deny from all
allow from MyIP
</Files>
What happened was that my WordPress was with a load balancer, and the IP shown was from the load balancer.
so I added a HTML Header (X-Forwarded-For) to fix it.
<Files wp-login.php>
Order deny,allow
Deny from all
SetEnvIf X-Forwarded-For "myIP" env_allow_1
Allow from env=env_allow_1
</Files>
I want restrict all users to access WordPress website login.
For example: Suppose I have WordPress website domain example1.com and I want to restrict all users to access admin login with example1.com/wp-admin and example1.com/wp-login.php.
When any user hits these url it redirect to restrict_user page and also I want to access wordpress login page with example1.com/user_login instead of hit example1.com/wp-admin and example1.com/wp-login.php urls.
And please suggest me how can i make my WordPress website more secure from hacking?
You can lock down the wp-admin page with htaccess deny all and hen setting an allowed ip.
order deny,allow
deny from all
allow from 127.0.0.1
You can also set a htpasswd file with allowed logins and password protect the page. I would also make sure your username in wp-admin is not something easy like 'admin' or 'editor'.
<IfModule mod_auth.c>
AuthUserFile /home/path/.htpasswd
AuthName "Username and password required"
AuthType Basic
<Limit GET POST>
Require valid-user
</Limit>
</IfModule>
Furthermore i would highly recommend wordfence as a good plugin for protection from hacks etc.
Restricting access to wp-admin directory
Apache 2.4+
Add this snippet to your .htaccess file, created in wp-admin directory:
<RequireAny>
Require ip 64.176.174.0/255.255.255.0
Require ip 64.176.176.0/255.255.255.0
</RequireAny>
and add as many IP Address/Subnet Mask pairs, as you wish, regarding the client IP address you would like to have access to admin area. I have added two samples above.
Apache 2.4-
Add this snippet to your .htaccess file, created in wp-admin directory:
<Directory>
Order Deny,Allow
Deny from all
Allow from 64.176.174.0/255.255.255.0
</Directory>
Restricting access to wp-login.php path
Add this snippet to you current theme's functions.php file:
function my_checkRole(){
if( !( current_user_can( 'administrator' ) ) && !( defined('DOING_AJAX') && DOING_AJAX ) ){
wp_redirect( site_url( 'restrict_user' ) );
exit;
}
}
add_action( 'admin_init', 'my_checkRole' );
Changing the wp-admin path
It is possible to change it, but why do you think that has any value at all? You cannot hide anything from a Bot - that is just not possible to do.
Hackers use automated Bot programs to find whatever they want to find.
A good approach is Action Approach:
hacker X does bad action Y and the result is Z = Forbidden.
So just use the presented method in Restricting access to wp-login.php path section and that will be OK.
From nginx, using php7.0-fpm on Ubuntu 16.04LTS.
My base configuration I modified from:
https://www.digitalocean.com/community/tutorials/how-to-install-linux-nginx-mysql-php-lemp-stack-in-ubuntu-16-04
I found a bunch of configs online that tried to combine wp-login.php and wp-admin into the same rule, but allowed wp-login.php to be raw downloadable!
Granted, its a generic Wordpress file, but that is dangerous behaviour.
I've separated the rules, since wp-admin is a folder, anything accessed within will follow generic rules for images/php/etc. For wp-login.php I wanted to specifically replicate php execution. I've allows full internal network access to 10.x.x.x.
location ~ wp-login\.php {
allow 10.0.0.0/8
deny all;
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}
location /wp-admin/ {
allow 10.0.0.0/8
deny all;
index index.php index.html index.htm;
try_files $uri $uri/ /index.php?$args;
}
I have a domain I use for development purposes. In this domain I have several subdirectories with different wordpress installations.
To hide the whole area I made a simple htpasswd protection in the root.
Now I have one of this Wordpress in the domain that uses timthumb library to resize images, and due to the htpasswd, I get "NetworkError: 400 Bad Request" instead of the image.
This is an example of the request that gets the error
http://subdomain.domain.com/WP/wp-content/plugins/plugin-directory/timthumb.php?src=http%3A%2F%2Fsubdomain.domain.com%2FWP%2Fwp-content%2Fuploads%2F2015%2F01%2F012015_valentines_hp_budvase.jpg&w=300&h=620&zc=1
Is there a way to bypass the protection only for that file?
More details on my paths to better read my .htaccess snippets:
I'm in a subdomain pointed to a subdirectory called 'subdomain_folder'
.htaccess I'm working on is located in 'subdomain_folder'
WP is in a subdirectory called 'WP' inside 'subdomain_folder'
Complete Path to WP: '/home/some-folder/public_html/subdomain_folder/WP
Complete Path to Uploads: '/home/some-folder/public_html/subdomain_folder/WP/wp-content/uploads
I tried this:
SetEnvIf Request_URI "^/WP/wp-content/plugins/plugin-dir/timthumb\.php$" allow
AuthType Basic
AuthName "Restricted Area"
AuthUserFile "/home/some-folder/.htpasswds/public_html/subdomain_folder/passwd"
Require valid-user
Order allow,deny
Allow from env=allow
Satisfy any
UPDATE
Someone adviced me that allowing access to timthumb.php file it's pointless, instead I should allow him to make http requests, or allow full access to uploads folders so, I tried the following, allowing requests from localhost ip
AuthType Basic
AuthName "Reserverd Area"
AuthUserFile "/home/some-folder/.htpasswds/public_html/subdomain_folder/passwd"
Require valid-user
Order Deny,Allow
Deny from all
Allow from 127.0.0.1
Satisfy Any
Tried both localhost and 127.0.0.1
I even tried to add another .htaccess in the single WP upload folder (where timthumb asks for images) with rule to allow from any
Satisfy Any
Order Allow,Deny
Allow from all
Still I cant' get images shown, and I keep getting the NetworkError: 400 Bad Request" instead of the image.
Last Detail, the .htaccess in the WP directory is a standard wp htaccess --> pastebin.com/8PRqEYQ2
I Found the solution.
The right way is indeed allowing requests from the server itself, but the localhost IP (127.0.0.1) was not the right adress to allow.
I made a Reverse IP Lookup searching for the domain I'm on, and I used that IP.
This is the .htaccess that works
RewriteEngine On
<IfModule mod_authn_file.c>
AuthName "Restricted Area"
AuthUserFile "/home/path-to-passfile/passwd"
AuthType Basic
Require valid-user
Order Deny,Allow
Deny from all
# Use your server ip:
Allow from 111.111.111.11
Satisfy Any
</IfModule>
With this rules I can develop apps using timthumb.php in .htpasswd protected directory.
Criticisms and improvements are welcome :)
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.
Is there a module I can use to disable some Drupal system pages? For example, I'd like to disable node, taxonomy/term/*, filter/tips.
I'm not sure if there is a module that does that, but it's not too hard to write your own custom module for this. You only need to implement hook_menu_alter (and clear the cache after changing your code). You can choose to return an 'access denied' page or a '404 not found':
<?php
function MODULENAME_menu_alter(&$items) {
// This will deny access to taxonomy/term/* for all users.
$items['taxonomy/term/%']['access callback'] = FALSE;
// This will completely remove filter/tips, resulting in a 404.
unset($items['filter/tips']);
}
?>
If you want to know more about writing Drupal modules, see http://drupal.org/developing/modules.
This seems to be more of a "one time" configuration to me. So I wonder if its necessary to have an admin interface for this that you have requested in one of your comments.
If you're using apache, in the virtual host configuration of your site you can include the following directives:
<LocationMatch ^/taxonomy/term>
SetHandler server-status
Order Deny,Allow
Deny from all
</LocationMatch>
<LocationMatch ^/filter/tips>
SetHandler server-status
Order Deny,Allow
Deny from all
</LocationMatch>
This will deny access to those URLs. But you need to make sure that you don't have an URL aliased to taxonomy/term/ etc paths. Otherwise the user can access those URLs.
Check http://httpd.apache.org/docs/2.0/mod/core.html#locationmatch
and http://httpd.apache.org/docs/2.0/mod/core.html#location for some documentation