I am familiar with hardening IPv4 on Ubuntu server, but when I use the same rules for IPv6 with ip6tables, the IPv6 connectivity is lost resulting in Destination unreachable: Address unreachable
errors during ping. Could you please advise on how to fix this issue? My logic is the following:
#IPv6
#Reset all rules (F) and chains (X)
ip6tables -F
ip6tables -X
#Force SYN packets check
ip6tables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
#Drop XMAS packets
ip6tables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
#Drop null packets
ip6tables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
#Drop incoming packets with fragments
#ip6tables -A INPUT -f -j DROP #this does not really work like in iptables
#Drop traffic
ip6tables -t filter -P INPUT DROP
ip6tables -t filter -P FORWARD DROP
ip6tables -t filter -P OUTPUT DROP
#Keep established
ip6tables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
ip6tables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
#Accept loopback
ip6tables -t filter -A INPUT -i lo -j ACCEPT
ip6tables -t filter -A OUTPUT -o lo -j ACCEPT
#ICMP
ip6tables -t filter -A INPUT -p icmp -j ACCEPT
ip6tables -t filter -A OUTPUT -p icmp -j ACCEPT
#ServiceX
ip6tables -t filter -A DESTINATION -p PROTOCOL --dport PORT -j ACCEPT
#ServiceY
ip6tables -t filter -A DESTINATION -p PROTOCOL --dport PORT -j ACCEPT
#ServiceZ
ip6tables -t filter -A DESTINATION -p PROTOCOL --dport PORT -j ACCEPT
...
Example for ssh server, though I never use the default port 22...
#SSH
ip6tables -t filter -A INPUT -p tcp --dport 22 -j ACCEPT
ip6tables -t filter -A OUTPUT -p tcp --dport 22 -j ACCEPT
The script is made executable, so it runs across reboots in /etc/init.d/scriptname. The idea is to block everything and allow only what is actually known to be used by the server services.
Any better approach, please? Why this works in IPv4, but not in IPv6? When I issue ip6tables -t filter -P INPUT ACCEPT
it works, but that's not the point. How do I really secure IPv6 on Ubuntu servers? Thanks!