If there’s an IPv6 netblock you’d like your host to stop responding to, one tactic is to blackhole the traffic. That is, send any traffic from your host destined to the troublesome IPv6 netblock into a blackhole. Blackholes are also called null routes.
A Simple Example
Let’s say I’m getting repeated SQL injection attacks from various hosts in IPv6 block 2a09:8700:1::/48. Just a totally random example with no basis in reality whatsoever, whoever you are in Belize. 🙄 There are various ways I can defend against this, but one (sorta ugly) option (I don’t actually recommend, read to the bottom to see my logic) is to create a blackhole aka a null route.
On many flavors of Linux, including Ubuntu 18.04, 20.04, and 22.04, I can accomplish this task with the ip route utility. Let’s take a look at our existing host routing table.
user@host:~$ ip route
default via 123.94.146.1 dev enp1s0 proto dhcp src 123.94.146.227 metric 100
169.254.169.254 via 123.94.146.1 dev enp1s0 proto dhcp src 123.94.146.227 metric 100
123.94.146.0/23 dev enp1s0 proto kernel scope link src 123.94.146.227
user@host:~$
Huh. No IPv6 addresses in there. Right. We need the -6 flag to work with the v6 routing table.
user@host:~$ ip -6 route
2001:9abc:cba8:1234::/64 dev enp1s0 proto ra metric 100 pref medium
fe80::/64 dev enp1s0 proto kernel metric 256 pref medium
default via fe80::fc00:3ff:f99b:8121 dev enp1s0 proto ra metric 100 mtu 1500 pref medium
user@host:~$
Ah, that’s more like it. We see the IPv6 routing table. Now, let’s add the blackhole route. Adding routes to the routing table is a big deal, so you’ll need to flex your superuser powers.
user@host:~$ sudo ip -6 route add blackhole 2a09:8700:1::/48
[sudo] password for user:
user@host:~$ ip -6 route
2001:9abc:cba8:1234::/64 dev enp1s0 proto ra metric 100 pref medium
blackhole 2a09:8700:1::/48 dev lo metric 1024 error -22 pref medium
fe80::/64 dev enp1s0 proto kernel metric 256 pref medium
default via fe80::fc00:3ff:f99b:8121 dev enp1s0 proto ra metric 100 mtu 1500 pref medium
user@host:~$
And there we have it. The blackhole route is present.
Removing Blackhole Routes
If you add a blackhole route to defend against an ongoing attack, you should plan to delete that blackhole route when the attack is over. To remove the route we added above, you’d use ip -6 route delete like so…
sudo ip -6 route delete blackhole 2a09:8700:1::/48
Is Blackhole Routing On A Host A Good Defense Technique?
Blackhole routing is not my first choice when it comes to host defense. Why? Netblocks like the /48 I use in my example above contain huge amounts of potential addresses. If you null route an entire /48 because of a few bad actors, legitimate hosts from that block won’t be able to reach the host either. Therefore, my primary use case for host-based blackhole routing is as a temporary option that might help a host when under severe attack.
That said, blocking a /48 isn’t quite as “scorched earth” as it might seem. /48s are, in the context of IPv6, the smallest blocks advertised to the global internet routing table. /48s are typically allocated to individual organizations to split up however they’d like. ARIN won’t even issue a block smaller than a /48 to end users. Thus, even though a /48 seems like this huge amount of address space and you’d be blackholing more hosts than your brain can conceive of–about 1.2 septillion–that’s not what’s happening practically speaking. Null routing a /48 will likely impact one organization at most, and possibly even just a few hosts.
Nonetheless, from a ops standpoint, I’d prefer to use one of the following options rather than add a blackhole route into a host’s kernel.
- Use a web application firewall (WAF). Assuming the attack is on a web server specifically, a WAF can discern between nasty traffic and legitimate traffic within the same netblock. WAFs can also do things like temporarily block offending IPs (rather than nuking them forever), throttle aggressive clients, and so on. WAF vendors often maintain a global database of known malicious actors, a handy gatekeeping filter.
- Intelligently filter the offending netblock upstream from the host. Maintaining null routes on individual hosts doesn’t scale. The more hosts you have and the more null routes you want to implement, the more annoying the ops tasks become. The better option is to hand off this security function to centralized firewalls positioned at key network checkpoints. In the modern IT stack, “centralized firewall” probably means a PaaS service running on your favorite cloud or SaaS security tool, but could imply many different architectures.