How to Block an IPv6 Address Range
So, your server is receiving unwanted network traffic.
You'd normally add a new iptables rule and block the troublemaker. But this time, the source comes from a network set with an IPv6 address.
Wat do?
Who This Post is For
This post covers the absolute basics of dealing with IPv6 addresses. It delivers the bare-bones summary I had hoped to find when I searched for how to block IPv6 traffic.
If you want detailed information, the IPv6 Wikipedia Page is a good place to start.
But you don't want that, do you.
You want to:
- understand the syntax of an IPv6 address;
- learn how to specify an IPv6 address range; and
- see how to write an iptables rule that blocks an IPv6 address range.
At least I did. And now I know!
And, in a few minutes, you're going to know as well.
The Basics of IPv6
IPv6 syntax is similar to traditional IPv4.
Hexadecimal values are listed in order of network detail, with each four-byte group delimited by ":".
An address you'll often see is: 2001:db8::
That's not a special value; it's just a standard subnet chosen for IPv6 documentation. Think of it as the www.example.com of IPv6, or the equivalent of the 192.168.0.1 you might use for an IPv4 document.
We'll be using that 2001:db8:: subnet in the examples outlined here.
"But," you might ask, "isn't that example address a bit short for IPv6?"
Nope! The address is just written in IPv6 short form.
IPv6 Short Form
The IPv6 address 2001:db8:: can be fully written as:
2001:0db8:0000:0000:0000:0000:0000:0000
Leading 0s can be omitted. So, we can write a snipped equivalent of the above with:
2001:db8:0:0:0:0:0:0
Snipping further, ranges of 0s can be indicated with a double colon "::", like so:
2001:db8::
We can also snip out 0s in the middle of an address. For example, this address:
2001:0db8:0000:0000:0000:0000:0000:0045
can be written as:
2001:db8::45
The IBM documentation page at https://www.ibm.com/docs/en/i/7.4?topic=concepts-ipv6-address-formats does an excellent job of describing IPv6 syntax.
I recommend reading that page before continuing (it's very short -- it'll take you two minutes) to make sure you understand IPv6 syntax.
How to Specify an IPv6 Subnet
We now know how to write out one of the 340,282,366,920,938,463,463,374,607,431,768,211,456 possible IPv6 addresses.
Yeah, there are a lot. And we'll have to block many nefarious IPv6 subnets in the years to come.
IPv6 subnets are identified through the address's four-byte groups. So, just as we can write:
192.168.0.0/24
to indicate all IPv4 addresses from 192.168.0.0 to 192.168.0.255, we can write:
2001:0db8::/32
to indicate all IPv6 addresses from 2001:0db8:0000:0000:0000:0000:0000:0000 to 2001:0db8:ffff:ffff:ffff:ffff:ffff:ffff
Similarly, the notation:
2001:0db8:4567::/48
would indicate all IPv6 addresses from 2001:0db8:4567:0000:0000:0000:0000:0000 to 2001:0db8:4567:ffff:ffff:ffff:ffff:ffff
If you're wondering what /32 and /48 mean, this page about IPv6 subnetting does a fantastic job of explaining values for IPv6 slash "/" notation.
I recommend reading that page before continuing (again, it's very short -- you'll be done in minutes) to make sure you understand how IPv6 subnets are written.
Want to Test What You've Learned?
Of course you do!
This IPv6 Subnet Calculator will accept an entered IPv6 subnet and show the range of addresses it covers.
A few experiments there will confirm you've caught the basics.
How to Block an IPv6 Subnet
Now that we know how to specify an IPv6 subnet, how do we go about blocking it?
Why, using ip6tables, of course!
I'm assuming here that you're familiar with how to use the iptables tool to block unwanted IPv4 network traffic. If iptables is new to you, you'll find Linode's iptables tutorial a helpful guide to get started with the basics.
Using iptables, we could block traffic from the IPv4 address range 192.168.0.0 to 192.168.0.255 with the command:
iptables -A INPUT -s 192.168.0.0/24 -j DROP
In the same way, we can block all traffic from an IPv6 subnet using ip6tables.
Using our range example above, the IPv6 address range 2001:0db8:0000:0000:0000:0000:0000:0000 to 2001:0db8:ffff:ffff:ffff:ffff:ffff:ffff can be blocked using the ip6tables command:
ip6tables -A INPUT -s 2001:0db8::/32 -j DROP
Similarly, a more precise targeting of the IPv6 address range 2001:0db8:4567:0000:0000:0000:0000:0000 to 2001:0db8:4567:ffff:ffff:ffff:ffff:ffff can be blocked with:
ip6tables -A INPUT -s 2001:0db8:4567::/48 -j DROP
You can specify your subnet of choice using the examples covered above.
And That's It!
You're good to go.
You're armed and ready to block any IPv6 traffic dispatched to hassle your servers.
Good luck!
(Special thanks to demu.red's post about IPv6 range blocking at https://demu.red/blog/2016/09/blocking-ipv6-ranges-with-iptables/. That gave me a good starting point for figuring out the basics.)