mirror of
https://dev.iopsys.eu/feed/iopsys.git
synced 2025-12-10 07:44:50 +01:00
following cases/bugs are handled in this change: 1. Ignore schedule if access_policy is deny 2. For access policy allow, with schedule, deny for time outside the defined schedule. 3. Default value for days 4. Handle scenario when start time is not defined by initializing the start time to 00:00 5. Handle scenario when duration is not defined
295 lines
7.3 KiB
Bash
Executable file
295 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 ac_section="$2"
|
|
local acs_id
|
|
local start_time
|
|
local duration
|
|
|
|
IP_RULE="$ACCESS_RULE"
|
|
IP_RULE1=""
|
|
day=""
|
|
next_days=""
|
|
prev_days=""
|
|
|
|
config_get acs_id "$schd_section" "dm_parent"
|
|
|
|
if [ "$acs_id" != "$ac_section" ]; then
|
|
return # schedule not for this access control section
|
|
fi
|
|
|
|
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_foreach handle_schedule ac_schedule "$ac_section"
|
|
|
|
# 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_forward=$(iptables -t filter --list | grep hosts_forward)
|
|
if [ -z "$hosts_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
|
|
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
|