Finagling stable ipv6 addresses using Comcast residential SLAAC?

Hi,

I am pretty new to VyOS and ipv6. I’m trying to run a couple AD DCs (for “fun”) behind VyOS using a comcast residential gateway. VyOS is set to use the DCs as system-dns and then forward to them on requests (simple). This seems to work great for ipv4.

In the past I’ve had issues with my ipv6 config changing based on the ISP, which borks my DC’s dns+dhcp configurations when assigning them based on track interface addresses on my last router (OPNsense).

I had originally thought I needed autoconf in dhcpv6-options to get an ipv6 address on WAN, but I finally managed to get a /128 address after much frustration from dhcpv6 by turning off autoconfig on bond0 (before this, bond0 would not acquire/generate anything ipv6 addresses except a single link-local address). I also assigned bond0 a MAC address that was the same from my WAN NIC eth1, which was working with ipv6 previously. I’m not sure if assigning a MAC to bond0 had an effect on acquiring a /128 address on WAN/bond0.

Here are the addresses it generated (obscured, but similar):
2001:558:600a:c3:b0b5:dead:beef:6fff/128 (WAN) to 2601:603:beef:dead::/64 (LAN)

The only way I’ve been able to get my DCs to work with ipv6 is when I have a full /128 gateway address to point them at, and then /128 addresses to point at each other for dns. In addition, any gateway/router I’ve used (VyOS or otherwise) doesn’t appear to have an ipv6 connection to the internet unless it’s assigned a /128 address, either.

On the DCs, the /128 addresses always appear to follow the same pattern: The first two hextets are always the same (e.g.) 2601:603:xxx:xxx: + link-local (minus the fe80:: at the start).

Here’s a full example:
2601:603:xxx:xxx:7d2e:beef:dead:4ff/128 – where the 7d2e:beef:dead:4ff === link-local for that DC (minus fe80::)

the xxx:xxx: part is what appears to change, AFAIK the 2601:603: at the start always stays the same, even after re-allocation, and of course the link-local part is always the end of the /128 address.

tl;dr

So I’m wondering, if I want my DCs to be “stable” and have non-changing static ipv6 addresses (questions):

I’ve tried assigning addresses such as 2601:603::1/64, 2601:603::2/64 in the past and it hasn’t worked, is there something I am missing here?

Is there a way I can configure the DCs so they will use any two “middle” hextets that are generated? Something like:
2601:603::7d2e:beef:dead:4ff/128 ?

If that’s not possible, can I assign the first 4 hextets via eui-64 in VyOS? E.g.: 2601:603:dead:beef::/64?

Lastly, is this just the wrong way to go about this?

Should I instead look at setting up NPTv6 (fc00::/64, etc.)? I’d been avoiding it because it adds another layer of complexity, but I am really not sure if I am doing any of this the “right” way.

Resources:

config
carl@gateway:~$ show configuration
firewall {
    all-ping enable
    broadcast-ping enable
    config-trap disable
    ipv6-name OUTSIDE-6-IN {
        default-action drop
        rule 10 {
            action accept
            state {
                established enable
                related enable
            }
        }
        rule 20 {
            action accept
            protocol ipv6-icmp
        }
    }
    ipv6-name OUTSIDE-6-LOCAL {
        default-action drop
        rule 10 {
            action accept
            state {
                established enable
                related enable
            }
        }
        rule 20 {
            action accept
            description "Allow DHCPv6"
            destination {
                address fe80::/10
                port 546
            }
            protocol udp
            source {
                address fe80::/10
            }
        }
        rule 21 {
            action accept
            description "Allow MLD"
            protocol icmpv6
            source {
                address fe80::/10
            }
        }
        rule 22 {
            action accept
            limit {
                burst 1
                rate 1000/second
            }
            protocol icmpv6
        }
    }
    ipv6-receive-redirects disable
    ipv6-src-route disable
    ip-src-route disable
    log-martians enable
    name OUTSIDE-IN {
        default-action drop
        description "Allow traffic from WAN"
        rule 10 {
            action accept
            state {
                established enable
                related enable
            }
        }
        rule 20 {
            action accept
            destination {
                address xxx.xxx.0.999
                port 00000
            }
            protocol tcp_udp
            state {
                new enable
            }
        }
        rule 30 {
            action accept
            destination {
                address xxx.xxx.xxx.1
                port 99999
            }
            protocol tcp
            state {
                new enable
            }
        }
    }
    name OUTSIDE-LOCAL {
        default-action drop
        rule 10 {
            action accept
            state {
                established enable
                related enable
            }
        }
        rule 20 {
            action accept
            icmp {
                type-name echo-request
            }
            protocol icmp
            state {
                new enable
            }
        }
    }
    receive-redirects disable
    send-redirects enable
    source-validation disable
    syn-cookies enable
    twa-hazards-protection disable
}
interfaces {
    bonding bond0 {
        address dhcp
        address dhcpv6
        description WAN
        dhcpv6-options {
            pd 0 {
                interface eth0 {
                    address 0
                    sla-id 0
                }
            }
        }
        firewall {
            in {
                ipv6-name OUTSIDE-6-IN
                name OUTSIDE-IN
            }
            local {
                ipv6-name OUTSIDE-6-LOCAL
                name OUTSIDE-LOCAL
            }
        }
        ip {
        }
        ipv6 {
            address {
            }
        }
        lacp-rate slow
        mac 01:23:45:67:89:49
        member {
            interface eth1
            interface eth2
        }
        min-links 0
        mode 802.3ad
    }
    ethernet eth0 {
        address xxxx.xxx.xxx.1/24
        description LAN
        dhcpv6-options {
        }
        hw-id 01:23:45:67:89:ea
    }
    ethernet eth1 {
        hw-id 01:23:45:67:89:49
    }
    ethernet eth2 {
        hw-id 01:23:45:67:89:48
    }
    loopback lo {
    }
}
nat {
    destination {
        rule 10 {
            description "Port forward: https to xxxx.xxx.xxx.0:99999 for Ookla Speed Test"
            destination {
                port 99999
            }
            inbound-interface bond0
            protocol tcp
            translation {
                address xxxx.xxx.xxx.1
            }
        }
        rule 20 {
            description "Port forward: http(s) to xxxx.xxx.xxx.75:00000 for brand X web server"
            destination {
                port 00000
            }
            inbound-interface bond0
            protocol tcp_udp
            translation {
                address xxxx.xxx.xxx.75
            }
        }
    }
    source {
        rule 100 {
            outbound-interface bond0
            source {
                address xxxx.xxx.xxx.0/24
            }
            translation {
                address masquerade
            }
        }
    }
}
protocols {
    static {
        route 0.0.0.0/0 {
            interface bond0 {
            }
            next-hop xxxx.xxx.xxx.1 {
            }
        }
    }
}
service {
    dns {
        dynamic {
            interface eth1 {
                service blah {
                yadda
                }
                use-web {
                    derpider
                }
            }
        }
    }
    mdns {
    }
    router-advert {
        interface eth0 {
        }
    }
    ssh {
        access-control {
            allow {
                user carl
            }
        }
        ciphers up-yomama
        listen-address xxxx.xxx.xxx.1
        mac hmac-fuk-yaal
        port 1234
    }
}
system {
    config-management {
        commit-revisions 100
    }
    console {
        device ttyS0 {
            speed 115200
        }
    }
    domain-name man-cave.net
    domain-search {
        domain man-cave.net
    }
    host-name gateway
    ipv6 {
    }
    login {
        user carl {
            authentication {
                encrypted-password ****************
                public-keys beepboop {
                    key ****************
                    type iamrobot
                }
            }
        }
    }
    name-server xxxx.xxx.xxx.2
    name-server xxxx.xxx.xxx.3
    name-servers-dhcp eth0
    ntp {
        server xxxx.xxx.xxx.2 {
        }
        server xxxx.xxx.xxx.3 {
        }
    }
    option {
        ctrl-alt-delete reboot
        reboot-on-panic
        ssh-client {
            source-address xxxx.xxx.xxx.1
        }
    }
    syslog {
        global {
            facility all {
                level info
            }
            facility protocols {
                level debug
            }
        }
    }
}
commands
set firewall all-ping 'enable'
set firewall broadcast-ping 'enable'
set firewall config-trap 'disable'
set firewall ipv6-name OUTSIDE-6-IN default-action 'drop'
set firewall ipv6-name OUTSIDE-6-IN rule 10 action 'accept'
set firewall ipv6-name OUTSIDE-6-IN rule 10 state established 'enable'
set firewall ipv6-name OUTSIDE-6-IN rule 10 state related 'enable'
set firewall ipv6-name OUTSIDE-6-IN rule 20 action 'accept'
set firewall ipv6-name OUTSIDE-6-IN rule 20 protocol 'ipv6-icmp'
set firewall ipv6-name OUTSIDE-6-LOCAL default-action 'drop'
set firewall ipv6-name OUTSIDE-6-LOCAL rule 10 action 'accept'
set firewall ipv6-name OUTSIDE-6-LOCAL rule 10 state established 'enable'
set firewall ipv6-name OUTSIDE-6-LOCAL rule 10 state related 'enable'
set firewall ipv6-name OUTSIDE-6-LOCAL rule 20 action 'accept'
set firewall ipv6-name OUTSIDE-6-LOCAL rule 20 description 'Allow DHCPv6'
set firewall ipv6-name OUTSIDE-6-LOCAL rule 20 destination address 'fe80::/10'
set firewall ipv6-name OUTSIDE-6-LOCAL rule 20 destination port '546'
set firewall ipv6-name OUTSIDE-6-LOCAL rule 20 protocol 'udp'
set firewall ipv6-name OUTSIDE-6-LOCAL rule 20 source address 'fe80::/10'
set firewall ipv6-name OUTSIDE-6-LOCAL rule 21 action 'accept'
set firewall ipv6-name OUTSIDE-6-LOCAL rule 21 description 'Allow MLD'
set firewall ipv6-name OUTSIDE-6-LOCAL rule 21 protocol 'icmpv6'
set firewall ipv6-name OUTSIDE-6-LOCAL rule 21 source address 'fe80::/10'
set firewall ipv6-name OUTSIDE-6-LOCAL rule 22 action 'accept'
set firewall ipv6-name OUTSIDE-6-LOCAL rule 22 limit burst '1'
set firewall ipv6-name OUTSIDE-6-LOCAL rule 22 limit rate '1000/second'
set firewall ipv6-name OUTSIDE-6-LOCAL rule 22 protocol 'icmpv6'
set firewall ipv6-receive-redirects 'disable'
set firewall ipv6-src-route 'disable'
set firewall ip-src-route 'disable'
set firewall log-martians 'enable'
set firewall name OUTSIDE-IN default-action 'drop'
set firewall name OUTSIDE-IN description 'Allow traffic from WAN'
set firewall name OUTSIDE-IN rule 10 action 'accept'
set firewall name OUTSIDE-IN rule 10 state established 'enable'
set firewall name OUTSIDE-IN rule 10 state related 'enable'
set firewall name OUTSIDE-IN rule 20 action 'accept'
set firewall name OUTSIDE-IN rule 20 destination address 'xxx.xxx.xxx.75'
set firewall name OUTSIDE-IN rule 20 destination port '00000'
set firewall name OUTSIDE-IN rule 20 protocol 'tcp_udp'
set firewall name OUTSIDE-IN rule 20 state new 'enable'
set firewall name OUTSIDE-IN rule 30 action 'accept'
set firewall name OUTSIDE-IN rule 30 destination address 'xxx.xxx.xxx.1'
set firewall name OUTSIDE-IN rule 30 destination port '99999'
set firewall name OUTSIDE-IN rule 30 protocol 'tcp'
set firewall name OUTSIDE-IN rule 30 state new 'enable'
set firewall name OUTSIDE-LOCAL default-action 'drop'
set firewall name OUTSIDE-LOCAL rule 10 action 'accept'
set firewall name OUTSIDE-LOCAL rule 10 state established 'enable'
set firewall name OUTSIDE-LOCAL rule 10 state related 'enable'
set firewall name OUTSIDE-LOCAL rule 20 action 'accept'
set firewall name OUTSIDE-LOCAL rule 20 icmp type-name 'echo-request'
set firewall name OUTSIDE-LOCAL rule 20 protocol 'icmp'
set firewall name OUTSIDE-LOCAL rule 20 state new 'enable'
set firewall receive-redirects 'disable'
set firewall send-redirects 'enable'
set firewall source-validation 'disable'
set firewall syn-cookies 'enable'
set firewall twa-hazards-protection 'disable'
set interfaces bonding bond0 address 'dhcp'
set interfaces bonding bond0 address 'dhcpv6'
set interfaces bonding bond0 description 'WAN'
set interfaces bonding bond0 dhcpv6-options pd 0 interface eth0 address '0'
set interfaces bonding bond0 dhcpv6-options pd 0 interface eth0 sla-id '0'
set interfaces bonding bond0 firewall in ipv6-name 'OUTSIDE-6-IN'
set interfaces bonding bond0 firewall in name 'OUTSIDE-IN'
set interfaces bonding bond0 firewall local ipv6-name 'OUTSIDE-6-LOCAL'
set interfaces bonding bond0 firewall local name 'OUTSIDE-LOCAL'
set interfaces bonding bond0 ip
set interfaces bonding bond0 ipv6 address
set interfaces bonding bond0 lacp-rate 'slow'
set interfaces bonding bond0 mac '01:23:45:67:89:49'
set interfaces bonding bond0 member interface 'eth1'
set interfaces bonding bond0 member interface 'eth2'
set interfaces bonding bond0 min-links '0'
set interfaces bonding bond0 mode '802.3ad'
set interfaces ethernet eth0 address 'xxx.xxx.xxx.1/24'
set interfaces ethernet eth0 description 'LAN'
set interfaces ethernet eth0 dhcpv6-options
set interfaces ethernet eth0 hw-id '01:23:45:67:89:ea'
set interfaces ethernet eth1 hw-id '01:23:45:67:89:49'
set interfaces ethernet eth2 hw-id '01:23:45:67:89:48'
set interfaces loopback lo
set nat destination rule 10 description 'Port forward: https to xxx.xxx.xxx.0:99999 for Ookla Speed Test'
set nat destination rule 10 destination port '99999'
set nat destination rule 10 inbound-interface 'bond0'
set nat destination rule 10 protocol 'tcp'
set nat destination rule 10 translation address 'xxx.xxx.xxx.1'
set nat destination rule 20 description 'Port forward: http(s) to xxx.xxx.xxx.75:00000 for Milestone XProtect'
set nat destination rule 20 destination port '00000'
set nat destination rule 20 inbound-interface 'bond0'
set nat destination rule 20 protocol 'tcp_udp'
set nat destination rule 20 translation address 'xxx.xxx.xxx.75'
set nat source rule 100 outbound-interface 'bond0'
set nat source rule 100 source address 'xxx.xxx.xxx.0/24'
set nat source rule 100 translation address 'masquerade'
set protocols static route 0.0.0.0/0 interface bond0
set protocols static route 0.0.0.0/0 next-hop xxx.xxx.xxx.1
set service mdns
set service router-advert interface eth0
set service ssh access-control allow user 'carl'
set service ssh ciphers 'junkwarden'
set service ssh listen-address 'xxx.xxx.xxx.1'
set service ssh mac 'thegipper'
set service ssh port '22'
set system config-management commit-revisions '100'
set system console device ttyS0 speed '115200'
set system domain-name 'man-cave.net'
set system domain-search domain 'man-cave.net'
set system host-name 'shakeshack'
set system ipv6
set system login user carl authentication cleartext-password 'murrr'
set system login user carl authentication public-keys ... carl@shakeshack'
set system login user carl authentication public-keys secure type 'abicus'
set system name-server 'xxx.xxx.xxx.2'
set system name-server 'xxx.xxx.xxx.3'
set system name-servers-dhcp 'eth0'
set system ntp server xxx.xxx.xxx.2
set system ntp server xxx.xxx.xxx.3
set system option ctrl-alt-delete 'reboot'
set system option reboot-on-panic
set system option ssh-client source-address 'xxx.xxx.xxx.1'
set system syslog global facility all level 'info'
set system syslog global facility protocols level 'debug'

Thanks much for the help

Edit: I feel kind of dumb for not thinking of this until after writing this ginormous post, but if the link-local addresses haven’t been changing, why don’t I use those? I know they’re supposed to change every now and again, but I’ve never seen it (at least not on the DCs…)

Hello @AveryFreeman

If you have a dynamic prefix it will change 2601: 603: xxxx: xxxx :. If you configure the address 2601: 603: dead: beef :: / 64, the provider will not have a route to such a prefix. There are two solutions to this problem:

  1. Your ISP provides you with a static IPv6 prefix.
  2. Use NPTv6. Then you can statically configure the internal network.
    You choose one of the options that suits you.

Is there no 3rd option?

What if eth0 (lan) is set to EUI-64 address?

This is calculated from MAC address, it appears to be working, but I have no idea for how long:

carl@shakeshack # show interfaces
 bonding bond0 {
     address dhcp
     address dhcpv6
     description WAN
     dhcpv6-options {
         pd 0 {
             interface eth0 {
                 address 0
                 sla-id 0
             }
         }
     }
     firewall {
         in {
             ipv6-name OUTSIDE-6-IN
             name OUTSIDE-IN
         }
         local {
             ipv6-name OUTSIDE-6-LOCAL
             name OUTSIDE-LOCAL
         }
     }
     ip {
     }
     ipv6 {
         address {
         }
     }
     lacp-rate slow
     mac xx:xx:xx:xx:xx:49
     member {
         interface eth1
         interface eth2
     }
     min-links 0
     mode 802.3ad
 }
 ethernet eth0 {
     address 192.168.1.1/24
     description LAN
     dhcpv6-options {
     }
     hw-id xx:xx:xx:xx:xx:ea
     ipv6 {
         address {
             eui64 2601:603:dead:beef:250:56FF:beef:beef/64
         }
     }
 }
 ethernet eth1 {
     hw-id xx:xx:xx:xx:xx:49
 }
 ethernet eth2 {
     hw-id xx:xx:xx:xx:xx:48
 }
 loopback lo {
 }

and then name servers are set to DCs, which have static ipv6 addresses, also calculated via EUI-64 pattern:

carl@shakeshack # show system name-server
Possible completions:
   192.168.1.2
   192.168.1.3
   2601:603:dead:beef:c970:2c7b:b0b5:c0fe
   2601:603:dead:beef:7d2e:98f7:b0b5:add0

If this were to change as per ISP release/renew, which part of the address is volatile? The first 4 hextets? Just trying to understand.

Thank you

Hello,
You can configure RA:

set service router-advert interface eth0 other-config-flag
set service router-advert interface eth0 prefix ::/64

Exactly what will not change in the address is 2601
If the provider has received pool /32 then 2601: 603: will not change. The ISP then provides customers with the prefixes /48 or /64.
2601:603:xxxx::/48
2601:603:xxxx:xxxx::/64