# Here is a basic firewall policy for IPv6 on a Linux host ip6tables -P INPUT ACCEPT ip6tables -F INPUT # Always allow the loopback interface ip6tables -A INPUT -i lo -j ACCEPT # What ICMPv6 traffic should you permit, here is a starting point (note that conntrack "RELATED" state will catch a lot of it) ip6tables -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 1 -j ACCEPT # Destination Unreachable [RFC4443] ip6tables -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 2 -j ACCEPT # Packet Too Big [RFC4443] ip6tables -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 3 -j ACCEPT # Time Exceeded [RFC4443] ip6tables -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 4 -j ACCEPT # Parameter Problem [RFC4443] ip6tables -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 128 -j ACCEPT # Echo Request [RFC4443] ip6tables -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 130 -j ACCEPT # Multicast Listener Query [RFC2710] ip6tables -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 131 -j ACCEPT # Multicast Listener Report [RFC2710] ip6tables -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 132 -j ACCEPT # Multicast Listener Done [RFC2710] # You can use the "hop limit" module to match traffic by the TTL to determine if it's on-link or routed for the following ip6tables -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 134 -m hl --hl-eq 255 -j ACCEPT # Router Advertisement [RFC4861] ip6tables -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 135 -m hl --hl-eq 255 -j ACCEPT # Neighbor Solicitation [RFC4861] ip6tables -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 136 -m hl --hl-eq 255 -j ACCEPT # Neighbor Advertisement [RFC4861] ip6tables -A INPUT -p udp -m udp --sport 547 --dport 546 -m hl --hl-eq 255 -j ACCEPT # DHCPv6 # Stateful Firewall Policy ip6tables -A INPUT -m conntrack --ctstate INVALID -j DROP ip6tables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT # If you need to allow SSH you can rate-limit new connections per host to 3 per min to cut down on brute force noise ip6tables -A INPUT -p tcp -m tcp --dport 22 -m conntrack --ctstate NEW -m recent --set --name DEFAULT --rsource ip6tables -A INPUT -p tcp -m tcp --dport 22 -m conntrack --ctstate NEW -m recent --update --seconds 60 --hitcount 4 --name DEFAULT --rsource -j DROP ip6tables -A INPUT -p tcp -m tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT # Allow incomming traffice here (example HTTP and HTTPS) ip6tables -A INPUT -p tcp -m tcp --dport 80 -m conntrack --ctstate NEW -j ACCEPT ip6tables -A INPUT -p tcp -m tcp --dport 443 -m conntrack --ctstate NEW -j ACCEPT # Finally drop everything else (I prefer to have an explicit rule than setting the default policy to drop). # Optionally you can add a rule to log dropped traffic. ip6tables -A INPUT -j DROP