📜 ⬆️ ⬇️

One firewall for IPv4 and IPv6 (iptables and ip6tables)

After IPv6 setup, the firewall setup task for the new protocol appears Below I offer my script that allows you to configure the firewall immediately for IPv4 and IPv6. Although there are not so many common rules for both firewalls, it’s still more convenient for me to edit one common file than two different ones.


We will consider the most common network with one Internet connection and one local network behind the firewall. For a local network in IPv4, you need to do NAT, in IPv6 you need to route and filter packets.

If you just have one computer, then removing all references to the local network will get a suitable firewall.
')
I do not cite any specific explanations, you just need to correct a few variables at the beginning and a few “tables” in the middle.

#!/bin/bash <br>
# License: GPL3 <br>
# Author: Dmitri Gribenko <gribozavr@gmail.com> <br>
<br>

LAN_IF = " eth0 " <br>
INET_IF = " eth1 " <br>
INET_IP = " 192.0.2.123 " <br>
INET6_IF = " he-ipv6 " <br>
<br>

# for dynamic IPs: <br>
# INET_IP=$(get_ip_ipv4 $INET_IF) <br>
<br>
LOOPBACK_IF = " lo " <br>
<br>
IPTABLES = " /sbin/iptables " <br>
IP6TABLES = " /sbin/ip6tables " <br>

#IPTABLES="echo 4" <br>
#IP6TABLES="echo 6" <br>
IP = " /sbin/ip " <br>
<br>
# IPs that need to be NAT'ed to our $INET_IP. <br>
NAT_IPV4 = ' <br>

192.168.1.3 pc1 <br>
192.168.1.4 pc2 <br>
192.168.1.5 <br>
' <br>
<br>
# Set to 0 to disable updating IPv4 or IPv6 firewall. <br>
DO_IPV4 = " 1 " <br>

DO_IPV6 = " 1 " <br>
<br>
function get_ip_ipv4 <br>
{ <br>
$IP addr show dev $1 primary | sed -n -e ' /^\s*inet / s/^\s*inet \(.*\)\/.\{1,2\} .*$/\1/ p ' <br>

} <br>
<br>
ipt4() <br>
{ <br>
[ " $DO_IPV4 " = "1" ] && $IPTABLES " $@ " <br>
} <br>

<br>
ipt6() <br>
{ <br>
[ " $DO_IPV6 " = "1" ] && $IP6TABLES " $@ " <br>
} <br>
<br>
ipt46() <br>

{ <br>
ipt4 " $@ " <br>
ipt6 " $@ " <br>
} <br>
<br>
############################################################################## <br>
################################ filter table ################################ <br>
############################################################################## <br>

<br>
ipt46 -t filter -P INPUT ACCEPT<br>
ipt46 -t filter -P OUTPUT ACCEPT<br>
ipt46 -t filter -P FORWARD ACCEPT<br>

<br>
ipt46 -t filter -F <br>
ipt46 -t filter -X <br>
<br>
FILTER_CHAINS46 = " bad_tcp inet_input inet_output inet_banned_input inet_banned_output inet_tcp_input inet_tcp_output inet_udp_input inet_udp_output " <br>
for i in $FILTER_CHAINS46 ; do <br>

ipt46 -t filter -N $i <br>
ipt46 -t filter -F $i <br>
done <br>
<br>
FILTER_CHAINS4 = " inet_icmp_input inet_icmp_output " <br>

for i in $FILTER_CHAINS4 ; do <br>
ipt4 -t filter -N $i <br>
ipt4 -t filter -F $i <br>

done <br>
<br>
FILTER_CHAINS6 = " inet_icmpv6_input inet_icmpv6_output inet_icmpv6_forward " <br>
for i in $FILTER_CHAINS6 ; do <br>
ipt6 -t filter -N $i <br>

ipt6 -t filter -F $i <br>
done <br>
<br>
################################# <br>
## filter -- INPUT <br>
## <br>
<br>
# allow ipv6 in ipv4 <br>

ipt4 -t filter -A INPUT -p ipv6 -j ACCEPT<br>
<br>
ipt46 -t filter -A INPUT -i $LOOPBACK_IF -j ACCEPT<br>

ipt46 -t filter -A INPUT -i $LAN_IF -j ACCEPT<br>
ipt4 -t filter -A INPUT -i $INET_IF -j inet_input<br>

ipt6 -t filter -A INPUT -i $INET6_IF -j inet_input<br>
<br>
#ipt46 -t filter -A INPUT -m limit --limit 3/minute --limit-burst 3 -j LOG --log-level INFO --log-prefix "IPT INPUT packet died: " <br>
#ipt46 -t filter -A INPUT -j LOG --log-level INFO --log-prefix "IPT INPUT packet died: " <br>

ipt46 -t filter -A INPUT -j DROP<br>
<br>
################################# <br>
## filter -- OUTPUT <br>
## <br>
<br>
ipt46 -t filter -A OUTPUT -o $LOOPBACK_IF -j ACCEPT<br>

ipt46 -t filter -A OUTPUT -o $LAN_IF -j ACCEPT<br>
ipt4 -t filter -A OUTPUT -o $INET_IF -j inet_output<br>

ipt6 -t filter -A OUTPUT -o $INET6_IF -j inet_output<br>
<br>
#ipt46 -t filter -A OUTPUT -j LOG --log-level INFO --log-prefix "IPT OUTPUT: " <br>
ipt46 -t filter -A OUTPUT -j ACCEPT<br>

<br>
################################# <br>
## filter -- bad_tcp <br>
## <br>
<br>
ipt46 -t filter -A bad_tcp -p tcp -m state --state NEW ! --syn -j DROP<br>

ipt46 -t filter -A bad_tcp -m state --state INVALID -j DROP<br>
<br>
ipt46 -t filter -A bad_tcp -j RETURN<br>

<br>
################################ <br>
## filter -- inet_input <br>
## <br>
<br>
# filter out bad packets so they don't even reach other checks <br>
ipt46 -t filter -A inet_input -j inet_banned_input<br>

ipt46 -t filter -A inet_input -p tcp -j bad_tcp<br>
<br>
ipt46 -t filter -A inet_input -m state --state ESTABLISHED,RELATED -j ACCEPT<br>

<br>
ipt46 -t filter -A inet_input -p tcp -j inet_tcp_input<br>
ipt46 -t filter -A inet_input -p udp -j inet_udp_input<br>

ipt4 -t filter -A inet_input -p icmp -j inet_icmp_input<br>
ipt6 -t filter -A inet_input -p icmpv6 -j inet_icmpv6_input<br>

ipt4 -t filter -A inet_input -p igmp -j ACCEPT<br>
<br>
ipt46 -t filter -A inet_input -j RETURN<br>

<br>
################################ <br>
## filter -- inet_output <br>
## <br>
<br>
ipt46 -t filter -A inet_output -j inet_banned_output<br>
<br>

# allow established -- fast path <br>
ipt46 -t filter -A inet_output -m state --state ESTABLISHED,RELATED -j ACCEPT<br>
<br>
ipt46 -t filter -A inet_output -p tcp -j inet_tcp_output<br>

ipt46 -t filter -A inet_output -p udp -j inet_udp_output<br>
ipt4 -t filter -A inet_output -p icmp -j inet_icmp_output<br>

ipt6 -t filter -A inet_output -p icmpv6 -j inet_icmpv6_output<br>
ipt4 -t filter -A inet_output -p igmp -j ACCEPT<br>

<br>
ipt46 -t filter -A inet_output -j RETURN<br>
<br>
################################# <br>
## filter -- inet_banned_input, inet_banned_output <br>
## <br>
<br>

# Drop packets from private, local and reserved addresses. <br>
# You can add 10.0.0.0/8 if your ISP doesn't use it. <br>
# You can also add 224.0.0.0/4 if you don't use multicast. <br>
for ip in 172.16.0.0/12 192.168.0.0/16 127.0.0.0/8 240.0.0.0/5 ; do <br>
ipt4 -t filter -A inet_banned_input -s $ip -j DROP<br>

ipt4 -t filter -A inet_banned_output -d $ip -j REJECT --reject-with icmp-admin-prohibited<br>
done <br>
<br>
if [ -e /etc/firewall/inet_banned4 ] ; then <br>

while read ext_ip ;   do <br>
ipt4 -t filter -A inet_banned_input -s $ext_ip -j DROP<br>
ipt4 -t filter -A inet_banned_output -d $ext_ip -j REJECT --reject-with icmp-admin-prohibited<br>

done < /etc/firewall/inet_banned4<br>
fi <br>
<br>
if [ -e /etc/firewall/inet_banned6 ] ; then <br>
while read ext_ip ;   do <br>

ipt6 -t filter -A inet_banned_input -s $ext_ip -j DROP<br>
ipt6 -t filter -A inet_banned_output -d $ext_ip -j REJECT --reject-with adm-prohibited<br>

done < /etc/firewall/inet_banned6<br>
fi <br>
<br>
ipt46 -t filter -A inet_banned_input -j RETURN<br>
ipt46 -t filter -A inet_banned_output -j RETURN<br>

<br>
################################# <br>
## filter -- inet_tcp_input <br>
## <br>
<br>
while read proto port comment ;   do <br>
if [ -n " $proto " ] ; then <br>

$proto -t filter -A inet_tcp_input -p tcp --dport $port -j ACCEPT<br>
fi <br>
done <<__EOF__ <br>
ipt46 20 ftp-data <br>

ipt46 21 ftp <br>
ipt46 12500:13000 ftp-data <br>
<br>
ipt46 22 ssh <br>
__EOF__ <br>
<br>
# drop all MS stuff so that it won't clutter logs <br>
ipt46 -t filter -A inet_tcp_input -p tcp -m multiport --ports 137 , 138 , 139 , 445 -j DROP<br>

<br>
ipt46 -t filter -A inet_tcp_input -j RETURN<br>
<br>
################################# <br>
## filter -- inet_tcp_output <br>
## <br>
<br>

# drop all MS stuff so that it won't clutter logs <br>
ipt46 -t filter -A inet_tcp_output -p tcp -m multiport --ports 137 , 138 , 139 , 445 -j DROP<br>

<br>
ipt46 -t filter -A inet_tcp_output -j RETURN<br>
<br>
################################# <br>
## filter -- inet_udp_input <br>
## <br>
<br>

# iptv <br>
ipt4 -t filter -A inet_udp_input -p udp -d 224.0.0.0/4 -j ACCEPT<br>
<br>
# drop all MS stuff so that it won't clutter logs <br>

ipt46 -t filter -A inet_udp_input -p udp -m multiport --ports 137 , 138 , 139 , 445 -j DROP<br>

<br>
# some unknown flood on my ISP's net <br>
ipt4 -t filter -A inet_udp_input -p udp --dport 631 -j DROP<br>
<br>
ipt46 -t filter -A inet_udp_input -j RETURN<br>

<br>
################################# <br>
## filter -- inet_udp_output <br>
## <br>
<br>
# drop all MS stuff so that it won't clutter logs <br>
ipt46 -t filter -A inet_udp_output -p udp -m multiport --ports 137 , 138 , 139 , 445 -j DROP<br>

<br>
ipt46 -t filter -A inet_udp_output -j RETURN<br>
<br>
################################# <br>
## filter -- inet_icmp_input <br>
## <br>
<br>

# echo-reply should be handled by conntrack <br>
ipt4 -t filter -A inet_icmp_input -p icmp -m icmp --icmp-type echo -request -j ACCEPT <br>
ipt4 -t filter -A inet_icmp_input -p icmp -m icmp --icmp-type time -exceeded -j ACCEPT<br>

ipt4 -t filter -A inet_icmp_input -p icmp -m icmp --icmp-type destination-unreachable -j ACCEPT<br>
ipt4 -t filter -A inet_icmp_input -p icmp -j DROP<br>

<br>
ipt4 -t filter -A inet_icmp_input -j RETURN<br>
<br>
################################# <br>
## filter -- inet_icmp_output <br>
## <br>
<br>

ipt4 -t filter -A inet_icmp_output -j RETURN<br>
<br>
################################# <br>
## filter -- inet_icmpv6_input <br>
## <br>
<br>
# See RFC 4890. <br>

<br>
# echo-reply should be handled by conntrack <br>
ipt6 -t filter -A inet_icmpv6_input -p icmpv6 -m icmp6 --icmpv6-type echo -request -j ACCEPT <br>

ipt6 -t filter -A inet_icmpv6_input -p icmpv6 -m icmp6 --icmpv6-type destination-unreachable -j ACCEPT<br>
ipt6 -t filter -A inet_icmpv6_input -p icmpv6 -m icmp6 --icmpv6-type packet-too-big -j ACCEPT<br>

ipt6 -t filter -A inet_icmpv6_input -p icmpv6 -m icmp6 --icmpv6-type time -exceeded -j ACCEPT<br>
ipt6 -t filter -A inet_icmpv6_input -p icmpv6 -m icmp6 --icmpv6-type parameter-problem -j ACCEPT<br>

<br>
ipt6 -t filter -A inet_icmpv6_input -p icmpv6 -m icmp6 --icmpv6-type router-solicitation -m hl --hl-eq 255 -j ACCEPT<br>

ipt6 -t filter -A inet_icmpv6_input -p icmpv6 -m icmp6 --icmpv6-type router-advertisement -m hl --hl-eq 255 -j ACCEPT<br>

ipt6 -t filter -A inet_icmpv6_input -p icmpv6 -m icmp6 --icmpv6-type neighbour-solicitation -m hl --hl-eq 255 -j ACCEPT<br>

ipt6 -t filter -A inet_icmpv6_input -p icmpv6 -m icmp6 --icmpv6-type neighbour-advertisement -m hl --hl-eq 255 -j ACCEPT<br>

ipt6 -t filter -A inet_icmpv6_input -p icmpv6 -m icmp6 --icmpv6-type redirect -m hl --hl-eq 255 -j ACCEPT<br>

ipt6 -t filter -A inet_icmpv6_input -p icmpv6 -m icmp6 --icmpv6-type 141 -m hl --hl-eq 255 -j ACCEPT # Inverse neighbour discovery solicitation <br>

ipt6 -t filter -A inet_icmpv6_input -p icmpv6 -m icmp6 --icmpv6-type 142 -m hl --hl-eq 255 -j ACCEPT # Inverse neighbour discovery advertisement <br>

<br>
ipt6 -t filter -A inet_icmpv6_input -p icmpv6 -s fe80::/ 10 -m icmp6 --icmpv6-type 130 -j ACCEPT # Listener query <br>

ipt6 -t filter -A inet_icmpv6_input -p icmpv6 -s fe80::/ 10 -m icmp6 --icmpv6-type 131 -j ACCEPT # Listener report <br>

ipt6 -t filter -A inet_icmpv6_input -p icmpv6 -s fe80::/ 10 -m icmp6 --icmpv6-type 132 -j ACCEPT # Listener done <br>

ipt6 -t filter -A inet_icmpv6_input -p icmpv6 -s fe80::/ 10 -m icmp6 --icmpv6-type 143 -j ACCEPT # Listener report v2 <br>

<br>
ipt6 -t filter -A inet_icmpv6_input -p icmpv6 -m icmp6 --icmpv6-type 148 -m hl --hl-eq 255 -j ACCEPT # Certificate path solicitation <br>

ipt6 -t filter -A inet_icmpv6_input -p icmpv6 -m icmp6 --icmpv6-type 149 -m hl --hl-eq 255 -j ACCEPT # Certificate path advertisement <br>

<br>
ipt6 -t filter -A inet_icmpv6_input -p icmpv6 -s fe80::/ 10 -m icmp6 --icmpv6-type 151 -m hl --hl-eq 1 -j ACCEPT # Multicast router advertisement <br>

ipt6 -t filter -A inet_icmpv6_input -p icmpv6 -s fe80::/ 10 -m icmp6 --icmpv6-type 152 -m hl --hl-eq 1 -j ACCEPT # Multicast router solicitation <br>

ipt6 -t filter -A inet_icmpv6_input -p icmpv6 -s fe80::/ 10 -m icmp6 --icmpv6-type 153 -m hl --hl-eq 1 -j ACCEPT # Multicast router termination <br>

<br>
ipt6 -t filter -A inet_icmpv6_input -j RETURN<br>
<br>
################################# <br>
## filter -- inet_icmpv6_output <br>
## <br>
<br>

ipt6 -t filter -A inet_icmpv6_output -j RETURN<br>
<br>
################################# <br>
## filter -- inet_icmpv6_forward <br>
## <br>
<br>
ipt6 -t filter -A inet_icmpv6_forward -p icmpv6 -m icmp6 --icmpv6-type echo -request -j ACCEPT <br>

ipt6 -t filter -A inet_icmpv6_forward -p icmpv6 -m icmp6 --icmpv6-type destination-unreachable -j ACCEPT<br>
ipt6 -t filter -A inet_icmpv6_forward -p icmpv6 -m icmp6 --icmpv6-type packet-too-big -j ACCEPT<br>

ipt6 -t filter -A inet_icmpv6_forward -p icmpv6 -m icmp6 --icmpv6-type time -exceeded -j ACCEPT<br>
ipt6 -t filter -A inet_icmpv6_forward -p icmpv6 -m icmp6 --icmpv6-type parameter-problem -j ACCEPT<br>

<br>
ipt6 -t filter -A inet_icmpv6_forward -j RETURN<br>
<br>
################################# <br>
## filter -- FORWARD <br>
## <br>
<br>

ipt46 -t filter -A FORWARD -i $INET_IF -j inet_banned_input<br>
ipt46 -t filter -A FORWARD -o $INET_IF -j inet_banned_output<br>

ipt46 -t filter -A FORWARD -p tcp -j bad_tcp<br>
<br>
# don't forward MS stuff <br>
ipt46 -t filter -A FORWARD -p tcp -m multiport --ports 137 , 138 , 139 , 445 -j DROP<br>

ipt46 -t filter -A FORWARD -p udp -m multiport --ports 137 , 138 , 139 , 445 -j DROP<br>

<br>
ipt6 -t filter -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT<br>
<br>
ipt6 -t filter -A FORWARD -p icmpv6 -j inet_icmpv6_forward<br>

<br>
while read proto port ip comment ;   do <br>
if [ -n " $proto " ] ; then <br>
ipt6 -t filter -A FORWARD -d $ip -p $proto --dport $port -j ACCEPT<br>

fi <br>
done <<__EOF__ <br>
tcp 22 ::/0 ssh <br>
tcp 80 2001:db8::1 http <br>
__EOF__ <br>
<br>
ipt6 -t filter -A FORWARD -i $INET6_IF -p tcp -j REJECT --reject-with tcp-reset<br>

ipt6 -t filter -A FORWARD -i $INET6_IF -j DROP<br>
ipt6 -t filter -A FORWARD -o $INET6_IF -j ACCEPT<br>

<br>
echo   " $NAT_IPV4 "   | while read int_ip comment ;   do <br>
if [ -n " $int_ip " ] ; then <br>

ipt4 -t filter -A FORWARD -s $int_ip -o $INET_IF -j ACCEPT<br>
ipt4 -t filter -A FORWARD -d $int_ip -i $INET_IF -j ACCEPT<br>

fi <br>
done <br>
<br>
#ipt46 -t filter -A FORWARD -j LOG --log-level INFO --log-prefix "IPT FORWARD packet died: " <br>
ipt46 -t filter -A FORWARD -j DROP<br>
<br>

############################################################################## <br>
################################ mangle table ################################ <br>
############################################################################## <br>
<br>
ipt46 -t mangle -P INPUT ACCEPT<br>
ipt46 -t mangle -P OUTPUT ACCEPT<br>

ipt46 -t mangle -P FORWARD ACCEPT<br>
ipt46 -t mangle -P PREROUTING ACCEPT<br>
ipt46 -t mangle -P POSTROUTING ACCEPT<br>

<br>
ipt46 -t mangle -F <br>
ipt46 -t mangle -X <br>
<br>
############################################################################## <br>
################################## nat table ################################# <br>
############################################################################## <br>

<br>
ipt4 -t nat -P OUTPUT ACCEPT<br>
ipt4 -t nat -P PREROUTING ACCEPT<br>
ipt4 -t nat -P POSTROUTING ACCEPT<br>

<br>
ipt4 -t nat -F <br>
ipt4 -t nat -X <br>
<br>
#################################### <br>
## nat -- PREROUTING <br>
## <br>

<br>
# Port forwarding <br>
while read proto port int_ip comment ;   do <br>
if [ -n " $proto " ] ; then <br>

ipt4 -t nat -A PREROUTING -i $INET_IF -p $proto --dport $port -j DNAT --to-destination $int_ip : $port <br>

fi <br>
done <<__EOF__ <br>
tcp 1234 192.168.1.3 something <br>
udp 5678 192.168.1.3 something else <br>
__EOF__ <br>
<br>
#################################### <br>
## nat -- POSTROUTING <br>
## <br>

<br>
echo   " $NAT_IPV4 "   | while read int_ip comment ;   do <br>
if [ -n " $int_ip " ] ; then <br>

ipt4 -t nat -A POSTROUTING -s $int_ip -o $INET_IF -j SNAT --to- source $INET_IP <br>
fi <br>
done <br>

<br>
echo 1 > /proc/sys/net/ipv4/ip_forward<br>
<br>
## <br>
## __END__ <br>
#################################


Download: bin-login.name/rc.firewall.txt
Here you can check how firewall works for TCP in IPv6: www.subnetonline.com/pages/ipv6-network-tools/online-ipv6-port-scanner.php

Source: https://habr.com/ru/post/82885/


All Articles