Please consider donating:


Getting connected to the internet over IPv6 using Juniper/screenos

It started snowing today, so I guessed it would be the perfect timing to write a quick and dirty howto on getting connected to the internet over IPv6, using a Juniper ssg5.  I’ll also discuss the easy steps to configure Windows and Linux clients for IPv6 and access to the internet.

Before looking at the steps & procedures, this is a view from our appartment, about 15 minutes ago.


Main configuration steps

  • register with a tunnel broker, set up heartbeat and set up the IPv6 over IPv4 tunnel
  • keep the tunnel alive
  • request a IPv6 subnet and make it available via the tunnel
  • configure Windows clients
  • configure Linux clients
  • deal with DNS resolution for IPv6 hosts


Get registered with a tunnel broker

Because not a lot of ISP’s offer native IPv6 routing towards the internet, we’ll use a tunnel broker service, which will allow us to tunnel IPv6 packets over IPv4 packets. You can find more information about IPv6 tunnel brokers on wikipedia.

In my example, I have registered for a tunnel with SixXS (  Once your request for a tunnel has been approved, you can set up the tunnel.

We need this tunnel so we can route IPv6 traffic between your clients and other IPv6 hosts on the internet, and vice versa. Without the tunnel, your options are limited, especially if you want to host servers/services on the IPv6 network etc.

Most (if not all) tunnel brokers offer software that can be installed on an individual client (AICCU client software), allowing you to set up the tunnel towards the broker and route your IPv6 subnet with that client.  But I wanted to make it more generic and use my SSG5 Juniper firewall to host the tunnel, so I can route my entire IPv6 subnet (see later) through the tunnel without using an AICCU client for routing.

That doesn’t mean that you don’t need an AICCU client. In fact, my ISP uses dynamic/DHCP assigned IP addresses, so I cannot register for a static tunnel. I will need to use some sort of heartbeat protocol to keep the tunnel up and re-establish the tunnel when my internet IP changes.

In my setup, I am using an AICCU client, but only for heartbeat. We’ll come to that in a minute.

After registering your tunnel (in my case with, you will get the tunnel information, usually containing at least the following items : SixXS IPv6, Your IPv6, SixXS IPv4 and Tunnel Type. As indicated above, because I don’t have a static IP, I needed to register a heartbeat tunnel.

The “SixXS IPv6” address indicates the IPv6 pop IP address inside the tunnel. The “Your IPv6” address indicates your IPv6 address in the tunnel. These addresses are only used to set up the tunnel. You cannot use these addresses for hosts behind the tunnel. You’ll have to register a subnet with your tunnel broker in order to get an entire subnet of usable and routable IPv6 addresses that are routed via your tunnel.

The SixXS IPv4 address will be the target address of your tunnel.  So the tunnel will be set up between your own public IP address (provided by your own ISP) and this IPv4 address (at SixXS)

Let’s assume the following parameters :

SixXS IPv6         : 2001:6f8:001:001::1/64
Your IPv6          : 2001:6f8:001:001::2/64
SixXS IPv4         :
Tunnel Type        : Dynamic (heartbeat)


Set up the heartbeat

Before doing anything else, I have set up the AICCU client on a Windows host. The Juniper screenOS does not support the heartbeat protocol, so I will be used an aiccu client to keep the tunnel alive. 

First, download the aiccu client. The client I’m using is aiccu-2006-07-23-windows-gui.exe

Launch the client, fill out your tunnel information (username, password, etc) and see if you can connect. Make sure to set “Behind NAT” if you are behind NAT, and to enable “Auto Enable”


Next, register the application as a service  (aiccu-2006-07-23-windows-gui.exe /i) or use some other script to ensure that, when this host is up, the tunnel is up as well.

Note : you can do the same thing on a linux host as well. You’ll have to create a .conf file, specify the same parameters, and see if it connects.

If the tunnel aiccu client is running, you should see that your tunnel state is set to Heartbeat and the Last Alive timestamp gets updated (for SixXS users : look on their website)



Register a IPv6 subnet

Before we can set up the tunnel on ScreenOS and use it to route traffic, we need to register our own IPv6 subnet, so we can use addresses from this subnet for our local hosts.

When you have registered your tunnel (and when the tunnel is approved) you will get something like this :

  PoP Name     : bebru01 (de.easynet [AS4589])
  Subnet IPv6  : 2001:6f8:1430::/48
  Routed to    : 2001:6f8:001:001::2/64
  Your IPv4    : heartbeat

As you can see, this subnet (in my case 2001:6f8:1430::/48) will be routed towards my end of the tunnel (2001:6f8:001:001::2/64).



Create the tunnel on Juniper ScreenOS

We have already set up the tunnel using the aiccu client, but we’ll only use that aiccu client for the heartbeat, not for routing.  The idea is to use the Juniper ssg firewall to provide the routing towards the tunnel (and to route incoming requests from external IPv6 hosts back to your own subnet).  The windows host that is running the aiccu client is just part of my private IPv4 network and that will not change. 

You’ll need 3 interfaces to set this up : 1 public interface (the interface that has the ISP assigned public IP address), 1 private interface (either an interface that is already used for your LAN, or a new dedicated interface if you want to separate IPv4 and IPv6 traffic), and one tunnel interface (a virtual interface that will be used for setting up the tunnel towards the tunnel broker and the route IPv6 traffic into.

Let’s assume that eth0/0 is the public interface, eth0/4 is a dedicated private interface, and tunnel.1 is the tunnel interface.

Since I’m going to use eth0/4 as a dedicated interface for IPv6, I’m also going to create a separate zone for this. After all, any IPv6 host from your subnet behind this interface can reachable over the internet. There is no NAT involved, only routing. So if you want to keep things secured, I would strongly recommend created a dedicated interface and setting up a new zone.

In my setup, the zone that holds my public interface is called “Public”. (= “Untrust’” zone in most default setups”).  We will need to bind the tunnel interface to this zone.  The eth0/4 will act as default gateway for the hosts in my own IPv6 subnet, so we’ll need to set an IPv6 address from this subnet to this interface.  In theory, you can use the entire /48 network, but that would be overkill. A /64 subnet would be more than big enough, so we’ll subnet the/48 network into /64 networks first, and use IPv6 addresses from one of the subnets for now.  I’ll use 2001:6f8:1430::1/64 as IPv6 address for the private eth0/4 interface.  By the way, you can find an excellent subnet calculator  at

Before you can use IPv6, you’ll need to enable IPv6 first, and reboot the firewall

set envar ipv6=yes

You’ll notice, after the reboot, that the “ANY” policy elements are now gone. “ANY” is now replaced with “ANY-IPv4”, and a new “ANY-IPv6” was added.

After the reboot, set up the zones and interfaces

#create a new zone set zone name PublicIPv6 #assign eth0/4 to the new zone set interface eth0/4 zone PublicIPv6 #set interface mode set interface eth0/4 ipv6 mode "router" # set the IPv6 address of this interface to a IPv6 IP address in the subnet that was assigned to you (not the tunnel, use subnet Ip) set interface eth0/4 ipv6 ip 2001:6f8:1430::1/64 set interface eth0/4 ipv6 enable set interface eth0/4 mode route

set interface ethernet0/4 ipv6 nd nud
set interface ethernet0/4 ipv6 nd dad-count 0

#create a tunnel interface set interface tunnel.1 zone Public #bind tunnel interface to the public interface set interface tunnel.1 ip unnumbered interface ethernet0/0 set interface "tunnel.1" ipv6 mode "host" set interface "tunnel.1" ipv6 enable set interface tunnel.1 tunnel encap ip6in4 manual #connect the tunnel to your IPv6 tunnel broker pop IP address set interface tunnel.1 tunnel local-if ethernet0/0 dst-ip set interface tunnel.1 mtu 1480 set interface tunnel.1 ipv6 nd nud set interface tunnel.1 ipv6 nd dad-count 0 #set up the public interface set interface eth0/0 ipv6 mode "host" #assign Your IPv6 address to this interface set interface eth0/0 ipv6 ip 2001:6f8:001:001::2/64 set interface eth0/0 ipv6 enable set interface ethernet0/0 ipv6 nd nud

Note : SixXS will attempt to ping your public interface in order to verify that it can still access your end of the tunnel. This means that you will need to allow incoming ping on your public interface.  Add the IPv4 address of the broker to the list of manager-ip and enable ping on eth0/0 :

set admin manager-ip
set interface ethernet0/0 ip manageable
set interface ethernet0/0 manage ping

The interfaces and tunnel are now ready. If you look at the tunnel.1 interface state, it should say “link up”

ssg5-1-> get int tunnel.1
Interface tunnel.1:
  description tunnel.1
  number 20, if_info 1768, if_index 1, mode route
  link up
  ipv6 is enable/operable, host mode.
  ipv6 operating mtu 1480, learned mtu 0
  ipv6 Interface-ID: 000000004e157114
  ipv6 fe80::4e15:7114/64, link local, PREFIX
  ipv6 ff02::1:ff15:7114, solicited-node scope
  vsys Root, zone Public, vr trust-vr
  admin mtu 1480, operating mtu 1480, default mtu 1500
  *ip  unnumbered, source interface ethernet0/0
  *manage ip
  pmtu-v4 disabled, pmtu-v6 enabled(1480), 
  ping disabled, telnet disabled, SSH disabled, SNMP disabled
  web disabled, ident-reset disabled, SSL disabled

  OSPF disabled  BGP disabled  RIP disabled  RIPng disabled  mtrace disabled
  PIM: not configured  IGMP not configured
  NHRP disabled
  bandwidth: physical 0kbps, configured egress [gbw 0kbps mbw 0kbps]
             configured ingress mbw 0kbps, current bw 0kbps
             total allocated gbw 0kbps
tunnel: local ethernet0/0, remote
  encap: IP6IN4_MANUAL (2)
  keep-alive: off, interval 10(using default), threshold 3(using default)
      status: last send 0, last recv 0
Number of SW session: 8024, hw sess err cnt 0


Route traffic towards the tunnel

Now you need to route your IPv6 traffic towards the tunnel. This will ensure your IPv6 hosts can use eth0/4 as default gateway, and that IPv6 traffic is sent into the tunnel.

We need 2 commands to do this : One for ‘all traffic’, and one specific host route, needed to reach the SixXS IPv6 IP address (the other end of the tunnel) :

set route ::/0 interface tunnel.1 gateway :: preference 20
set route 2001:6f8:001:001::1/128 interface tunnel.1 gateway :: preference 20

On the firewall, you should now be able to ping the SixXS IPv6 address :

ping 2001:6f8:001:001::1
Type escape sequence to abort

Sending 5, 100-byte ICMP Echos to 2001:6f8:001:001::1, timeout is 1 seconds 
Success Rate is 100 percent (5/5), round-trip time min/avg/max=18/30/73 ms


Set up Windows clients behind the Juniper firewall : static IP

Both Windows 2008 and Vista seem to more or less support IPv6 out of the box, so I’ll use these Operating Systems in this post as example. You can set up IPv6 on XP and 2003 as well, but you’ll need to enable IPv6 first and use netsh CLI commands to set up the IP addresses.

On 2008/Vista, you can edit the IPv6 settings by editing the properties of the network connection, enabling IPv6 and editing the IP settings.

The hosts that need to be able to be IPv6 enabled and need to be able to route to the IPv6 internet via the tunnel, need to be connected to eth0/4. They will use the IPv6 address as default gateway. So if you want to set static IPv6 2001:6f8:1430::3 (/64) to a Windows 2008 host, this is what you would have to do :



Don’t worry about DNS yet. Save the settings and see if you can access other IPv6 hosts, and that other IPv6 hosts can reach you.

You will need to create a new IPv6 policy. So if you want to allow ping from your subnet towards the internet, and to allow hosts on the internet to connect to you, this is what you need to to :

eth0/4 is in zone PublicIPv6, and the tunnel interface is in the Public zone (or “Untrust” in a default setup), so we need a policy between those 2 zones :

#allow outbound traffic
set policy from PublicIPv6 to Public any any ping permit
#allow incoming traffic
set policy from Public to PublicIPv6 any any ping permit

From your windows host, try to ping the SixXS IPv6 tunnel IP address. This will ensure your tunnel works and IPv6 routing works as well :

C:\>ping -6 2001:6f8:001:001::1

Pinging 2001:6f8:001:001::1 from 2001:6f8:1430::3 with 32 bytes of data:
Reply from 2001:6f8:001:001::1: time=27ms
Reply from 2001:6f8:001:001::1: time=19ms
Reply from 2001:6f8:001:001::1: time=18ms
Reply from 2001:6f8:001:001::1: time=18ms

Ping statistics for 2001:6f8:001:001::1:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 18ms, Maximum = 27ms, Average = 20ms

See if hosts on the internet can ping you. On a regular IPv4 host, navigate to, enter the public IPv6 address of your Windows host (2001:6f8:1430::3) and hit the “Ping IPv6” button

You should get 4 replies :


This proves that the tunnel works, and all traffic gets routed correctly.


Set up Windows clients behind the Juniper firewall : dynamic IP (RA or DHCP)

If you don’t need/want to assign static IPv6 addresses, you can use router advertisements (RA) or DHCP to configure your clients.

The easiest way to set up dynamic assignment is to use RA

set interface ethernet0/4 ipv6 ra link-mtu
unset interface ethernet0/4 ipv6 ra link-address
set interface ethernet0/4 ipv6 ra preference high
set interface ethernet0/4 ipv6 ra transmit

Change the static IP of your windows host to “dynamically assigned” IP and you’ll notice that it will have received a dynamic address within your subnet.

Routing towards the internet should work right away.

You can also using DHCPv6 if you want to, but RA will do the trick just fine.


Set up Linux client behind the Juniper firewall : dynamic IP using RA

On Linux (I’ll use Fedora Core 9), this is what you need to do in order to set up IPv6 :





(make sure not to set BOOTPROTO to DHCP, or RA assignment won’t work)

Reboot the host and your Linux host should have received an IPv6 IP address from your own IP subnet


Set up Linux client behind the Juniper firewall : static IP

Make sure /etc/sysconfig/network contains the “NETWORKING_IPV6=yes” statement

Edit /etc/sysconfig/network-scripts/ifcfg-eth1 and use the following 2 statements to specify a static IPv6 IP :

Example :
Show IPv6 routing table on Linux :
route -n -A inet6

Kernel IPv6 routing table
Destination                                 Next Hop                                Flags Metric Ref    Use Iface
2001:6f8:1430::/64                          ::                                      U     256    1        0 eth0    
fe80::/64                                   ::                                      U     256    0        0 eth0 
::/0                                        2001:6f8:1430::1                        UG    1      50       0 eth0    
::1/128                                     ::                                      U     0      0        1 lo      
2001:6f8:1430::/128                         ::                                      U     0      0        1 lo      
2001:6f8:1430::4/128                        ::                                      U     0      21       1 lo      
fe80::/128                                  ::                                      U     0      0        1 lo      
fe80::/128                                  ::                                      U     0      0        1 lo      
fe80::20c:29ff:fe94:6f4d/128                ::                                      U     0      0        1 lo      
fe80::20c:29ff:fe94:6f57/128                ::                                      U     0      3        1 lo      
ff00::/8                                    ::                                      U     256    0        0 eth0 


What about DNS ?

If you have hosts that are configured for both IPv6 and IPv4, then name resolution should work as long as the IPv4 DNS server can resolve hostnames into IPv6 addresses.  This means that a DNS query for an AAAA record must resolve into an IPv6 address. Of course, there are not an awfull lot of IPv6 DNS entries available yet.  You should be able, though, to resolve the following hostnames into IPv4 and IPv6 addresses : (that’s right, this blog)

You can test the resolution using nslookup (which should show both the A record and the AAAA record)


Non-authoritative answer:
Addresses:  2001:4860:0:1001::68


Your ISP should be able to handle this resolution. If not, perhaps you should consider using the opendns DNS servers.  If you now connect with your multi-stack (IPv4 and IPv6) hosts to these websites, the browser/OS should query for an A record (IPv4 host record); and if the record was found, it will attempt to find the AAAA record as well. If an AAAA record is found, the browser will attempt to connect to the Ipv6 address. If you connect to my blog, you should see your IPv6 IP address at the bottom of the homepage, indicating that you are using the IPv6 address

So far so good, but what if you only use IPv6 on your hosts (and not both IPv4 and IPv6) ?  You won’t be able to connect to an IPv4 DNS server to resolve hostnames.

You may try to use the IPv6 NS servers at ripe (but I’m not sure if that is a good idea), or you can set up a multi-stack host in your own network, acting as DNS server, configured to forward all requests to your ISP (or opendns) DNS servers. That way, you can configure your local IPv6 only hosts to connect to the IPv6 IP address of your local DNS server (which will forward requests over IPv4 to the ISP or opendns), and name resolution will work as well.

I have configured 2001:6f8:1430::3 as a DNS server, and this machine also has an IPv4 IP address and gateway. The DNS server will forward requests to opendns.

When I try to use this server as DNS server in Linux, this is what you should get :

[user@mylinux /]# ifconfig eth0
eth0      Link encap:Ethernet  HWaddr 00:0C:29:C5:1E:1F  
          inet6 addr: 2001:6f8:1430:0:20c:29ff:fec5:1e1f/64 Scope:Global
          inet6 addr: fe80::20c:29ff:fec5:1e1f/64 Scope:Link
          RX packets:26188 errors:1 dropped:2 overruns:0 frame:0
          TX packets:20944 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:17151695 (16.3 MiB)  TX bytes:2237737 (2.1 MiB)
          Interrupt:18 Base address:0x1400

[user@mylinux /]# nslookup
> set q=aaaa
Server:         2001:6f8:1430::3
Address:        2001:6f8:1430::3#53

Non-authoritative answer: canonical name =       has AAAA address 2001:4860:0:1001::68

You can configure DNS on Linux by editing /etc/sysconfig/network-scripts/ifcfg-eth0

add a line that says

DNS1=ipv6_ip_of_your_DNS_server (so in my case, this is DNS1=2001:6f8:1430::3)

Save the file, run “service network restart” and it should work

© 2008 – 2021, Peter Van Eeckhoutte (corelanc0d3r). All rights reserved.

Comments are closed.

Corelan Training

We have been teaching our win32 exploit dev classes at various security cons and private companies & organizations since 2011

Check out our schedules page here and sign up for one of our classes now!


Want to support the Corelan Team community ? Click here to go to our donations page.

Want to donate BTC to Corelan Team?

Your donation will help funding server hosting.

Corelan Team Merchandise

You can support Corelan Team by donating or purchasing items from the official Corelan Team merchandising store.

Protected by Copyscape Web Plagiarism Tool

Corelan on Slack

You can chat with us and our friends on our Slack workspace:

  • Go to our facebook page
  • Browse through the posts and find the invite to Slack
  • Use the invite to access our Slack workspace
  • Categories