mirror of
https://dev.iopsys.eu/feed/iopsys.git
synced 2025-12-10 07:44:50 +01:00
* The Schedule object is deprecated in 2.18 and ScheduleRef is introduced, update script to generate rules accordingly. * Some shell script improvements.
293 lines
7.3 KiB
Bash
Executable file
293 lines
7.3 KiB
Bash
Executable file
#!/bin/sh
|
|
|
|
. /lib/functions.sh
|
|
|
|
day=""
|
|
next_days=""
|
|
prev_days=""
|
|
schedule_added=""
|
|
|
|
ACCESS_RULE=""
|
|
IP_RULE=""
|
|
IP_RULE1=""
|
|
|
|
get_next_day() {
|
|
local weekday="$1"
|
|
case "$weekday" in
|
|
"Mon"|"Monday") echo "Tuesday"
|
|
;;
|
|
"Tue"|"Tuesday") echo "Wednesday"
|
|
;;
|
|
"Wed"|"Wednesday") echo "Thursday"
|
|
;;
|
|
"Thu"|"Thursday") echo "Friday"
|
|
;;
|
|
"Fri"|"Friday") echo "Saturday"
|
|
;;
|
|
"Sat"|"Saturday") echo "Sunday"
|
|
;;
|
|
"Sun"|"Sunday") echo "Monday"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
get_previous_day() {
|
|
local weekday="$1"
|
|
case "$weekday" in
|
|
"Mon"|"Monday") echo "Sunday"
|
|
;;
|
|
"Tue"|"Tuesday") echo "Monday"
|
|
;;
|
|
"Wed"|"Wednesday") echo "Tuesday"
|
|
;;
|
|
"Thu"|"Thursday") echo "Wednesday"
|
|
;;
|
|
"Fri"|"Friday") echo "Thursday"
|
|
;;
|
|
"Sat"|"Saturday") echo "Friday"
|
|
;;
|
|
"Sun"|"Sunday") echo "Saturday"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
ip_rule_west_zone() {
|
|
local utc_start_t_h="$1"
|
|
local utc_stop_t_h="$2"
|
|
local local_start_t_h="$3"
|
|
local local_stop_t_h="$4"
|
|
local utc_start_time="$5"
|
|
local utc_stop_time="$6"
|
|
|
|
if [ "$utc_start_t_h" -lt "$local_start_t_h" ]; then
|
|
IP_RULE="$IP_RULE -m time --timestart $utc_start_time --timestop $utc_stop_time"
|
|
if [ -n "$next_days" ]; then
|
|
IP_RULE="$IP_RULE --weekdays $next_days"
|
|
fi
|
|
else
|
|
if [ "$utc_stop_t_h" -lt "$local_stop_t_h" ]; then
|
|
IP_RULE1="$IP_RULE"
|
|
IP_RULE="$IP_RULE -m time --timestart $utc_start_time --timestop 23:59"
|
|
IP_RULE1="$IP_RULE1 -m time --timestart 00:00 --timestop $utc_stop_time"
|
|
if [ -n "$next_days" ]; then
|
|
IP_RULE1="$IP_RULE1 --weekdays $next_days"
|
|
fi
|
|
else
|
|
IP_RULE="$IP_RULE -m time --timestart $utc_start_time --timestop $utc_stop_time"
|
|
fi
|
|
if [ -n "$day" ]; then
|
|
IP_RULE="$IP_RULE --weekdays $day"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
ip_rule_east_zone() {
|
|
local utc_start_t_h="$1"
|
|
local utc_stop_t_h="$2"
|
|
local local_start_t_h="$3"
|
|
local local_stop_t_h="$4"
|
|
local utc_start_time="$5"
|
|
local utc_stop_time="$6"
|
|
|
|
if [ "$utc_start_t_h" -lt "$local_start_t_h" ]; then
|
|
IP_RULE="$IP_RULE -m time --timestart $utc_start_time --timestop $utc_stop_time"
|
|
if [ -n "$day" ]; then
|
|
IP_RULE="$IP_RULE --weekdays $day"
|
|
fi
|
|
else
|
|
if [ "$utc_stop_t_h" -lt "$local_stop_t_h" ]; then
|
|
IP_RULE1="$IP_RULE"
|
|
IP_RULE="$IP_RULE -m time --timestart 00:00 --timestop $utc_stop_time"
|
|
IP_RULE1="$IP_RULE1 -m time --timestart $utc_start_time --timestop 23:59"
|
|
if [ -n "$prev_days" ]; then
|
|
IP_RULE1="$IP_RULE1 --weekdays $prev_days"
|
|
fi
|
|
else
|
|
IP_RULE="$IP_RULE -m time --timestart $utc_start_time --timestop $utc_stop_time"
|
|
fi
|
|
if [ -n "$day" ]; then
|
|
IP_RULE="$IP_RULE --weekdays $day"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
|
|
add_access_rule() {
|
|
local rule="$1"
|
|
echo "iptables -w -A hosts_forward ${rule}" >> "$ACL_FILE"
|
|
echo "ip6tables -w -A hosts_forward ${rule}" >> "$ACL_FILE"
|
|
}
|
|
|
|
handle_day_list() {
|
|
local value=$1
|
|
|
|
val=$(echo "$value" | cut -c 1-3)
|
|
next_day_val=$(get_next_day "$val")
|
|
prev_day_val=$(get_previous_day "$val")
|
|
if [ -z $day ]; then
|
|
day="$val"
|
|
next_days="$next_day_val"
|
|
prev_days="$prev_day_val"
|
|
else
|
|
day="$day,$val"
|
|
next_days="$next_days,$next_day_val"
|
|
prev_days="$prev_days,$prev_day_val"
|
|
fi
|
|
}
|
|
|
|
handle_schedule() {
|
|
local schd_section="$1"
|
|
local start_time
|
|
local duration
|
|
|
|
IP_RULE="$ACCESS_RULE"
|
|
IP_RULE1=""
|
|
day=""
|
|
next_days=""
|
|
prev_days=""
|
|
|
|
config_load schedules
|
|
|
|
local is_enabled
|
|
config_get is_enabled "$schd_section" "enable" 0
|
|
if [ "$is_enabled" == "0" ]; then
|
|
return
|
|
fi
|
|
|
|
local all_days="Monday Tuesday Wednesday Thursday Friday Saturday Sunday"
|
|
local day_config
|
|
config_get day_config "$schd_section" "day" "$all_days"
|
|
|
|
IFS=" "
|
|
for d in $day_config; do
|
|
handle_day_list "$d"
|
|
done
|
|
|
|
config_get start_time "$schd_section" "start_time" "00:00"
|
|
config_get duration "$schd_section" "duration"
|
|
|
|
zone=$(date +%z | cut -c 1)
|
|
local_start_time=$start_time
|
|
hh=$(echo "$local_start_time" | awk -F: '{ print $1 }')
|
|
mm=$(echo "$local_start_time" | awk -F: '{ print $2 }')
|
|
hh_s=`expr $hh \* 3600`
|
|
mm_s=`expr $mm \* 60`
|
|
ss=$(( hh_s + mm_s ))
|
|
local_start_hh=$hh
|
|
|
|
if [ -n "$duration" ]; then
|
|
stop_ss=$(( ss + duration ))
|
|
hh=$(( stop_ss / 3600 ))
|
|
rem_ss=$(( stop_ss % 3600 ))
|
|
mm=$(( rem_ss / 60 ))
|
|
ss=$(( rem_ss % 60 ))
|
|
local_stop_time="$hh:$mm:$ss"
|
|
local_stop_hh=$hh
|
|
else
|
|
# if duartion is not specified, then apply rule to end of the day
|
|
local_stop_time="23:59:59"
|
|
local_stop_hh="23"
|
|
fi
|
|
|
|
utc_start_time=$(date -u -d @$(date "+%s" -d "$local_start_time") +%H:%M)
|
|
utc_stop_time=$(date -u -d @$(date "+%s" -d "$local_stop_time") +%H:%M)
|
|
utc_start_hh=$(echo "$utc_start_time" | awk -F: '{ print $1 }')
|
|
utc_stop_hh=$(echo "$utc_stop_time" | awk -F: '{ print $1 }')
|
|
if [ "$zone" == "-" ]; then
|
|
ip_rule_west_zone "$utc_start_hh" "$utc_stop_hh" "$local_start_hh" "$local_stop_hh" "$utc_start_time" "$utc_stop_time"
|
|
else
|
|
ip_rule_east_zone "$utc_start_hh" "$utc_stop_hh" "$local_start_hh" "$local_stop_hh" "$utc_start_time" "$utc_stop_time"
|
|
fi
|
|
|
|
IP_RULE="$IP_RULE -j ACCEPT"
|
|
if [ -n "$IP_RULE1" ]; then
|
|
IP_RULE1="$IP_RULE1 -j ACCEPT"
|
|
fi
|
|
|
|
add_access_rule "$IP_RULE"
|
|
if [ -n "$IP_RULE1" ]; then
|
|
add_access_rule "$IP_RULE1"
|
|
fi
|
|
|
|
# for access rules to be effective for a schedule, need to add DROP rule
|
|
# to block the access outside the defined schedule
|
|
if [ "$schedule_added" == "0" ]; then
|
|
schedule_added="1"
|
|
fi
|
|
}
|
|
|
|
handle_access_control() {
|
|
local ac_section="$1"
|
|
local is_enabled
|
|
|
|
# default value of Hosts.AccessControl.{i}.Enable is false,
|
|
# so, if not defined in uci as 1, assume 0
|
|
config_get is_enabled "$ac_section" "enable" 0
|
|
if [ "$is_enabled" == "0" ]; then
|
|
return
|
|
fi
|
|
|
|
local mac_addr
|
|
config_get mac_addr "$ac_section" "macaddr"
|
|
if [ -z "$mac_addr" ]; then
|
|
return
|
|
else
|
|
ACCESS_RULE="-m mac --mac-source $mac_addr"
|
|
fi
|
|
|
|
local access_policy
|
|
config_get access_policy "$ac_section" "access_policy"
|
|
if [ -z "$access_policy" ]; then
|
|
return # since system default is allow so no need to do anything
|
|
fi
|
|
|
|
# As per Data Model, if access policy is deny, then schedule is to be ignored
|
|
# and no access is to be provided for the device
|
|
if [ "$access_policy" == "Deny" ]; then
|
|
ACCESS_RULE="$ACCESS_RULE -j DROP"
|
|
add_access_rule "$ACCESS_RULE"
|
|
return # no need to parse schedule
|
|
fi
|
|
|
|
schedule_added="0"
|
|
# check if schedule is defined for this access_control instance
|
|
# and if yes, create rule accordingly
|
|
config_list_foreach "$ac_section" access_control_schedule handle_schedule
|
|
|
|
# for access rule to work, need to have default drop rule as last rule
|
|
if [ "$schedule_added" == "1" ]; then
|
|
IP_RULE="$ACCESS_RULE -j DROP"
|
|
add_access_rule "$IP_RULE"
|
|
fi
|
|
}
|
|
|
|
ACL_FILE="/tmp/hosts_access_control/access_control.rules"
|
|
|
|
rm -f $ACL_FILE
|
|
|
|
mkdir -p /tmp/hosts_access_control/
|
|
touch $ACL_FILE
|
|
|
|
echo "iptables -w -F hosts_forward" >> $ACL_FILE
|
|
echo "ip6tables -w -F hosts_forward" >> $ACL_FILE
|
|
|
|
hosts_ipv4_forward=$(iptables -t filter --list -n | grep hosts_forward)
|
|
if [ -z "$hosts_ipv4_forward" ]; then
|
|
echo "iptables -w -t filter -N hosts_forward" >> $ACL_FILE
|
|
ret=$?
|
|
[ $ret -eq 0 ] && echo "iptables -w -t filter -I FORWARD -j hosts_forward" >> $ACL_FILE
|
|
fi
|
|
|
|
hosts_ipv6_forward=$(ip6tables -t filter --list -n | grep hosts_forward)
|
|
if [ -z "$hosts_ipv6_forward" ]; then
|
|
echo "ip6tables -w -t filter -N hosts_forward" >> $ACL_FILE
|
|
ret=$?
|
|
[ $ret -eq 0 ] && echo "ip6tables -w -t filter -I FORWARD -j hosts_forward" >> $ACL_FILE
|
|
fi
|
|
|
|
# Load /etc/config/hosts UCI file
|
|
config_load hosts
|
|
config_foreach handle_access_control access_control
|
|
|
|
# apply the rules
|
|
sh $ACL_FILE
|