The DoD has done an excellent job in annotating the best security practices for operating systems for years with its Security Technical Implementation Guides, or STIGs. In fact, STIGs for networking systems like routers, IDS/IPS, switches, devices, etc have been updated to reflect the new reality: IPv6. However, with STIGs on the operating system there is one sad commonality: disable IPv6.
Now that it’s 2015, many DoD enterprises have started looking past this sad concept and enabling IPv6 on their operating systems. Considering DISA has fallen a bit behind in this area, we at Tachyon Dynamics would like to help you out. Let us know your thoughts and comments here!
Securely Enable IPv6
Enabling IPv6 should always be more than a “flip it, and forget it” action. Having a secure and feature-rich IPv6 enterprise requires deep thought, planning, and committed execution. Therefore, we are assuming you as the DoD enterprise have already followed and designed to this fact, and we want to give you our tried and true best security practices on enabling and operating IPv6 on your server operating systems.
Networking Considerations
In the below areas, we are going to make certain address distribution assumptions based on IPv6 enterprise best practices. Each server operating system instruction will include options for each of these scenarios:
- Scenario #1: Static IPv6 Addressing with Router Advertisements (RA) enabled on the network. This scenario is mainly for subnets that still require that specific networking options are sent to devices/servers on the subnet like Maximum Transmission Unit (MTU) preference, On-Link flags, etc, but want to ensure each server statically configures its address. This could be standard virtual or physical servers in a data center.
- Scenario #2: Static IPv6 Addressing with RAs disabled. This scenario is mainly for subnets that want to avoid having any interaction with other hosts and routers unless negotiated through the configured default gateway. This could be optimal for cloud-based virtual networking like Vmware NSX or OpenStack’s Neutron.
- Scenario #3: Dynamic Host Configuration Protocol Version 6 (DHCPv6) client for servers. This scenario is mainly for subnets that want to control addressing, and re-addressing, with a DHCPv6 server. This is optimal with cloud provisioned servers from OpenStack and others. Reference RFC 3315.
- Scenario #4: Stateless Address Autoconfiguration with EUI-64 defaults. This scenario is mainly for subnets that may be constantly changing and require automated functions without the requirement for a stateful server addressing them. This could be optimal for public-facing web services using automated provisioning systems from Vmware or OpenStack. Reference RFC 4862
- Scenario #5: Stateless Address Autoconfiguration with Privacy Addressing. This scenario is mainly for subnets that may be constantly changing and require automated functions without the requirement for a stateful server addressing them. However, for more security minded enterprises, the use of EUI-64 may cause too much operating system fingerprinting. This could be optimal for public-facing web services using automated provisioning systems from Vmware or OpenStack. Reference RFC 2941.
Linux Distributions
Considering most of the DoD falls into the following distribution flavors of Linux: RedHat Enterprise Linux, SuSE Enterprise Linux, and on the rare occasion – Ubuntu Server/Debian. So follow our recommendations as shown below for each and please let us know if you have a distribution that doesn’t fall into these categories. There is also a firewall section for using IP6TABLES at the end.
Red Hat Enterprise Linux 5 – 7
Static IPv6 Addressing with RAs
Enable the IPv6 module (in case you disabled it previously) and ensure RAs are enabled
modprobe ipv6 sysctl -q -w net/ipv6/conf/eth0/accept_ra=1
*if not eth0, change the device to the correct one
Edit the file: /etc/sysconfig/network-scripts/ifcfg-* and add the following
IPV6INIT=yes IPV6ADDR="IPv6 address""/prefix length" IPV6_DEFAULTGW="IPv6 address""%interface" DNS{1,2}="IPv6 address"
Lastly, ensure everything is locked down with no forwarding, DAD, and disable redirects:
sysctl -q -w net/ipv6/conf/eth0/forwarding=0 sysctl -q -w net/ipv6/conf/eth0/accept_redirects=0
Finally, reboot the machine.
Static IPv6 Addressing without RAs
Enable the IPv6 module (in case you disabled it previously) and ensure RAs are disabled
modprobe ipv6 sysctl -q -w net/ipv6/conf/eth0/accept_ra=1
*if not eth0, change the device to the correct one
Edit the file: /etc/sysconfig/network-scripts/ifcfg-* and add the following
IPV6INIT=yes IPV6ADDR="IPv6 address""/prefix length" IPV6_DEFAULTGW="IPv6 address""%interface" DNS{1,2}="IPv6 address"
Lastly, ensure everything is locked down with no forwarding, DAD, and disable redirects:
sysctl -q -w net/ipv6/conf/eth0/forwarding=0 sysctl -q -w net/ipv6/conf/eth0/autoconf=0 sysctl -q -w net/ipv6/conf/eth0/accept_redirects=0
Finally, reboot the machine.
DHCPv6 Client
Enable the IPv6 module (in case you disabled it previously) and ensure RAs are enabled. We also want to ensure we only have a maximum amount of addresses, otherwise, it could get messy with DHCPv6.
modprobe ipv6 sysctl -q -w net/ipv6/conf/eth0/accept_ra=1
*if not eth0, change the device to the correct one
Edit the file: /etc/sysconfig/network-scripts/ifcfg-* and add the following
IPV6INIT=yes
Lastly, ensure everything is locked down with no forwarding, DAD, and disable redirects:
sysctl -q -w net/ipv6/conf/eth0/forwarding=0 sysctl -q -w net/ipv6/conf/eth0/autoconf=0 sysctl -q -w net/ipv6/conf/eth0/accept_redirects=0
Finally, reboot the machine.
SLAAC with EUI-64
Enable the IPv6 module (in case you disabled it previously) and ensure RAs are enabled. We also want to ensure we only have a maximum amount of addresses, otherwise, it could get messy with SLAAC.
modprobe ipv6 sysctl -q -w net/ipv6/conf/eth0/accept_ra=1
*if not eth0, change the device to the correct one
Edit the file: /etc/sysconfig/network-scripts/ifcfg-* and add the following
IPV6INIT=yes
Lastly, ensure everything is locked down with no forwarding, DAD, and disable redirects:
sysctl -q -w net/ipv6/conf/eth0/forwarding=0 sysctl -q -w net/ipv6/conf/eth0/autoconf=1 sysctl -q -w net/ipv6/conf/eth0/accept_redirects=0
Finally, reboot the machine.
SLAAC with privacy Addressing
Enable the IPv6 module (in case you disabled it previously) and ensure RAs are enabled. We also want to ensure we only have a maximum amount of addresses, otherwise, it could get messy with SLAAC.
modprobe ipv6 sysctl -q -w net/ipv6/conf/eth0/accept_ra=1
*if not eth0, change the device to the correct one
Edit the file: /etc/sysconfig/network-scripts/ifcfg-* and add the following
IPV6INIT=yes
Lastly, ensure everything is locked down with no forwarding, DAD, and disable redirects – this is where we need to enable IPv6 Privacy Addresses as well:
sysctl -q -w net/ipv6/conf/eth0/forwarding=0 sysctl -q -w net/ipv6/conf/eth0/autoconf=1 sysctl -q -w net/ipv6/conf/eth0/accept_redirects=0 sysctl -q -w net/ipv6/conf/eth0/use_tempaddr=1
Finally, reboot the machine.
SuSE Enterprise Linux
Static IPv6 Addressing with RAs:
Enable the IPv6 module (in case you disabled it previously)
modprobe ipv6
Edit the file: /etc/sysconfig/network/ifcfg-eth-id-${ETHIDFILE} and add the following (sample address provided below)
LABEL_0='0' IPADDR_0='2001:db8:1:11:0000:0000:0000:000f' PREFIXLEN_0='64'
Now add the default route (again, sample address provided below)
echo 'default 2001:db8:1:11:0000:0000:0000:0001 - -' >> /etc/sysconfig/network/routes
Then, ensure everything is locked down by editing the file /etc/sysctl.conf and adding the below (note: eth0 is a sample interlace, replace as necessary) – ensure RA’s are enabled
net.ipv6.conf.eth0.accept_ra=1 net.ipv6.conf.eth0.forwarding=0 net.ipv6.conf.eth0.accept_redirects=0
Lastly, add the following boot.sysct file:
echo -n \\\"Setting current sysctl status from /etc/sysctl.conf\\\" # Force ipv6 module to load modprobe ipv6 sysctl -e -q -p /etc/sysctl.conf
Finally, reboot the machine.
Static IPv6 Addressing without RAs
Enable the IPv6 module (in case you disabled it previously)
modprobe ipv6
Edit the file: /etc/sysconfig/network/ifcfg-eth-id-${ETHIDFILE} and add the following (sample address provided below)
LABEL_0='0' IPADDR_0='2001:db8:1:11:0000:0000:0000:000f' PREFIXLEN_0='64'
Now add the default route (again, sample address provided below)
echo 'default 2001:db8:1:11:0000:0000:0000:0001 - -' >> /etc/sysconfig/network/routes
Then, ensure everything is locked down by editing the file /etc/sysctl.conf and adding the below (note: eth0 is a sample interlace, replace as necessary) – ensure RA’s are enabled
net.ipv6.conf.eth0.accept_ra=1 net.ipv6.conf.eth0.forwarding=0 net.ipv6.conf.eth0.accept_redirects=0
Lastly, add the following boot.sysct file:
echo -n \\\"Setting current sysctl status from /etc/sysctl.conf\\\" # Force ipv6 module to load modprobe ipv6 sysctl -e -q -p /etc/sysctl.conf
Finally, reboot the machine.
DHCPv6 Client
Enable the IPv6 module (in case you disabled it previously)
modprobe ipv6
The easiest and most efficient way with SuSE Enterprise 12+ to use DHCPv6 client functionality is to use the Wicked service. First, make Wicked the network controller
systemctl enable --force wicked
Now start the wicked service
systemctl start wickedd.service
Keep in mind this also starts the service for the following configurations:
/usr/lib/wicked/bin/wickedd-auto4 --systemd --foreground /usr/lib/wicked/bin/wickedd-dhcp4 --systemd --foreground /usr/lib/wicked/bin/wickedd-dhcp6 --systemd --foreground /usr/sbin/wickedd --systemd --foreground /usr/sbin/wickedd-nanny --systemd --foreground
Then, ensure everything is locked down by editing the file /etc/sysctl.conf and adding the below (note: eth0 is a sample interlace, replace as necessary) – ensure RA’s are enabled
net.ipv6.conf.eth0.accept_ra=1 net.ipv6.conf.eth0.forwarding=0 net.ipv6.conf.eth0.accept_redirects=0
Lastly, add the following boot.sysct file:
echo -n \\\"Setting current sysctl status from /etc/sysctl.conf\\\" # Force ipv6 module to load modprobe ipv6 sysctl -e -q -p /etc/sysctl.conf
Finally, reboot the machine.
SLAAC with EUI-64
Enable the IPv6 module (in case you disabled it previously)
modprobe ipv6
Then, ensure everything is locked down by editing the file /etc/sysctl.conf and adding the below (note: eth0 is a sample interlace, replace as necessary) – ensure RA’s are enabled and that Stateless Address Autoconfiguration (SLAAC) is also enabled!
net.ipv6.conf.eth0.accept_ra=1 net.ipv6.conf.eth0.forwarding=0 net.ipv6.conf.eth0.accept_redirects=0 net.ipv6.conf.eth0.autoconf=1
Lastly, add the following boot.sysct file:
echo -n \\\"Setting current sysctl status from /etc/sysctl.conf\\\" # Force ipv6 module to load modprobe ipv6 sysctl -e -q -p /etc/sysctl.conf
Finally, reboot the machine.
SLAAC with Privacy Addressing
Enable the IPv6 module (in case you disabled it previously)
modprobe ipv6
Then, ensure everything is locked down by editing the file /etc/sysctl.conf and adding the below (note: eth0 is a sample interlace, replace as necessary) – ensure RA’s are enabled and that Stateless Address Autoconfiguration (SLAAC) and Privacy Addressing are also enabled!
net.ipv6.conf.eth0.autoconf=1 net.ipv6.conf.eth0.use_tempaddr=1 net.ipv6.conf.eth0.accept_ra=0 net.ipv6.conf.eth0.forwarding=0 net.ipv6.conf.eth0.accept_redirects=0
Lastly, add the following boot.sysct file:
echo -n \\\"Setting current sysctl status from /etc/sysctl.conf\\\" # Force ipv6 module to load modprobe ipv6 sysctl -e -q -p /etc/sysctl.conf
Finally, reboot the machine.
Ubuntu Server Linux
Static IPv6 Addressing with RAs:
Enable the IPv6 module (in case you disabled it previously)
modprobe ipv6
Edit the file: /etc/network/interfaces and add the following (sample address provided below)
iface eth0 inet6 static address 2001:db8:1:11:0000:0000:0000:000F netmask 64 gateway 2001:db8:1:11:0000:0000:0000:0001
Then, ensure everything is locked down by editing the file /etc/sysctl.conf and adding the below (note: eth0 is a sample interlace, replace as necessary) – ensure RA’s are enabled
net.ipv6.conf.eth0.autoconf=0 net.ipv6.conf.eth0.use_tempaddr=0 net.ipv6.conf.eth0.accept_ra=1 net.ipv6.conf.eth0.forwarding=0 net.ipv6.conf.eth0.accept_redirects=0
Finally, reboot the machine.
Static IPv6 Addressing without RAs:
Enable the IPv6 module (in case you disabled it previously)
modprobe ipv6
Edit the file: /etc/network/interfaces and add the following (sample address provided below)
iface eth0 inet6 static address 2001:db8:1:11:0000:0000:0000:000F netmask 64 gateway 2001:db8:1:11:0000:0000:0000:0001
Then, ensure everything is locked down by editing the file /etc/sysctl.conf and adding the below (note: eth0 is a sample interlace, replace as necessary) – ensure RA’s are disabled
net.ipv6.conf.eth0.autoconf=0 net.ipv6.conf.eth0.use_tempaddr=0 net.ipv6.conf.eth0.accept_ra=0 net.ipv6.conf.eth0.forwarding=0 net.ipv6.conf.eth0.accept_redirects=0
Finally, reboot the machine.
DHCPv6 Client:
Enable the IPv6 module (in case you disabled it previously)
modprobe ipv6
Edit the file: /etc/network/interfaces and add the following (sample address provided below)
iface eth0 inet6 auto
In some cases, there may not be a DHCPv6 client installed on the server. If this is the case make sure you install the “wide-dhcpv6-client.” Then make sure the /etc/wide-dhcpv6/dhcp6c.conf includes at least the following:
interface eth0 { request domain-name-servers; request domain-name; send rapid-commit; send ia-na 15; script "/etc/wide-dhcpv6/dhcp6c-script"; }; id-assoc na 15 { # };
**Note, the number 15 can be anything, just not blank**
Then, ensure everything is locked down by editing the file /etc/sysctl.conf and adding the below (note: eth0 is a sample interlace, replace as necessary) – ensure RA’s are enabled
net.ipv6.conf.eth0.autoconf=0 net.ipv6.conf.eth0.use_tempaddr=0 net.ipv6.conf.eth0.accept_ra=1 net.ipv6.conf.eth0.forwarding=0 net.ipv6.conf.eth0.accept_redirects=0
Finally, reboot the machine.
SLAAC with EUI-64:
Enable the IPv6 module (in case you disabled it previously)
modprobe ipv6
Edit the file: /etc/network/interfaces and add the following (sample address provided below)
iface eth0 inet6 auto
Then, ensure everything is locked down by editing the file /etc/sysctl.conf and adding the below (note: eth0 is a sample interlace, replace as necessary) – ensure RA’s are enabled
net.ipv6.conf.eth0.autoconf=1 net.ipv6.conf.eth0.use_tempaddr=0 net.ipv6.conf.eth0.accept_ra=1 net.ipv6.conf.eth0.forwarding=0 net.ipv6.conf.eth0.accept_redirects=0
Finally, reboot the machine.
SLAAC with Privacy Addressing:
Enable the IPv6 module (in case you disabled it previously)
modprobe ipv6
Edit the file: /etc/network/interfaces and add the following (sample address provided below)
iface eth1 inet6 auto
Then, ensure everything is locked down by editing the file /etc/sysctl.conf and adding the below (note: eth0 is a sample interlace, replace as necessary) – ensure RA’s are enabled
net.ipv6.conf.eth0.autoconf=1 net.ipv6.conf.eth0.use_tempaddr=1 net.ipv6.conf.eth0.accept_ra=1 net.ipv6.conf.eth0.forwarding=0 net.ipv6.conf.eth0.accept_redirects=0
Finally, reboot the machine.
IP6TABLES
We are almost there on the Linux front! Make sure the firewall rules for IP6TABLES you are using properly permit and deny the right traffic. Recommend you use these as a good baseline:
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 128 -j ACCEPT ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 129 -j ACCEPT ip6tables -A OUTPUT -p ipv6-icmp --icmpv6-type 128 -j ACCEPT ip6tables -A OUTPUT -p ipv6-icmp --icmpv6-type 129 -j ACCEPT ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 130 -j ACCEPT ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 131 -j ACCEPT ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 132 -j ACCEPT ip6tables -A OUTPUT -p ipv6-icmp --icmpv6-type 130 -j ACCEPT ip6tables -A OUTPUT -p ipv6-icmp --icmpv6-type 131 -j ACCEPT ip6tables -A OUTPUT -p ipv6-icmp --icmpv6-type 132 -j ACCEPT ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 133 -j ACCEPT ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 134 -j ACCEPT ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 135 -j ACCEPT ip6tables -A OUTPUT -p ipv6-icmp --icmpv6-type 135 -j ACCEPT ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 136 -j ACCEPT ip6tables -A OUTPUT -p ipv6-icmp --icmpv6-type 136 -j ACCEPT ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 143 -j ACCEPT ip6tables -A OUTPUT -p ipv6-icmp --icmpv6-type 143 -j ACCEPT ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 2 -j ACCEPT ip6tables -A OUTPUT -p ipv6-icmp --icmpv6-type 2 -j ACCEPT ip6tables -A INPUT -p ipv6-icmp --icmpv6-type time-exceeded -j ACCEPT ip6tables -A OUTPUT -p ipv6-icmp --icmpv6-type time-exceeded -j ACCEPT ip6tables -A INPUT -p ipv6-icmp -j DROP #established OK ip6tables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT #all of your inbound services ip6tables -A INPUT -m state --state NEW -m tcp -p tcp --dport <PORT> -j ACCEPT ip6tables -A INPUT -m state --state NEW -m udp -p udp --dport <PORT> -j ACCEPT #SSH server ip6tables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set ip6tables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 2 -j DROP ip6tables -A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT ip6tables -A INPUT -p ipv6 -j DROP
**Note: the <PORT> means to add the inbound TCP or UDP port for the specific application your server hosts
***Note: the additional SSH rules allow for you to maintain SSH services for remote administration, but keeps those annoying bots and script kiddies away. It limits a login attempt from a single IPv6 address to attempt to login once every 60 seconds. So if after one connection attempt at trying to login (up to 3 attempts in the connection), the firewall will terminate the session and block all attempts from that source address for 60 seconds.
Windows Server 2008 – 2012
With Windows, ever since the first Windows 2008 Server OS up to 2012, the TCP/IPv6 module has remained the same. So security functionality applies across these platforms. It is also good for Windows Vista through Windows 10 on the desktop/workstation side.
Enable the IPv6 module (in case you disabled it previously)
- Go to the registry – can be done manually, by GPO, or powershell
- Edit or Create the following 32-bit DWORD “DisabledComponents” under the following hive:
- HKLM\System\CurrentControlSet\Services\TCPIP6\Parameters
- Change or add its value to the following:
- 0x01 = enable IPv6, but disable all IPv6 over IPv6 tunneling
- 0x20 = enable IPv6, but prefer IPv4 over IPv6 (useful for networks that have an internal IPv6 implementation, but for whatever reason (*cough DISA*) you are waiting on your service provider to enable IPv6 on your internet-facing connection.
Static IPv6 Addressing with RAs:
Now go to the network connection, click “IPv6,” then properties like shown below:
Then add your IPv6 address in the address field and “64” in the netmask field as shown below. Leave the gateway blank, because we are allowing RAs in this scenario. The gateway is appended by the Windows OS when the RA is received.
Now add the following power shell/command prompt commands ( these can also be scripted or added via GPO). This will disable ICMPv6 redirects and DHCPv6 client functionality, but enable RAs.
netsh int ipv6 set global icmpredirects=disabled store=p netsh int ipv6 set int routerdiscovery=enabled managedaddress=disabled store=p
Static IPv6 Addressing without RAs:
Now go to the network connection, click “IPv6,” then properties like shown below:
Then add your IPv6 address in the address field and “64” in the netmask field. Now add the gateway IPv6 address in the gateway field as shown below:
Now add the following power shell/command prompt commands ( these can also be scripted or added via GPO). This will disable RAS, ICMPv6 redirects and DHCPv6 client functionality.
netsh int ipv6 set global icmpredirects=disabled store=p netsh int ipv6 set int routerdiscovery=disabled managedaddress=disabled store=p
DHCPv6 Client:
Now go to the network connection, click “IPv6,” then properties like shown below:
Then ensure the radio button for “obtain IPv6 address automatically” is checked:
Now add the following power shell/command prompt commands ( these can also be scripted or added via GPO). This will disable ICMPv6 redirects, but enable RAs and DHCPv6 client functionality.
netsh int ipv6 set global icmpredirects=disabled store=p netsh int ipv6 set int routerdiscovery=enabled managedaddress=enabled store=p
SLAAC with EUI-64
Now go to the network connection, click “IPv6,” then properties like shown below:
Then ensure the radio button for “obtain IPv6 address automatically” is checked:
Now add the following power shell/command prompt commands ( these can also be scripted or added via GPO). This will disable ICMPv6 redirects, but enable RAs and SLACC functionality with EUI-64 addressing.
netsh int ipv6 set global icmpredirects=disabled store=p netsh int ipv6 set int routerdiscovery=enabled managedaddress=disabled store=p netsh int ipv6 set privacy state=disabled store=p
SLAAC with EUI-64
Now go to the network connection, click “IPv6,” then properties like shown below:
Then ensure the radio button for “obtain IPv6 address automatically” is checked:
Now add the following power shell/command prompt commands ( these can also be scripted or added via GPO). This will disable ICMPv6 redirects, but enable RAs and SLAAC functionality with privacy addressing. This allows for IPv6 Privacy Addressing but instead of cycling them every single day. Cycling them every day causes pain on your dynamic DNS systems, set the preferred lifetime to 7. This will keep better synchronization with IPv4 DHCP.
netsh int ipv6 set global icmpredirects=disabled store=p netsh int ipv6 set int routerdiscovery=enabled managedaddress=disabled store=p netsh int ipv6 set privacy state=enabled maxpreferredlifetime=7 store=p