What are the essential iptables rules for IPv6 to work properly?

8,728

Solution 1

The essential rules will depend on the network as a network might instead use SLAAC instead of DHCPv6, or there can be other complications depending on tunnels, ICMP handling, etc.

-A INPUT -m conntrack --ctstate NEW -m udp -p udp --dport 546 -d fe80::/64 -j ACCEPT

is suitable for a DHCPv6 client. DHCP clients should not accept server port 547 traffic as presumably they are not also a DHCP server. Packets will come from the DHCP server from port 547 to port 546 on the client; connection tracking will not apply as the client broadcasts (or really multicasts under IPv6) and the server replies from an address unrelated to where the client broadcasted to.

This is fairly safe as root is necessary to listen on ports <1024 so random users on the client system should not be able to start a malicious service there by default (maybe they could DoS network access?). fe80 is link-local traffic so remote malicious users on some other subnet should not be able to route traffic to that port (if you have malicious users on your subnet you probably have other more important problems to deal with, such as the use of network gear that prevents rogue DHCP servers).

ICMPv6 can get very complicated depending on what you want to permit or deny, though probably can be handled with the connection tracking defaults for a simple IPv6 client. See RFC 4443 and RFC 4890 for more details.

Solution 2

I looked for examples in ufw, the firewall created by Ubuntu. It seems that once you've allowed both ICMP and DHCP, there's not much else left to worry about.

https://git.launchpad.net/ufw/tree/conf/before6.rules?id=release/0.35

As thrig points out, it seems that there's a lot of different ICMP codes to look at. Your current rules avoid doing so by allowing all ICMP; I can definitely see the appeal of this approach :).

Unfortunately ufw is not perfectly helpful as a reference for these. It doesn't justify why e.g. packet-too-big wouldn't be accepted by RELATED already. But it seems a plausible source for a iptables6 default taken from RFC4890.

RFC4890 actually only mentions one type of ICMP as having "significant security risk" - "Redirect (Type 137)". ICMP redirects are only useful on local networks which have several independent routers, and are not optimally configured. Handling the redirect is not essential, but it would not use the network as efficiently as possible. ufw does not explicitly allow redirects. Based on this, I think it would be reasonable to allow most or all ICMP but not allow ICMP redirects.

# ok icmp codes for INPUT (rfc4890, 4.4.1 and 4.4.2)
-A ufw6-before-input -p icmpv6 --icmpv6-type destination-unreachable -j ACCEPT
-A ufw6-before-input -p icmpv6 --icmpv6-type packet-too-big -j ACCEPT
# codes 0 and 1
-A ufw6-before-input -p icmpv6 --icmpv6-type time-exceeded -j ACCEPT
# codes 0-2
-A ufw6-before-input -p icmpv6 --icmpv6-type parameter-problem -j ACCEPT
-A ufw6-before-input -p icmpv6 --icmpv6-type echo-request -j ACCEPT
-A ufw6-before-input -p icmpv6 --icmpv6-type echo-reply -j ACCEPT
-A ufw6-before-input -p icmpv6 --icmpv6-type router-solicitation -m hl --hl-eq 255 -j ACCEPT
-A ufw6-before-input -p icmpv6 --icmpv6-type router-advertisement -m hl --hl-eq 255 -j ACCEPT
-A ufw6-before-input -p icmpv6 --icmpv6-type neighbor-solicitation -m hl --hl-eq 255 -j ACCEPT
-A ufw6-before-input -p icmpv6 --icmpv6-type neighbor-advertisement -m hl --hl-eq 255 -j ACCEPT
# IND solicitation
-A ufw6-before-input -p icmpv6 --icmpv6-type 141 -m hl --hl-eq 255 -j ACCEPT
# IND advertisement
-A ufw6-before-input -p icmpv6 --icmpv6-type 142 -m hl --hl-eq 255 -j ACCEPT
# MLD query
-A ufw6-before-input -p icmpv6 --icmpv6-type 130 -s fe80::/10 -j ACCEPT
# MLD report
-A ufw6-before-input -p icmpv6 --icmpv6-type 131 -s fe80::/10 -j ACCEPT
# MLD done
-A ufw6-before-input -p icmpv6 --icmpv6-type 132 -s fe80::/10 -j ACCEPT
# MLD report v2
-A ufw6-before-input -p icmpv6 --icmpv6-type 143 -s fe80::/10 -j ACCEPT
# SEND certificate path solicitation
-A ufw6-before-input -p icmpv6 --icmpv6-type 148 -m hl --hl-eq 255 -j ACCEPT
# SEND certificate path advertisement
-A ufw6-before-input -p icmpv6 --icmpv6-type 149 -m hl --hl-eq 255 -j ACCEPT
# MR advertisement
-A ufw6-before-input -p icmpv6 --icmpv6-type 151 -s fe80::/10 -m hl --hl-eq 1 -j ACCEPT
# MR solicitation
-A ufw6-before-input -p icmpv6 --icmpv6-type 152 -s fe80::/10 -m hl --hl-eq 1 -j ACCEPT
# MR termination
-A ufw6-before-input -p icmpv6 --icmpv6-type 153 -s fe80::/10 -m hl --hl-eq 1 -j ACCEPT

# ok icmp codes for OUTPUT (rfc4890, 4.4.1 and 4.4.2)
-A ufw6-before-output -p icmpv6 --icmpv6-type destination-unreachable -j ACCEPT
-A ufw6-before-output -p icmpv6 --icmpv6-type packet-too-big -j ACCEPT
# codes 0 and 1
-A ufw6-before-output -p icmpv6 --icmpv6-type time-exceeded -j ACCEPT
# codes 0-2
-A ufw6-before-output -p icmpv6 --icmpv6-type parameter-problem -j ACCEPT
-A ufw6-before-input -p icmpv6 --icmpv6-type echo-request -j ACCEPT
-A ufw6-before-input -p icmpv6 --icmpv6-type echo-reply -j ACCEPT
-A ufw6-before-output -p icmpv6 --icmpv6-type router-solicitation -m hl --hl-eq 255 -j ACCEPT
-A ufw6-before-output -p icmpv6 --icmpv6-type neighbor-advertisement -m hl --hl-eq 255 -j ACCEPT
-A ufw6-before-output -p icmpv6 --icmpv6-type neighbor-solicitation -m hl --hl-eq 255 -j ACCEPT
-A ufw6-before-output -p icmpv6 --icmpv6-type router-advertisement -m hl --hl-eq 255 -j ACCEPT
# IND solicitation
-A ufw6-before-output -p icmpv6 --icmpv6-type 141 -m hl --hl-eq 255 -j ACCEPT
# IND advertisement
-A ufw6-before-output -p icmpv6 --icmpv6-type 142 -m hl --hl-eq 255 -j ACCEPT
# MLD query
-A ufw6-before-output -p icmpv6 --icmpv6-type 130 -s fe80::/10 -j ACCEPT
# MLD report
-A ufw6-before-output -p icmpv6 --icmpv6-type 131 -s fe80::/10 -j ACCEPT
# MLD done
-A ufw6-before-output -p icmpv6 --icmpv6-type 132 -s fe80::/10 -j ACCEPT
# MLD report v2
-A ufw6-before-output -p icmpv6 --icmpv6-type 143 -s fe80::/10 -j ACCEPT
# SEND certificate path solicitation
-A ufw6-before-output -p icmpv6 --icmpv6-type 148 -m hl --hl-eq 255 -j ACCEPT
# SEND certificate path advertisement
-A ufw6-before-output -p icmpv6 --icmpv6-type 149 -m hl --hl-eq 255 -j ACCEPT
# MR advertisement
-A ufw6-before-output -p icmpv6 --icmpv6-type 151 -s fe80::/10 -m hl --hl-eq 1 -j ACCEPT
# MR solicitation
-A ufw6-before-output -p icmpv6 --icmpv6-type 152 -s fe80::/10 -m hl --hl-eq 1 -j ACCEPT
# MR termination
-A ufw6-before-output -p icmpv6 --icmpv6-type 153 -s fe80::/10 -m hl --hl-eq 1 -j ACCEPT

# ok icmp codes for FORWARD (rfc4890, 4.3.1)
-A ufw6-before-forward -p icmpv6 --icmpv6-type destination-unreachable -j ACCEPT
-A ufw6-before-forward -p icmpv6 --icmpv6-type packet-too-big -j ACCEPT
# codes 0 and 1
-A ufw6-before-forward -p icmpv6 --icmpv6-type time-exceeded -j ACCEPT
# codes 0-2
-A ufw6-before-forward -p icmpv6 --icmpv6-type parameter-problem -j ACCEPT
-A ufw6-before-forward -p icmpv6 --icmpv6-type echo-request -j ACCEPT
-A ufw6-before-forward -p icmpv6 --icmpv6-type echo-reply -j ACCEPT
# ok icmp codes for FORWARD (rfc4890, 4.3.2)
# Home Agent Address Discovery Reques
-A ufw6-before-input -p icmpv6 --icmpv6-type 144 -j ACCEPT
# Home Agent Address Discovery Reply
-A ufw6-before-input -p icmpv6 --icmpv6-type 145 -j ACCEPT
# Mobile Prefix Solicitation
-A ufw6-before-input -p icmpv6 --icmpv6-type 146 -j ACCEPT
# Mobile Prefix Advertisement
-A ufw6-before-input -p icmpv6 --icmpv6-type 147 -j ACCEPT

(end of ICMP rules)

# allow dhcp client to work
-A ufw6-before-input -p udp -s fe80::/10 --sport 547 -d fe80::/10 --dport 546 -j ACCEPT

The following is needed if you want to use avahi for anything on the local network. Multiple popular distributions that have polices about network services, consider avahi trustworthy enough to listen to the network by default.

# allow MULTICAST mDNS for service discovery
-A ufw6-before-input -p udp -d ff02::fb --dport 5353 -j ACCEPT

UPnP is sometimes useful on client machines, but it's complex, and I haven't heard as good things about it.

# allow MULTICAST UPnP for service discovery
-A ufw6-before-input -p udp -d ff02::f --dport 1900 -j ACCEPT
Share:
8,728

Related videos on Youtube

Pierre
Author by

Pierre

Updated on September 18, 2022

Comments

  • Pierre
    Pierre over 1 year

    I had a problem where I lost connectivity to a server on the IPv6 address after some time and it turned out to be caused by DHCPv6 client packets (port 546) being dropped by the default INPUT policy of DROP, this is my question about the problem, my rules were:

    -A INPUT -i lo -j ACCEPT
    -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
    -A INPUT -p ipv6-icmp -j ACCEPT
    -A INPUT -s IP_OF_ANOTHER_HOST -j ACCEPT
    -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
    -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
    -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
    -P INPUT DROP
    

    I thought that these rules are enough especially allowing RELATED and ESTABLISHED connections as my OUTPUT chain's default policy is ACCEPT, but I had to add this rule to accept DHCPv6 client packets:

    -A INPUT -m conntrack --ctstate NEW -m udp -p udp --dport 546 -d fe80::/64 -j ACCEPT
    

    The thing is I don't want to add more rules that I might not need, I want to keep my rules as simple as possible.

    So what are the essential rules that must be set for IPv6 to work properly ? Should I also enable DHCPv6 server port 547 ? and is it OK to accept all ICMPv6 packets ?

  • Jari Turkia
    Jari Turkia almost 4 years
    I'm doing -A INPUT -m udp -p udp --dport 546 -m state --state NEW -d fe80::/64 -j ACCEPT to get the same result.