What's new

Error Message 382.1.2 on AC88 Port Forwarding New Limitation - HELP

  • SNBForums Code of Conduct

    SNBForums is a community for everyone, no matter what their level of experience.

    Please be tolerant and patient of others, especially newcomers. We are all here to share and learn!

    The rules are simple: Be patient, be nice, be helpful or be gone!

Milton

New Around Here
Dear SNB Gurus,


I need your help all the SNB Gurus a step by step GUIDE to configure portforward using a NAT START SCRIPT / MANUAL IPTABLES

If I can use a spreadsheet or CSV table then would be great as I have more than 90s ports per set up.


BACKGROUND:
Error Message "Resulting list of Port Forwards is too long - remove some, or use
shorter description"

I was upgrading from the older version of Merlin to this new 382.1.2, We have about 98 Port to be forwarded.
Unfortunately after 48 lines or so we no longer can save the port to be forwarded as new Error message was out.
So the 128 Port Quota is no longer the absolute number.

I tried to shortened the Description but it does not help a whole lot only add few extra line for additional ports. All done via the Web GUI.

From the Merlin Guru - Eric , I found out that as cited below from Eric response
1. Asus now enforces and validates nvram setting length to protect against buffer overruns. This means there is now a fixed limit on the total length of each nvram setting.
2. The port forwarding number will be variable, since it's now based on the total length rather than the actual number of entries.

Try asking on the support forums at SNBForums, someone should be able to guide you through configuring port forwards using a nat-start script.
If you absolutely need so many forwards, you will have to start configuring them manually through iptables.
 
How complex are your port forwarding rules. The more complex they are the more complex the nat-start script would have to be.

For example; Do you only use TCP and not UDP? Are you forwarding ranges of ports or just single ports. Are the source and destination port numbers always the same as each other or are they different? Do you specify the source IP address or do you leave it blank?
 
Dear SNB Gurus,


I need your help all the SNB Gurus a step by step GUIDE to configure portforward using a NAT START SCRIPT / MANUAL IPTABLES

If I can use a spreadsheet or CSV table then would be great as I have more than 90s ports per set up.


BACKGROUND:
Error Message "Resulting list of Port Forwards is too long - remove some, or use
shorter description"

I was upgrading from the older version of Merlin to this new 382.1.2, We have about 98 Port to be forwarded.
Unfortunately after 48 lines or so we no longer can save the port to be forwarded as new Error message was out.
So the 128 Port Quota is no longer the absolute number.

I tried to shortened the Description but it does not help a whole lot only add few extra line for additional ports. All done via the Web GUI.

From the Merlin Guru - Eric , I found out that as cited below from Eric response
1. Asus now enforces and validates nvram setting length to protect against buffer overruns. This means there is now a fixed limit on the total length of each nvram setting.
2. The port forwarding number will be variable, since it's now based on the total length rather than the actual number of entries.

Try asking on the support forums at SNBForums, someone should be able to guide you through configuring port forwards using a nat-start script.
If you absolutely need so many forwards, you will have to start configuring them manually through iptables.

I suggest before adding it to nat-start, call it say PortForwardRules.sh then you can test it from the command line in isolation, and it won't cause any issue if you happen to have an unscheduled reboot during testing!
Code:
#!/bin/sh
VER="v1.05"
#======================================================================================================= © 2018 Martineau, v1.05
#
# Import Port Forwarding rules and apply manually rather than create NVRAM variable as v382.xx/v384.xx limits variable size
#
#     PortForwardRules     [-h|help] ['csv_file_name'] ['del'] ['test']
#
#     PortForwardRules
#                          Import Port Forward rules from CSV file 'PortForwards.csv'
#     PortForwardRules     /mnt/USB/This_file
#                          Import Port Forward rules from CSV file '/mnt/USB/This_file'
#     PortForwardRules     del
#                          Delete Port Forward rules using CSV file 'PortForwards.csv'
#     PortForwardRules     test
#                          List simulated Port Forward rules using CSV file 'PortForwards.csv'
#
# Import file is in format:
#
#        Service Name, Source IP, Port Range, Local IP, Local Port, Protocol
#
#        If Protocol is omitted, then the default is TCP, but TCP,UDP or BOTH may be specified
#        If Port Range is omitted, then it will be set to the Local Port
#        If Local Port is omitted, then it will be set to the Port Range, unless Port Range is in the form 'nnnnn:nnnnn'


SayT(){
   echo -e $$ $@ | /usr/bin/logger -t "($(basename $0))"
}
# Print between line beginning with'#==' to first blank line inclusive
ShowHelp() {
 awk '/^#==/{f=1} f{print; if (!NF) exit}' $0
}
ANSIColours () {
 cRESET="\e[0m";cBLA="\e[30m";cRED="\e[31m";cGRE="\e[32m";cYEL="\e[33m";cBLU="\e[34m";cMAG="\e[35m";cCYA="\e[36m";cGRA="\e[37m"
 cBGRA="\e[90m";cBRED="\e[91m";cBGRE="\e[92m";cBYEL="\e[93m";cBBLU="\e[94m";cBMAG="\e[95m";cBCYA="\e[96m";cBWHT="\e[97m"
 aBOLD="\e[1m";aDIM="\e[2m";aUNDER="\e[4m";aBLINK="\e[5m";aREVERSE="\e[7m"
 cRED_="\e[41m";cGRE_="\e[42m"
}


ANSIColours

TXT="import from"
ACTION="-I"
if [ $(echo $@ | grep -cw "del") -gt 0 ];then
 ACTION="-D"
 TXT="deletion using"
fi

EXEC="iptables"
TEST_MODE=
if [ "$(echo $@ | grep -cw "test")" -ge 1 ];then
 EXEC="echo -e $cCYA\tSimulate:"
 TEST_MODE="Simulate: "
fi

FN="PortForward.csv"
if [ ! -z "$1" ] && [ "$ACTION" != "-D" ] && [ "$1" != "test" ];then
 FN=$1
fi

# Need assistance!???
if [ "$1" == "help" ] || [ "$1" == "-h" ]; then
 echo -e $cBWHT
 ShowHelp
 echo -e $cRESET
 exit 0
fi

echo -e $cBWHT
logger -st "($(basename $0))" $$ "Port Forward rule" $TXT "CSV file '"$FN"' starting....."
echo -e

READ_CNT=0
SUCCESS_CNT=0
LINE_NUMBER=0

#          Service Name,Source IP,Port Range,Local IP,Local Port,Protocol
while IFS="," read DESC    SRC_IP   EXT_PORT  DEST_IP   INT_PORT PROTOCOLS
 do
  LINE_NUMBER=$((LINE_NUMBER+1))
  if [ "$(echo $DESC | grep -oE "^#")" == "#" ] || [ -z "$DESC" ];then
   continue            # Ignore comments and blank lines
  fi
  READ_CNT=$((READ_CNT+1))
  if [ -z "$PROTOCOLS" ];then
   PROTOCOLS="TCP"           # Default Protocol if not specified
  fi
  PROTOCOLS=$(echo "$PROTOCOLS" | tr "A-Z" "a-z")
  case $PROTOCOLS in           # Only accept Protocols TCP,UDP or BOTH
    tcp|udp)
     ;;
    both)
     PROTOCOLS="tcp udp"
     READ_CNT=$((READ_CNT+1))      # Allow for creation of 2 physical rules!
     ;;
    *)
     # GUI 'other' means accept a value 1-255 e.g. 8 etc., but I suspect it is rarely used but let user know that (for now) we are ignoring it!
     # NOTE: see http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml
     #       e.g. TCP=6, UDP=17, ICMP=1 EGP=8 etc.
     logger -t "($(basename $0))" $$ "***ERROR: Invalid Protocol '"$PROTOCOLS"'" $DESC","$SRC_IP","$EXT_PORT","$DEST_IP","$INT_PORT","$PROTOCOLS"'"
     ;;
   esac
   SRC=
   if [ ! -z "$SRC_IP" ];then
    SRC="-s "$SRC_IP
   fi
 
   # If 'Local Port' is missing then Error message: "iptables v1.4.15: Port `' not valid"
   # if 'Port Range' is missing then Error message: "iptables v1.4.15: invalid port/service `-j' specified"
   if [ -z "$EXT_PORT" ] && [ -z "$INT_PORT" ];then
    EXT_PORT="<?????>"          # Create Error message "iptables v1.4.15: invalid port/service `?????' specified"
    INT_PORT="<?????>"          # Set 'eye-catcher' for missing 'Local Port'
   fi
 
   if [ -z "$EXT_PORT" ] && [ ! -z "$INT_PORT" ];then
    EXT_PORT=$INT_PORT          # Set 'Port Range' to 'Local Port'
   fi
 
   if [ ! -z "$EXT_PORT" ] && [ -z "$INT_PORT" ] && [ -z "$(echo $EXT_PORT | grep -oF ":" )" ];then
    INT_PORT=$EXT_PORT          # Set 'Local Port' to 'Port Range' unless Port Range is 'nnnnn:nnnnn'
   fi
   EXT_PORT=$(echo $EXT_PORT | tr '+' ',')     # e.g. '444:555+666' -> '444:555,666'
 
   if [ -z "$TEST_MODE" ];then
    echo -en $cRED
   else
    echo -en $cWHT
   fi
 
   for PROTOCOL in $PROTOCOLS
    do
     iptables -t nat -C VSERVER -p $PROTOCOL -m $PROTOCOL $SRC --dport $EXT_PORT -j DNAT --to-destination $DEST_IP":"$INT_PORT 2> /dev/null
     RC=$?
 
     # For insert RC=1 means rule doesn't exist; RC=2 means syntax Error i.e. Invalid IP or Protocol
     if [ "$ACTION" == "-D" ] || [ $RC -eq 1 ] || [ $RC -eq 2 ];then
      $EXEC -t nat $ACTION VSERVER -p $PROTOCOL -m $PROTOCOL $SRC --dport $EXT_PORT -j DNAT --to-destination $DEST_IP":"$INT_PORT
      RC=$?
      if [ $RC -eq 0 ];then
       SUCCESS_CNT=$((SUCCESS_CNT+1))
      else
       echo -e $cBRED"\n\t\a**ERROR: rc="$RC "        for record number" $LINE_NUMBER":\t'"$DESC","$SRC_IP","$EXT_PORT","$DEST_IP","$INT_PORT","$PROTOCOL"'\n"
       SayT "***ERROR: rc="$RC "for record number" $LINE_NUMBER": '"$DESC","$SRC_IP","$EXT_PORT","$DEST_IP","$INT_PORT","$PROTOCOL"'"
      fi
     else
      if [ $RC -ne 2 ];then
       echo -e $cBYEL"\t*Warning: Rule exists for record number" $LINE_NUMBER":\t'"$DESC","$SRC_IP","$EXT_PORT","$DEST_IP","$INT_PORT","$PROTOCOL"'"
       SayT "*Warning: Rule exists for record number" $LINE_NUMBER": '"$DESC","$SRC_IP","$EXT_PORT","$DEST_IP","$INT_PORT","$PROTOCOL"'"
      else
       echo -e $cBRED"\n\t\a**ERROR: rc="$RC "        for record number" $LINE_NUMBER":\t'"$DESC","$SRC_IP","$EXT_PORT","$DEST_IP","$INT_PORT","$PROTOCOL"'\n"
       SayT "***ERROR: rc="$RC "for record number" $LINE_NUMBER": '"$DESC","$SRC_IP","$EXT_PORT","$DEST_IP","$INT_PORT","$PROTOCOL"'"
      fi
     fi
    done
 done < $FN

echo -e $cBMAG
iptables -t nat -nvL VSERVER --line

TXT_STATUS=$cBGRE"Success Count="${SUCCESS_CNT}$cBWHT" out of"$cBCYA
if [ ! -z "$TEST_MODE" ];then
 TXT_STATUS=
fi

logger -t "($(basename $0))" $$ "Port Forward" $TXT "CSV file '"$FN"' complete, "$TXT_STATUS
echo -e $cBWHT"\n\t"$TEST_MODE"Port Forward" $TXT "CSV file '"$FN"' complete, "$TXT_STATUS "Total="$READ_CNT"\n"$cRESET

exit 0
 
Last edited:
How complex are your port forwarding rules. The more complex they are the more complex the nat-start script would have to be.

For example; Do you only use TCP and not UDP? Are you forwarding ranges of ports or just single ports. Are the source and destination port numbers always the same as each other or are they different? Do you specify the source IP address or do you leave it blank?

Hi Colin, Thank u for the reply.
1. Mostly TCP some are both
2. Mostly Single Port
3. Most are same between source and destination,
4. in the old version only 1 ip per line on the new i fill both same ip

thx
 
Crude but should work ;)
EDIT: v1.02 tidied code and provides more ERROR messages to Syslog
EDIT: v1.03 added delete option


I suggest before adding it to nat-start, call it say Mass_import.sh then you can test it from the command line in isolation, and it won't cause any issue if you happen to have an unscheduled reboot during testing!
Code:
#!/bin/sh
VER="v1.03"
#======================================================================================================= © 2018 Martineau, v1.03
#
# Import Port Forwarding rules and apply manually rather than create NVRAM variable as v382.xx/v384.xx limits variable size
#
#          Mass_import     [-h|help] ['csv_file_name'] ['del']
#
#          Mass_import
#                          Import Port Forward rules from CSV file 'PortForwards.csv'
#          Mass_import     /mnt/USB/This_file
#                          Import Port Forward rules from CSV file '/mnt/USB/This_file'
#          Mass_import     del
#                          Delete Port Forward rules using CSV file 'PortForwards.csv'
#
# Import file is in format:
#
#        Service Name, Source IP, Port Range, Local IP, Local Port, Protocol
#
#        If Protocol is omitted, then the default is TCP, but TCP,UDP or BOTH may be specified

SayT(){
   #echo -e $cBYEL$(date "+%b   %d %T") $MYROUTER "($(basename $0))" $$  $@ $cRESET >>/tmp/syslog.log
   logger -t "($(basename $0))" $$ $@
}
# Print between line beginning with'#==' to first blank line inclusive
ShowHelp() {
 awk '/^#==/{f=1} f{print; if (!NF) exit}' $0
}
ANSIColours () {
 cRESET="\e[0m";cBLA="\e[30m";cRED="\e[31m";cGRE="\e[32m";cYEL="\e[33m";cBLU="\e[34m";cMAG="\e[35m";cCYA="\e[36m";cGRA="\e[37m"
 cBGRA="\e[90m";cBRED="\e[91m";cBGRE="\e[92m";cBYEL="\e[93m";cBBLU="\e[94m";cBMAG="\e[95m";cBCYA="\e[96m";cBWHT="\e[97m"
 aBOLD="\e[1m";aDIM="\e[2m";aUNDER="\e[4m";aBLINK="\e[5m";aREVERSE="\e[7m"
 cRED_="\e[41m";cGRE_="\e[42m"
}

ANSIColours

TXT="import from"
ACTION="-I"
if [ $(echo $@ | grep -cw "del") -gt 0 ];then
 ACTION="-D"
 TXT="rule deletion using"
fi

FN="PortForward.csv"
if [ ! -z "$1" ] && [ "$ACTION" != "-D" ];then
 FN=$1
fi

# Need assistance!???
if [ "$1" == "help" ] || [ "$1" == "-h" ]; then
 echo -e $cBWHT
 ShowHelp
 echo -e $cRESET
 exit 0
fi

echo -e $cBWHT
logger -st "($(basename $0))" $$ "Port Forward rule" $TXT "CSV file '"$FN"' starting....."
echo -e

READ_CNT=0
SUCCESS_CNT=0
LINE_NUMBER=0

#          Service Name,Source IP,Port Range,Local IP,Local Port,Protocol
while IFS="," read DESC    SRC_IP   EXT_PORT  DEST_IP   INT_PORT PROTOCOLS
 do
  LINE_NUMBER=$((LINE_NUMBER+1))
  if [ "$(echo $DESC | grep -oE "^#")" == "#" ] || [ -z "$DESC" ];then
   continue            # Ignore comments and blank lines
  fi
  READ_CNT=$((READ_CNT+1))

  if [ -z "$PROTOCOLS" ];then
   PROTOCOLS="TCP"           # Default Protocol if not specified
  fi

  PROTOCOLS=$(echo "$PROTOCOLS" | tr "A-Z" "a-z")

  case $PROTOCOLS in           # Only accept Protocols TCP,UDP or BOTH
    tcp|udp)
     ;;
    both)
     PROTOCOLS="tcp udp"
     READ_CNT=$((READ_CNT+1))      # Allow for creation of 2 physical rules!
     ;;
    *)
     # GUI 'other' means accept a value 1-255 e.g. 8 etc., but I suspect it is rarely used but let user know that (for now) we are ignoring it!
     # NOTE: see http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml
     #       e.g. TCP=6, UDP=17, ICMP=1 EGP=8 etc.
     logger -t "($(basename $0))" $$ "***ERROR: Invalid Protocol '"$PROTOCOLS"'" $DESC","$SRC_IP","$EXT_PORT","$DEST_IP","$INT_PORT","$PROTOCOLS"'"
     ;;
   esac

   SRC=
   if [ ! -z "$SRC_IP" ];then
    SRC="-s "$SRC_IP
   fi

   echo -en $cRED
 
   for PROTOCOL in $PROTOCOLS
    do
     iptables -t nat -C VSERVER -p $PROTOCOL -m $PROTOCOL $SRC --dport $EXT_PORT -j DNAT --to-destination $DEST_IP":"$INT_PORT 2> /dev/null
     RC=$?
   
     # For insert RC=1 means rule doesn't exist; RC=2 means syntax Error i.e. Invalid IP or Protocol
     if [ "$ACTION" == "-D" ] || [ $RC -eq 1 ] || [ $RC -eq 2 ];then
      iptables -t nat $ACTION VSERVER -p $PROTOCOL -m $PROTOCOL $SRC --dport $EXT_PORT -j DNAT --to-destination $DEST_IP":"$INT_PORT
      RC=$?
      if [ $RC -eq 0 ];then
       SUCCESS_CNT=$((SUCCESS_CNT+1))
      else
       echo -e $cBRED"\n\t\a**ERROR: rc="$RC "        for record number" $LINE_NUMBER":\t'"$DESC","$SRC_IP","$EXT_PORT","$DEST_IP","$INT_PORT","$PROTOCOL"'\n"
       SayT "***ERROR: rc="$RC "for record number" $LINE_NUMBER": '"$DESC","$SRC_IP","$EXT_PORT","$DEST_IP","$INT_PORT","$PROTOCOL"'"
      fi
     else
      if [ $RC -ne 2 ];then
       echo -e $cBYEL"\t*Warning: Rule exists for record number" $LINE_NUMBER":\t'"$DESC","$SRC_IP","$EXT_PORT","$DEST_IP","$INT_PORT","$PROTOCOL"'"
       SayT "*Warning: Rule exists for record number" $LINE_NUMBER": '"$DESC","$SRC_IP","$EXT_PORT","$DEST_IP","$INT_PORT","$PROTOCOL"'"
      else
       echo -e $cBRED"\n\t\a**ERROR: rc="$RC "        for record number" $LINE_NUMBER":\t'"$DESC","$SRC_IP","$EXT_PORT","$DEST_IP","$INT_PORT","$PROTOCOL"'\n"
       SayT "***ERROR: rc="$RC "for record number" $LINE_NUMBER": '"$DESC","$SRC_IP","$EXT_PORT","$DEST_IP","$INT_PORT","$PROTOCOL"'"
      fi
     fi
    done
 done < $FN

echo -e $cBMAG
iptables -t nat -nvL VSERVER --line

logger -t "($(basename $0))" $$ "Port Forward" $TXT "CSV file '"$FN"' complete,  Success Count="$SUCCESS_CNT "out of Total="$READ_CNT
echo -e $cBWHT"\n\tPort Forward" $TXT "CSV file '"$FN"' complete, "$cBGRE"Success Count="$SUCCESS_CNT $cBWHT"out of"$cBCYA" Total="$READ_CNT"\n"$cRESET

exit 0
Hi Martineau,

Thank u for ur quick response,

My apology, in the past i only used Web GUI, im lost in how to implement this let say i want to open lort 5656 on 192.168.1.23 tcp n udp

thx in advanced
 
In the past i only used Web GUI, im lost in how to implement this

let say i want to open lort 5656 on 192.168.1.23 tcp n udp

So if you have created the script say

/jffs/scripts/PortForwardRules.sh

by simply copy'n'paste (using the router's nano editor, or if using a Win PC, WinSCP is the preferred editor!) and made it executable (see RMerlin Wiki) then you need to create the CSV file containing your (98) desired Port Forwarding rules.

For your single example, SSH to the router and issue:
Code:
cd /jffs/scripts
echo -e "Test Service,,5656,192.168.1.23,5656,both" >> PortForward.csv
or use the nano or WinSCP editor to create/populate '/jffs/scripts/PortForwards.csv'

Now if you run the script you should see the rules added to the '-t nat VSERVER' chain and the rules will be displayed
e.g.
Code:
./PortForwardRules.sh

(PortForwardUpload.sh): 28699 Port Forward rule import from CSV file 'PortForward.csv' starting.....

Chain VSERVER (1 references)
num   pkts bytes target     prot opt in     out     source               destination  
1        0     0 DNAT       udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp dpt:5656 to:192.168.1.23:5656
2        0     0 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:5656 to:192.168.1.23:5656
3      198  9585 VUPNP      all  --  *      *       0.0.0.0/0            0.0.0.0/0

 Port Forward import from CSV file 'PortForward.csv' complete, Success Count=2 out of Total=2
which shows two rules were added since 'Protocol=both' was specified in the CSV record.

If you wish to remove the rules, simply rerun the script with the 'del' keyword
Code:
./PortForwardRules.sh   del
Once you have tested the script and populated the CSV with all (98) of your desired Port Forwarding rules, then you can create/edit script

/jffs/scripts/nat-start

Code:
#!/bin/sh
/jffs/scripts/PortForwardRules.sh
to run it automatically during the boot sequence etc.

NOTE: You will need at least one Port Forwarding rule defined in the GUI.
It doesn't matter if it is a duplicate, the script will not create duplicate rules.
 
Last edited:
So if you have created the script say

/jffs/scripts/PortForwardRules.sh

by simply copy'n'paste (using the router's nano editor, or if using a Win PC, WinSCP is the preferred editor!) and made it executable (see RMerlin Wiki) then you need to create the CSV file containing your (98) desired Port Forwarding rules.

For your single example, SSH to the router and issue:
Code:
cd /jffs/scripts
echo -e "Test Service,,5656,192.168.1.23,5656,both" >> PortForward.csv
or use the nano or WinSCP editor to create/populate '/jffs/scripts/PortForwards.csv'

Now if you run the script you should see the rules added to the '-t nat VSERVER' chain and the rules will be displayed
e.g.
Code:
./PortForwardRules.sh

(PortForwardUpload.sh): 28699 Port Forward rule import from CSV file 'PortForward.csv' starting.....

Chain VSERVER (1 references)
num   pkts bytes target     prot opt in     out     source               destination 
1        0     0 DNAT       udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp dpt:5656 to:192.168.1.23:5656
2        0     0 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:5656 to:192.168.1.23:5656
3      198  9585 VUPNP      all  --  *      *       0.0.0.0/0            0.0.0.0/0

 Port Forward import from CSV file 'PortForward.csv' complete, Success Count=2 out of Total=2
which shows two rules were added since 'Protocol=both' was specified in the CSV record.

If you wish to remove the rules, simply rerun the script with the 'del' keyword
Code:
./PortForwardRules.sh   del
Once you have tested the script and populated the CSV with all (98) of your desired Port Forwarding rules, then you can create/edit script

/jffs/scripts/nat-start

Code:
#!/bin/sh
/jffs/scripts/PortForwardRules.sh
to run it automatically during the boot sequence etc.

NOTE: You will need at least one Port Forwarding rule defined in the GUI.
It doesn't matter if it is a duplicate, the script will not create duplicate rules.
Hi Martineau,

Thank you for the very detail info, I will try next month when I am back in Canada, as I am traveling now.
I am sure more question will come, many thanks..

Regards
 

Similar threads

Sign Up For SNBForums Daily Digest

Get an update of what's new every day delivered to your mailbox. Sign up here!
Top