With global IPv6 routing, every single host has its own global unicast IPv6 address (GUA). No NAT anymore. No dirty tricks between hosts and routers. Great. Security is made merely by firewalls and policies. Site-to-site VPNs between partners can be build without address conflicts. Great again!
However, one problem to consider is the proper IPv6 routing via site-to-site VPNs since both sides now can reach each other even without a VPN. This was (mostly) not true with IPv4 in which both partners heavily relied on private RFC 1918 addresses that were not routable in the Internet. If specific IPv6 traffic should flow through a VPN but does actually traverse the Internet, it would be easy for a hacker to eavesdrop this traffic, leading to a security issue!
The following principles should be realized properly to assure that IPv6 traffic is never routed through the mere Internet when a site-to-site VPN tunnel is in place. Even in a failure of that tunnel. The principles can be applied to any IPv6 tunnels between partners, remote sites, home offices, etc., as long as the other site has its own global unicast IPv6 address space. (For VPNs in which a sub-prefix from the headquarters prefix is routed to a remote site, the situation behaves different. This article focuses on the routing between different IPv6 adress spaces.)
IPv6 Site-to-Site VPN Principles
On both sites of the VPN tunnel, the following steps must be accomplished:
- Static and permanent (!) route to the other site through VPN: For route-based VPNs, the static route through the tunnel should be “permanent”, i.e., should remain in the routing table even if the VPN is not established. Otherwise, in case of a VPN error, new connections could take the default route directly to the Internet. This principle might be problematic with policy-based VPNs. In such cases (if the policy-vpn has precedence over the routing table), a static route to the remote site subnet into the Null0 interface can be set.
- Unicast Reverse Path Forwarding (uRPF): If the static and permanent route is set and the remote site sends packets through the Internet, these IPv6 packets come from the untrust interface and will be discarded because they should only come in from the VPN tunnel interface.
- Explicit policy from “trust -> untrust” that denies traffic to the remote site: If someone accidentally deletes the static route, traffic would be routed directly through the Internet. With this deny policy, it would be blocked at the firewall before it leaves it. (Another option would be to “reject” the traffic, i.e., send an ICMP unreachable back to the sender. This would help troubleshooting the issue.) Note that a policy from “trust -> vpn” must be set to allow traffic through the VPN at all.
- Explicit policy from “untrust -> trust” that denies traffic from the remote site: If not an explicit “deny any any” is already set, this rule helps to block incoming traffic if the remote site has not implemented the preceding steps correctly.
All four points at-a-glance:
Some notes:
- Of course, a policy from “trust -> vpn” that allows certain traffic must be in place, too. But this should be the case anyway, because otherwise the VPN would not work. Similarly, a policy from “vpn -> trust”, if needed.
- With static IPv6 addresses/prefixes at the remote site, certain allow policy from “untrust -> trust” with limitations of the source IPv6 addresses of the remote site would be ok, if ony secured protocols (such as https, ssh, ftps, …) are used. However, if it was decided to use a site-to-site VPN tunnel, this should not be the case anymore.
- It is necessary to have the deny policies in place to not only rely on proper routing. Security must be made at a security stage (policy) and not at the network layer (routing)! [Similar to: Why NAT has nothing to do with Security!]
Example
The following paragraphs show an example of these principles with two Juniper ScreenOS firewalls. I used a site-to-site VPN that is established over IPv4 but routes IPv6 traffic. This is the lab:
Before VPN
Before the site-to-site VPN tunnel was configured, the remote office could reach the headquarter directly via the Internet. The following traceroute output is made from a Windows PC in the remote office, pinging into the headquarter. Note that this IPv6 connection traverses directly through the Internet:
C:\Users\Johannes Weber>tracert -d lx.webernetz.net Routenverfolgung zu jw-nb12.webernetz.net [2003:51:6012:110::9] über maximal 30 Hops: 1 1 ms 1 ms 1 ms 2003:50:aa0a:3584::1 2 3 ms 2 ms 2 ms 2003:0:1301:4205::1 3 4 ms 6 ms 6 ms 2003:0:1301:4238::2 4 6 ms 7 ms 7 ms 2003:0:1302:403::1 5 4 ms 3 ms 4 ms 2003:0:1302:403::2 6 5 ms 4 ms 4 ms 2003:51:6012::2 7 5 ms 5 ms 5 ms 2003:51:6012:110::9 Ablaufverfolgung beendet.
A route lookup to the destination IPv6 address on the router/firewall looks like that: It uses the default route (in my case through interface eth0/0):
fd-we-fw01-> get vrouter trust-vr route ip 2003:51:6012:110::9 Dest for 2003:51:6012:110::9 -------------------------------------------------------------------------------------- trust-vr : => ::/0 (id=1) via fe80::462b:3ff:fe19:300 (vr: trust-vr) Interface ethernet0/0 , metric 1
With VPN
Now, a site-to-site VPN between the two firewalls is established. The following screenshots document the static routes and policies on both Juniper SSG firewalls:
Now, the same traceroute command reveals the route through the encrypted VPN tunnel. (The second hop is not answering, because I am only using link-local IPv6 addresses on the tunnel interfaces):
C:\Users\Johannes Weber>tracert -d lx.webernetz.net Routenverfolgung zu jw-nb12.webernetz.net [2003:51:6012:110::9] über maximal 30 Hops: 1 1 ms 1 ms 1 ms 2003:50:aa0a:3584::1 2 * * * Zeitüberschreitung der Anforderung. 3 6 ms 6 ms 7 ms 2003:51:6012:110::9 Ablaufverfolgung beendet.
The routing table lookup on the firewall on the remote site now shows the usage of the tunnel interface:
fd-we-fw01-> get vrouter trust-vr route ip 2003:51:6012:110::9 Dest for 2003:51:6012:110::9 -------------------------------------------------------------------------------------- trust-vr : => 2003:51:6012:110::/64 (id=14) via :: (vr: trust-vr) Interface tunnel.1 , metric 1
Broken VPN -> Still Permanent Route
In this example, the VPN could not establish a connection. But due to the permanent route, traffic is not exposed in the Internet since it is still routed to the tunnel interface. Of course, the connections did not work. (Tested from the remote site.)
C:\Users\Johannes Weber>tracert -d lx.webernetz.net Routenverfolgung zu jw-nb12.webernetz.net [2003:51:6012:110::9] über maximal 30 Hops: 1 1 ms 1 ms 1 ms 2003:50:aa0a:3584::1 2 * * * Zeitüberschreitung der Anforderung. 3 * * * Zeitüberschreitung der Anforderung. 4 * * * Zeitüberschreitung der Anforderung. 5 * * * Zeitüberschreitung der Anforderung. 6 * * * Zeitüberschreitung der Anforderung. 7 * * * Zeitüberschreitung der Anforderung. 8 ^C
Deleted Route -> Still Policy
In this example someone misconfigured the routing table and deleted the specific route through the VPN. No traffic traverses the Internet because of principle number three, which still has the “deny” policy from trust -> untrust. (Tested from the remote site.)
Deleted Remote Policy -> Still Headquarter Policy
In this example, the route and all policies on the remote site were deleted. Now the connection worked until the headquarter firewall through the Internet, but was blocked there due to principle 2 and 4:
C:\Users\Johannes Weber>tracert -d lx.webernetz.net Routenverfolgung zu jw-nb12.webernetz.net [2003:51:6012:110::9] über maximal 30 Hops: 1 1 ms 1 ms 1 ms 2003:50:aa0a:3584::1 2 3 ms 3 ms 3 ms 2003:0:1301:4205::1 3 7 ms 4 ms 5 ms 2003:0:1301:4238::2 4 6 ms 18 ms 16 ms 2003:0:1302:403::1 5 3 ms 3 ms 3 ms 2003:0:1302:403::2 6 * * * Zeitüberschreitung der Anforderung. 7 * * * Zeitüberschreitung der Anforderung. 8 * * * Zeitüberschreitung der Anforderung. 9 * * * Zeitüberschreitung der Anforderung. 10 * * * Zeitüberschreitung der Anforderung. 11 ^C
Principle 2 (uRPF) on the headquarter worked, because it did not expect traffic from the remote site’s IPv6 subnet from the untrust interface, and therefore blocked it:
But even after I deleted the route on the headquarter firewall into the remote site (uRPF won’t block connections anymore), the connections were blocked due to principle number 4, which is the untrust -> trust DENY policy:
Conclusion
With this four principles/recommendations it is possible to ensure that IPv6 traffic which should only traverse through a secure VPN connection won’t ever traverse through the Internet, even in case of a VPN failure. They furthermore ensure, that security is not made only at the network layer (routing), but at a firewall stage (policy).