I put some time into this because I intend create a derivative to convert my customized iptables coding/rules to nftables (the designated iptables replacement).
I love doing stuff with bash, and I tried very hard to make it work for bash only, but that became far too frustrating.
I abandoned bash to do a re-write using awk as the main workhorse. If there are thousands of rules, awk will be a much better choice for this type of parsing/translation.
The below script will perform what I believe to be the logic you put forward above, but there was some ambiguity arising from what I feel was a malformed statement for the "[[ ${entry[0]} =~ - ]]" condition. I made the interpretation that such cases are ranges and don't need to be "split up".
Also, there are cases where you would encounter comma-separated lists, which again you wouldn't want to split up, so I modified the format of the input to use the vertical bar (or pipe, "|") for field delimiter.
You will also notice that I again modified it to add the accept/reject specification as the first field ("class") for each specification line.
I also did not quite understand what you were trying to do for Target values other than "Anywhere" or "Local". If possible, I would suggest you consider defining the specifications without the double quotes around those to reduce the parsing and logical efforts involved.
One other comment. Maybe not for the above limited ruleset, but you may wish to be mindfull of the order in which you define you specifications. That order WILL have impact on what is allowed thru the firewall and might prevent what you would otherwise want to allow.
The below is the resulting code logic. I hope it works for you.
#!/bin/bash
if [[ ! $EUID -eq 0 && ! $USER -eq "root" ]]; then
echo "You're not running as administator(root)!";
exit 1;
fi
DBG=0
#declare -i allowRulesIDX=0;
#declare -A allowRules;
#allowRulesIDX=$((++allowRulesIdx));
#allowRules[$allowRulesIDX]='[port]=80,[comment]="TLS/HTTP",[target]="Local"';
#allowRulesIDX=$((++allowRulesIdx));
#allowRules[$allowRulesIDX]='[port]=443,[comment]="SSL/HTTPS",[target]="Local"';
#allowRulesIDX=$((++allowRulesIdx));
#allowRules[$allowRulesIDX]='[port]=3306,[comment]="MySQL",[target]="Local"';
#allowRulesIDX=$((++allowRulesIdx));
#allowRules[$allowRulesIDX]='[port]=53,[comment]="DNS",[target]="Local"';
#allowRulesIDX=$((++allowRulesIdx));
#allowRules[$allowRulesIDX]='[port]=68,[comment]="DHCP",[target]="Local"';
#allowRulesIDX=$((++allowRulesIdx));
#allowRules[$allowRulesIDX]='[port]=5353,[comment]="mDNS",[target]="Local"';
#allowRulesIDX=$((++allowRulesIdx));
#allowRules[$allowRulesIDX]='[port]=853,[comment]="DNS",[target]="Local"';
#allowRulesIDX=$((++allowRulesIdx));
#allowRules[$allowRulesIDX]='[port]=546,[comment]="DHCPv6",[target]="Local"';
#allowRulesIDX=$((++allowRulesIdx));
#allowRules[$allowRulesIDX]='[port]=547,[comment]="DHCPv6",[target]="Local"';
#allowRulesIDX=$((++allowRulesIdx));
#allowRules[$allowRulesIDX]='[port]=123,[comment]="NTP",[target]="Local"';
#allowRulesIDX=$((++allowRulesIdx));
#allowRules[$allowRulesIDX]='[port]=5000,[comment]="UPnP",[target]="Local"';
#
#
#declare -i rejectRulesIDX=0;
#declare -A rejectRules;
#rejectRulesIDX=$(($rejectRulesIDX+1));
#rejectRules[$rejectRulesIDX]='[port]=5900,[comment]="VNC",[target]="Anywhere"';
### NOTE: Commas as delimiter are not ideal because some of the fields could have commas, causing confusion/difficulties for proper parsing.
### Vertical bar (or pipe, "|") is a better choice for delimiter.
RULES_FILE="FW_rules.txt"
cat >"${RULES_FILE}" <<"EnDoFiNpUt"
[class]=allow|[port]=80|[target]="Local"|[comment]="TLS/HTTP"
[class]=allow|[port]=443|[target]="Local"|[comment]="SSL/HTTPS"
[class]=allow|[port]=3306|[target]="Local"|[comment]="MySQL"
[class]=allow|[port]=53|[target]="Local"|[comment]="DNS"
[class]=allow|[port]=68|[target]="Local"|[comment]="DHCP"
[class]=allow|[port]=5353|[target]="Local"|[comment]="mDNS"
[class]=allow|[port]=853|[target]="Local"|[comment]="DNS"
[class]=allow|[port]=546|[target]="Local"|[comment]="DHCPv6"
[class]=allow|[port]=547|[target]="Local"|[comment]="DHCPv6"
[class]=allow|[port]=123|[target]="Local"|[comment]="NTP"
[class]=allow|[port]=5000,95,303|[target]="Local"|[comment]="UPnP"
[class]=reject|[port]=5900|[target]="Anywhere"|[comment]="VNC"
EnDoFiNpUt
awk -F "|" -v dbg="${DBG}" 'BEGIN{
ufwRulesIDX=0 ;
split("", ufwRules) ;
allowRulesIDX=0 ;
split("", allowRules) ;
rejectRulesIDX=0 ;
split("", rejectRules) ;
split("", Actions) ;
Actions[1]="accept" ;
Actions[2]="reject" ;
split("", Protos) ;
Protos[1]="udp" ;
Protos[2]="tcp" ;
split("", Directions) ;
Directions[1]="in" ;
Directions[2]="out" ;
split("", LocalTargets) ;
LocalTargets[1]="127.0.0.0/24" ;
LocalTargets[2]="192.168.1.0/24" ;
port=1 ;
target=2 ;
comment=3 ;
unknown=4 ;
br1="[" ;
br2="]" ;
}{
if( $0 == "" ){
exit ;
} ;
ufwRulesIDX++ ;
ufwRules[ufwRulesIDX]=$0 ;
if( dbg == 1 ){ printf("#\n#*** ufwRules[%s] = '%s' ...\n", ufwRulesIDX, ufwRules[ufwRulesIDX] ) ; } ;
split("", hold) ;
for( i=1 ; i<=NF ; i++ ){
if( dbg == 1 ){ printf("# $%s = %s ...\n", i, $i ) ; } ;
#[class]=allow|[port]=5000|[target]="Local"|[comment]="UPnP"
split("", tmp) ; # initialize to empty
split($i, tmp, "=") ;
gsub(/\[/, "", tmp[1] ) ;
gsub(/\]/, "", tmp[1] ) ;
if( dbg == 1 ){ printf("#\t tmp[1] = %s\n", tmp[1] ) ; } ;
if( dbg == 1 ){ printf("#\t tmp[2] = %s\n", tmp[2] ) ; } ;
switch (tmp[1]) {
case "class" : {
assign=tmp[2];
if( dbg == 1 ){ print "#\t\t assign = ", assign ; }
break ;
} ;
case "port" : {
hold[port]=tmp[2] ;
break ;
} ;
case "target" : {
hold[target]=tmp[2] ;
break ;
} ;
case "comment" : {
hold[comment]=tmp[2] ;
break ;
} ;
default : {
printf("\t Unrecognized field label '%s' in rule [NR]: %s\n" ) ; break ;
hold[unknown]=tmp[2] ;
} ;
} ;
} ;
switch (assign) {
case "allow" : {
allowRulesIDX++ ;
allowRules[allowRulesIDX,port]=hold[port] ;
allowRules[allowRulesIDX,target]=hold[target] ;
allowRules[allowRulesIDX,comment]=hold[comment] ;
allowRules[allowRulesIDX,unknown]=hold[unknown] ;
if( dbg == 1 ){ print "#\t allowRulesIDX = ", allowRulesIDX ; } ;
break ;
} ;
case "reject" : {
rejectRulesIDX++ ;
rejectRules[rejectRulesIDX,port]=hold[port] ;
rejectRules[rejectRulesIDX,target]=hold[target] ;
rejectRules[rejectRulesIDX,comment]=hold[comment] ;
rejectRules[rejectRulesIDX,unknown]=hold[unknown] ;
if( dbg == 1 ){ print "#\t rejectRulesIDX = ", rejectRulesIDX ; } ;
break ;
} ;
} ;
}END{
if( dbg == 1 ){ printf("#S\n#S================== INPUT DEFINITIONS =====================\n") ; } ;
for( i=1 ; i<=ufwRulesIDX ; i++ ){
printf("#S\t [%02d] = %s\n", i, ufwRules[i] ) ;
} ;
if( dbg == 1 ){ printf("#A\n#A================== ALLOW RULES =====================\n") ; } ;
for( i=1 ; i <= allowRulesIDX ; i++ ){
printf("#A\t [A %02d] = ", i ) ;
for( j=1 ; j<=3 ; j++ ){
printf(" %s |", allowRules[i,j] ) ;
} ;
printf("\n") ;
} ;
if( dbg == 1 ){ printf("#R\n#R================== REJECT RULES =====================\n") ; } ;
for( i=1 ; i <= rejectRulesIDX ; i++ ){
printf("#R\t [R %02d] = ", i ) ;
for( j=1 ; j<=3 ; j++ ){
printf(" %s |", rejectRules[i,j] ) ;
} ;
printf("\n") ;
} ;
if( dbg == 1 ){ printf("#UA\n#UA================== UFW ALLOW RULES =====================\n") ; } ;
for( i=1 ; i <= allowRulesIDX ; i++ ){
if( dbg == 1 ){ printf("#UA\t allowRules[%02d,port] = %s ...\n", i, allowRules[i,port] ) ; } ;
n=split(allowRules[i,port], Ports, "," ) ;
for( j=1 ; j<=n ; j++ ){
if( dbg == 1 ){ printf("#UA\t Ports[%02d] = %s ...\n", j, Ports[j] ) ; } ;
for( k=1 ; k<=2 ; k++ ){
if( dbg == 1 ){ printf("#UA\t Protos[%02d] = %s ...\n", k, Protos[k] ) ; } ;
for( m=1 ; m<=2 ; m++ ){
if( dbg == 1 ){ printf("#UA\t Directions[%02d] = %s ...\n", m, Directions[m] ) ; } ;
Target=allowRules[allowRulesIDX,target] ;
gsub(/"/, "", Target ) ;
switch (Target) {
case "Anywhere" : {
if(dbg == 1 ){ printf("#UAA\t\t Target = %s\n", Target ) ; } ;
printf("ufw %s %s log-all Proto %s from any to any port %s comment %s\n", Actions[1], Directions[m], Protos[k], Ports[j], allowRules[allowRulesIDX,comment] ) ;
break ;
} ;
case "Local" : {
if(dbg == 1 ){ printf("#UAL\t\t Target = %s\n", Target ) ; } ;
for( p=1 ; p<=2 ; p++ ){
if( dbg == 1 ){ printf("#UL\t LocalTargets[%02d] = %s ...\n", p, LocalTargets[p] ) ; } ;
printf("ufw %s %s log-all Proto %s from %s to any port %s comment %s\n", Actions[1], Directions[m], Protos[k], LocalTargets[p], Ports[j], allowRules[allowRulesIDX,comment] ) ;
} ;
break ;
} ;
default : {
if(dbg == 1 ){ printf("#UAO\t\t Target = %s\n", Target ) ; } ;
printf("ufw %s %s log-all Proto %s from %s to any port %s comment %s\n", Actions[1], Directions[m], Protos[k], allowRules[allowRulesIDX,target], Ports[j], allowRules[allowRulesIDX,comment] ) ;
break ;
} ;
} ;
} ;
} ;
} ;
} ;
if( dbg == 1 ){ printf("#UR\n#UR================== UFW REJECT RULES =====================\n") ; } ;
for( i=1 ; i <= rejectRulesIDX ; i++ ){
if( dbg == 1 ){ printf("#UR\t rejectRules[%02d,port] = %s ...\n", i, rejectRules[i,port] ) ; } ;
n=split(rejectRules[i,port], Ports, "," ) ;
for( j=1 ; j<=n ; j++ ){
if( dbg == 1 ){ printf("#UR\t Ports[%02d] = %s ...\n", j, Ports[j] ) ; } ;
for( k=1 ; k<=2 ; k++ ){
if( dbg == 1 ){ printf("#UR\t Protos[%02d] = %s ...\n", k, Protos[k] ) ; } ;
for( m=1 ; m<=2 ; m++ ){
if( dbg == 1 ){ printf("#UR\t Directions[%02d] = %s ...\n", m, Directions[m] ) ; } ;
Target=rejectRules[rejectRulesIDX,target] ;
gsub(/"/, "", Target ) ;
switch (Target) {
case "Anywhere" : {
if(dbg == 1 ){ printf("#URA\t\t Target = %s\n", Target ) ; } ;
printf("ufw %s %s log-all Proto %s from any to any port %s comment %s\n", Actions[2], Directions[m], Protos[k], Ports[j], rejectRules[rejectRulesIDX,comment] ) ;
break ;
} ;
case "Local" : {
if(dbg == 1 ){ printf("#URL\t\t Target = %s\n", Target ) ; } ;
for( p=1 ; p<=2 ; p++ ){
if( dbg == 1 ){ printf("#\t LocalTargets[%02d] = %s ...\n", p, LocalTargets[p] ) ; } ;
printf("ufw %s %s log-all Proto %s from %s to any port %s comment %s\n", Actions[2], Directions[m], Protos[k], LocalTargets[p], Ports[j], rejectRules[rejectRulesIDX,comment] ) ;
} ;
break ;
} ;
default : {
if(dbg == 1 ){ printf("#URO\t\t Target = %s\n", Target ) ; } ;
printf("ufw %s %s log-all Proto %s from %s to any port %s comment %s\n", Actions[2], Directions[m], Protos[k], rejectRules[rejectRulesIDX,target], Ports[j], rejectRules[rejectRulesIDX,comment] ) ;
break ;
} ;
} ;
} ;
} ;
} ;
} ;
}' "${RULES_FILE}"
exit 0
Session log is as follows:
#S [01] = [class]=allow|[port]=80|[target]="Local"|[comment]="TLS/HTTP"
#S [02] = [class]=allow|[port]=443|[target]="Local"|[comment]="SSL/HTTPS"
#S [03] = [class]=allow|[port]=3306|[target]="Local"|[comment]="MySQL"
#S [04] = [class]=allow|[port]=53|[target]="Local"|[comment]="DNS"
#S [05] = [class]=allow|[port]=68|[target]="Local"|[comment]="DHCP"
#S [06] = [class]=allow|[port]=5353|[target]="Local"|[comment]="mDNS"
#S [07] = [class]=allow|[port]=853|[target]="Local"|[comment]="DNS"
#S [08] = [class]=allow|[port]=546|[target]="Local"|[comment]="DHCPv6"
#S [09] = [class]=allow|[port]=547|[target]="Local"|[comment]="DHCPv6"
#S [10] = [class]=allow|[port]=123|[target]="Local"|[comment]="NTP"
#S [11] = [class]=allow|[port]=5000,95,303|[target]="Local"|[comment]="UPnP"
#S [12] = [class]=reject|[port]=5900|[target]="Anywhere"|[comment]="VNC"
#A [A 01] = 80 | "Local" | "TLS/HTTP" |
#A [A 02] = 443 | "Local" | "SSL/HTTPS" |
#A [A 03] = 3306 | "Local" | "MySQL" |
#A [A 04] = 53 | "Local" | "DNS" |
#A [A 05] = 68 | "Local" | "DHCP" |
#A [A 06] = 5353 | "Local" | "mDNS" |
#A [A 07] = 853 | "Local" | "DNS" |
#A [A 08] = 546 | "Local" | "DHCPv6" |
#A [A 09] = 547 | "Local" | "DHCPv6" |
#A [A 10] = 123 | "Local" | "NTP" |
#A [A 11] = 5000,95,303 | "Local" | "UPnP" |
#R [R 01] = 5900 | "Anywhere" | "VNC" |
ufw accept in log-all Proto udp from 127.0.0.0/24 to any port 80 comment "UPnP"
ufw accept in log-all Proto udp from 192.168.1.0/24 to any port 80 comment "UPnP"
ufw accept out log-all Proto udp from 127.0.0.0/24 to any port 80 comment "UPnP"
ufw accept out log-all Proto udp from 192.168.1.0/24 to any port 80 comment "UPnP"
ufw accept in log-all Proto tcp from 127.0.0.0/24 to any port 80 comment "UPnP"
ufw accept in log-all Proto tcp from 192.168.1.0/24 to any port 80 comment "UPnP"
ufw accept out log-all Proto tcp from 127.0.0.0/24 to any port 80 comment "UPnP"
ufw accept out log-all Proto tcp from 192.168.1.0/24 to any port 80 comment "UPnP"
ufw accept in log-all Proto udp from 127.0.0.0/24 to any port 443 comment "UPnP"
ufw accept in log-all Proto udp from 192.168.1.0/24 to any port 443 comment "UPnP"
ufw accept out log-all Proto udp from 127.0.0.0/24 to any port 443 comment "UPnP"
ufw accept out log-all Proto udp from 192.168.1.0/24 to any port 443 comment "UPnP"
ufw accept in log-all Proto tcp from 127.0.0.0/24 to any port 443 comment "UPnP"
ufw accept in log-all Proto tcp from 192.168.1.0/24 to any port 443 comment "UPnP"
ufw accept out log-all Proto tcp from 127.0.0.0/24 to any port 443 comment "UPnP"
ufw accept out log-all Proto tcp from 192.168.1.0/24 to any port 443 comment "UPnP"
ufw accept in log-all Proto udp from 127.0.0.0/24 to any port 3306 comment "UPnP"
ufw accept in log-all Proto udp from 192.168.1.0/24 to any port 3306 comment "UPnP"
ufw accept out log-all Proto udp from 127.0.0.0/24 to any port 3306 comment "UPnP"
ufw accept out log-all Proto udp from 192.168.1.0/24 to any port 3306 comment "UPnP"
ufw accept in log-all Proto tcp from 127.0.0.0/24 to any port 3306 comment "UPnP"
ufw accept in log-all Proto tcp from 192.168.1.0/24 to any port 3306 comment "UPnP"
ufw accept out log-all Proto tcp from 127.0.0.0/24 to any port 3306 comment "UPnP"
ufw accept out log-all Proto tcp from 192.168.1.0/24 to any port 3306 comment "UPnP"
ufw accept in log-all Proto udp from 127.0.0.0/24 to any port 53 comment "UPnP"
ufw accept in log-all Proto udp from 192.168.1.0/24 to any port 53 comment "UPnP"
ufw accept out log-all Proto udp from 127.0.0.0/24 to any port 53 comment "UPnP"
ufw accept out log-all Proto udp from 192.168.1.0/24 to any port 53 comment "UPnP"
ufw accept in log-all Proto tcp from 127.0.0.0/24 to any port 53 comment "UPnP"
ufw accept in log-all Proto tcp from 192.168.1.0/24 to any port 53 comment "UPnP"
ufw accept out log-all Proto tcp from 127.0.0.0/24 to any port 53 comment "UPnP"
ufw accept out log-all Proto tcp from 192.168.1.0/24 to any port 53 comment "UPnP"
ufw accept in log-all Proto udp from 127.0.0.0/24 to any port 68 comment "UPnP"
ufw accept in log-all Proto udp from 192.168.1.0/24 to any port 68 comment "UPnP"
ufw accept out log-all Proto udp from 127.0.0.0/24 to any port 68 comment "UPnP"
ufw accept out log-all Proto udp from 192.168.1.0/24 to any port 68 comment "UPnP"
ufw accept in log-all Proto tcp from 127.0.0.0/24 to any port 68 comment "UPnP"
ufw accept in log-all Proto tcp from 192.168.1.0/24 to any port 68 comment "UPnP"
ufw accept out log-all Proto tcp from 127.0.0.0/24 to any port 68 comment "UPnP"
ufw accept out log-all Proto tcp from 192.168.1.0/24 to any port 68 comment "UPnP"
ufw accept in log-all Proto udp from 127.0.0.0/24 to any port 5353 comment "UPnP"
ufw accept in log-all Proto udp from 192.168.1.0/24 to any port 5353 comment "UPnP"
ufw accept out log-all Proto udp from 127.0.0.0/24 to any port 5353 comment "UPnP"
ufw accept out log-all Proto udp from 192.168.1.0/24 to any port 5353 comment "UPnP"
ufw accept in log-all Proto tcp from 127.0.0.0/24 to any port 5353 comment "UPnP"
ufw accept in log-all Proto tcp from 192.168.1.0/24 to any port 5353 comment "UPnP"
ufw accept out log-all Proto tcp from 127.0.0.0/24 to any port 5353 comment "UPnP"
ufw accept out log-all Proto tcp from 192.168.1.0/24 to any port 5353 comment "UPnP"
ufw accept in log-all Proto udp from 127.0.0.0/24 to any port 853 comment "UPnP"
ufw accept in log-all Proto udp from 192.168.1.0/24 to any port 853 comment "UPnP"
ufw accept out log-all Proto udp from 127.0.0.0/24 to any port 853 comment "UPnP"
ufw accept out log-all Proto udp from 192.168.1.0/24 to any port 853 comment "UPnP"
ufw accept in log-all Proto tcp from 127.0.0.0/24 to any port 853 comment "UPnP"
ufw accept in log-all Proto tcp from 192.168.1.0/24 to any port 853 comment "UPnP"
ufw accept out log-all Proto tcp from 127.0.0.0/24 to any port 853 comment "UPnP"
ufw accept out log-all Proto tcp from 192.168.1.0/24 to any port 853 comment "UPnP"
ufw accept in log-all Proto udp from 127.0.0.0/24 to any port 546 comment "UPnP"
ufw accept in log-all Proto udp from 192.168.1.0/24 to any port 546 comment "UPnP"
ufw accept out log-all Proto udp from 127.0.0.0/24 to any port 546 comment "UPnP"
ufw accept out log-all Proto udp from 192.168.1.0/24 to any port 546 comment "UPnP"
ufw accept in log-all Proto tcp from 127.0.0.0/24 to any port 546 comment "UPnP"
ufw accept in log-all Proto tcp from 192.168.1.0/24 to any port 546 comment "UPnP"
ufw accept out log-all Proto tcp from 127.0.0.0/24 to any port 546 comment "UPnP"
ufw accept out log-all Proto tcp from 192.168.1.0/24 to any port 546 comment "UPnP"
ufw accept in log-all Proto udp from 127.0.0.0/24 to any port 547 comment "UPnP"
ufw accept in log-all Proto udp from 192.168.1.0/24 to any port 547 comment "UPnP"
ufw accept out log-all Proto udp from 127.0.0.0/24 to any port 547 comment "UPnP"
ufw accept out log-all Proto udp from 192.168.1.0/24 to any port 547 comment "UPnP"
ufw accept in log-all Proto tcp from 127.0.0.0/24 to any port 547 comment "UPnP"
ufw accept in log-all Proto tcp from 192.168.1.0/24 to any port 547 comment "UPnP"
ufw accept out log-all Proto tcp from 127.0.0.0/24 to any port 547 comment "UPnP"
ufw accept out log-all Proto tcp from 192.168.1.0/24 to any port 547 comment "UPnP"
ufw accept in log-all Proto udp from 127.0.0.0/24 to any port 123 comment "UPnP"
ufw accept in log-all Proto udp from 192.168.1.0/24 to any port 123 comment "UPnP"
ufw accept out log-all Proto udp from 127.0.0.0/24 to any port 123 comment "UPnP"
ufw accept out log-all Proto udp from 192.168.1.0/24 to any port 123 comment "UPnP"
ufw accept in log-all Proto tcp from 127.0.0.0/24 to any port 123 comment "UPnP"
ufw accept in log-all Proto tcp from 192.168.1.0/24 to any port 123 comment "UPnP"
ufw accept out log-all Proto tcp from 127.0.0.0/24 to any port 123 comment "UPnP"
ufw accept out log-all Proto tcp from 192.168.1.0/24 to any port 123 comment "UPnP"
ufw accept in log-all Proto udp from 127.0.0.0/24 to any port 5000 comment "UPnP"
ufw accept in log-all Proto udp from 192.168.1.0/24 to any port 5000 comment "UPnP"
ufw accept out log-all Proto udp from 127.0.0.0/24 to any port 5000 comment "UPnP"
ufw accept out log-all Proto udp from 192.168.1.0/24 to any port 5000 comment "UPnP"
ufw accept in log-all Proto tcp from 127.0.0.0/24 to any port 5000 comment "UPnP"
ufw accept in log-all Proto tcp from 192.168.1.0/24 to any port 5000 comment "UPnP"
ufw accept out log-all Proto tcp from 127.0.0.0/24 to any port 5000 comment "UPnP"
ufw accept out log-all Proto tcp from 192.168.1.0/24 to any port 5000 comment "UPnP"
ufw accept in log-all Proto udp from 127.0.0.0/24 to any port 95 comment "UPnP"
ufw accept in log-all Proto udp from 192.168.1.0/24 to any port 95 comment "UPnP"
ufw accept out log-all Proto udp from 127.0.0.0/24 to any port 95 comment "UPnP"
ufw accept out log-all Proto udp from 192.168.1.0/24 to any port 95 comment "UPnP"
ufw accept in log-all Proto tcp from 127.0.0.0/24 to any port 95 comment "UPnP"
ufw accept in log-all Proto tcp from 192.168.1.0/24 to any port 95 comment "UPnP"
ufw accept out log-all Proto tcp from 127.0.0.0/24 to any port 95 comment "UPnP"
ufw accept out log-all Proto tcp from 192.168.1.0/24 to any port 95 comment "UPnP"
ufw accept in log-all Proto udp from 127.0.0.0/24 to any port 303 comment "UPnP"
ufw accept in log-all Proto udp from 192.168.1.0/24 to any port 303 comment "UPnP"
ufw accept out log-all Proto udp from 127.0.0.0/24 to any port 303 comment "UPnP"
ufw accept out log-all Proto udp from 192.168.1.0/24 to any port 303 comment "UPnP"
ufw accept in log-all Proto tcp from 127.0.0.0/24 to any port 303 comment "UPnP"
ufw accept in log-all Proto tcp from 192.168.1.0/24 to any port 303 comment "UPnP"
ufw accept out log-all Proto tcp from 127.0.0.0/24 to any port 303 comment "UPnP"
ufw accept out log-all Proto tcp from 192.168.1.0/24 to any port 303 comment "UPnP"
ufw reject in log-all Proto udp from any to any port 5900 comment "VNC"
ufw reject out log-all Proto udp from any to any port 5900 comment "VNC"
ufw reject in log-all Proto tcp from any to any port 5900 comment "VNC"
ufw reject out log-all Proto tcp from any to any port 5900 comment "VNC"
$var=value(you use$to get the value of a variable, not to set it), using-eqto compare strings (it does numeric comparison), using the wrong comment marker, etc. I'd recommend 1) starting with something simpler and 2) using shellcheck.net to check for common scripting mistakes.$allowRulesIDX=$(($allowRulesIDX+1));, what you need is((++allowRulesIdx)). Or even better,allowRules[allowRulesIDX++]='80 "TLS/HTTP" "Local"'. Which is still flawed; if you just doallowRules+=(80 "TLS/HTTP" "Local"), you add 3 elements to the array;allowRules+=('80 "TLS/HTTP" "Local"')adds one. There are no multi-dimensional arrays in Bash. You can “simulate” them using dynamic name generation anddeclare -n.line 10 ==> $allowRulesIDX=$(($allowRulesIDX+1));... both sides of the=are replaced with their corresponding values, namely:0=$((0+1))=>0=1, which in turnbashtries to process as a command but since0=1is not a valid command the error is generated,:0=1: command not found(ie,0=1is not a valid command); for assignments the left side of the=does not start with a$so line 10 should be:allowRulesIDX=$(($allowRulesIDX+1))$from the left side will leave us withallowRules[$allowRulesIDX]=(80 "TLS/HTTP" "Local")(the$is required on the left for$allowRulesIDXsince we're referencing the value stored in the variable) which should generate an error like:allowRules[$allowRulesIDX]: cannot assign list to array memberwhich is another way of saying you cannot assign an array of values to another array ... this is an error becausebashdoes not support multi-dimensional arrays (aka arrays of arrays)