hostmngr: update implementation

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
This commit is contained in:
Rahul Thakur 2024-02-23 12:21:34 +05:30
parent ddfab6f729
commit 2f20ec448d

View file

@ -5,6 +5,9 @@
day="" day=""
next_days="" next_days=""
prev_days="" prev_days=""
schedule_added=""
ACCESS_RULE=""
IP_RULE="" IP_RULE=""
IP_RULE1="" IP_RULE1=""
@ -108,70 +111,77 @@ ip_rule_east_zone() {
fi fi
} }
process_ac_schedule() {
local acs_id="$1"
local is_enabled
local access_control
local start_time=""
local mac=""
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() { handle_day_list() {
local value=$1 local value=$1
val=$(echo $value | cut -c 1-3) val=$(echo $value | cut -c 1-3)
next_day_val=$(get_next_day $val) next_day_val=$(get_next_day $val)
prev_day_val=$(get_previous_day $val) prev_day_val=$(get_previous_day $val)
if [ -z $day ]; then if [ -z $day ]; then
day="$val" day="$val"
next_days="$next_day_val" next_days="$next_day_val"
prev_days="$prev_day_val" prev_days="$prev_day_val"
else else
day="$day,$val" day="$day,$val"
next_days="$next_days,$next_day_val" next_days="$next_days,$next_day_val"
prev_days="$prev_days,$prev_day_val" prev_days="$prev_days,$prev_day_val"
fi fi
} }
config_list_foreach "$acs_id" "day" handle_day_list handle_schedule() {
config_get is_enabled "$acs_id" "enable" 1 local schd_section="$1"
config_get access_control "$acs_id" "dm_parent" local ac_section="$2"
local acs_id
local start_time
local duration
if [ "$is_enabled" == "0" ] || [ -z "$access_control" ]; then IP_RULE="$ACCESS_RULE"
return 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 fi
IP_RULE="" local is_enabled
IP_RULE1="" config_get is_enabled "$schd_section" "enable" 0
config_get is_enabled "$access_control" "enable" 1
if [ "$is_enabled" == "0" ]; then if [ "$is_enabled" == "0" ]; then
return return
fi fi
mac=$(uci -q get hosts.$access_control.macaddr) local all_days="Monday Tuesday Wednesday Thursday Friday Saturday Sunday"
access_policy=$(uci -q get hosts.$access_control.access_policy) local day_config
config_get day_config "$schd_section" "day" "$all_days"
config_get start_time "$acs_id" "start_time" IFS=" "
config_get duration "$acs_id" "duration" for d in $day_config; do
handle_day_list $d
done
if [ -z "$mac" ] && [ -z "$start_time" ] && [ -z "$duration" ] && [ -z "$day" ] && [ -z "$access_policy" ]; then config_get start_time "$schd_section" "start_time" "00:00"
return config_get duration "$schd_section" "duration"
fi
if [ -n "$mac" ]; then
IP_RULE="$IP_RULE -m mac --mac-source $mac"
fi
zone=$(date +%z | cut -c 1) zone=$(date +%z | cut -c 1)
local_start_time=$start_time local_start_time=$start_time
if [ -n "$duration" ]; then hh=$(echo $local_start_time | awk -F: '{ print $1 }')
hh=$(echo $local_start_time | awk -F: '{ print $1 }') mm=$(echo $local_start_time | awk -F: '{ print $2 }')
mm=$(echo $local_start_time | awk -F: '{ print $2 }') hh_s=`expr $hh \* 3600`
hh_s=`expr $hh \* 3600` mm_s=`expr $mm \* 60`
mm_s=`expr $mm \* 60` ss=$(( hh_s + mm_s ))
ss=$(( hh_s + mm_s )) local_start_hh=$hh
local_start_hh=$hh
if [ -n "$duration" ]; then
stop_ss=$(( ss + duration )) stop_ss=$(( ss + duration ))
hh=$(( stop_ss / 3600 )) hh=$(( stop_ss / 3600 ))
rem_ss=$(( stop_ss % 3600 )) rem_ss=$(( stop_ss % 3600 ))
@ -179,6 +189,10 @@ process_ac_schedule() {
ss=$(( rem_ss % 60 )) ss=$(( rem_ss % 60 ))
local_stop_time="$hh:$mm:$ss" local_stop_time="$hh:$mm:$ss"
local_stop_hh=$hh 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 fi
utc_start_time=$(date -u -d @$(date "+%s" -d "$local_start_time") +%H:%M) utc_start_time=$(date -u -d @$(date "+%s" -d "$local_start_time") +%H:%M)
@ -191,43 +205,91 @@ process_ac_schedule() {
ip_rule_east_zone $utc_start_hh $utc_stop_hh $local_start_hh $local_stop_hh $utc_start_time $utc_stop_time ip_rule_east_zone $utc_start_hh $utc_stop_hh $local_start_hh $local_stop_hh $utc_start_time $utc_stop_time
fi fi
if [ "$access_policy" == "Deny" ]; then IP_RULE="$IP_RULE -j ACCEPT"
IP_RULE="$IP_RULE -j DROP"
if [ -n "$IP_RULE1" ]; then
IP_RULE1="$IP_RULE1 -j DROP"
fi
else
IP_RULE="$IP_RULE -j ACCEPT"
if [ -n "$IP_RULE1" ]; then
IP_RULE1="$IP_RULE1 -j ACCEPT"
fi
fi
iptables -w -A hosts_forward ${IP_RULE}
ip6tables -w -A hosts_forward ${IP_RULE}
if [ -n "$IP_RULE1" ]; then if [ -n "$IP_RULE1" ]; then
iptables -w -A hosts_forward ${IP_RULE1} IP_RULE1="$IP_RULE1 -j ACCEPT"
ip6tables -w -A hosts_forward ${IP_RULE1}
fi fi
day="" add_access_rule "$IP_RULE"
next_days="" if [ -n "$IP_RULE1" ]; then
prev_days="" 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
} }
iptables -w -F hosts_forward handle_access_control() {
ip6tables -w -F hosts_forward 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) hosts_forward=$(iptables -t filter --list | grep hosts_forward)
if [ -z "$hosts_forward" ]; then if [ -z "$hosts_forward" ]; then
iptables -w -t filter -N hosts_forward echo "iptables -w -t filter -N hosts_forward" >> $ACL_FILE
ret=$? ret=$?
[ $ret -eq 0 ] && iptables -w -t filter -I FORWARD -j hosts_forward [ $ret -eq 0 ] && echo "iptables -w -t filter -I FORWARD -j hosts_forward" >> $ACL_FILE
ip6tables -w -t filter -N hosts_forward echo "ip6tables -w -t filter -N hosts_forward" >> $ACL_FILE
ret=$? ret=$?
[ $ret -eq 0 ] && ip6tables -w -t filter -I FORWARD -j hosts_forward [ $ret -eq 0 ] && echo "ip6tables -w -t filter -I FORWARD -j hosts_forward" >> $ACL_FILE
fi fi
# Load /etc/config/hosts UCI file # Load /etc/config/hosts UCI file
config_load hosts config_load hosts
config_foreach process_ac_schedule ac_schedule config_foreach handle_access_control access_control
# apply the rules
sh $ACL_FILE