This article is to complete the previous one. I decided to write appart all things related to ipv6.


My ISP does not provide ipv6 yet, and the tunnel service I used before (Sixxs) is willing to close down. So I decided to use tunnelbroker from HE, which provide static configurations for OpenBSD with a gif(4) virtual interface, while Sixxs uses a dynamic system (You need an aiccu process to have the tunnel. It happens once in a while that the tunnel fails, without reason.).

I advice you to run the ipv6 certification from HE. It is quite easy and you have a nice T-shirt at the end telling the whole world about your status as an internet guru.

Yes, I am an IPv6 Sage.

I am once again to describe my installation and you can adapt it to your situation, using the previous tutorial or not.

A slice of reflexion

You have to, sort of, copy your configuration/topology from ipv4 to ipv6.

HE will give you automatically a /64. If you read my article about ipv6, so you know that your network is of minimal size: you cannot have sub-nets in it. If you have several sub-nets in ipv4 (Ethernet and Wifi separated), then you will have to do the same with ipv6. HE will give you a /48 if the server you registered your tunnel on has enough place while you request it.

On the router

Public address : gif0 - the tunnel

In order for your ipv6 tunnel to work, you need to have actual ipv4 connectivity on your router.

As soon as you are connected to tunnelbroker, servers statisctics are available here, to compare with the available servers on the new tunnel page.

So choose a server close to you, but not too much loaded if you need a /48.

In the field Ipv4 Endpoint, set your public routable ipv4 address. For example, in my case, it’s re0 on the Alix router: And voila, you should now have a tunnel with /64.

If needed, request for a /48 now.

The second tab on the tunnel page will provide you with a serie of command to activate your ipv6 connectivity.

You should not yet have any gif virtual interface. It will be gif0 to be created on the fly, with the /etc/hostname.gif0 that you have to create and edit.

For example, tunnelbroker gives me this command:

ifconfig gif0 tunnel
ifconfig gif0 inet6 alias 2001:470:1f1a:db::2 2001:470:1f1a:db::1 prefixlen 128
route -n add -inet6 default 2001:470:1f1a:db::1

Which gives, in hostname.gif0:

!ifconfig gif0 inet6    2001:470:1f1a:db::2 2001:470:1f1a:db::1 prefixlen 128
!route -n add -inet6 default 2001:470:1f1a:db::1

You just have to start it:

doas sh /etc/netstart gif0    

Try ping6:

stephane@alix:/home/stephane ping6
PING6 (2a00:1450:400f:804::2004): 24 data bytes
32 bytes from 2a00:1450:400f:804::2004, icmp_seq=0 hlim=50 time=92.946 ms
32 bytes from 2a00:1450:400f:804::2004, icmp_seq=1 hlim=50 time=93.678 ms
^C--- ping6 statistics ---
2 packets transmitted, 2 packets received, 0.0% packet loss
round-trip min/avg/max/std-dev = 92.946/93.312/93.678/0.366 ms

It is all good !

LAN addresses

You have to chose now how to address your lan. I have assigned my interfaces re2 and athn0 addresses such as:

re2     $prefix48:e2::
athn0   $prefix48:a0::

That way, connected devices’ addresses tell whether they are on Wifi or Ethernet (eth -> re2 -> e2 in the ipv6 addresse). It looks obvious or nothing, but it might be useful in the future for debugging, and it is the same work as $prefix48:1::, $prefix48:2::.

It is considered good practice to give the router the prefix address. But it is actually not mandatory. It is what I do.


inet6           2001:470:2099:e2::      64


You have to allow forwarding in the kernel. So in /etc/sysctl.conf:

net.inet6.ip6.forwarding=1      # 1=Permit forwarding (routing) of IPv6 packets
net.inet6.ip6.accept_rtadv=0    # 1=Permit IPv6 autoconf, 0=refuse autoconf

Forwarding in PF

It looks like you need to explicitly enable forwarding in pf.conf. I am going to check more.

Here, all packets arriving on the ipv6 internet (so coming from the ipv6 tunnel) to the web server itself are allowed to go through. The line can be adated easily to any other service (imap, git…), protocol (udp) or both (domain name service).

pass in on $intv6       proto tcp       from any to $blackblock_ipv6    port { https,www }


If you want to use NAT64, you need that in pf.conf:

# nat64
# found here :
pass in         quick   inet6 from any to 64:ff9b::/96 af-to inet from (egress:0) keep state rtable 0

Actually, Unbound will create out of the box a fake ipv6 (I show the setting below) for all queries without AAAA to answer. Your computer can then contacter the distant address in ipv6, without even be aware it’s a fake (out of the prefix used). It is the router itself that ensure linking.


Dnsmasq will act as Dhcpv6, local DNS and router-advertissement daemon (radvd). You will find the manual here, but I am going to describe the main plot.

The big thing is the dhcp-range option. I set here a segment from ::100 to ::1000 on each interface (constructor). Dnsmasq will use network configuration from the interface itself (address and netmask), to figure out the prefix and chose an address between the limits.

Ra-names will calculate the SLAAC autogenerated address of each machine doing an ipv4 dhcp request, and test it with a ping6. If the test works fine, the address is stored in the local DNS.

Slaac tells to the machines to use autogenerated address and Ra-stateless allows to have a dhcpv6 answering requests.

To sum up, I think these settings enable every possible machine or OS to connect. One can get addresses and/or DNS settings via dhcpv6 or router-advertissement or both.

Privacy extensions to ipv6 are not handled by Dnsmasq itself, but by the client machine, which pick up a random address in the network. It makes no trouble in itself, but it means Dnsmasq is not aware of it, meaning it may be a pain in the ass to debug, if you have any problem.

# If you want dnsmasq to listen for DHCP and DNS requests only on
# specified interfaces (and the loopback) give the name of the
# interface (eg eth0) here.
# Repeat the line for more than one interface.



# Set this (and domain: see below) if you want to have a domain
# automatically added to simple names in a hosts-file.

# Set the domain for dnsmasq. this is optional, but if it is set, it
# does the following things.
# 1) Allows DHCP hosts to have fully qualified domain names, as long
#     as the domain part matches this setting.
# 2) Sets the "domain" DHCP option thereby potentially setting the
#    domain of all systems configured by DHCP
# 3) Provides the domain part for "expand-hosts"



# Send DHCPv6 option for namservers as the machine running dnsmasq

On the main server


You need all configuration about ipv6. Nothing specific out of DNS64. Just don’t forget the specific listening addresses for unbound, coordonnated with Dnsmasq.

    verbosity: 0

    interface: ::1
    interface: 2001:470:2099:e2::3
    interface: fe80::be5f:f4ff:fe73:a7e0%re0
    do-ip6: yes
    do-udp: yes
    do-tcp: yes
    access-control: ::0/0 refuse
    access-control: ::1/128 allow
    access-control: fe80::/64 allow
    access-control: 2001:470:2099::/48 allow

    log-queries: no
    val-log-level: 2

    root-hints: "named.cache"

    module-config: "dns64 validator iterator"

    dns64-prefix: 64:FF9B::/96

    name: ""
    forward-addr: 2001:470:2099:e2::

    name: ""
    forward-addr: 2001:470:2099:e2::

    name: ""
    forward-addr: 2001:470:2099:e2::

One should notice the forward-zone, which will forward all local request to the router, so Dnsmasq.

Something else to notice is all the local network with prefix/48 should be in access-control: it means the local network can make DNS requests.

server adress: re0

The server is obviously set in static ip address.

I could have set as well the slaac address. You can set as many address as you want.


inet6           2001:470:2099:e2::2      64
inet6           2001:470:2099:e2::3      64


Hosts files on the router and the server itself should be the same, or almost, completed with the various static addresses.       localhost
::1             localhost

2001:470:2099:e2::2             blackblock                        blackblock                        unbound
2001:470:2099:e2::3             unbound                        alix
2001:470:2099:e2::              alix                        alix
2001:470:2099:a0::              alix

What is missing ?

There are still part of the OS that don’t talk ipv6. I think of spamd(8), which means I cannot announce an ipv6 mail server.