{"id":499,"date":"2021-12-20T01:18:11","date_gmt":"2021-12-20T01:18:11","guid":{"rendered":"https:\/\/mfdutra.com\/blog\/?p=499"},"modified":"2025-09-18T23:09:38","modified_gmt":"2025-09-18T23:09:38","slug":"linux-ipv6-and-att","status":"publish","type":"post","link":"https:\/\/mfdutra.com\/blog\/2021\/12\/20\/linux-ipv6-and-att\/","title":{"rendered":"Linux, IPv6 and AT&#038;T"},"content":{"rendered":"\n<p>If you have a Linux router and AT&amp;T Gigabit fiber, you may want to have all your VLANs addressed with IPv6. This is assuming you set up the AT&amp;T modem to do IP passthrough, so you have an actual IPv4 address in your router.<\/p>\n\n\n\n<!--more-->\n\n\n\n<h2 class=\"wp-block-heading\">WAN Setup<\/h2>\n\n\n\n<p>First and foremost, your router needs to speak IPv6 to the world. You need to accept AT&amp;Ts router advertisement, so you can set up your IPv6 address using <a href=\"https:\/\/en.wikipedia.org\/wiki\/IPv6#Stateless_address_autoconfiguration_(SLAAC)\">SLAAC<\/a>.<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:100%\">\n<pre class=\"wp-block-code\"><code>echo 2 &gt; \/proc\/sys\/net\/ipv6\/conf\/att0\/accept_ra<\/code><\/pre>\n<\/div>\n<\/div>\n\n\n\n<p>As you want to be a router, you need to enable forwarding for both v4 and v6:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>echo 1 &gt; \/proc\/sys\/net\/ipv4\/ip_forward\necho 1 &gt; \/proc\/sys\/net\/ipv6\/conf\/all\/forwarding<\/code><\/pre>\n\n\n\n<p>I named the WAN interface <code>att0<\/code> and the LAN interface <code>home0<\/code>.<\/p>\n\n\n\n<p>You should see something like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ ip addr show att0\n2: att0: &lt;BROADCAST,MULTICAST,UP,LOWER_UP&gt; mtu 1500 qdisc mq state UP group default qlen 1000\n    link\/ether 00:11:22:33:44:55 brd ff:ff:ff:ff:ff:ff\n    inet 99.1.2.3\/22 brd 99.1.3.255 scope global dynamic att0\n       valid_lft 2755sec preferred_lft 2755sec\n    inet6 2600:1:2:3::45\/128 scope global\n       valid_lft forever preferred_lft forever\n    inet6 2600:4:5:6:7:8:9:10\/64 scope global dynamic mngtmpaddr\n       valid_lft 3350sec preferred_lft 3350sec\n    inet6 fe80::1:2:3:4\/64 scope link\n       valid_lft forever preferred_lft forever<\/code><\/pre>\n\n\n\n<p>With everything working, a ping6 to Google should work:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ ping6 -n -c 1 google.com\nPING google.com(2607:f8b0:4005:802::200e) 56 data bytes\n64 bytes from 2607:f8b0:4005:802::200e: icmp_seq=1 ttl=117 time=6.04 ms\n\n--- google.com ping statistics ---\n1 packets transmitted, 1 received, 0% packet loss, time 0ms\nrtt min\/avg\/max\/mdev = 6.041\/6.041\/6.041\/0.000 ms<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">LAN Setup<\/h2>\n\n\n\n<p>To request prefixes for your internal VLANs, you will ask a prefix delegation (PD) via DHCPv6. Some ISPs, like Comcast, allow you to request a \/60 block, so you can chop it yourself. AT&amp;T doesn&#8217;t allow that, but they do allow requesting multiple \/64s, which has the same effect at the end.<\/p>\n\n\n\n<p>On Debian\/Ubuntu, install the package <code>wide-dhcpv6-client<\/code>.<\/p>\n\n\n\n<p>Your <code>\/etc\/wide-dhcpv6\/dhcp6c.conf<\/code> will look like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>interface att0 {\n  send ia-pd 0;\n  send ia-pd 1;\n  send ia-pd 2;\n  send ia-pd 3;\n  send ia-na 0;\n  send rapid-commit;\n};\n\nid-assoc pd 0 {\n  prefix ::\/64 infinity;\n\n  prefix-interface home0.2 {\n    sla-len 0;\n    sla-id 0;\n  };\n};\n\nid-assoc pd 1 {\n  prefix ::\/64 infinity;\n\n  prefix-interface home0.3 {\n    sla-len 0;\n    sla-id 0;\n  };\n};\n\nid-assoc pd 2 {\n  prefix ::\/64 infinity;\n\n  prefix-interface home0.4 {\n    sla-len 0;\n    sla-id 0;\n  };\n};\n\nid-assoc pd 3 {\n  prefix ::\/64 infinity;\n\n  prefix-interface home0 {\n    sla-len 0;\n    sla-id 0;\n  };\n};\n\nid-assoc na {\n};<\/code><\/pre>\n\n\n\n<p>As you can see, I use <meta charset=\"utf-8\"><code>send ia-pd<\/code> multiple times with a different ID. Then later I associate each PD to a different interface. The order doesn&#8217;t matter.<\/p>\n\n\n\n<p>If everything worked, <code>ip -6 addr<\/code> should show all interfaces addressed correctly.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Addressing your clients<\/h2>\n\n\n\n<p>So far, your internal clients have no idea your network can speak IPv6. You need to advertise your prefixes to them. That&#8217;s a job for the package <code>radvd<\/code>.<\/p>\n\n\n\n<p>Your <code>\/etc\/radvd.conf<\/code> will look like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>interface home0.2\n{\n   AdvSendAdvert on;\n   prefix ::\/64\n   {\n      AdvValidLifetime 900;\n      AdvPreferredLifetime 900;\n   };\n   RDNSS 2001:4860:4860::8888 2001:4860:4860::8844 {};\n};\n\ninterface home0.3\n{\n   AdvSendAdvert on;\n   prefix ::\/64\n   {\n      AdvValidLifetime 900;\n      AdvPreferredLifetime 900;\n   };\n   RDNSS 2001:4860:4860::8888 2001:4860:4860::8844 {};\n};\n\ninterface home0.4\n{\n   AdvSendAdvert on;\n   prefix ::\/64\n   {\n      AdvValidLifetime 900;\n      AdvPreferredLifetime 900;\n   };\n   RDNSS 2001:4860:4860::8888 2001:4860:4860::8844 {};\n};\n\ninterface home0\n{\n   AdvSendAdvert on;\n   prefix ::\/64\n   {\n      AdvValidLifetime 900;\n      AdvPreferredLifetime 900;\n   };\n   RDNSS 2001:4860:4860::8888 2001:4860:4860::8844 {};\n};<\/code><\/pre>\n\n\n\n<p>You pretty much repeat the same thing over and over for each interface. RDNSS in my example is announcing the Google&#8217;s DNS servers, which are the IPv6 version of 8.8.8.8 and 8.8.4.4.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Firewall<\/h2>\n\n\n\n<p>Do not filter ICMPv6 on your input and forward chains, unless you know what you are doing. ICMP is a crucial part of IPv6.<\/p>\n\n\n\n<p>For DHCPv6 work, you need to accept UDP datagrams on ports 546 and 547.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Security<\/h2>\n\n\n\n<p>Once you address all your internal clients, they will all have a valid IPv6 address and are able to receive traffic directly from the Internet. You probably don&#8217;t want that, so you need to set up some firewall to prevent undesired incoming traffic.<\/p>\n\n\n\n<p>This is a simple example with NFTables, only showing the forward chain:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>table inet filter {\n  chain forward {\n    type filter hook forward priority 0; policy drop;\n\n    ct state related,established accept\n    iifname {home0.2, home0.3} oifname att0 accept\n\n    ip6 nexthdr ipv6-icmp iifname att0 icmpv6 type {1,2,3,4,128,129} accept\n  }\n}<\/code><\/pre>\n\n\n\n<p>That&#8217;s all!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you have a Linux router and AT&amp;T Gigabit fiber, you may want to have all your VLANs addressed with IPv6. This is assuming you set up the AT&amp;T modem to do IP passthrough, so you have an actual IPv4 address in your router.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[25],"tags":[],"class_list":["post-499","post","type-post","status-publish","format-standard","hentry","category-tech","entry"],"_links":{"self":[{"href":"https:\/\/mfdutra.com\/blog\/wp-json\/wp\/v2\/posts\/499","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mfdutra.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mfdutra.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mfdutra.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mfdutra.com\/blog\/wp-json\/wp\/v2\/comments?post=499"}],"version-history":[{"count":10,"href":"https:\/\/mfdutra.com\/blog\/wp-json\/wp\/v2\/posts\/499\/revisions"}],"predecessor-version":[{"id":520,"href":"https:\/\/mfdutra.com\/blog\/wp-json\/wp\/v2\/posts\/499\/revisions\/520"}],"wp:attachment":[{"href":"https:\/\/mfdutra.com\/blog\/wp-json\/wp\/v2\/media?parent=499"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mfdutra.com\/blog\/wp-json\/wp\/v2\/categories?post=499"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mfdutra.com\/blog\/wp-json\/wp\/v2\/tags?post=499"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}