0

I have a CentOS6 box which I've used as a NAT router for years, with /proc/sys/net/ipv4/ip_forward=1

I now have both an IPv4 address and an IPv6 address from Starlink, with inet6 addr: 2605:****:****:****:****:****:****:3660/64 Scope:Global. That seemed to magically appear even though I had IPv6 set to "ignore" in the NetworkManager GUI.

How can I get an IPv6 internet connection for other devices on my local network ?

I tried using NetworkManager to set both local and internet interfaces to "IPv6 Automatic" with no success. I assume I might be able to assign local addresses in the FD00 range and set /proc/sys/net/ipv6/conf/all/forwarding=1, i.e. NAT, but I thought I was supposed to get 64 global addresses for my devices.

2 Answers 2

0

I thought I was supposed to get 64 global addresses for my devices.

Yes, but that is less automatic than the host getting its own address. To get a /64 (or larger) routed to you, you need a DHCPv6-PD client to get the Prefix Delegation lease and to set up some address auto-configuration (e.g. radvd for SLAAC) on the LAN interface.

I don't know what PD-capable DHCPv6 clients are available on CentOS 6, but "WIDE DHCPv6 Client" used to be the popular one, and systemd-networkd might already have DHCPv6-PD in your version.

(Depending on ISP you might be able to get a PD lease for a whole /60 or /56. Individual interfaces still must be /64, but this would allow having several subnets.)

However: from what I remember about Starlink, its equipment in itself is the customer router which has obtained a /64 for you, and might not support providing further delegations to your own router. It's common with ISP equipment to not account for more than one subnet, just like how ISP-provided routers usually don't let you define static LAN routes even for IPv4 and force you to NAT internally.

and set /proc/sys/net/ipv6/conf/all/forwarding=1, i.e. NAT

That is absolutely not NAT. Do not confuse IP forwarding with NAT. Source NAT (address masquerading) is a separate step done after routing and forwarding (hence it usually going in the iptables 'postrouting' chain), while destination NAT (aka "port forwarding") is likewise a separate step that happens before routing.

In other words, NAT is performed by iptables modules, while routing even without NAT will require the forwarding=1 setting.

Side note: The per-interface forwarding sysctl has a different meaning in IPv6; it no longer controls actual forwarding but rather enables a few other "router behaviors". So you'll want net.ipv6.conf.all.forwarding=1, but net.ipv6.conf.WAN_IF.forwarding=0.

You can do NAT with IPv6 in the same way as IPv4 (using ip6tables SNAT or MASQUERADE actions), it's just not the "normal" way of doing things.

4
  • Per Starlink's website, they provide "One IPv6 /64 prefix for the customer’s wide area network (WAN), provisioned via Stateless Address Auto Configuration (SLAAC) for routers/firewalls using IPv6. One IPv6 /56 prefix for the customer’s local area network (LAN), provisioned to routers capable of issuing a DHCPv6-PD request". I have dhclient which has a -6 option but that's not running. Not sure if it's PD-capable. Commented Mar 10 at 1:49
  • dhclient -6 gets an IA_NA lease (a regular network address), you need to use the -P option to enable IA_PD (and probably other options to request a /56 if you want that as opposed to a single /64). Commented Mar 10 at 5:14
  • dhclient -P -6 doesn't seem to work; after allowing it in ip6tables I get " PRC: Lease failed to satisfy" starting it by hand. I can't seem to get it running from NetworkManager anyway despite it being in the scripts. I found an SRPM for wide-dhcpv6-20080615. That has more detailed logs and appears to work when started by hand, in that it says it got a /56 prefix with a lifetime of 300s. But while the example config says it will configure derived IPv6 prefixes on a local network, I don't see that. Commented Mar 12 at 1:44
  • I have some things running with wide-dhcpv6 and radvd, but there's no glue. I pasted the prefix from the dhcp6c logs into the radvd config. Would dhcp6-relay be a better option ? Commented Mar 12 at 18:52
0

I have this working now, though I have not yet set it up to happen at boot time.

Starlink offers a /64 IPv6 address, using Router Advertisements (RA). RA's are handled by the kernel, per /proc/sys/net/ipv6/conf/<interface>/accept_ra, documented in the kernel source Documentation/networking/ip-sysctl.txt. By default this is true, so that my computer got a global IPv6 address.

Starlink also offers a /56 prefix, but you have to ask for it by sending a "Solicit XID" ICMPv6 packet with an IA_PD option, typically from a DHCP client. To receive the replies, you need to allow dhcpv6-client packets, e.g. with ip6tables -I INPUT -p udp --dport 546 -j ACCEPT. I installed wide-dhcpv6 with the following config

interface eth7 {
  send ia-pd 0;
  request domain-name-servers;
  script "/etc/wide-dhcpv6/my-dhcp6c-script" ;
};

id-assoc pd {
  prefix-interface eth0 {
    sla-id 0;
    sla-len 8;
  };
};

The sla-id's must match.

My upstream interface is eth7, the local one eth0. This gives a global address to eth0. dhcp6c doesn't actually tell you the prefix, though, except with debugging turned on. It passes parameters such as domain-name-servers to an optional script. I modified dhcp6c so it would also pass the prefix and associated lifetimes.

I run radvd with a config file

interface eth0 {
  AdvSendAdvert on;
  MinRtrAdvInterval 30;
  MaxRtrAdvInterval 100;
  AdvDefaultLifetime 300;
  prefix 2605:xxxx:xxx:xx00::/64 {
    AdvOnLink on;
    AdvAutonomous on;
    AdvRouterAddr off;
    AdvValidLifetime 300;
    AdvPreferredLifetime 150;
  };
};

building that with my-dhcp6c-script to fill in the values for prefix and lifetime. With that running, devices on my local network get a global IPv6 address. They also get a default route to the link-local address on eth0, using the sla-id of 0.

For forwarding to work, it must be allowed in ip6tables. It must also be set in /proc/sys/net/ipv6/conf/all/forwarding. Normally, accept_ra is disabled if forwarding is enabled. Since kernel 2.6, an accept_ra of 2 allows it regardless, so I have net.ipv6.conf.all.forwarding=1 and net.ipv6.conf.eth7.accept_ra=2 in /etc/sysctl.conf, which sets them at boot time.

See patch for dhcp6c

See Starlink's article

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.