mirror of
https://github.com/firehol/firehol.git
synced 2024-06-28 18:02:33 +00:00
marks can now be stateful/stateless and temporary/permanent as per #50
This commit is contained in:
parent
55e445e033
commit
4f2b99298a
194
sbin/firehol.in
194
sbin/firehol.in
@ -99,18 +99,12 @@ declare -A MARKS_BITS=()
|
||||
declare -A MARKS_MASKS=()
|
||||
declare -A MARKS_MAX=()
|
||||
declare -A MARKS_SHIFT=()
|
||||
declare -A MARKS_SAVERESTORE=()
|
||||
declare -A MARKS_STATEFUL=()
|
||||
MARKS_SAVERESTORE_STATEFUL_MASK="0x00000000"
|
||||
MARKS_SAVERESTORE_STATELESS_MASK="0x00000000"
|
||||
MARKS_TOTAL_BITS=0
|
||||
|
||||
marksreset() {
|
||||
#echo >&2 "${FUNCNAME} ${*}: Reseting marks..."
|
||||
MARKS_BITS=()
|
||||
MARKS_MASKS=()
|
||||
MARKS_MAX=()
|
||||
MARKS_SHIFT=()
|
||||
MARKS_TOTAL_BITS=0
|
||||
#declare -p MARKS_BITS MARKS_MASKS MARKS_MAX MARKS_SHIFT >&2
|
||||
}
|
||||
|
||||
# taken from http://stackoverflow.com/questions/109023/how-to-count-the-number-of-set-bits-in-a-32-bit-integer
|
||||
# and http://books.google.gr/books?id=iBNKMspIlqEC&pg=PA66&redir_esc=y#v=onepage&q&f=false
|
||||
# counts the number of bits set in a number
|
||||
@ -135,12 +129,56 @@ ispoweroftwo() {
|
||||
return 1
|
||||
}
|
||||
|
||||
marksreset() { markdef clear; }
|
||||
markdef() {
|
||||
# echo >&2 "${FUNCNAME} ${*}"
|
||||
|
||||
if [ "$1" = "reset" -o "$1" = "clear" ]
|
||||
then
|
||||
MARKS_BITS=()
|
||||
MARKS_MASKS=()
|
||||
MARKS_MAX=()
|
||||
MARKS_SHIFT=()
|
||||
MARKS_SAVERESTORE=()
|
||||
MARKS_STATEFUL=()
|
||||
MARKS_SAVERESTORE_STATEFUL_MASK="0x00000000"
|
||||
MARKS_SAVERESTORE_STATELESS_MASK="0x00000000"
|
||||
MARKS_TOTAL_BITS=0
|
||||
return 0
|
||||
fi
|
||||
|
||||
local saverestore=1
|
||||
local stateful=1
|
||||
local name="${1}"; shift
|
||||
local max="${1}"; shift
|
||||
|
||||
while [ ! -z "${1}" ]
|
||||
do
|
||||
case "${1}" in
|
||||
save|restore|permanent)
|
||||
local saverestore=1
|
||||
;;
|
||||
|
||||
nosave|norestore|temp|temporary)
|
||||
local saverestore=0
|
||||
;;
|
||||
|
||||
stateless)
|
||||
local stateful=0
|
||||
;;
|
||||
|
||||
stateful)
|
||||
local stateful=1
|
||||
;;
|
||||
|
||||
*)
|
||||
echo >&2 "${FUNCNAME}: Unknown keyword '${1}'."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if [ ! -z "${MARKS_MASKS[$name]}" ]
|
||||
then
|
||||
echo >&2 "Mark type '${name}' already exists with mask ${MARKS_MASKS[$name]}. Please use 'marksreset' to reset them before re-defining them."
|
||||
@ -191,9 +229,21 @@ markdef() {
|
||||
MARKS_MAX[$name]=$max
|
||||
MARKS_BITS[$name]=$bits
|
||||
MARKS_MASKS[$name]=$(printf "0x%08x" $mask)
|
||||
MARKS_STATEFUL[$name]=$stateful
|
||||
MARKS_SAVERESTORE[$name]=$saverestore
|
||||
|
||||
if [ $saverestore -eq 1 ]
|
||||
then
|
||||
if [ $stateful -eq 1 ]
|
||||
then
|
||||
MARKS_SAVERESTORE_STATEFUL_MASK=$(printf "0x%08x" $[MARKS_SAVERESTORE_STATEFUL_MASK | mask])
|
||||
else
|
||||
MARKS_SAVERESTORE_STATELESS_MASK=$(printf "0x%08x" $[MARKS_SAVERESTORE_STATELESS_MASK | mask])
|
||||
fi
|
||||
fi
|
||||
|
||||
# echo "Mark $name with $[MARKS_MAX[$name] + 1] possible values (from 0 to ${MARKS_MAX[$name]}), uses ${MARKS_BITS[$name]} bits, has mask ${MARKS_MASKS[$name]} and values should be shifted by ${MARKS_SHIFT[$name]} bits"
|
||||
# declare -p MARKS_BITS MARKS_MASKS MARKS_MAX MARKS_SHIFT >&2
|
||||
# declare -p MARKS_BITS MARKS_MASKS MARKS_MAX MARKS_SHIFT MARKS_STATEFUL MARKS_SAVERESTORE MARKS_SAVERESTORE_STATEFUL_MASK MARKS_SAVERESTORE_STATELESS_MASK >&2
|
||||
|
||||
MARKS_TOTAL_BITS=$[ MARKS_TOTAL_BITS + bits ]
|
||||
}
|
||||
@ -439,11 +489,60 @@ FIREHOL_TRUST_LOOPBACK=1
|
||||
|
||||
# FireHOL allows multiple independent MARKs.
|
||||
# By default FireHOL requires 'connmark' and 'usermark'.
|
||||
# The possible values supported by each may be defined here.
|
||||
# The value must be a power of two.
|
||||
|
||||
# reset the internal marks to empty - do not remove
|
||||
marksreset
|
||||
# Mark types may be defined with this template:
|
||||
#
|
||||
# markdef NAME VALUES [stateful|stateless] [permanent|temporary]
|
||||
#
|
||||
# NAME = a name for this mark type
|
||||
# connmark and usermark should always be defined.
|
||||
#
|
||||
# VALUES = max number of marks to support (0 to VALUES - 1)
|
||||
# VALUES must be a power of two.
|
||||
#
|
||||
# stateful = all statements that assign this mark should
|
||||
# only apply it on NEW packets.
|
||||
#
|
||||
# stateless = all statements that assign this mark type should
|
||||
# only apply it only to traffic matched by the
|
||||
# optional rule parameters given.
|
||||
#
|
||||
# temporary = do not save/restore to/from connection marks.
|
||||
# This means RESPONSES to the matched packets
|
||||
# will not get the mark.
|
||||
#
|
||||
# permanent = save/restore to/from connection marks
|
||||
# This means that RESPONSES will get the mark.
|
||||
#
|
||||
# NOTES ABOUT markdef OPTIONS
|
||||
#
|
||||
# default is : stateful permanent
|
||||
# in this mode, only NEW packets of connections need
|
||||
# to be marked. ESTABLISHED and RELATED packets
|
||||
# will automatically get the same mark too.
|
||||
# So, in FireHOL mark helpers (connmark, mark, custommark)
|
||||
# you will only need to match a REQUEST packet and
|
||||
# automatically all the packets of the connection will
|
||||
# get the mark.
|
||||
#
|
||||
# - stateful temporary
|
||||
# In this mode, only NEW packets will be marked for each
|
||||
# connection. ESTABLISHED and RELATED packets will NOT
|
||||
# get the mark.
|
||||
#
|
||||
# - stateless permanent
|
||||
# In this mode, whatever the helper statement matches
|
||||
# will get the mark. This mark will also be applied to
|
||||
# all the packets that are encountered after the marked
|
||||
# packet and are part of the same socket.
|
||||
#
|
||||
# - stateless temporary
|
||||
# In this mode, only whatever the helper statement matches
|
||||
# will get the mark. Nothing else.
|
||||
#
|
||||
|
||||
# clear the internal marks - do not remove this line
|
||||
markdef clear
|
||||
|
||||
# connmarks are used by the connmark helper
|
||||
markdef connmark 64
|
||||
@ -451,11 +550,12 @@ markdef connmark 64
|
||||
# usermark are used by the mark helper
|
||||
markdef usermark 128
|
||||
|
||||
# Additional types may be defined like this:
|
||||
# Custom mark example:
|
||||
#
|
||||
# markdef qosmark 8
|
||||
# To use it use 'custommark' helper and match
|
||||
# The first argument to both is the mark name (qosmark in this case)
|
||||
|
||||
#
|
||||
# To use it use 'custommark' helper and optional rule parameter.
|
||||
# The first argument to both should the mark name (qosmark in this case)
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# IPTABLES PACKETS LOGGING
|
||||
@ -552,7 +652,7 @@ then
|
||||
fi
|
||||
|
||||
# save the information for the other tools
|
||||
declare -p MARKS_BITS MARKS_MASKS MARKS_MAX MARKS_SHIFT >"${FIREHOL_SPOOL_DIR}/marks.conf"
|
||||
declare -p MARKS_BITS MARKS_MASKS MARKS_MAX MARKS_SHIFT MARKS_STATEFUL MARKS_SAVERESTORE MARKS_SAVERESTORE_STATEFUL_MASK MARKS_SAVERESTORE_STATELESS_MASK >"${FIREHOL_SPOOL_DIR}/marks.conf"
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
@ -696,8 +796,8 @@ which_cmd FLOCK_CMD flock
|
||||
|
||||
if [ ! -f "${FIREHOL_CONFIG_DIR}/firehol-defaults.conf" ]
|
||||
then
|
||||
"${EGREP_CMD}" "^# --- BEGIN OF FIREHOL DEFAULTS ---" -A 600 "${FIREHOL_FILE}" |\
|
||||
"${EGREP_CMD}" "^# --- END OF FIREHOL DEFAULTS ---" -B 600 >"${FIREHOL_CONFIG_DIR}/firehol-defaults.conf" || exit 1
|
||||
"${EGREP_CMD}" "^# --- BEGIN OF FIREHOL DEFAULTS ---" -A 1000 "${FIREHOL_FILE}" |\
|
||||
"${EGREP_CMD}" "^# --- END OF FIREHOL DEFAULTS ---" -B 1000 >"${FIREHOL_CONFIG_DIR}/firehol-defaults.conf" || exit 1
|
||||
"${CHOWN_CMD}" root:root "${FIREHOL_CONFIG_DIR}/firehol-defaults.conf" || exit 1
|
||||
"${CHMOD_CMD}" 600 "${FIREHOL_CONFIG_DIR}/firehol-defaults.conf" || exit 1
|
||||
fi
|
||||
@ -3636,12 +3736,23 @@ connmark() {
|
||||
do
|
||||
case "${chain}" in
|
||||
interface)
|
||||
rule table mangle chain PREROUTING custom '-m conntrack --ctstate NEW' inface "${@}" action MARK to "${mark}" || return 1
|
||||
rule table mangle chain POSTROUTING custom '-m conntrack --ctstate NEW' outface "${@}" action MARK to "${mark}" || return 1
|
||||
if [ ${MARKS_STATEFUL[connmark]} -eq 1 ]
|
||||
then
|
||||
rule table mangle chain PREROUTING custom '-m conntrack --ctstate NEW' inface "${@}" action MARK to "${mark}" || return 1
|
||||
rule table mangle chain POSTROUTING custom '-m conntrack --ctstate NEW' outface "${@}" action MARK to "${mark}" || return 1
|
||||
else
|
||||
rule table mangle chain PREROUTING inface "${@}" action MARK to "${mark}" || return 1
|
||||
rule table mangle chain POSTROUTING outface "${@}" action MARK to "${mark}" || return 1
|
||||
fi
|
||||
;;
|
||||
|
||||
*)
|
||||
rule table mangle chain "${chain}" custom '-m conntrack --ctstate NEW' "${@}" action MARK to "${mark}" || return 1
|
||||
if [ ${MARKS_STATEFUL[connmark]} -eq 1 ]
|
||||
then
|
||||
rule table mangle chain "${chain}" custom '-m conntrack --ctstate NEW' "${@}" action MARK to "${mark}" || return 1
|
||||
else
|
||||
rule table mangle chain "${chain}" action MARK to "${mark}" || return 1
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
@ -3673,7 +3784,12 @@ custommark() {
|
||||
local mark="$(mark_value $name $num)"
|
||||
test -z "${mark}" && work_error=$[work_error + 1] && return 1
|
||||
|
||||
rule table mangle chain "${where}" custom '-m conntrack --ctstate NEW' "${@}" action MARK to "${mark}" || return 1
|
||||
if [ ${MARKS_STATEFUL[$name]} -eq 1 ]
|
||||
then
|
||||
rule table mangle chain "${where}" custom '-m conntrack --ctstate NEW' "${@}" action MARK to "${mark}" || return 1
|
||||
else
|
||||
rule table mangle chain "${where}" "${@}" action MARK to "${mark}" || return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
@ -4826,13 +4942,27 @@ close_router() {
|
||||
close_master() {
|
||||
set_work_function "Finilizing firewall policies"
|
||||
|
||||
# copy CONNMARK to MARK at the top of mangle, on entry points
|
||||
iptables_both -t mangle -I OUTPUT 1 -m conntrack --ctstate ESTABLISHED,RELATED -j CONNMARK --restore-mark
|
||||
iptables_both -t mangle -I PREROUTING 1 -m conntrack --ctstate ESTABLISHED,RELATED -j CONNMARK --restore-mark
|
||||
if [ ! "${MARKS_SAVERESTORE_STATEFUL_MASK}" = "0x00000000" ]
|
||||
then
|
||||
# copy CONNMARK to MARK at the top of mangle, on entry points
|
||||
iptables_both -t mangle -I OUTPUT 1 -m conntrack --ctstate ESTABLISHED,RELATED -j CONNMARK --restore-mark --mask ${MARKS_SAVERESTORE_STATEFUL_MASK}
|
||||
iptables_both -t mangle -I PREROUTING 1 -m conntrack --ctstate ESTABLISHED,RELATED -j CONNMARK --restore-mark --mask ${MARKS_SAVERESTORE_STATEFUL_MASK}
|
||||
|
||||
# save MARK to CONNMARK at the end of mangle, on exit points
|
||||
iptables_both -t mangle -A INPUT -m conntrack --ctstate NEW -j CONNMARK --save-mark
|
||||
iptables_both -t mangle -A POSTROUTING -m conntrack --ctstate NEW -j CONNMARK --save-mark
|
||||
# save MARK to CONNMARK at the end of mangle, on exit points
|
||||
iptables_both -t mangle -A INPUT -m conntrack --ctstate NEW -j CONNMARK --save-mark --mask ${MARKS_SAVERESTORE_STATEFUL_MASK}
|
||||
iptables_both -t mangle -A POSTROUTING -m conntrack --ctstate NEW -j CONNMARK --save-mark --mask ${MARKS_SAVERESTORE_STATEFUL_MASK}
|
||||
fi
|
||||
|
||||
if [ ! "${MARKS_SAVERESTORE_STATELESS_MASK}" = "0x00000000" ]
|
||||
then
|
||||
# copy CONNMARK to MARK at the top of mangle, on entry points
|
||||
iptables_both -t mangle -I OUTPUT 1 -j CONNMARK --restore-mark --mask ${MARKS_SAVERESTORE_STATELESS_MASK}
|
||||
iptables_both -t mangle -I PREROUTING 1 -j CONNMARK --restore-mark --mask ${MARKS_SAVERESTORE_STATELESS_MASK}
|
||||
|
||||
# save MARK to CONNMARK at the end of mangle, on exit points
|
||||
iptables_both -t mangle -A INPUT -j CONNMARK --save-mark --mask ${MARKS_SAVERESTORE_STATELESS_MASK}
|
||||
iptables_both -t mangle -A POSTROUTING -j CONNMARK --save-mark --mask ${MARKS_SAVERESTORE_STATELESS_MASK}
|
||||
fi
|
||||
|
||||
# Accept all related traffic to the established connections
|
||||
rule chain INPUT state RELATED action ACCEPT || return 1
|
||||
|
Loading…
Reference in New Issue
Block a user