IPv6 Security and Configuration

  • Be sure to checkout “Tips & Tricks”
    Dear Guest Visitor → Once you register and log-in please checkout the “Tips & Tricks” page for some very handy tips!

    /Steve.
  • BootAble – FreeDOS boot testing freeware

    To obtain direct, low-level access to a system's mass storage drives, SpinRite runs under a GRC-customized version of FreeDOS which has been modified to add compatibility with all file systems. In order to run SpinRite it must first be possible to boot FreeDOS.

    GRC's “BootAble” freeware allows anyone to easily create BIOS-bootable media in order to workout and confirm the details of getting a machine to boot FreeDOS through a BIOS. Once the means of doing that has been determined, the media created by SpinRite can be booted and run in the same way.

    The participants here, who have taken the time to share their knowledge and experience, their successes and some frustrations with booting their computers into FreeDOS, have created a valuable knowledgebase which will benefit everyone who follows.

    You may click on the image to the right to obtain your own copy of BootAble. Then use the knowledge and experience documented here to boot your computer(s) into FreeDOS. And please do not hesitate to ask questions – nowhere else can better answers be found.

    (You may permanently close this reminder with the 'X' in the upper right.)

bdub76

Member
Oct 19, 2024
8
2
OpenBSD 7.6 finally added a DHCPv6-PD app (dhcp6leased) in base, so I decided to convert my network into a dual stack IPv4/IPv6 network. I have everything up and running, and now, I'm at the stage of hardening my setup. And I have a few questions I was hoping folks here could help me out with.

The first concerns martian packets for IPv6.


I have followed the following two sites and have come up with the following to reject from my network.



table <martians> { 0.0.0.0/8 127.0.0.0/8 169.254.0.0/16 \
192.0.0.0/24 192.0.2.0/24 \
192.168.0.0/16 198.18.0.0/15 198.51.100.0/24 \
203.0.113.0/24 224.0.0.0/3 240.0.0.0/4 \
::1/128 ::/128 100::/64 2001::/23 2001::/32 \
2001:2::/48 2001:db8::/32 2001:10::/28 \
3fff::/20 }

Does my reduced list of the IPv6 addresses make sense? Are there more that I should add, or are there ones I should remove?

The next thing I looked at was ICMPv6.

I've read through this doc: https://www.rfc-editor.org/rfc/rfc4890 And I'm not sure really what to keep and not keep since so much of IPv6s functionality depends on ICMPv6. For now, I'm passing all ICMPv6 traffic. Let me know your thoughts on this one. It does look like I should have some restriction here, but I'm not sure. My current rule passes it all and keeps state.

# allow ICMP6 traffic
pass in quick inet6 proto icmp6
pass out quick inet6 proto icmp6

I'm also still trying to get my head around the idea that I'm not NATing anything for IPv6. My IPv6 only egress pass in rule is as follows to get my 64 bit PD from my ISP. My router is setup to default block all.

# dhcpv6 traffic for WAN
pass in on egress inet6 proto udp \
from fe80::/10 port dhcpv6-server \
to fe80::/10 port dhcpv6-client no state

The other items that I'm trying to get my head around that is going to require more reading on my part is settings things up locally equivalent for IPv6. My SSH on my router is still only setup for IPv4 and only accepts login via certs. I haven't configured my unbound to a IPv6 address yet, but hosts are getting IPv6 from the AAAA record currently. These are on my todo list. I'm not passing DNS yet with a RA daemon yet.

I haven't done anything to my Synology NAS for IPv6. I'm using an ASUS router as an AP only connected to my switch, and I can't figure out how to give it a static IPv6 address. Both the NAS and AP and my printer have static IPv4 addresses from my DHCP by MAC address. I'm not sure what the equivalent is for IPv6. The good news is that my ISP continues to give me the same 64 bit PD each day. Right now, I'm dual stack, so I'm not worried about it. But I'd like to know approaches.

Everything appears to work correctly. I'm trying to tie up loose ends. IPv6 is definitely more complex than IPv4 even though you don't have to NAT.

Anything I'm missing?

Also, this interesting. Here's Steve talking about the state of IPv6:


and here's the current status. Lots has changed, and I'm trying to catch up.

 
As a theoretical/learning exercise, IPv6 is a fun project. As a need, it's probably not needed or even desirable to have IPv6 to the home unless you're going to use an IPv6 NAT/Firewall to eliminate its sole real advantage, "direct" connection to the Internet as a whole.
 
As a theoretical/learning exercise, IPv6 is a fun project. As a need, it's probably not needed or even desirable to have IPv6 to the home unless you're going to use an IPv6 NAT/Firewall to eliminate its sole real advantage, "direct" connection to the Internet as a whole.

My router is an ASUS mini PC with two NICs running openBSD 7.6. I might add a third with a USB to Ethernet adapter for another sub net, but that's for another post.

I'm not performing any NAT on my IPv6 connections through my router. The only connections using NAT are IPv4. So my router isn't eliminating any of the direct connections to the Internet.

Here are my two NAT rules (both IPv4; thus, the inet). I have two because my PS5 requires a static port.

match out on egress inet from $ps5 to any nat-to (egress:0) static-port
match out on egress inet from !(egress:network) to any nat-to (egress:0)

I can see a case for disabling IPv6 on my Synology NAS. Looks like it auto configs for IPv6. But no external traffic can reach it based on my firewall (pf) rule set. I have to pass in on egress to open it up to external traffic. The pass rule is different because there is no nat-to.

What are the specific downsides of running a IPv4/IPv6 dual stack at home? And why would you NAT IPv6?

This is a good read:

 
OpenBSD 7.6 finally added a DHCPv6-PD app (dhcp6leased) in base, so I decided to convert my network into a dual stack IPv4/IPv6 network. I have everything up and running, and now, I'm at the stage of hardening my setup. And I have a few questions I was hoping folks here could help me out with.

The first concerns martian packets for IPv6.


Your firewall shouldn't allow RFC1812 packets onto the Internet. Even if you do your ISP will certainly block them, as they should. Your firewall should block egress and ingress RFC1812 packets on your exterior interface. It should also block localhost (127.0.0.1, ::1) and should block packets with your internal network addresses in the src of the IP header.

I run IPv4 and IPv6 on my network. My ISP is stingy, giving me one address and only one address. I need to resort to NAT6.

I have followed the following two sites and have come up with the following to reject from my network.


Yes, use this.


Another good source. (Though I go directly to the IETF site.)

table <martians> { 0.0.0.0/8 127.0.0.0/8 169.254.0.0/16 \
192.0.0.0/24 192.0.2.0/24 \
192.168.0.0/16 198.18.0.0/15 198.51.100.0/24 \
203.0.113.0/24 224.0.0.0/3 240.0.0.0/4 \
::1/128 ::/128 100::/64 2001::/23 2001::/32 \
2001:2::/48 2001:db8::/32 2001:10::/28 \
3fff::/20 }

Does my reduced list of the IPv6 addresses make sense? Are there more that I should add, or are there ones I should remove?

The next thing I looked at was ICMPv6.

I've read through this doc: https://www.rfc-editor.org/rfc/rfc4890 And I'm not sure really what to keep and not keep since so much of IPv6s functionality depends on ICMPv6. For now, I'm passing all ICMPv6 traffic. Let me know your thoughts on this one. It does look like I should have some restriction here, but I'm not sure. My current rule passes it all and keeps state.

Typically you want to allow error message ICMP to pass but deny anything that could expose your network architecture to the outside world.

# allow ICMP6 traffic
pass in quick inet6 proto icmp6
pass out quick inet6 proto icmp6

I use ipfilter on FreeBSD. My ICMP config is below.

#
# Allow administrative ICMP (was superceeded by ICMP keep state rule above)
#
pass IN/OUT quick ICMP all ICMP-TYPES
pass IN/OUT quick INET6 ICMP6 all ICMP6-TYPES

The ICMP types I allow are:

[ICMP-TYPES]
"icmp-type 3"
"icmp-type 4"
"icmp-type 11"
"icmp-type 12"

[ICMP6-TYPES]
"icmp-type 128"
"icmp-type 129"
"icmp-type 133"
"icmp-type 134"
"icmp-type 135"
"icmp-type 136"
"icmp-type 137"
"icmp-type 138"
"icmp-type 139"
"icmp-type 140"

IN/OUT is yet another macro that generates two rules (times the number of ICMP_TYPE objects.

(I use a macro language to generate my firewall rules for me.)

I'm also still trying to get my head around the idea that I'm not NATing anything for IPv6. My IPv6 only egress pass in rule is as follows to get my 64 bit PD from my ISP. My router is setup to default block all.

# dhcpv6 traffic for WAN
pass in on egress inet6 proto udp \
from fe80::/10 port dhcpv6-server \
to fe80::/10 port dhcpv6-client no state

This should be ok if your ISP supports DHCP6. Mine supports autodisovery. You may be able to avoid this if using autodiscovery.

The other items that I'm trying to get my head around that is going to require more reading on my part is settings things up locally equivalent for IPv6. My SSH on my router is still only setup for IPv4 and only accepts login via certs. I haven't configured my unbound to a IPv6 address yet, but hosts are getting IPv6 from the AAAA record currently. These are on my todo list. I'm not passing DNS yet with a RA daemon yet.

I haven't done anything to my Synology NAS for IPv6. I'm using an ASUS router as an AP only connected to my switch, and I can't figure out how to give it a static IPv6 address. Both the NAS and AP and my printer have static IPv4 addresses from my DHCP by MAC address. I'm not sure what the equivalent is for IPv6. The good news is that my ISP continues to give me the same 64 bit PD each day. Right now, I'm dual stack, so I'm not worried about it. But I'd like to know approaches.

I use ISC's KEA to assign static IPv6 IPs. IIRC OpenBSD uses dhcpcd (or is that NetBSD that uses it?). You should be able to do the same with it.

Everything appears to work correctly. I'm trying to tie up loose ends. IPv6 is definitely more complex than IPv4 even though you don't have to NAT.

Anything I'm missing?

Also, this interesting. Here's Steve talking about the state of IPv6:


and here's the current status. Lots has changed, and I'm trying to catch up.

 
What are the specific downsides of running a IPv4/IPv6 dual stack at home? And why would you NAT IPv6?
My opinions don't have to agree with yours, but here's my thinking. NAT is basically a form of auto-firewall plus remapping. Aside from allowing IPv4 hosts to share one IP address, it also prevents outsiders from knowing anything useful about the inside of your network. It's locking against inward packets unless you initiate an outward connection and then there are inward responses. On a NATed network, if all the devices inside went silent running (or turned off) then there should be no listening ports on your public IP address and no way for anything to "worm" it's way in.

If you enjoy firewall configuration, and the potential worry that you might not have done a good enough job, then by all means expose your inside IPv6 addresses to the outside world. However, since I don't personally run any public service, I see no advantage to being "more present" on the public Internet. Since, by definition, you won't know about any 0-day risk until potentially it's too late, why chance letting in ANY random packet from any rando on the Internet if you don't have to? Additionally, a firewall can (and likely should) be configured to block most outbound from your network as well, to slow down anything bad that does crawl in and try to ex-filtrate data or connect to a command-and-control server.

[Probably a theoretical issue, but, because of availability, it would be MUCH easier for rouge software to pick an unused/available publicly exposed IPv6 address and just go, than it would be to succeed that way with IPv4... so your firewall rules should consider that.]
 
I use ipfilter on FreeBSD. My ICMP config is below.

#
# Allow administrative ICMP (was superceeded by ICMP keep state rule above)
#
pass IN/OUT quick ICMP all ICMP-TYPES
pass IN/OUT quick INET6 ICMP6 all ICMP6-TYPES

The ICMP types I allow are:

[ICMP-TYPES]
"icmp-type 3"
"icmp-type 4"
"icmp-type 11"
"icmp-type 12"

[ICMP6-TYPES]
"icmp-type 128"
"icmp-type 129"
"icmp-type 133"
"icmp-type 134"
"icmp-type 135"
"icmp-type 136"
"icmp-type 137"
"icmp-type 138"
"icmp-type 139"
"icmp-type 140"

IN/OUT is yet another macro that generates two rules (times the number of ICMP_TYPE objects.

(I use a macro language to generate my firewall rules for me.)
I'll dig into this more this week. pf also does macro lists for icmp-type and icmp6-type: https://man.openbsd.org/pf.conf I'll review your ICMP6 types and see what I want to do this week with this bit. I'll probably also add type 1-4 as well for icmp6.

This should be ok if your ISP supports DHCP6. Mine supports autodisovery. You may be able to avoid this if using autodiscovery.
My ISP works with DHCP6. I have a /64 PD right now, which is far more than I need for a local network. I have around 30 devices. I haven't messed with any NATing for IPv6 at this point.

I use ISC's KEA to assign static IPv6 IPs. IIRC OpenBSD uses dhcpcd (or is that NetBSD that uses it?). You should be able to do the same with it.
dhcpcd was the go to before the addition of dhcp6leased, which has some of the functionality of dhcpcd but not all of it. It's good enough for me for now. And I don't have to deal with another package install to maintain on my router. Right now, I'm only running wget to update my root hints file for unbound.

Here's the man page with the info: https://man.openbsd.org/dhcp6leased.conf.5 It's very limited, but it's good enough for me for now.

Thanks for the suggestions. That's what I was looking for.
 
Last edited:
I'll dig into this more this week. pf also does macro lists for icmp-type and icmp6-type: https://man.openbsd.org/pf.conf I'll review your ICMP6 types and see what I want to do this week with this bit. I'll probably also add type 1-4 as well for icmp6.

pf uses variable substitution. The FreeBSD pf and ipfw do as well, as does ipfilter. Howerver I use an external package called ipfmeta because it's more like m4 but not nearly as arcane. In that sense it's like using the C preprocessor.

These are ok. I'm not sure why I didn't include them. I document my rules changes in a git log. I'll need to review why I never allowed them.

#define ICMP6_DST_UNREACH 1 /* dest unreachable, codes: */
#define ICMP6_PACKET_TOO_BIG 2 /* packet too big */
#define ICMP6_TIME_EXCEEDED 3 /* time exceeded, code: */
#define ICMP6_PARAM_PROB 4 /* ip6 header bad */

BTW, ipftiler was the OpenBSD f/w before Theo de Raadt ripped it out and wrote his own. This was after Daren Reed, its author, joined Sun Microsystems, changing the IP Filter license to GPL at the same time. He has since changed the license back for some BSDs.

My ISP works with DHCP6. I have a /64 PD right now, which is far more than I need for a local network. I have around 30 devices. I haven't messed with any NATing for IPv6 at this point.

Lucky you. Not me. They give me one address, so NAT6 it must be. I use it as an opportunity to test the NAT code anyway.

dhcpcd was the go to before the addition of dhcp6leased, which has some of the functionality of dhcpcd but not all of it. It's good enough for me for now. And I don't have to deal with another package install to maintain on my router. Right now, I'm only running wget to update my root hints file for unbound.

Here's the man page with the info: https://man.openbsd.org/dhcp6leased.conf.5 It's very limited, but it's good enough for me for now.

Thanks for the suggestions. That's what I was looking for.
 
Last edited:
pf uses variable substitution. The FreeBSD pf and ipfw do as well, as does ipfilter. Howerver I use an external package called ipfmeta because it's more like m4 but not nearly as arcane. In that sense it's like using the C preprocessor.

These are ok. I'm not sure why I didn't include them. I document my rules changes in a git log. I'll need to review why I never allowed them.

#define ICMP6_DST_UNREACH 1 /* dest unreachable, codes: */
#define ICMP6_PACKET_TOO_BIG 2 /* packet too big */
#define ICMP6_TIME_EXCEEDED 3 /* time exceeded, code: */
#define ICMP6_PARAM_PROB 4 /* ip6 header bad */
I've been using obsd as my router since around 3.x. First, on a Soekris box. Second, on a APU2. And now on an ASUS mini PC. It's been a while, and I'm still learning new things.

This is what I ended up with:

icmp6_types = "{ unreach toobig timex paramprob \
echoreq echorep \
listqry listenrep listendone \
routersol routeradv neighbrsol neighbradv }

with the following rule:

# allow certain ICMP6 traffic into egress
pass in quick on egress inet6 proto icmp6 all \
icmp6-type $icmp6_types

Based on these definitions: https://man.openbsd.org/icmp6.4 and following RFC 4890.

There are additional ones I'm considering: 141 142 143 148 149 151 152 153 that don't have a corresponding entry in the man page.

I do have another question about your list. Why are you including 137? That one is pointed out as a potential security risk in the RFC.

I also found some behind the scenes stuff done on these packets already:


The one thing that is definitely weird to me for IPv6 is all the different loopback interfaces I see in my routing table. I need to dig into that further.
 
I've been using obsd as my router since around 3.x. First, on a Soekris box. Second, on a APU2. And now on an ASUS mini PC. It's been a while, and I'm still learning new things.
There was no OpenBSD when I switched from Linux kernel 0.95 to a BSD. The choice was FreeBSD 2.0.5 or NetBSD 1.1. I chose FreeBSD. Long story. I started out with ipfw. Then used some Solaris 2.6 boxes at $JOB as firewalls after installing ipfilter from source. Later switched to ipfilter on FreeBSD.

ipfilter was the firewall on NetBSD. When Theo forked NetBSD to create OpenBSD, ipfilter was there as well. A decade later the GPL issue came up and now you have pf. I digress.

This is what I ended up with:

icmp6_types = "{ unreach toobig timex paramprob \
echoreq echorep \
listqry listenrep listendone \
routersol routeradv neighbrsol neighbradv }

This looks about right. You should allow these in and you should allow all egress icmptypes.
with the following rule:

# allow certain ICMP6 traffic into egress
pass in quick on egress inet6 proto icmp6 all \
icmp6-type $icmp6_types
This looks about right. It's what I do in ipfilter.
Based on these definitions: https://man.openbsd.org/icmp6.4 and following RFC 4890.
Yeah, that man page is in all the BSDs. You can find the spec here; https://datatracker.ietf.org/doc/html/rfc4890.

There are additional ones I'm considering: 141 142 143 148 149 151 152 153 that don't have a corresponding entry in the man page.
RFC 4890 discusses this, see the above URL. RFC 7279 also discusses them.
I do have another question about your list. Why are you including 137? That one is pointed out as a potential security risk in the RFC.
Good catch. I thought I'd already dealt with this but apparently had fixed IPv4 only back in the day. Shows how easy it is to miss something like this.

The other way to accomplish this is through a sysctl. This is probably the best approach. Or do both. I'd done the latter. Now both. Layers of an onion.
I also found some behind the scenes stuff done on these packets already:


The one thing that is definitely weird to me for IPv6 is all the different loopback interfaces I see in my routing table. I need to dig into that further.

This is because of the many auto configured IP addresses. Your interfaces IP will loop through lo0. You will see the same with your IPv4 routing table too. Multi-homed hosts will have one entry to lo0 for each IP on each interface.

The reason for this is, there's no sense sending a packet down the stack to the device driver only to have it come back up the stack again. Using the loopback interface circumvents this.
 
Last edited:

"The bottom line was that IPv6 did not offer any new functionality that was not already present in IPv4. It did not introduce any significant changes to the operation of IP. It was just IP, with larger addresses," Huston wrote.
 
Because there's money to be made in that real estate market.

The IPv4 market reminds me of the housing market. Just as a two bedroom bungalow costs a couple of million dollars in a lot of places around the world (including here). So do IPv4 addresses. Supply and demand. ;)
 
Last edited:
If you read the article, it says people have chosen NAT. It's a band-aid solution. Even though the IETF has chosen not to standardize NAT in order to discourage it, people (corporations) have chosen to NAT. Yeah, part of the reason is the IPv4 space is valuable. The other reason is the conversion effort will cost a lot of money.

It's all about the money. And as there's a band-aid solution out there, people will use NAT until something breaks. After that, knowing human nature, they'll cobble together another workaround, like I've seen in some networks, NAT behind NAT behind even more NAT. And yeah, those networks do break, quite often.

You pay the price up front to do it properly or continually pay to keep the bubble gum and string workaround just sustainable enough to get you to the next day. Seen too much of this. But this is what humans do.
 
If you read the article, it says people have chosen NAT. It's a band-aid solution. Even though the IETF has chosen not to standardize NAT in order to discourage it, people (corporations) have chosen to NAT. Yeah, part of the reason is the IPv4 space is valuable. The other reason is the conversion effort will cost a lot of money.

It's all about the money. And as there's a band-aid solution out there, people will use NAT until something breaks. After that, knowing human nature, they'll cobble together another workaround, like I've seen in some networks, NAT behind NAT behind even more NAT. And yeah, those networks do break, quite often.

You pay the price up front to do it properly or continually pay to keep the bubble gum and string workaround just sustainable enough to get you to the next day. Seen too much of this. But this is what humans do.
Reminds me of work. Lots of band aids to keep stuff going to minimize investment.

CDNs help minimize the route. And DNS helps the CDNs.

What is interesting is that Netflix is going to IPv6 on AWS because of private IPv4 exhaustion.

Also, with my dual stack network, I was able to send 1080p video on Teams today. This is a first.
 
Yesterday's podcast covering IPv6 was pretty bang on. Working with a number of "commercial-like" entities, none has plans to move to IPv6. They all say their reason is cost -- hardware cost and people cost. In one case we remove IPv6 support from the Linux kernel so that the network is purely IPv4.

IPv4 with NAT is a definite PITA when maintaining a firewall and NAT rules.

Our efforts to stretch IPv4 using whatever means available reminds me of our stretching the Intel architecture long past its best before date. We as humans have a tendency to stretch whatever technology we have to avoid putting in the effort for real long-term solutions. And, this is not just WRT computers but other technologies too. It's a human thing.