Accept ICMP(v6) RELATED packets ASAP in interface

ICMP and ICMPv6 handling in the Linux kernel ensures all ICMP errors
will be marked as RELATED packets. These are important for the correct
functioning of other layers such as TCP (for instance Path MTU discovery).

Since 3.0.0, matches have been automatically added to firehol interfaces
and routers, so the user does not have to do anything special. It was
however possible to accidentally interfere with this by putting an
explicit drop of any packets towards the end of an interface.

This patch moves the ICMP RELATED match to the beginning of the firewall
(and similiarly the TCP-RESET RELATED match), so such a rule cannot
interfere with correct network operation.

At the same time, the ipv6error service has been marked as deprecated
since it has not done anything useful since 3.0.0.
This commit is contained in:
Philip Whineray 2016-11-26 16:19:14 +00:00
parent 4efbdbf4b3
commit 1557cb6b98
3 changed files with 50 additions and 123 deletions

@ -587,38 +587,12 @@ SERVICE ipv6error
EXAMPLE
server ipv6error accept
NOTES
Not all icmpv6 error types should be treated equally
inbound and outbound.
This service is not needed from 3.0.0. It will do nothing
but issue a warning from 3.1.0; it will be removed in 4.0.0.
-
The ipv6error rule wraps all of them in the following way:
* allow incoming messages only for existing sessions
* allow outgoing messages always
-
The following ICMPv6 messages are handled:
-
* destination-unreachable
* packet-too-big
* ttl-zero-during-transit
* ttl-zero-during-reassembly
* unknown-header-type
* unknown-option
-
Interfaces should always have this set:
-
`server ipv6error accept`
-
In a router with inface being internal and outface being
external the following will meet the recommendations of
[RFC 4890](http://tools.ietf.org/html/rfc4890):
-
`server ipv6error accept`
-
Do not use:
`client ipv6error accept`
unless you are controlling traffic on a router interface
where outface is the internal destination.
-
This service implicitly sets its client or server to ipv6 mode.
The linux connection tracker ensures that ICMPv6 errors
are marked as RELATED. Since 3.0.0, these are automatially
accepted by FireHOL, making a separate command redundant.
SERVICE ipv6neigh
NAME IPv6 Neighbour discovery

@ -16,8 +16,6 @@ wan=wan0
# The key provision is there is no src/dst supplied which will
# interfere since can be sent to multicast addresses, even in
# the case where they are not unsolicited.
#
# Note: DO NOT use 'client ipv6error accept' here
ipv6 interface any ipv6interop proto icmpv6
policy return
client ipv6neigh accept
@ -29,9 +27,6 @@ ipv6 interface any ipv6interop proto icmpv6
#server ipv6router accept
#server ipv6mld accept
# Normal error packets - is RELATED sufficient without this?
server ipv6error accept
interface "$lan" lan
policy reject
@ -47,8 +42,6 @@ interface "$wan" wan
server ping accept
router lan2wan inface "$lan" outface "$wan"
# Normal error packets - is RELATED sufficient without this?
server ipv6error accept
# Neighbour Discover / Router Disscovery packets should not
# Neighbour Discovery / Router Discovery packets should not
# traverse a firewall normally. You may need to add some rules
# if you are firewalling a bridge.

@ -2300,30 +2300,6 @@ add_icmpv6_rule_pair_stateless() {
return 0
}
add_icmpv6_rule_error() {
# Unlike stateful and stateless icmpv6 packets, for a server
# or client we do the same thing:
# ingress error packets allowed if we think we have a connection
# egress error packets allowed whatever
# Possibly we could restrict the whatever to be related also?
local mychain="${1}" \
type="${2}" \
icmpv6error="${3}"
shift 3
local in=in out=out
if [ "${type}" = "client" ]
then
in=out
out=in
fi
rule ${in} reverse action "${@}" chain "${in}_${mychain}" proto icmpv6 custom "--icmpv6-type $icmpv6error" state ESTABLISHED,RELATED || return 1
rule ${out} action "${@}" chain "${out}_${mychain}" proto icmpv6 custom "--icmpv6-type $icmpv6error" || return 1
return 0
}
# --- XBOX ---------------------------------------------------------------------
# Contributed by andrex@alumni.utexas.net
@ -2883,24 +2859,8 @@ rules_ipv6error() {
type="${2}"
shift 2
if ! push_namespace ipv6; then return 1; fi
warning "ipv6error service deprecated - no longer useful and will be removed in 4.0.0"
for icmptype in destination-unreachable \
packet-too-big \
ttl-zero-during-transit \
ttl-zero-during-reassembly \
unknown-header-type \
unknown-option
do
add_icmpv6_rule_error $mychain $type $icmptype "${@}"
if [ $? -ne 0 ]
then
pop_namespace
return 1
fi
done
pop_namespace
return 0
}
@ -5581,7 +5541,28 @@ interface() {
create_chain filter "in_${work_name}" INPUT push_flow_inheritance in in set_work_inface "${@}" inface "${inface}" outface any || return 1
create_chain filter "out_${work_name}" OUTPUT push_flow_inheritance out out set_work_outface reverse "${@}" inface "${inface}" outface any || return 1
# accepting RELATED ICMP/ICMPv6 packets
set_work_function "Accepting all ICMP RELATED sockets in interface '${work_name}'"
if running_ipv4
then
push_namespace ipv4
rule chain "in_${work_name}" state RELATED proto icmp action ACCEPT || return 1
rule chain "out_${work_name}" state RELATED proto icmp action ACCEPT || return 1
pop_namespace
fi
if running_ipv6
then
push_namespace ipv6
rule chain "in_${work_name}" state RELATED proto icmpv6 action ACCEPT || return 1
rule chain "out_${work_name}" state RELATED proto icmpv6 action ACCEPT || return 1
pop_namespace
fi
set_work_function "Accepting TCP-RESET on the output of interface '${work_name}'"
rule chain "out_${work_name}" state RELATED proto tcp custom '--tcp-flags ALL ACK,RST' action ACCEPT || return 1
return 0
}
@ -5627,6 +5608,27 @@ router() {
create_chain filter "in_${work_name}" FORWARD push_flow_inheritance in in set_work_inface set_work_outface "${@}" || return 1
create_chain filter "out_${work_name}" FORWARD push_flow_inheritance out out reverse "${@}" || return 1
set_work_function "Accepting all ICMP RELATED sockets in router '${work_name}'"
if running_ipv4
then
push_namespace ipv4
rule chain "in_${work_name}" state RELATED proto icmp action ACCEPT || return 1
rule chain "out_${work_name}" state RELATED proto icmp action ACCEPT || return 1
pop_namespace
fi
if running_ipv6
then
push_namespace ipv6
rule chain "in_${work_name}" state RELATED proto icmpv6 action ACCEPT || return 1
rule chain "out_${work_name}" state RELATED proto icmpv6 action ACCEPT || return 1
pop_namespace
fi
set_work_function "Accepting TCP-RESET on router '${work_name}'"
rule chain "in_${work_name}" state RELATED proto tcp custom '--tcp-flags ALL ACK,RST' action ACCEPT || return 1
rule chain "out_${work_name}" state RELATED proto tcp custom '--tcp-flags ALL ACK,RST' action ACCEPT || return 1
FIREHOL_ROUTING=1
return 0
}
@ -6339,27 +6341,6 @@ close_interface() {
set_work_function "Finilizing interface '${work_name}'"
# accepting RELATED packets
set_work_function "Accepting all ICMP RELATED sockets in interface '${work_name}'"
if running_ipv4
then
push_namespace ipv4
rule chain "in_${work_name}" state RELATED proto icmp action ACCEPT || return 1
rule chain "out_${work_name}" state RELATED proto icmp action ACCEPT || return 1
pop_namespace
fi
if running_ipv6
then
push_namespace ipv6
rule chain "in_${work_name}" state RELATED proto icmpv6 action ACCEPT || return 1
rule chain "out_${work_name}" state RELATED proto icmpv6 action ACCEPT || return 1
pop_namespace
fi
set_work_function "Accepting TCP-RESET on the output of interface '${work_name}'"
rule chain "out_${work_name}" state RELATED proto tcp custom '--tcp-flags ALL ACK,RST' action ACCEPT || return 1
pop_flow_inheritance
# make sure we have a policy
@ -6402,27 +6383,6 @@ close_router() {
close_all_groups
set_work_function "Finilizing router '${work_name}'"
set_work_function "Accepting all ICMP RELATED sockets in router '${work_name}'"
if running_ipv4
then
push_namespace ipv4
rule chain "in_${work_name}" state RELATED proto icmp action ACCEPT || return 1
rule chain "out_${work_name}" state RELATED proto icmp action ACCEPT || return 1
pop_namespace
fi
if running_ipv6
then
push_namespace ipv6
rule chain "in_${work_name}" state RELATED proto icmpv6 action ACCEPT || return 1
rule chain "out_${work_name}" state RELATED proto icmpv6 action ACCEPT || return 1
pop_namespace
fi
set_work_function "Accepting TCP-RESET on router '${work_name}'"
rule chain "in_${work_name}" state RELATED proto tcp custom '--tcp-flags ALL ACK,RST' action ACCEPT || return 1
rule chain "out_${work_name}" state RELATED proto tcp custom '--tcp-flags ALL ACK,RST' action ACCEPT || return 1
pop_flow_inheritance