mirror of
https://dev.iopsys.eu/feed/iopsys.git
synced 2025-12-10 07:44:50 +01:00
206 lines
4.7 KiB
Desktop File
Executable file
206 lines
4.7 KiB
Desktop File
Executable file
#!/bin/sh
|
|
|
|
. /lib/functions.sh
|
|
|
|
ZONE_NAME_FILE="/tmp/service_fw_zone"
|
|
|
|
log() {
|
|
echo "${@}"|logger -t firewall.service -p info
|
|
}
|
|
|
|
exec_cmd() {
|
|
if ! "$@"; then
|
|
log "Failed to run [$*]"
|
|
echo "-1"
|
|
return 0
|
|
fi
|
|
|
|
echo "0"
|
|
return 0
|
|
}
|
|
|
|
collect_zone_name() {
|
|
local name network
|
|
|
|
config_get name "${1}" name ""
|
|
if [ -z "${name}" ]; then
|
|
return
|
|
fi
|
|
|
|
config_get network "${1}" network ""
|
|
for i in ${network}; do
|
|
var="${i}_zone"
|
|
echo "${var}=${name}" >> "${ZONE_NAME_FILE}"
|
|
done
|
|
}
|
|
|
|
load_zone_names() {
|
|
rm -f "${ZONE_NAME_FILE}"
|
|
config_foreach collect_zone_name zone
|
|
}
|
|
|
|
get_firewall_zone() {
|
|
if [ ! -f "${ZONE_NAME_FILE}" ]; then
|
|
echo ""
|
|
return
|
|
fi
|
|
|
|
var="${1}_zone="
|
|
name="$(cat ${ZONE_NAME_FILE} | grep ${var} | head -n 1 | cut -d'=' -f 2)"
|
|
echo "${name}"
|
|
}
|
|
|
|
add_iptable_rule() {
|
|
chain_name=$1
|
|
protocol=$2
|
|
dest_port=$3
|
|
icmp_type=$4
|
|
family=$5
|
|
src_prefix=$6
|
|
action=$7
|
|
res=-1
|
|
|
|
cmd="-I ${chain_name}"
|
|
|
|
if [ -n "${protocol}" ]; then
|
|
cmd="${cmd} -p $protocol"
|
|
|
|
if [ "${protocol}" -eq 41 ] || [ "${protocol}" -eq 43 ] || [ "${protocol}" -eq 44 ] ||
|
|
[ "${protocol}" -eq 58 ] || [ "${protocol}" -eq 59 ] || [ "${protocol}" -eq 60 ]; then
|
|
# Explicit v6 protocols
|
|
if [ "${family}" = "ipv4" ]; then
|
|
echo $res
|
|
return 0
|
|
else
|
|
family="ipv6"
|
|
fi
|
|
elif [ "${protocol}" -eq 1 ]; then
|
|
# Explicit v4 protocols
|
|
if [ "${family}" = "ipv6" ]; then
|
|
echo $res
|
|
return 0
|
|
else
|
|
family="ipv4"
|
|
fi
|
|
fi
|
|
|
|
# Limitation:: iptables do not accept dport without specific protocol
|
|
count=$(echo "${dest_port}" | sed -n "/-1/p" | wc -l)
|
|
|
|
if [ "${count}" -eq 0 ]; then
|
|
# dest_port not contains -1 so need to have this match criteria
|
|
count=$(echo "${dest_port}" | wc -w)
|
|
if [ "${count}" -gt 1 ]; then
|
|
# multiple ports present
|
|
port=$(echo "${dest_port}" | sed "s/ /,/g")
|
|
cmd="${cmd} -m multiport --dports ${port}"
|
|
else
|
|
cmd="${cmd} --dport ${dest_port}"
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
if [ "${family}" = "ipv4" ] || [ "${family}" = "-1" ]; then
|
|
if [ "${protocol}" -eq 1 ] && [ "${icmp_type}" -ge 0 ]; then
|
|
cmd="${cmd} --icmp-type ${icmp_type}"
|
|
fi
|
|
|
|
if [ -z "${src_prefix}" ]; then
|
|
res=$(exec_cmd iptables -w ${cmd} -m comment --comment IPtables_service_rule -j "${action}")
|
|
else
|
|
#Add ipv4 sources if any
|
|
src_list=""
|
|
for src in $src_prefix; do
|
|
ret=$(echo $src | grep ":" | wc -l)
|
|
if [ "${ret}" -eq 0 ]; then
|
|
src_list="$src,$src_list"
|
|
fi
|
|
done
|
|
|
|
if [ -n "$src_list" ]; then
|
|
src_list=$(echo "${src_list}" | sed "s/,$//")
|
|
res=$(exec_cmd iptables -w -s "$src_list" ${cmd} -m comment --comment IPtables_service_rule -j "${action}")
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
if [ "${family}" = "ipv6" ] || [ "${family}" = "-1" ]; then
|
|
if [ "${protocol}" -eq 58 ] && [ "${icmp_type}" -ge 0 ]; then
|
|
cmd="${cmd} --icmpv6-type ${icmp_type}"
|
|
fi
|
|
|
|
if [ -z "${src_prefix}" ]; then
|
|
res=$(exec_cmd ip6tables -w ${cmd} -m comment --comment IP6tables_service_rule -j "${action}")
|
|
else
|
|
#Add ipv6 sources if any
|
|
src_list=""
|
|
for src in $src_prefix; do
|
|
ret=$(echo $src | grep ":" | wc -l)
|
|
if [ "${ret}" -eq 1 ]; then
|
|
src_list="$src,$src_list"
|
|
fi
|
|
done
|
|
|
|
if [ -n "$src_list" ]; then
|
|
src_list=$(echo "${src_list}" | sed "s/,$//")
|
|
res=$(exec_cmd ip6tables -w -s "$src_list" ${cmd} -m comment --comment IP6tables_service_rule -j "${action}")
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
echo $res
|
|
}
|
|
|
|
add_service() {
|
|
local enable proto family dest_port interface target icmp_type
|
|
|
|
config_get enable "$1" enable "0"
|
|
config_get icmp_type "$1" icmp_type "-1"
|
|
config_get target "$1" target "Accept"
|
|
config_get interface "$1" interface ""
|
|
config_get family "$1" family "-1"
|
|
config_get dest_port "$1" dest_port "-1"
|
|
config_get proto "$1" proto "-1"
|
|
config_get src_prefix "$1" src_prefix ""
|
|
|
|
if [ "${enable}" -eq 0 ] || [ -z "${interface}" ]; then
|
|
return 0
|
|
fi
|
|
|
|
action=$(echo "${target}" | tr a-z A-Z)
|
|
zone_name="$(get_firewall_zone ${interface})"
|
|
if [ -z "${zone_name}" ]; then
|
|
log "Rule can not be added without zone name for interface ${interface}"
|
|
return
|
|
fi
|
|
|
|
chain_name="zone_${zone_name}_input"
|
|
res=0
|
|
count=$(echo "${proto}" | sed -n "/-1/p" | wc -l)
|
|
|
|
if [ "${count}" -eq 0 ]; then
|
|
# proto not contains -1 so need to have this match criteria
|
|
for protocol in $proto; do
|
|
res=$(add_iptable_rule "$chain_name" "$protocol" "$dest_port" "$icmp_type" "$family" "$src_prefix" "$action")
|
|
done
|
|
else
|
|
# proto contains -1 so no need to have this match criteria
|
|
res=$(add_iptable_rule "$chain_name" "" "$dest_port" "$icmp_type" "$family" "$src_prefix" "$action")
|
|
fi
|
|
|
|
if [ "${res}" -ne 0 ]; then
|
|
uci -q set firewall."${1}".status="Error"
|
|
else
|
|
uci -q set firewall."${1}".status=""
|
|
fi
|
|
|
|
uci commit firewall
|
|
}
|
|
|
|
config_load firewall
|
|
|
|
load_zone_names
|
|
|
|
config_foreach add_service "service"
|
|
|
|
rm -f "${ZONE_NAME_FILE}"
|