From 2f20ec448d9478b819bb9cc161a0a78faf6406a5 Mon Sep 17 00:00:00 2001 From: Rahul Thakur Date: Fri, 23 Feb 2024 12:21:34 +0530 Subject: [PATCH] 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 --- hostmngr/files/scripts/hosts_acl.sh | 208 ++++++++++++++++++---------- 1 file changed, 135 insertions(+), 73 deletions(-) diff --git a/hostmngr/files/scripts/hosts_acl.sh b/hostmngr/files/scripts/hosts_acl.sh index 0696b2e66..b2a9aeeb9 100755 --- a/hostmngr/files/scripts/hosts_acl.sh +++ b/hostmngr/files/scripts/hosts_acl.sh @@ -5,6 +5,9 @@ day="" next_days="" prev_days="" +schedule_added="" + +ACCESS_RULE="" IP_RULE="" IP_RULE1="" @@ -108,70 +111,77 @@ ip_rule_east_zone() { 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() { - local value=$1 +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 - } + 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 +} - config_list_foreach "$acs_id" "day" handle_day_list - config_get is_enabled "$acs_id" "enable" 1 - config_get access_control "$acs_id" "dm_parent" +handle_schedule() { + local schd_section="$1" + local ac_section="$2" + local acs_id + local start_time + local duration - if [ "$is_enabled" == "0" ] || [ -z "$access_control" ]; then - return + 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 - IP_RULE="" - IP_RULE1="" - - config_get is_enabled "$access_control" "enable" 1 + local is_enabled + config_get is_enabled "$schd_section" "enable" 0 if [ "$is_enabled" == "0" ]; then return fi - mac=$(uci -q get hosts.$access_control.macaddr) - access_policy=$(uci -q get hosts.$access_control.access_policy) + local all_days="Monday Tuesday Wednesday Thursday Friday Saturday Sunday" + local day_config + config_get day_config "$schd_section" "day" "$all_days" - config_get start_time "$acs_id" "start_time" - config_get duration "$acs_id" "duration" + IFS=" " + 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 - return - fi - if [ -n "$mac" ]; then - IP_RULE="$IP_RULE -m mac --mac-source $mac" - fi + 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 - if [ -n "$duration" ]; then - 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 + 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 )) @@ -179,6 +189,10 @@ process_ac_schedule() { 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) @@ -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 fi - if [ "$access_policy" == "Deny" ]; then - 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} + IP_RULE="$IP_RULE -j ACCEPT" if [ -n "$IP_RULE1" ]; then - iptables -w -A hosts_forward ${IP_RULE1} - ip6tables -w -A hosts_forward ${IP_RULE1} + IP_RULE1="$IP_RULE1 -j ACCEPT" fi - day="" - next_days="" - prev_days="" + 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 } -iptables -w -F hosts_forward -ip6tables -w -F hosts_forward +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 - iptables -w -t filter -N hosts_forward + echo "iptables -w -t filter -N hosts_forward" >> $ACL_FILE ret=$? - [ $ret -eq 0 ] && iptables -w -t filter -I FORWARD -j hosts_forward - ip6tables -w -t filter -N hosts_forward + [ $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 ] && 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 # Load /etc/config/hosts UCI file config_load hosts -config_foreach process_ac_schedule ac_schedule +config_foreach handle_access_control access_control + +# apply the rules +sh $ACL_FILE