Home > Networking, SysAdmin > Configuring native IPv6 in pfSense firewall

Configuring native IPv6 in pfSense firewall

pfSense

Today, we’re going to talk about pfSense. A software stateful-firewall based on the excellent pf firewall in FreeBSD. It’s an easy to install from-ISO appliance.

From the pfSense website:

pfSense is a free, open source customized distribution of FreeBSD tailored for use as a firewall and router. In addition to being a powerful, flexible firewalling and routing platform, it includes a long list of related features and a package system allowing further expandability without adding bloat and potential security vulnerabilities to the base distribution. pfSense is a popular project with more than 1 million downloads since its inception, and proven in countless installations ranging from small home networks protecting a PC and an Xbox to large corporations, universities and other organizations protecting thousands of network devices.

pfSense is a nice piece of software, but the developers don’t seem to be very interested in integrating IPv6 support in the interface. Too bad, because IPv6 is hot and will replace IPv4 within the next few years. I’m not going to integrate IPv6 in the GUI of pfsense with this tutorial, but after following the instructions you will have a working IPv6 router/firewall with support for stateless autoconfiguration. The configuration is built from my own needs, so if it doesn’t match your expectations please add your features.

For this setup i use pfSense 1.2.3-RC1 which is out for quite a while and pretty stable in it’s use.

I’m not going to discuss the installation of pfSense. If you can’t install the pfSense ISO, you shouldn’t be doing IPv6 on it anyway :) . First of all, make sure you enable SSH in pfSense. You can find the feature at “System” > “Advanced”

Enable SSH on pfSense

After enabling, connect (via SSH) to the pfSense box. Ofcourse, if you’re sitting behind the box you can do it on the console also :) .

You will be presented a nice text menu:

*** Welcome to pfSense 1.2.3-RC1-pfSense on myFirewall ***

WAN*                     ->    bce0    ->    123.123.123.1
LAN*                     ->    bce1    ->    192.168.0.254

pfSense console setup
***********************
0)  Logout (SSH only)
1)  Assign Interfaces
2)  Set LAN IP address
3)  Reset webConfigurator password
4)  Reset to factory defaults
5)  Reboot system
6)  Halt system
7)  Ping host
8)  Shell
9)  PFtop
10)  Filter Logs
11)  Restart webConfigurator
12)  pfSense PHP shell
13)  Upgrade from console
14)  Disable Secure Shell (sshd)

We want to go to the CLI shell. Select 8.

On my box, i’m using Broadcom network interfaces. On FreeBSD these are named ‘bce0′ and ‘bce1′. You can find the respective names with the ‘ifconfig’ command. On my setup, bce0 is the outside interface and bce1 is the inside interface.
My setup is fully native-IPv6, which means that i’m not doing any tunnelling at all. On the outside interface, i have an IPv6 address from my provider’s /64 block he used for my connection. On the inside, i have  a /64 of IPv6 addresses which are publically reachable (global-unicast). Ofcourse i’m using fake addresses to prevent my firewall being bombed all-over :) .

Let’s say, these are my network variables :

  • The WAN IPv6 network is : 2001:4cb8:a95:1::/64
  • The WAN IPv6 address is : 2001:4cb8:a95:1::2
  • The WAN IPv6 default gateway is : 2001:4cb8:a95:1::1
  • The LAN IPv6 network is : 2001:4cb8:b95:1::/64
  • The LAN IPv6 address is : 2001:4cb8:b95:1::1

With this information, we’re going to create our boot-script to configure the interfaces and routing.

cd /usr/local/etc/rc.d
vi 00_config-ipv6-if.sh

#!/bin/sh
#
# IFOUT = outside interface
# IFIN = inside interface
# DFGW = default gateway
IFOUT="bce0"
IFIN="bce1"
DFGW="2001:4cb8:a95:1::1"

####### Configure the stuff

# Configure the interfaces
ifconfig $IFOUT inet6 alias 2001:4cb8:a95:1::2 prefixlen 64
ifconfig $IFIN inet6 alias 2001:4cb8:b95:1::1 prefixlen 64

# Set the default route
route -n add -inet6 default $DFGW

# Configure IPv6 forwarding
sysctl net.inet6.ip6.forwarding=1

# My /etc/rtadvd.conf looks like this
#
# bce1:\
#   :addrs#1:addr="2001:4cb8:b95:1::":prefixlen#64:tc=ether:
#
# Startup rtadvd
/usr/sbin/rtadvd -d -D -c /etc/rtadvd.conf $IFIN

Ok, that’s pretty much all there is to enable IPv6 and configure the static routing to the ISP.
Next, we need to change permissions on this file :

chmod 755 /usr/local/etc/rc.d/00_config-ipv6-if.sh

After bootup, IPv6 will be running on the pfSense box, but it won’t do a thing. This is because we need to change the filter (PF) also. This is going to be our next script.

cd /usr/local/etc/rc.d
vi 10_config-ipv6-pf.sh

#!/bin/sh
#
# IFOUT = outside interface
# IFIN = inside interface
# DFGW = default gateway
IFOUT="bce0"
IFIN="bce1"

####### Configure the stuff

# Configure PF
# pfSense puts it's rules in /tmp/rules.debug for debugging purposes after boot
# We will use these rules, add IPv6 additions, read the config with pfctl and
# disable and enable PF
cat /tmp/rules.debug | sed "/User-defined rules follow/{
p;s/.*/\
pass in quick on $IFIN inet6 from any to any\\
pass out quick on $IFIN inet6 from any to any\\
pass out quick on $IFOUT inet6 from any to any\\
pass quick proto ipv6-icmp from any to any\\
pass in on $IFOUT inet6 proto tcp from any to any port 22\\
/;}" > /tmp/rules.config-ipv6.txt

# Read the new PF configuration file
pfctl -f /tmp/rules.config-ipv6.txt
pfctl -d; pfctl -e

And change the permissions also:

chmod 755 /usr/local/etc/rc.d/10_config-ipv6-pf.sh

Finally, we need to configure the router advertisement daemon (rtadvd) to get stateful autoconfiguration to work.

vi /etc/rtadvd.conf

bce1:\
  :addrs#1:addr="2001:4cb8:b95:1::":prefixlen#64:tc=ether:

After rebooting the pfSense firewall (or run script 00 and 10) IPv6 will work on your box.
But.. when you change filter rules (or anything actually) in the GUI, the filter settings are overwritten and your IPv6 connectivity will break.
After some searching on the box, i noticed that after changing things in the GUI the function filter_configure_sync() is called and the rules will be flushed.
This function can be found in /etc/inc/filter.inc (line 78). In the function, there’s a hook to a plugin directory. When the function filter_configure_sync() is called, the function will look in the /usr/local/pkg/pf directory for scripts, which will be executed. This only happens if scripts end with “.sh” as the extension.
We will symlink the 10_config-ipv6-pf.sh script to this location to make it work.

ln -s /usr/local/etc/rc.d/10_config-ipv6-pf.sh /usr/local/pkg/pf/

Congratulation! You got yourself a working IPv6 setup.

If you want to know more ins and outs about IPv6, i suggest reading the book “Running IPv6″ by Iljitsch van Beijnum. You can find more information at http://runningipv6.net/

Share and Enjoy:
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  1. August 29th, 2009 at 20:05 | #1

    Respect!

    But then why using pfsense at all, if it seemingly is an obstacle for the implementation? By using such an ammunition you use to hack the core functionality of the pfsense, you would better take a naked freebsd as basis for a production ipv6 router and firewall (eg. there are no magic php scripts you have to fight with in the dark of your shell).

  2. September 1st, 2009 at 00:57 | #2

    I definitely agree with you on that. In my case that’s not a problem, but if you work in a big networking team where changes in the firewall / IPSEC / OpenVPN policy get applied almost every day this is not a good option. Not everyone is skilled enough to edit on the CLI although i wish everything was. Thanks for the respect.

  3. September 5th, 2009 at 02:53 | #3

    Thanks very much for the great post, I’ve stumbled upon it multiple times in my web travels! While it may be possible to go through all this trouble to get IPv6 tunnels working through pfSense, would it be possible to simply give pfSense a link-local IPv6 address?

    The reason I ask is because I don’t necessarily need outward IPv6 connectivity yet, but when configuring servers on the network it would be nice to be able to reach the gateway over IPv6 fabric only. In other words, I’d like to be able to turn off IPv4 completely and still have a fully functioning network and web access.

    How would that be done?

  4. September 17th, 2009 at 08:35 | #4

    rbressers: (this is my 2nd post to 2nd site like here)

    Great work :)

    But i have some few issues.. I am not an CLI guy of course..So this is my story..

    1st i cd /usr/local/etc/rc.d and vi 00_config-ipv6-if.sh and then i paste this:
    #!/bin/sh
    #
    # IFOUT = outside interface
    # IFIN = inside interface
    # DFGW = default gateway
    IFOUT=”vr0″
    IFIN=”dc0″
    DFGW=”2001:4cb8:a95:1::1″

    ####### Configure the stuff

    # Configure the interfaces
    ifconfig $IFOUT inet6 alias 2001:4cb8:a95:1::2 prefixlen 64
    ifconfig $IFIN inet6 alias 2001:4cb8:b95:1::1 prefixlen 64

    # Set the default route
    route -n add -inet6 default $DFGW

    # Configure IPv6 forwarding
    sysctl net.inet6.ip6.forwarding=1

    # My /etc/rtadvd.conf looks like this
    #
    # bce1:\
    # :addrs#1:addr=”2001:4cb8:b95:1::”:prefixlen#64:tc=ether:
    #
    # Startup rtadvd
    /usr/sbin/rtadvd -d -D -c /etc/rtadvd.conf $IFIN

    then i save..I type this after saving :

    chmod 755 /usr/local/etc/rc.d/00_config-ipv6-if.sh

    and reboot…

    I type this command:
    cd /usr/local/etc/rc.d
    vi 10_config-ipv6-pf.shI

    and paste this:

    #!/bin/sh
    #
    # IFOUT = outside interface
    # IFIN = inside interface
    # DFGW = default gateway
    IFOUT=”vr0″
    IFIN=”dc0″

    ####### Configure the stuff

    # Configure PF
    # pfSense puts it’s rules in /tmp/rules.debug for debugging purposes after boot
    # We will use these rules, add IPv6 additions, read the config with pfctl and
    # disable and enable PF
    cat /tmp/rules.debug | sed “/User-defined rules follow/{
    p;s/.*/\
    pass in quick on $IFIN inet6 from any to any\\
    pass out quick on $IFIN inet6 from any to any\\
    pass out quick on $IFOUT inet6 from any to any\\
    pass quick proto ipv6-icmp from any to any\\
    pass in on $IFOUT inet6 proto tcp from any to any port 22\\
    /;}” > /tmp/rules.config-ipv6.txt

    # Read the new PF configuration file
    pfctl -f /tmp/rules.config-ipv6.txt
    pfctl -d; pfctl -e

    Save the code and i type this: chmod 755 /usr/local/etc/rc.d/10_config-ipv6-pf.sh

    Then i type this : vi /etc/rtadvd.conf

    and paste the code:

    bce1:\
    :addrs#1:addr=”2001:4cb8:b95:1::”:prefixlen#64:tc=ether:

    then save and reboot…

    After reboot i type this: ln -s /usr/local/etc/rc.d/10_config-ipv6-pf.sh /usr/local/pkg/pf/

    then reboot again..

    I go to workstation and do “ifconfig” linux or “ipconfig” for windows..

    Nothing happen really.. All i see is 192.168.4.245 ip address when i do “ipconfig”.. I dont see ip like this:

    2001:4cb8:b95:1

    My config is:

    192.168.4.0/24
    subnet mask: 255.255.255.0
    Gateway: 192.168.4.1
    WAN: isp

    I tried to change the number 64 into 24 but no luck..
    # Configure the interfaces
    ifconfig $IFOUT inet6 alias 2001:4cb8:a95:1::2 prefixlen 64 changed to 24
    ifconfig $IFIN inet6 alias 2001:4cb8:b95:1::1 prefixlen 64 changed to 24
    ….

    I use “ipconfig on windows workstations but i dont see this kind of ipv6 ips..

    jigp
    1.2.2

  5. Gary Barclay
    November 27th, 2009 at 18:41 | #5

    You could also try m0n0wall. This has IPv6 out of the box.

  6. December 14th, 2009 at 22:05 | #6

    Hi,
    Thanks!! Your investigations helped me out of a big problem ;-) I have a m0n0wall/pfSense combination and had the problem that pfSense blocked IPv6 between the (bridged) LAN and WLAN. Developers are sadly zero interested in resolving. Your Text helped me a lot to manipulate pf in needed order. But anyway.. looking for IPv6 capable home-firewall project with 802.11n capable WLAN.

  7. December 22nd, 2009 at 21:48 | #7

    IPV6 will be backported from m0n0wall shortly after 2.0 releases. 2.0 will be going BETA on xmas so it is not as far off as some might think.

    And saying we do not care at all about IPV6 is false. It is extremely hard to get a IPV6 connection where we live without using a tunnel.

  8. P. Harmor
    December 23rd, 2009 at 20:52 | #8

    Thanx for this howto! I now have hope again, that IPv6 and pfSense might work together, for me. However, I use a tunnel (/48) with tunnelbroker.com, and don’t yet know quite what changes need to be made to accommodate for that difference.

    ATM, my IPv4 network is trashed, as I believe it’s all trying to be routed thru the tunnel, and I’m not sure what to do to fix it…

  9. pfsense user
    January 29th, 2010 at 10:09 | #9

    P. Harmor were you able to find anything with getting this to work on tunnelbroker.com?
    I can’t get a native tunnel through my ISP either and am facing this problem

    I like how this is addressed and hope it works with tunnelbroker.com… but I just do not know :(

  10. February 5th, 2010 at 09:19 | #10

    There is still enough V4 space left, but I have played with V6, too and it seems to work well with pfsense now. I made a tunnel between two locations with V6 without any trouble.

  11. mthode
    April 24th, 2010 at 08:29 | #11

    I know this is old but it’s worth a shot.

    All I’d need to do for vlan support is to change the interface name to be the vlan interface name?

  12. barf
    June 3rd, 2010 at 16:17 | #12

    you can also use git0 interface for a 6-to-4 tunnel if you don’t have native IPv6
    ifconfig gif0 create
    ifconfig gif0 tunnel x.x.xx.xxx 192.88.99.1
    ifconfig gif0 inet6 alias 2002:beef:b00b::f00d
    route add -inet6 default -interface gif0

    but you will then need to add a route for the new ipv6 subnetwork you send router advertisments to:
    route add -net -inet6 2002:beef:b00b:face::/64 -interface rl0

  13. halli
    August 11th, 2010 at 10:51 | #13

    @Scott Ullrich

    rh@bdsm:~$ date
    Mi 11. Aug 10:47:07 CEST 2010

    pfSense : pfSense-2.0-BETA4-20100811-0244.iso.gz

    As Larry Wall did xmas but wich year ?

  1. No trackbacks yet.

Anti-Spam Protection by WP-SpamFree