Simple & Fast but not 100% secure method:
This method is not 100% secure, but for most users (like 99%), it’ll work.
Here, basically you’ll use a .htaccess
file inside the restricted directory, say: /var/www/html/link
with the following CODE:
SetEnvIf Cookie "^.*wordpress_logged_in.*$" WP_LOGGED_IN=maybe
Order allow,deny
Require all granted
# Our Network
#Allow from ip-address/22
#Allow from ip-address/24
#Allow from ip-address/24
#Allow from ip-address/24
# and even longer list of IPs
# Perhaps WordPress is logged in according to cookie: works for trivial cases, but not 100% secure
Allow from env=WP_LOGGED_IN
So basically, instead of apache config, you’ll put the allowed IP networks in this .htaccess
file (without the <Directory>
block), which will also check the WordPress login cookie using SetEnvIf
directive. If the IP is not in the match & login cookie isn’t found either, with this CODE the remaining visitors will be denied access.
No change in the .htaccess
file of the root web directory is necessary.
Secure method:
If you need 100% secure method, then it’s best to do it with PHP.
First remove all existing IP restrictions (for the corresponding directory) from the apache config file.
Then, use the following CODE in the .htaccess
file of your root web directory.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^link/access\.php$ - [L]
RewriteRule ^link/.*$ /link/access.php [L]
# Your remaining rewrite rules for WordPress
</IfModule>
Then in /var/www/html/link/access.php
file, use the following PHP CODE:
<?php
function network_match( $ip, $networks ) {
foreach( $networks as $network ) {
$net_parts = explode( "https://wordpress.stackexchange.com/", $network );
$net = $net_parts[0];
if( count( $net_parts ) === 2 ) {
$netmask = $net_parts[1];
if( ( ip2long( $net ) & ~ ( ( 1 << ( 32 - $netmask ) ) - 1 ) ) === ( ip2long( $ip ) & ~ ( ( 1 << ( 32 - $netmask ) ) - 1 ) ) ) {
return true;
}
}
else if( $ip === $net ) {
return true;
}
}
return false;
}
$networks = array(
// Put your allowed networks HERE
"192.168.0.0/24",
"127.0.0.1"
);
$allowed = false;
if( network_match( $_SERVER['REMOTE_ADDR'], $networks ) ) {
$allowed = true;
}
else {
// assuming WordPress is installed one directory above
// if not, then change accordingly
require_once dirname( dirname( __FILE__ ) ) . "/wp-load.php";
if( is_user_logged_in() ) {
$allowed = true;
}
}
if( $allowed ) {
// HERE you SERVE THE REQUESTED FILE WITH PHP
echo "You are allowed";
}
else {
die("Access denied!");
}
As it is now, this CODE basically internally rewrites all the requests to /var/www/html/link/
directory to /var/www/html/link/access.php
file & it checks IP access permission & WordPress login.
You may modify this PHP CODE (in the line that says: // HERE you SERVE THE REQUESTED FILE WITH PHP
) to serve requested files from the link
directory.
You may check this post to server files from PHP CODE.