

I got an email where someone asked whether I know how to change the link-local IPv6 addresses on a FortiGate similar to any other network/firewall devices. He could not find anything about this on the Fortinet documentation nor on Google.
Well, I could not find anything either. What’s up? It’s not new to me that you cannot really configure IPv6 on the FortiGate GUI, but even on the CLI I couldn’t find anything about changing this link-local IPv6 address from the default EUI-64 based one to a manually assigned one. Hence I opened a ticket at Fortinet. It turned out that you cannot *change* this address at all, but that you must *add* another LL address which will be used for the router advertisements (RA) after a reboot (!) of the firewall. Stupid design!
Again and again and again I am not happy at all with the IPv6 implementation on the FortiGates. Too many bugs and features missing, while everything is too complicated to configure. (Have a look at my Fortinet feature requests.) For the following tests I used a FortiGate FG-90D with firmware v5.6.5 build1600 (GA).
Before I touched the config the state of IPv6 was the following. Have a look at the “fg-trust” interface with its link-local address in line 12:
fg # diagnose ipv6 address list dev=31 devname=vsys_fgfm flag=P scope=254 prefix=128 addr=::1 dev=29 devname=vsys_ha flag=P scope=254 prefix=128 addr=::1 dev=28 devname=fg-server flag=P scope=0 prefix=64 addr=2003:de:2016:220::1 dev=27 devname=fg-trust2 flag=P scope=0 prefix=64 addr=2003:de:2016:211::1 dev=26 devname=fg-trust flag=P scope=0 prefix=64 addr=2003:de:2016:210::1 dev=24 devname=root flag=P scope=254 prefix=128 addr=::1 dev=5 devname=wan1 flag=P scope=0 prefix=64 addr=2003:de:2016::2 dev=6 devname=wan2 flag=P scope=253 prefix=10 addr=fe80::a5b:eff:fea1:8360 dev=28 devname=fg-server flag=P scope=253 prefix=10 addr=fe80::a5b:eff:fea1:835e dev=27 devname=fg-trust2 flag=P scope=253 prefix=10 addr=fe80::a5b:eff:fea1:835e dev=26 devname=fg-trust flag=P scope=253 prefix=10 addr=fe80::a5b:eff:fea1:835e dev=5 devname=wan1 flag=P scope=253 prefix=10 addr=fe80::a5b:eff:fea1:835f
The configuration at this point was:
config system interface edit "fg-trust" set vdom "root" set ip 192.168.210.1 255.255.255.0 set allowaccess ping https ssh set role lan set snmp-index 5 config ipv6 set ip6-address 2003:de:2016:210::1/64 set ip6-allowaccess ping https ssh set ip6-send-adv enable config ip6-prefix-list edit 2003:de:2016:210::/64 set autonomous-flag enable set onlink-flag enable next end end set interface "internal1" set vlanid 210 next end
And a Linux machine got the following routing table, in which the default route had a gateway of
fe80::a5b:eff:fea1:835e:
weberjoh@jw-vm05-Ubuntu-Test-3:~$ ip -6 r s 2003:de:2016:210::/64 dev ens32 proto kernel metric 256 expires 2591699sec pref medium fe80::/64 dev ens32 proto kernel metric 256 pref medium default via fe80::a5b:eff:fea1:835e dev ens32 proto ra metric 1024 expires 1499sec pref medium
To add a link-local address you need the “config ip6-extra-addr” submenu. I added the quite simple
fe80::1/64address to that interface, that is:
config system interface edit fg-trust config ipv6 config ip6-extra-addr edit fe80::1/64 next end end end
Now, in order to have the router advertisements sent from this newly created link-local address, you have to reboot the firewall! Come on Fortinet, you need a complete reboot for this?!? (Note that the support ticket told me to disable the “ip6-send-adv” before adding the LL address, and enabling it again after that. But this was not successful. At this point the RAs were still sent from the old EUI-64 based LL address.) Hence a reboot:
execute reboot
After this changes and the reboot the added link-local IPv6 was present (line 6):
fg # diagnose ipv6 address list dev=31 devname=vsys_fgfm flag=P scope=254 prefix=128 addr=::1 dev=29 devname=vsys_ha flag=P scope=254 prefix=128 addr=::1 dev=28 devname=fg-server flag=P scope=0 prefix=64 addr=2003:de:2016:220::1 dev=27 devname=fg-trust2 flag=P scope=0 prefix=64 addr=2003:de:2016:211::1 dev=26 devname=fg-trust flag=SP scope=253 prefix=64 addr=fe80::1 dev=26 devname=fg-trust flag=P scope=0 prefix=64 addr=2003:de:2016:210::1 dev=24 devname=root flag=P scope=254 prefix=128 addr=::1 dev=5 devname=wan1 flag=P scope=0 prefix=64 addr=2003:de:2016::2 dev=6 devname=wan2 flag=P scope=253 prefix=10 addr=fe80::a5b:eff:fea1:8360 dev=28 devname=fg-server flag=P scope=253 prefix=10 addr=fe80::a5b:eff:fea1:835e dev=27 devname=fg-trust2 flag=P scope=253 prefix=10 addr=fe80::a5b:eff:fea1:835e dev=26 devname=fg-trust flag=P scope=253 prefix=10 addr=fe80::a5b:eff:fea1:835e dev=5 devname=wan1 flag=P scope=253 prefix=10 addr=fe80::a5b:eff:fea1:835f
The complete configuration section for this interface looked like this:
config system interface edit "fg-trust" set vdom "root" set ip 192.168.210.1 255.255.255.0 set allowaccess ping https ssh set role lan set snmp-index 5 config ipv6 set ip6-address 2003:de:2016:210::1/64 set ip6-allowaccess ping https ssh config ip6-extra-addr edit fe80::1/64 next end set ip6-send-adv enable config ip6-prefix-list edit 2003:de:2016:210::/64 set autonomous-flag enable set onlink-flag enable next end end set interface "internal1" set vlanid 210 next end
And the Linux machine (after a reboot as well) got the correct next hop for its default route:
weberjoh@jw-vm05-Ubuntu-Test-3:~$ ip -6 r s 2003:de:2016:210::/64 dev ens32 proto kernel metric 256 expires 2591853sec pref medium fe80::/64 dev ens32 proto kernel metric 256 pref medium default via fe80::1 dev ens32 proto ra metric 1024 expires 1653sec pref medium
Accordingly I could verify that the router advertisements were sent from my added link-local address
fe80::1:
That’s it. I am not happy with this approach from Fortinet in “changing” the link-local address. On other firewalls such as the Palo Alto Networks firewall you can clearly change the behaviour of the interface ID portion, and it even works without rebooting the firewall:
Cheers.
Featured image “Buy Local” by Mariano Mantel is licensed under CC BY-NC 2.0.
IPv6 brings us enough addresses until the end of the world. Really? Well… No. There was an interesting talk at RIPE77 called “The Art of Running Out of IPv6 Addresses” by Benedikt Stockebrand that concludes that we will run out of IPv6 addresses some day.
Luckily Palo Alto Networks has already added one feature to expand the IPv6 address space by making them case sensitive. That is: you can now differentiate between upper and lower case values “a..f” and “A..F”. Instead of 16 different hexadecimal values you now have 22 which increases the IPv6 space from to about
. Here is how it works on the Palo Alto Networks firewall:
While the original RFC 4291 “IP Version 6 Addressing Architecture” declares IPv6 addresses to be 128 bits long, represented as hexadecimal values from 0..f, the case sensitive addressing scheme has 6 more values, that is:
0123456789 abcdef ABCDEF
This increases the overall IPv6 address space with a factor of 16384. Wow! From to
.
Palo Alto Networks has implemented this feature with PAN-OS 8.1.0. I am running a PA-220 with PAN-OS 8.1.6 in my lab. You can enable this feature at Device -> Setup -> Session -> Session Settings -> Enable IPv6 Case Sensitive Addressing:
After that you can commit layer 3 (sub-)interface IPv6 addresses that are only different in their lower/upper case notation of the abcdef/ABCDEF values:
Looking at the routing table via the CLI you can additionally verify this working setup (refer to lines 15-18):
weberjoh@pa> show routing route afi ipv6 flags: A:active, ?:loose, C:connect, H:host, S:static, ~:internal, R:rip, O:ospf, B:bgp, Oi:ospf intra-area, Oo:ospf inter-area, O1:ospf ext-type-1, O2:ospf ext-type-2, E:ecmp, M:multicast VIRTUAL ROUTER: default (id 1) ========== destination nexthop metric flags age interface next-AS ::/0 2001:470:1f0b:1024::1 10 A S ethernet1/2 2001:470:1f0b:1024::/64 2001:470:1f0b:1024::2 0 A C ethernet1/2 2001:470:1f0b:1024::2/128 :: 0 A H 2001:470:765b::/64 2001:470:765b::1 0 A C ethernet1/5.224 2001:470:765b::1/128 :: 0 A H 2001:470:765b:abcd::/64 2001:470:765b:abcd::1 0 A C ethernet1/5.6 2001:470:765b:abcd::1/128 :: 0 A H 2001:470:765b:ABCD::/64 2001:470:765b:ABCD::1 0 A C ethernet1/5.7 2001:470:765b:ABCD::1/128 :: 0 A H total routes shown: 9
However, keep in mind that this will only work if your overall network infrastructure supports this case sensitive IPv6 addressing scheme as well.
Yes, we will run out of IPv6 addresses one day. Since any kind of NAT/NPT solution should be avoided completely, this case sensitivity of IPv6 addresses is a quite good and working approach. Nice to see that Palo Alto Networks has already implemented it.
Featured image “ABC” by Jeremy Brooks is licensed under CC BY-NC 2.0.
Everyone uses NTP, that’s for sure. But are you using it with authentication on your own stratum 1 servers? You should since this is the only way to provide security against spoofed NTP packets, refer to Why should I run own NTP Servers?. As always, Palo Alto has implemented this security feature in a really easy way, since it requires just a few clicks on the GUI. (Which again is much better than other solutions, e.g., FortiGate, which requires cumbersome CLI commands.) However, monitoring the NTP servers, whether authentication was successful or not, isn’t implemented in a good way. Here we go:
For this post I am using a PA-220 with PAN-OS 8.1.7. I am querying my Raspberry Pi w/ GPS and my Meinberg M200, both delivering NTP authentication [1, 2]. Funnily enough I can only share this single screenshot which shows everything you need to set up NTP authentication. :) It is at Device -> Setup -> Services:
Note that I am using two out of my three NTP servers, of course with different key IDs, because otherwise it wouldn’t work. (Though you actually can configure both NTP servers with the same key ID while using *different* keys, it won’t work. Hence you MUST use two different key IDs for each of them.)
However, though it was fairly easy to configure I am not completely happy about the monitoring of the NTP daemon. The system logs don’t tell that much: (Above the red line I configured my own NTP servers)
while the CLI command
show ntpat least reveals a status of “synched“, but not clearly whether the authentication took place:
weberjoh@pa> show ntp NTP state: NTP synched to ntp2.weberlab.de NTP server: ntp3.weberlab.de status: available reachable: yes authentication-type: symmetric key NTP server: ntp2.weberlab.de status: synched reachable: yes authentication-type: symmetric key
And I haven’t found any more debug logs. Hm.
Ok, so there is still some room for improvements. Likewise the number of NTP servers to configure, which should be 3 rather than 2 in order to spot a falsified timestamp delivered by one NTP server, which isn’t possible with just 2 servers at all.
Featured image “Waves” by Kacper Gunia is licensed under CC BY-NC 2.0.
My lab rack of 2019 consists of multiple Cisco routers and switches, as well as Juniper ScreenOS firewalls for routing purposes, a Palo Alto Networks firewall, a Juniper SRX firewall, a server for virtualization and some Raspberry Pis. That is: This rack can be used for basic Cisco courses such as CCNA or CCNP, or for even bigger BGP/OSPF or IPsec VPN scenarios since those ScreenOS firewalls are perfect routers as well. Of course, everything is IPv6 capable. Having some PoE-powered Raspberry Pis you can simulate basic client-server connections. A Juniper SA-2500 (aka Pulse Connect Secure) for remote accessing the Lab rounds things up.
I am just writing down a few thoughts on why I have “designed” the rack in that way. It’s basically a reminder for myself. ;)
Let’s have a look at the rack first. I ordered one with wheels for easy transport. Previously the devices were mounted into several 19″ racks in the data center, which was not that movable. ;D Now the rack can be used by any of my colleagues for test purposes. I am using 24 rack units while some are left free for the cables. On the back side, I have two power strips. All power cables disappear in the rack space.
These are the basic ideas about how to use this lab rack. Of course, everything can be changed. Again, a picture is worth a thousand words:
What’s missing?
Featured image “Colours and Casks” by Jens Comiotto-Mayer is licensed under CC BY 2.0.