Commit 2e2bf5a2 authored by Branko Mikić's avatar Branko Mikić
Browse files

~ BugFix! In checkIPArgFormat() and obtainNetPrefix() the regex expression were revised.

~ obtainRuleIndices() didn't force hostnames of iptables output to be numeric only but could also be a FQDN entry which lead the regex expression to fail.
~ BugFix! In FORWARD_SUBNET_PROTECTIVE chain the ID could easily exceed the maximum length when used with IPv6 as they can naturally grow very large if short (::) notation is omitted. Especially when such an ID is used eg. as a chain name!
Therefore the chain name for forwarded IPv6 subnets now uses 'cksum' instead of the ID returned by formatSubnetAsHexID() function.
The new ID format is now a shorter version to fit them into chain names as well as comment fields of iptables.
~ In the BASE_RULE_SET command using the ANTI-FLOOD chain on anything regardless of being internal or external traffic wasn't a good idea at all. So the new LOCAL chain now allows internal traffic before ANTI-FLOOD protection is applied while any external traffic still needs to pass the ANTI-FLOOD and INVALID chains without creating wild, complex exceptions in the BLOCK chain to dinstinguish invalid, internal traffic from invalid, external traffic.
~ By reordering the rules in the BASE_RULE_SET a lot of stuff was simplyfied to be used on both (IPv4|6) protocols in the same manner.
~ EXPERIMENTAL! A new command called 6TO4 implemented for tunneling IPv6 traffic over IPv4 links. This code is heavily experimental not meant to be used in production environments.
~ NEW! ALLOW_PORT (or ALLOW_SERVICE) command implemented. This is a simple version of allowing traffic for specific ports on the router to reach local daemons.
It would be possible to do that manually by adding a rule to the USER-IN chain but this one uses iptables' 'multiport' feature so that one rule can allow multiple ports at once. Anyway ALLOW_PORT can also be used to only allow a single port per rule.
Attention!
There can be reasons to _not_ do that and have implicitly one rule for allowing one port especially when the firewall rules are tweaked at runtime and removing all ports at once isn't desired.
~ For IPv6 the filter for RH0 headers were removed (!) as nearly any new kernel version does that on it's own even without any netfilter.
~ Outbound traffic on safe ports (eg: 80,443) are now allowed by default for forwared subnets only.
parent 9ec7202f
......@@ -15,6 +15,7 @@ printAbout()
[ALLOW_LINK_LOCAL on_link]
[ALLOW_SERVICE_DISCOVERY on_link]
[ALLOW_TUNNEL mode on_link from_address]
[ALLOW_PORT|ALLOW_SERVICE port[,port,port,...] ip|link]
[FORWARD_SUBNET subnet/mask to_link]
[FORWARD_SUBNET_PROTECTIVE subnet/mask to_link]
[FORWARD_PORT|FORWARD_ROUTING ip|link port(s) to_address[:to_port]]
......@@ -46,6 +47,7 @@ error()
}
# some helpers
function isNaturalNumber() { [[ ${1} =~ ^[0-9]+$ ]]; }
function isInteger() { [[ ${1} == ?(-)+([0-9]) ]]; }
function isFloat() { [[ ${1} == ?(-)@(+([0-9]).*([0-9])|*([0-9]).+([0-9]))?(E?(-|+)+([0-9])) ]]; }
......@@ -262,7 +264,7 @@ obtainLinkFromSubnetPrefix()
{
local sz;
sz=$($IP -o route list | grep -o -P "(?<=$1 dev )\w*")
sz=$($IP -o route list | grep -P "^$1" | grep -o -P "(?<= dev )\w*")
(( $? == 0 )) && printf "%s" $sz && return 0
return 1
}
......@@ -289,7 +291,7 @@ checkIPArgFormat()
[ $ENVID -eq 4 ] && sz="(\d+\.){3}\d+((\:)+(\d)+)*$"
# TODO: check for IPv6 address! Format is untested and likely to fail
[ $ENVID -eq 6 ] && sz="^([\da-fA-F]+:)+:*[\da-fA-F]+$"
[ $ENVID -eq 6 ] && sz="^([\da-fA-F]+:)+(:[\da-fA-F]+)+$"
echo "$1" | grep -q -P "$sz" 1>/dev/nul 2>/dev/nul
return $?
......@@ -305,7 +307,7 @@ checkSubnetArgFormat()
local sz;
[ $ENVID -eq 4 ] && sz="(\d+\.){3}+\d+\/\d+"
[ $ENVID -eq 6 ] && sz="^([\da-fA-F]+:)+:*\/+\d+$"
[ $ENVID -eq 6 ] && sz="^([\da-fA-F]+:)+(:\/\d+)+$"
echo "$1" | grep -q -P "$sz" 1>/dev/nul 2>/dev/nul
return $?
......@@ -363,7 +365,7 @@ obtainRuleIndices()
[ -z "$1" ] && error 71 "obtainRuleIndices(): chain argument is mandatory."
[ -z "$2" ] && error 72 "obtainRuleIndices(): string pattern argument is mandatory."
sz=$($IPTABLES --line-numbers $sy -vL $1 | grep -P -o "^[0-9]*(?=.*$2)")
sz=$($IPTABLES --line-numbers $sy -vnL $1 | grep -P -o "^[0-9]*(?=.*$2)")
printf "%s " $sz
}
......@@ -461,11 +463,9 @@ formatSubnetAsHexID() {
fi
if [ $ENVID -eq 6 ]; then
sy=${1#*/}
sz=${1%/*}
sz=${sz//\:/}
sz+=$(printf "%02X" $sy)
printf "$sz"
printf ${sz//\:/}
[[ $1 =~ '/' ]] && printf "%02X" ${1#*/}
fi
}
......@@ -559,10 +559,18 @@ formatSubnetAsHexID() {
$IPTABLES -A BLOCK -m limit --limit 4/min --limit-burst 8 -j LOG --log-prefix "[BLOCK] "
$IPTABLES -A BLOCK -j DROP
# Will be used in INPUT, OUTPUT to add allowed subnets on internal links
$IPTABLES -N LOCAL
$IPTABLES -A LOCAL -m addrtype --dst-type LOCAL -j RETURN
$IPTABLES -A LOCAL -m addrtype --dst-type MULTICAST -j RETURN
[ $ENVID == "4" ] && $IPTABLES -A LOCAL -m addrtype --dst-type BROADCAST -j RETURN
$IPTABLES -A LOCAL -j BLOCK
# When this chain retuns it's either a local, multi- or broadcast packet
# create an ANTI-FLOOD protection chain. Maximises the rate of incoming connections.
# Used for protection against SYN or PING_OF_DEATH flooding
$IPTABLES -N ANTI-FLOOD
$IPTABLES -A ANTI-FLOOD -m limit --limit 2/s -j RETURN
$IPTABLES -A ANTI-FLOOD -m limit --limit 3/s -j RETURN
$IPTABLES -A ANTI-FLOOD -j LOG --log-prefix "[BLOCK] (ANTIFLOOD) "
$IPTABLES -A ANTI-FLOOD -j DROP
......@@ -570,8 +578,7 @@ formatSubnetAsHexID() {
# this chain should return always! (don't place DROP rules on specific ICMPs here!)
$IPTABLES -N ICMP
# place your custom rules in these chains
# used in INPUT & OUTPUT
# place your custom rules in these chains used in INPUT & OUTPUT
$IPTABLES -N USER-IN
$IPTABLES -N USER-OUT
......@@ -579,6 +586,9 @@ formatSubnetAsHexID() {
$IPTABLES -A INPUT -i lo -j ACCEPT
$IPTABLES -A OUTPUT -o lo -j ACCEPT
# stateful packets intiated by ourself coming back
$IPTABLES -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IPv4
if [ $ENVID == "4" ]; then
......@@ -590,48 +600,27 @@ formatSubnetAsHexID() {
$IPTABLES -A ICMP -p icmp -m icmp --icmp-type 11 -j ACCEPT -m comment --comment "time-exceeded"
$IPTABLES -A ICMP -p icmp -m icmp --icmp-type 12 -j ACCEPT -m comment --comment "parameter-problem"
# when this chain retuns it's either a local, multi- or broadcast packet
$IPTABLES -N LOCAL
$IPTABLES -A LOCAL -m addrtype --dst-type LOCAL -j RETURN
$IPTABLES -A LOCAL -m addrtype --dst-type MULTICAST -j RETURN
$IPTABLES -A LOCAL -m addrtype --dst-type BROADCAST -j RETURN
$IPTABLES -A LOCAL -j BLOCK
# ~~~ INPUT
# stateful packets intiated by ourself coming back
$IPTABLES -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# handle ICMP protocol
$IPTABLES -A INPUT -p icmp -j ICMP
$IPTABLES -A INPUT -m state --state INVALID -j BLOCK
# syn-flood protection
$IPTABLES -A INPUT -p tcp --syn -j ANTI-FLOOD
# furtive port scanner
$IPTABLES -A INPUT -p tcp --tcp-flags SYN,ACK,FIN,RST RST -j ANTI-FLOOD
# allow bootp
$IPTABLES -A INPUT -p udp -m udp --sport 67 --dport 68 -j ACCEPT -m comment --comment "bootp"
# only routable subnets allowed
$IPTABLES -A INPUT -j LOCAL
# allow some safe ports
$IPTABLES -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT -m comment --comment "ssh"
# ~~~ FORWARD (mangle table)
# intercept all the TCP handshakes and correct on-the-fly the wrong MSS value requested by internal hosts
# intercept all the TCP handshakes and correct on-the-fly the wrong
# MSS value requested by internal hosts in magle tables of FORWARD chain
$IPTABLES -A FORWARD -t mangle -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
fi
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IPv6
if [ $ENVID == "6" ]; then
# ICMPs allowed
# filter all packets that have RH0 headers:
#$IPTABLES -A INPUT -m rt --rt-type 0 --rt-segsleft 0 -j DROP
#$IPTABLES -A OUTPUT -m rt --rt-type 0 --rt-segsleft 0 -j DROP
#$IPTABLES -A FORWARD -m rt --rt-type 0 --rt-segsleft 0 -j DROP
# explicit rules for RH0 is many years obsolete and no longer necessary on modern Linux systems!
# https://serverfault.com/questions/410321/debian-ip6tables-rules-setup-for-ipv6/527334
# echo reply allow explicitly on link local
$IPTABLES -A ICMP -p ipv6-icmp -m icmp6 --icmpv6-type 129 -s fe80::/10 -j ACCEPT -m comment --comment "echo-reply allowed on link local"
# accept harmless ICMP requests
$IPTABLES -A ICMP -p ipv6-icmp -m icmp6 --icmpv6-type 1 -j ACCEPT -m comment --comment "destination unreachable"
$IPTABLES -A ICMP -p ipv6-icmp -m icmp6 --icmpv6-type 2 -j ACCEPT -m comment --comment "packet too big"
$IPTABLES -A ICMP -p ipv6-icmp -m icmp6 --icmpv6-type 3 -j ACCEPT -m comment --comment "time exceeded"
......@@ -639,64 +628,53 @@ formatSubnetAsHexID() {
$IPTABLES -A ICMP -p ipv6-icmp -m icmp6 --icmpv6-type 128 -j ANTI-FLOOD -m comment --comment "echo-request: Ping of death"
$IPTABLES -A ICMP -p ipv6-icmp -m icmp6 --icmpv6-type 128 -j ACCEPT -m comment --comment "echo-request"
# filter all packets that have RH0 headers:
$IPTABLES -A INPUT -m rt --rt-type 0 --rt-segsleft 0 -j DROP
$IPTABLES -A OUTPUT -m rt --rt-type 0 --rt-segsleft 0 -j DROP
$IPTABLES -A FORWARD -m rt --rt-type 0 --rt-segsleft 0 -j DROP
# ~~~ INPUT
# ICMP: handling of router|neighbor solicitation|advertisments (with special hop limits)
# ICMP: handling of router|neighbor solicitation|advertisments
# with special hop limits for traffic in and out
$IPTABLES -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 133 -m hl --hl-eq 255 -j ACCEPT -m comment --comment "multicast listener done"
$IPTABLES -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 134 -m hl --hl-eq 255 -j ACCEPT -m comment --comment "router advertisement"
$IPTABLES -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 135 -m hl --hl-eq 255 -j ACCEPT -m comment --comment "neighbor solicitation"
$IPTABLES -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 136 -m hl --hl-eq 255 -j ACCEPT -m comment --comment "neighbor advertisement"
# stateful packets intiated by ourself coming back
$IPTABLES -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# echo reply allow explicitly on link local
$IPTABLES -A INPUT -s fe80::/10 -p ipv6-icmp -m icmp6 --icmpv6-type 129 -j ACCEPT -m comment --comment "echo-reply allowed on link local"
$IPTABLES -A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type 133 -m hl --hl-eq 255 -j ACCEPT -m comment --comment "multicast listener done"
$IPTABLES -A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type 135 -m hl --hl-eq 255 -j ACCEPT -m comment --comment "neighbor solicitation"
$IPTABLES -A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type 136 -m hl --hl-eq 255 -j ACCEPT -m comment --comment "neighbor advertisement"
$IPTABLES -A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type 143 -m hl --hl-eq 1 -j ACCEPT -m comment --comment "V2 multicast listener report"
# handle ICMP protocol
$IPTABLES -A INPUT -p ipv6-icmp -j ICMP
fi
$IPTABLES -A INPUT -m state --state INVALID -j BLOCK
# syn-flood protection
$IPTABLES -A INPUT -p tcp --syn -j ANTI-FLOOD
# furtive port scanner
$IPTABLES -A INPUT -p tcp --tcp-flags SYN,ACK,FIN,RST RST -j ANTI-FLOOD
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for both IPv(4|6)
# allow bootp
$IPTABLES -A INPUT -p udp -m udp --sport 67 --dport 68 -j ACCEPT -m comment --comment "bootp"
# only routable subnets allowed
$IPTABLES -A INPUT -j LOCAL
# ~~~ OUTPUT
$IPTABLES -A INPUT -m state --state INVALID -j BLOCK
# ICMP: handling of router|neighbor solicitation|advertisments (with special hop limits)
$IPTABLES -A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type 133 -m hl --hl-eq 255 -j ACCEPT -m comment --comment "multicast listener done"
$IPTABLES -A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type 135 -m hl --hl-eq 255 -j ACCEPT -m comment --comment "neighbor solicitation"
$IPTABLES -A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type 136 -m hl --hl-eq 255 -j ACCEPT -m comment --comment "neighbor advertisement"
$IPTABLES -A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type 143 -m hl --hl-eq 1 -j ACCEPT -m comment --comment "V2 multicast listener report"
fi
# syn-flood protection
$IPTABLES -A INPUT -p tcp --syn -j ANTI-FLOOD
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for both IPv(4|6)
# furtive port scanner
$IPTABLES -A INPUT -p tcp --tcp-flags SYN,ACK,FIN,RST RST -j ANTI-FLOOD
# user customized rules for traffic coming in
$IPTABLES -A INPUT -j USER-IN -m comment --comment "add your custom INPUT rules in the USER-IN chain!"
# allow some safe ports
$IPTABLES -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT -m comment --comment "ssh"
# stateful packets intiated by ourself going out
$IPTABLES -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# user customized rules for traffic going out
$IPTABLES -A OUTPUT -j USER-OUT -m comment --comment "add your custom OUTPUT rules in the USER-OUT chain!"
# new packets are allowed to go out from anywhere
$IPTABLES -A OUTPUT -m state --state NEW -j ACCEPT
# only routable subnets allowed
$IPTABLES -A OUTPUT -j LOCAL
# ~~~ any of the default chains should end with this!
# user customized rules for traffic coming in & going out
$IPTABLES -A INPUT -j USER-IN -m comment --comment "add your custom INPUT rules in the USER-IN chain!"
$IPTABLES -A OUTPUT -j USER-OUT -m comment --comment "add your custom OUTPUT rules in the USER-OUT chain!"
# default log rules
# any of the default chains should end with this!
$IPTABLES -A INPUT -m limit --limit 8/min --limit-burst 16 -j LOG --log-prefix "[IN$ENVID-DROP] "
$IPTABLES -A OUTPUT -m limit --limit 8/min --limit-burst 16 -j LOG --log-prefix "[OU$ENVID-DROP] "
$IPTABLES -A FORWARD -m limit --limit 8/min --limit-burst 16 -j LOG --log-prefix "[FW$ENVID-DROP] "
......@@ -708,12 +686,12 @@ formatSubnetAsHexID() {
(( $? != 0 )) && sz=" (WARNING! '$1' is currently not available. Maybe invoked later?)"
printf "# allowing DHCP (IPv%s) client requests on '%s'.%s\n" $ENVID $1 "$sz"
ID="ALLOW_DHCP_CLIENT on $(getLinkID $1)"
ID="ALLOW_DHCP_CLIENT_on_$(getLinkID $1)"
deleteRules USER-IN "$ID"
if [ $ENVID -eq 4 ]; then
$IPTABLES -A USER-IN -p udp -m udp -i $1 -s 0.0.0.0 --sport 68 -d 255.255.255.255 --dport 67 -j ACCEPT -m comment --comment "$ID"
$IPTABLES -A USER-IN -p udp -m udp -i $1 --sport 67 --dport 68 -j ACCEPT -m comment --comment "$ID"
$IPTABLES -A USER-IN -p udp -m udp -i $1 --sport 67 --dport 68 -j ACCEPT -m comment --comment "$ID (dhcp/bootp)"
fi
if [ $ENVID -eq 6 ]; then
......@@ -721,20 +699,17 @@ formatSubnetAsHexID() {
fi
shift
unset ID;
;;
ALLOW_SUBNETS)
checkLink $1
(( $? != 0 )) && error 41 "ALLOW_SUBNETS expects an interface node argument (eg: eth0)"
probeChains USER-IN USER-OUT
(( $? != 0 )) && error 42 "The 'USER-IN' or 'USER-OUT' chain is missing. Setup a new base firewall with BASE_RULE_SET first."
ID="ALLOW_SUBNETS on $(getLinkID $1)"
probeChains LOCAL
(( $? != 0 )) && error 42 "The 'LOCAL' chain is missing. Setup a new base firewall with BASE_RULE_SET first."
deleteRules USER-IN "$ID"
deleteRules USER-OUT "$ID"
ID="ALLOW_SUBNETS_$(getLinkID $1)"
deleteRules LOCAL "$ID"
printf "# allowing subnets on $1 link:"
unset p
......@@ -747,14 +722,14 @@ formatSubnetAsHexID() {
echo "$p" | grep "$subnet" 1>/dev/nul 2>/dev/nul
(( $? == 0 )) && continue
$IPTABLES -A USER-IN -i $1 -s $subnet -j ACCEPT -m comment --comment "$ID"
$IPTABLES -A USER-OUT -o $1 -s $addr -d $subnet -j ACCEPT -m comment --comment "$ID"
$IPTABLES -I LOCAL 1 -i $1 -s $subnet -j ACCEPT -m comment --comment "$ID"
$IPTABLES -I LOCAL 1 -o $1 -s $addr -d $subnet -j ACCEPT -m comment --comment "$ID"
p+=" $subnet"
done
printf " %s" "(broadcast)"
$IPTABLES -A USER-IN -i $1 -m pkttype --pkt-type broadcast -j ACCEPT -m comment --comment "$ID (broadcast)"
printf " (broadcast)"
$IPTABLES -I LOCAL 1 -i $1 -m pkttype --pkt-type broadcast -j ACCEPT -m comment --comment "$ID (broadcast)"
# for IPv6 on this link
if [ $ENVID -eq 6 ]; then
......@@ -762,7 +737,7 @@ formatSubnetAsHexID() {
[[ $addr =~ fe80 ]] || error 43 "A link local address is not available for $1."
printf " %s" $addr
$IPTABLES -A USER-OUT -o $1 -s $addr -j ACCEPT -m comment --comment "$ID (outbound from link-local)"
$IPTABLES -I LOCAL 1 -o $1 -s $addr -j ACCEPT -m comment --comment "$ID (outbound from link-local)"
fi
echo ""
......@@ -774,21 +749,21 @@ formatSubnetAsHexID() {
checkLink $1
(( $? != 0 )) && error 41 "ALLOW_LINK_LOCAL expects an interface node argument (eg: eth0)"
probeChains USER-IN USER-OUT
probeChains LOCAL
(( $? != 0 )) && error 42 "The 'USER-IN' or 'USER-OUT' chain is missing. Setup a new base firewall with BASE_RULE_SET first."
ID="ALLOW_LINK_LOCAL on $(getLinkID $1)"
deleteRules USER-IN "$ID"
deleteRules USER-OUT "$ID"
deleteRules LOCAL "$ID"
[ $ENVID -eq 4 ] && sz="169.254.0.0/16"
[ $ENVID -eq 6 ] && sz="fe80::/10"
printf "# allowing link local (%s) on %s\n" $sz $1
$IPTABLES -A USER-IN -i $1 -d $sz -j ACCEPT -m comment --comment "$ID"
$IPTABLES -A USER-OUT -o $1 -s $sz -j ACCEPT -m comment --comment "$ID"
$IPTABLES -I LOCAL 1 -i $1 -d $sz -j ACCEPT -m comment --comment "$ID"
$IPTABLES -I LOCAL 1 -i $1 -s $sz -m pkttype --pkt-type multicast -j ACCEPT -m comment --comment "$ID (multicast)"
$IPTABLES -I LOCAL 1 -o $1 -s $sz -j ACCEPT -m comment --comment "$ID"
shift
;;
......@@ -797,27 +772,29 @@ formatSubnetAsHexID() {
checkLink $1
(( $? != 0 )) && error 36 "ALLOW_SERVICE_DISCOVERY expects an interface node argument (eg: eth0)"
probeChains USER-IN
probeChains LOCAL
(( $? != 0 )) && error 37 "The 'USER-IN' chain is missing. Setup a new base firewall with BASE_RULE_SET first."
printf "# allowing service discovery on %s link.\n" $1
ID="ALLOW_SERVICE_DISCOVERY on $(getLinkID $1)"
deleteRules USER-IN "$ID"
deleteRules LOCAL "$ID"
if [ $ENVID -eq 4 ]; then
$IPTABLES -A USER-IN -d 224.0.0.251/32 -p udp -m udp -i $1 --dport 5353 -j ACCEPT -m comment --comment "$ID (multicast mDNS)"
$IPTABLES -A USER-IN -d 239.255.255.250/32 -p udp -m udp -i $1 --dport 1900 -j ACCEPT -m comment --comment "$ID (multicast UPnP)"
$IPTABLES -I LOCAL 1 -d 224.0.0.251/32 -p udp -m udp -i $1 --dport 5353 -j ACCEPT -m comment --comment "$ID (multicast mDNS)"
$IPTABLES -I LOCAL 1 -d 239.255.255.250/32 -p udp -m udp -i $1 --dport 1900 -j ACCEPT -m comment --comment "$ID (multicast UPnP)"
fi
if [ $ENVID -eq 6 ]; then
$IPTABLES -A USER-IN -d ff02::fb/128 -p udp -m udp -i $1 --dport 5353 -j ACCEPT -m comment --comment "$ID (multicast mDNS)"
$IPTABLES -A USER-IN -d ff02::f/128 -p udp -m udp -i $1 --dport 1900 -j ACCEPT -m comment --comment "$ID (multicast UPnP)"
$IPTABLES -I LOCAL 1 -d ff02::fb/128 -p udp -m udp -i $1 --dport 5353 -j ACCEPT -m comment --comment "$ID (multicast mDNS)"
$IPTABLES -I LOCAL 1 -d ff02::f/128 -p udp -m udp -i $1 --dport 1900 -j ACCEPT -m comment --comment "$ID (multicast UPnP)"
fi
shift;
;;
ALLOW_TUNNEL)
[ $ENVID -eq 6 ] && error 90 "Only useful with IPv4."
probeChains USER-IN
(( $? != 0 )) && error 37 "The 'USER-IN' chain is missing. Setup a new base firewall with BASE_RULE_SET first."
probeChains USER-OUT
......@@ -849,6 +826,61 @@ formatSubnetAsHexID() {
shift; shift; shift;
;;
6TO4)
[ $ENVID -eq 6 ] && error 90 "Only useful with IPv4."
checkIPArgFormat "$1"
(( $? != 0 )) && error 91 "6to4 expects a public, routable IPv4 wan address."
checkLink $2
(( $? == 0 )) && error 92 "Tunnel name '$2' already in use.\n"
sz=$(printf "2002:%02x%02x:%02x%02x:e0::1" ${1//./ })
ip tunnel add $2 mode sit local $1 remote 192.88.99.1 ttl 125 dev eth2
ip -6 address add $sz dev $2
ip link set $2 up
ip -6 route add 2000::/3 dev $2 metric 1
#ip6tables -I FORWARD 1 -s 2002::/16 -o sit2 -j ACCEPT
shift; shift;
;;
ALLOW_PORT|ALLOW_SERVICE)
# $1 == port or ports
ay=${1//,/}
for sz in $ay; do
isNaturalNumber $sz
(( $? != 0 )) && error 70 "ALLOW_PORT expects a destination port or ports argument (eg: 80,443)"
done
# $2 == device node or IP address?
checkIPArgFormat "$2"
if (( $? != 0 )); then
[[ $2 =~ [:alnum:]+ ]] && error 71 "ALLOW_PORT expects either an IP or interface argument."
checkLink $2
(( $? != 0 )) && printf "# WARNING! '$2' currently not available. Maybe invoked later?\n"
FILTER_BY="-i $2"
printf "# allow port(s): %s to reach %s\n (WARNING! Ports reachable for any address configured on this device! Maybe this is unintended?)\n" $1 $2
else
sz=$(obtainNetPrefix $2)
[ -z $sz ] && error 73 "ALLOW_PORT has no route to '$2' or argument has malformed IP format"
sz=$(obtainLinkFromSubnetPrefix $sz)
FILTER_BY="-d $2"
printf "# allow port(s): %s to reach %s on %s\n" $1 $2 $sz
fi
ID="ALLOW_PORT_$1_$(formatSubnetAsHexID $2)_$sz"
deleteRules USER-IN "$ID"
$IPTABLES -A USER-IN $FILTER_BY -p tcp -m multiport --dports $1 -j ACCEPT -m comment --comment "$ID"
shift; shift;
unset FILTER_BY; unset ay; unset ID;
;;
FORWARD_SUBNET)
sz=""
[ $ENVID -eq 4 ] && sz=" (eg: 192.168.0.0/16)"
......@@ -907,9 +939,6 @@ formatSubnetAsHexID() {
CHAIN=$(printf "%X-IN" $(cksum <<<"$ID" | grep -oP "^\d*"))
allocChain $CHAIN
# forward to the inside for related or established traffic only!
$IPTABLES -A $CHAIN -m state --state RELATED,ESTABLISHED -j ACCEPT
# get index position for placing subchains in FORWARD chain
returnRuleCount FORWARD
n=$?
......@@ -923,19 +952,21 @@ formatSubnetAsHexID() {
$IPTABLES -A $CHAIN -m state --state INVALID -j BLOCK
# syn-flood protection
$IPTABLES -A $CHAIN -p tcp --syn -j ANTI-FLOOD
$IPTABLES -A $CHAIN ! -d $1 -p tcp --syn -j ANTI-FLOOD
# furtive port scanner
$IPTABLES -A $CHAIN -p tcp --tcp-flags SYN,ACK,FIN,RST RST -j ANTI-FLOOD
$IPTABLES -A $CHAIN ! -d $1 -p tcp --tcp-flags SYN,ACK,FIN,RST RST -j ANTI-FLOOD
# allow safe ports for inbound traffic
#$IPTABLES -A $CHAIN -p tcp -m tcp --sports 80,443 -j ACCEPT
# $IPTABLES -A $CHAIN -p tcp -m tcp -m multiport --sports 80,443 -j ACCEPT
# forward to the inside for related or established traffic only!
$IPTABLES -A $CHAIN -m state --state RELATED,ESTABLISHED -j ACCEPT
$IPTABLES -I FORWARD $n -i $2 -o $DEV -d $1 -j $CHAIN -m comment --comment "$ID"
# for IPv6 subnets the max chain name length can
# be easily exceeded so we need a shorter name
#CHAIN=$(printf "%s-%s-%s" $(formatSubnetAsHexID "$1") $DEV $2)
CHAIN=$(printf "%X-OUT" $(cksum <<<"$ID" | grep -oP "^\d*"))
allocChain $CHAIN
......@@ -968,7 +999,7 @@ formatSubnetAsHexID() {
[[ ! $1 =~ [A-Za-z]{3}[0-9]+ ]] && error 72 "FORWARD_ROUTING expects '$1' to be a device node or an IP address."
checkLink $1
(( $? != 0 )) && sz=" (WARNING! '$1' currently not available. Maybe invoked later?)"
(( $? != 0 )) && printf "# WARNING! '$1' currently not available. Maybe invoked later?\n"
FILTER_BY="-i $1"
else
......@@ -1076,7 +1107,6 @@ formatSubnetAsHexID() {
;;
REMOVE_RULES)
#TODO: REMOVE_RULES should also be able to delete rules by a link name
printf "# Removing rules containing '$1' in:"
for sz in $($IPTABLES -nvL | grep -o -P "(?<=Chain\s)\S+"); do
$IPTABLES -nvL $sz | grep "$1" 1>/dev/nul 2>/dev/nul
......@@ -1124,6 +1154,5 @@ formatSubnetAsHexID() {
esac
done
echo "#~~~ created by ${0##*/}"
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment