FreeRADIUS InkBridge
#	This is a virtual server that handles DHCPv6.

The DHCPv6 Virtual Server

The Virtual Server

server dhcpv6 {
namespace

Needs to be "dhcpv6" for DHCPv6 functionality.

	namespace = dhcpv6
all_dhcp_servers_and_relays

Predefined multicast address for DHCPv6 servers and relays.

This configuration item is here for convenience. It allows each listen section below to use this definition, so that those sections do not need to list magic numbers.

	all_dhcp_servers_and_relays = FF02::1:2
interface

Ethernet interface for DHCPv6.

DHCPv6 servers require multiple listeners, one for multicast packets, and one for unicast packets. Both listeners should use the same interface. So it is defined here once, and used below.

	interface = en0
port

The port where we accept packets.

DHCPv6 servers require multiple listeners, one for multicast packets, and one for unicast packets. Both listeners should use the same interface. So it is defined here once, and used below.

The default DHCPv6 port is 547. We use 5470 here, so that testing will not affect production systems. This value should be changed to 547 for production use.

	port = 547

The listen section

DHCPv6 relies on multicast packets to work. We suggest defining only one DHCPv6 "listen" per host machine. This suggestion is because all DHCPv6 listeners will receive all DHCPv6 packets.

	listen all_dhcp_servers_and_relays {
type

The type of packet to accept.

Multiple types can be accepted by using multiple lines of type = …​.

All DHCPv6 request types are supported. Relaying is not supported.

		type = Solicit
		type = Request
transport

The transport protocol.

Only udp is allowed.

		transport = udp

UDP Transport

When the listen section contains transport = udp, it looks for a "udp" subsection. This subsection contains all of the configuration for the UDP transport.

		udp {
ipaddr

The IP address where we accept packets.

The address can be IPv6, or a host name. If a host name is used, the IPv6 address is preferred. When there is no IPv6 address for a host name, an error will occur.

			ipaddr = ${...all_dhcp_servers_and_relays}
port

The port where we accept packets.

The port should be 547 for a production
network. We do NOT suggest setting it to
547 on a production network unless you
know what you are doing. Even if nothing
is configured below, the server may still
NAK legitimate responses from clients.
			port = ${...port}
interface

Interface where we receive packets.

When a multicast address is used for ipaddr above, and interface configuration MUST be given.

			interface = ${...interface}
src_ipaddr

The source IP address used for unicast messages.

If a src_ipaddr is not specified, then the server will try to choose one automatically:

  • If ipaddr is unicast, then the server will use that as src_ipaddr, too.

  • If ipaddr is multicast, then the server will look for the first "link local" address on the interface defined above, and use that.

In most cases, you should not need to specify src_ipaddr.

#			src_ipaddr = ${ipaddr}
		}
	}

The listen section

DHCPv6 relies on multicast packets to work. We suggest defining only one DHCPv6 "listen" per host machine. This suggestion is because all DHCPv6 listeners will receive all DHCPv6 packets.

	listen local_network {
type

The type of packet to accept.

Multiple types can be accepted by using multiple lines of type = …​.

A listener which is using a unicast ipaddr should not receive Solicit, Rebind, or Reconfirm packets. Those packets MUST be sent to a multicast address.

		type = Request
		type = Information-Request
transport

The transport protocol.

Only udp is allowed.

		transport = udp

UDP Transport

When the listen section contains transport = udp, it looks for a "udp" subsection. This subsection contains all of the configuration for the UDP transport.

		udp {
ipaddr

The IP address where we accept packets.

The address can be IPv6, or a host name. If a host name is used, the IPv6 address is preferred. When there is no IPv6 address for a host name, an error will occur.

If an ipaddr is not defined, then the configuration MUST specify an interface. The server will look for the first "link local" address on that interface, and use that as the value for ipaddr.

#			ipaddr = 2001:db8::

			port = ${...port}
			interface = ${...interface}
		}
	}

State machine configuration

	dhcpv6 {
status_code_on_success

Include a status-code option in the packet even when the operation is successful (status code 0).

RFC8415 states that the absence of a status-code option is identical to a status-code option with value (0). This option is included in case there are broken DHCPv6 clients that require an explicit success notification.

This config item is disabled by default as including status-code adds approximately 6 bytes per nested message, and some clients are buggy and count any status-code option as a failure indication.

#		status_code_on_success = no
send_failure_message

Concatenate the contents of any Module-Failure-Message attribute in the request, and include it in the message field of the status-code option when status-code is not 0 or when status_code_on_success = yes.

This is disabled by default as these messages may reveal sensitive information about the internal state of the server.

It’s recommended to only enable this config item for debugging, or in conjunction with move_failure_message_to_parent where the upstream relay is trusted and secure.

#		send_failure_message = no
move_failure_message_to_parent

Move all Module-Failure-Message attributes to the parent request.

Attributes are only moved when:

  • A parent request is available.

  • The parent request of type DHCPv6.

  • status-code != 0, or status_code_on_success = yes

When combined with send_failure_message and a secure upstream DHCPv6 relay this provides a useful debugging tool where the reason for a given allocation failure can be determined from packet traces, or trace functionality on the upstream relay.

As relays will strip off the outer relay-message as the packet moves through them, the contents of the Module-Failure-Message will not reach the end DHCPv6 client.

#		move_failure_message_to_parent = yes
	}

Receive a Solicit message

recv Solicit {
	ok
}

Send an Advertise message

send Advertise {

All replies MUST include a Server-ID option

	reply.Server-ID.DUID = UUID
	reply.Server-ID.DUID.UUID.Value := 0x00000000000000000000000000000000
}

Receive a Solicit message

recv Request {
	ok
}

send Offer {

All replies MUST include a Server-ID option

	reply.Server-ID.DUID = UUID
	reply.Server-ID.DUID.UUID.Value := 0x00000000000000000000000000000000
}

We also support recv / send for all normal DHCPv6 packet types.

See dictionary/dhcpv6/dictionary.freeradius.internal for a list of packet type names.

recv Information-Request {
	ok
}

send Reply {

All replies MUST include a Server-ID option

	reply.Server-ID.DUID = UUID
	reply.Server-ID.DUID.UUID.Value := 0x00000000000000000000000000000000
}

}

Default Configuration