Apache Redirect Range of IP Addresses (IPv4 and IPv6)
There are numerous ways to redirect requests using Apache’s mod_rewrite and mod_alias. This concise, friendly tutorial explains different ways to redirect a range of IP addresses, either IPv4 or IPv6.
Contents
- Definitions
- The OLD way to redirect a range of IP addresses
- The NEW way to redirect a range of IP addresses
Definitions
Before diving in, here are some examples showing the difference between IPv4 and IPv6 addresses. So we’re all on the same page.
- IPv4 address —
123.123.123.123
- IPv4 network —
123.123.123.0/24
- IPv6 address —
a1b2:c3d4:e5f6:g7h8:i9j0
- IPv6 network —
a1b2:c3d4:e5f6:g7h8:i9j0::/64
Lots of great resources online for more information and details about IP address mechanics, syntax, and so forth. Let’s stay focused here..
The OLD way to redirect a range of IP addresses
In the past, like with Apache version 2.2, we could redirect IPv4 addresses like so:
<IfModule mod_rewrite.c>
RewriteCond %{REMOTE_ADDR} ^123\.123\.[0-9]{1,3}\.[0-9]{1,3}$
RewriteRule .* /wherever/ [L]
</IfModule>
That will match and redirect requests from any IP address that begins with 123.123.
. It’s nothing exciting really, just using regular expressions to match whatever is needed. In plain language, the regex says this:
- Check if the first two octets are
123.
and123.
- And the third and fourth octets are any number (e.g.,
0-255
)
So this logic would enable you to define the first part of the IP address while matching any indeterminate number in the third and fourth octets. Effectively, this technique can be used to block a range of addresses.
Another example
Here is another example of the “old way” to illustrate. Say we want to redirect everything in the range 123.123.123.000/24
, we would write:
<IfModule mod_rewrite.c>
RewriteCond %{REMOTE_ADDR} !^123\.123\.123\.
RewriteRule .* /wherever/ [L]
</IfModule>
The regex pattern here will match any IP address that begins with 123.123.123.
, which means the fourth octet can be any number, thus matching the entire range of addresses (in this case 123.123.123.000/24
).
One more example
One more example showing how to redirect IP addresses the “old way” lol.
<IfModule mod_rewrite.c>
RewriteCond %{REMOTE_ADDR} !^123\.123\.123\.8[0-9]$
RewriteCond %{REMOTE_ADDR} !^123\.123\.123\.9[0-5]$
RewriteRule .* /wherever/ [L]
</IfModule>
That combination of rewrite rules will block any request coming from IP address in the range of 123.123.123.80
to 123.123.123.95
(i.e., 123.123.123.89/28
).
Again these examples show how to redirect IPv4 addresses. The same sort of regular expression matching can be used to redirect IPv6 addresses. But instead wrangling some complex regex, let’s look at a better “newer” way of doing it.
The NEW way to redirect a range of IP addresses
For Apache version 2.4 and better, we can simplify our redirects by using expressions. Expressions are powerful and enable us to do things like redirect a range of IP addresses like so:
<IfModule mod_rewrite.c>
RewriteCond expr "%{REMOTE_ADDR} -ipmatch '123.123.123.0/24'"
RewriteRule .* /wherever/ [L]
</IfModule>
Here we are matching the REMOTE_ADDR
variable against a CIDR mask. It’s nice because there is no need for regular expressions. You just enter the range directly in the RewriteCond
.
Even better way
There is an even simpler, perhaps more efficient way of writing the rewrite expression. Here is an example of what that looks like:
<IfModule mod_rewrite.c>
RewriteCond expr "-R '123.123.123.0/24'"
RewriteRule .* /wherever/ [L]
</IfModule>
The difference here is that %{REMOTE_ADDR} -ipmatch
is replaced by -R
. Easy peasy. And if you need to match the negative case:
<IfModule mod_rewrite.c>
RewriteCond expr "! -R '123.123.123.0/24'"
RewriteRule .* /wherever/ [L]
</IfModule>
So here instead of matching the specified range, we are matching any IP address that is not within range. I.e., we prepended the expression with an exclamation mark !
Redirect range of IPv6 addresses
The above examples show how to redirect a range of IPv4 addresses. But the same technique works with IPv6 addresses. For example:
<IfModule mod_rewrite.c>
RewriteCond expr "-R 'a1b2:c3d4:e5f6:g7h8:i9j0::/64'"
RewriteRule .* /wherever/ [L]
</IfModule>
So you can match and redirect literally any network range quite literally.
Redirect multiple ranges
Closing things out, here is one more example showing how to redirect multiple ranges of IP addresses.
<IfModule mod_rewrite.c>
RewriteCond expr "-R '123.123.123.0/24'" [OR]
RewriteCond expr "-R '123.123.123.0/24'" [OR]
RewriteCond expr "-R '123.123.123.0/24'"
RewriteRule .* /wherever/ [L]
</IfModule>
Here we are using IPv4 addresses for clarity/simplicity. The same technique can be used to redirect multiple ranges of IPv6 addresses. It’s all very logical ;)
[OR]
flag in the final RewriteCond
. That is required for the rules to work properly together.Related articles
- How to Redirect URLs
- .htaccess Redirect Examples
- Eight Ways to Redirect with Apache’s mod_rewrite
- Redirect Query String via .htaccess
- Articles about redirecting with Apache
- Archive: articles tagged as redirect