"Fossies" - the Fresh Open Source Software Archive

Member "aif-2.1.1/share/arno-iptables-firewall/plugins/20nat-loopback.plugin" (16 Sep 2020, 9386 Bytes) of package /linux/privat/aif-2.1.1.tar.gz:


As a special service "Fossies" has tried to format the requested text file into HTML format (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "20nat-loopback.plugin": 2.1.0_vs_2.1.1.

    1 # ------------------------------------------------------------------------------
    2 #            -= Arno's Iptables Firewall(AIF) - NAT Loopback plugin =-
    3 #
    4 PLUGIN_NAME="NAT Loopback plugin"
    5 PLUGIN_VERSION="1.02"
    6 PLUGIN_CONF_FILE="nat-loopback.conf"
    7 #
    8 # Last changed          : February 2, 2019
    9 # Requirements          : AIF 2.0.1g+
   10 # Comments              : NAT Loopback for local nets using existing NAT_FORWARD_TCP
   11 #                         and NAT_FORWARD_UDP rules.
   12 #                         Local nets may be able to use the external IPv4 address and
   13 #                         port to access NAT forwarded internal servers.
   14 #
   15 # Author                : (C) Copyright 2012-2019 by Lonnie Abelbeck & Arno van Amersfoort
   16 # Homepage              : https://rocky.eld.leidenuniv.nl/
   17 # Email                 : a r n o v a AT r o c k y DOT e l d DOT l e i d e n u n i v DOT n l
   18 #                         (note: you must remove all spaces and substitute the @ and the .
   19 #                         at the proper locations!)
   20 # ------------------------------------------------------------------------------
   21 # This program is free software; you can redistribute it and/or
   22 # modify it under the terms of the GNU General Public License
   23 # version 2 as published by the Free Software Foundation.
   24 #
   25 # This program is distributed in the hope that it will be useful,
   26 # but WITHOUT ANY WARRANTY; without even the implied warranty of
   27 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   28 # GNU General Public License for more details.
   29 #
   30 # You should have received a copy of the GNU General Public License
   31 # along with this program; if not, write to the Free Software
   32 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
   33 # ------------------------------------------------------------------------------
   34 
   35 NAT_LOOPBACK_DEFAULT_IPV4="/var/tmp/aif-nat-loopback-default-ipv4"
   36 
   37 nat_loopback_default_ext_ipv4()
   38 {
   39   local eif IFS
   40 
   41   IFS=' ,'
   42   for eif in $(wildcard_ifs $NAT_IF); do
   43     ip -o addr show dev $eif \
   44       | awk '$3 == "inet" { split($4, field, "/"); print field[1]; nextfile; }'
   45     break # Only use first external interface
   46   done
   47 }
   48 
   49 nat_loopback_update_default_ipv4()
   50 {
   51   local old_defaultip="$1" defaultip="$2" old_match line cnt IFS
   52 
   53   unset IFS
   54 
   55   # Replace 'dot' with 'backslash-dot' for regex match
   56   # ${old_defaultip//./\.} would be better, but dash does not support it
   57   old_match="$(echo "$old_defaultip" | sed 's/\./\\./g')"
   58 
   59   cnt=1
   60   ip4tables_save -t nat | grep -e '-A NAT_LOOPBACK_DNAT ' | while read line; do
   61     nline="$(echo "$line" | sed "s| ${old_match}/32| ${defaultip}/32|")"
   62     if [ "$nline" != "$line" ]; then
   63       ip4tables -t nat -R NAT_LOOPBACK_DNAT $cnt ${nline#-A NAT_LOOPBACK_DNAT }
   64     fi
   65     cnt=$((cnt + 1))
   66   done
   67 
   68   cnt=1
   69   ip4tables_save -t nat | grep -e '-A NAT_LOOPBACK_SNAT ' | while read line; do
   70     nline="$(echo "$line" | sed "s| ${old_match}$| ${defaultip}|")"
   71     if [ "$nline" != "$line" ]; then
   72       ip4tables -t nat -R NAT_LOOPBACK_SNAT $cnt ${nline#-A NAT_LOOPBACK_SNAT }
   73     fi
   74     cnt=$((cnt + 1))
   75   done
   76 }
   77 
   78 # Plugin start function
   79 plugin_start()
   80 {
   81   local defaultip eif net IFS
   82 
   83   ip4tables -t nat -N NAT_LOOPBACK_DNAT 2>/dev/null
   84   ip4tables -t nat -F NAT_LOOPBACK_DNAT
   85 
   86   ip4tables -t nat -N NAT_LOOPBACK_SNAT 2>/dev/null
   87   ip4tables -t nat -F NAT_LOOPBACK_SNAT
   88 
   89   if [ -z "$NAT_LOOPBACK_NET" ]; then
   90     NAT_LOOPBACK_NET="$NAT_INTERNAL_NET"
   91   fi
   92 
   93   defaultip="$(nat_loopback_default_ext_ipv4)"
   94   if [ -z "$defaultip" ]; then
   95     # Use an arbitrary IPv4 Link-Local address as a placeholder
   96     # for the currently unknown default IPv4 address
   97     defaultip="169.254.25.54"
   98   fi
   99   echo "$defaultip" > "$NAT_LOOPBACK_DEFAULT_IPV4"
  100 
  101   echo "${INDENT}NAT Loopback default IPv4: $defaultip"
  102   echo "${INDENT}NAT Loopback internal net(s): $NAT_LOOPBACK_NET"
  103   if [ "$NAT_LOOPBACK_FORWARD" = "1" ]; then
  104     echo "${INDENT}NAT Loopback local forwards are enabled."
  105   else
  106     echo "${INDENT}NAT Loopback local forwards are disabled."
  107   fi
  108 
  109   unset IFS
  110   for rule in $NAT_FORWARD_TCP; do
  111     if parse_rule "$rule" NAT_FORWARD_TCP "interfaces:NAT_IF-destips-shosts-ports-dhost_dport"; then
  112 
  113       IFS=' ,'
  114       for port in $ports; do
  115         for destip in $destips; do
  116           for eif in $interfaces; do
  117             dport="$(get_ports_hp "$dhost_dport" "$port")"
  118             dhost="$(get_hosts_hp "$dhost_dport")"
  119             if [ "$destip" = "0/0" ]; then
  120               destip="$defaultip"
  121             fi
  122             if [ -n "$dhost" -a -n "$destip" ]; then
  123               for net in $NAT_LOOPBACK_NET; do
  124                 ip4tables -t nat -A NAT_LOOPBACK_DNAT -s $net -d $destip \
  125                                  -p tcp --dport $port -j DNAT --to-destination $(echo "$dhost_dport" |tr "$SEP-" '::')
  126                 if [ "$NAT_LOOPBACK_FORWARD" = "1" ]; then
  127                   ip4tables -A POST_FORWARD_CHAIN -s $net -d $dhost -p tcp --dport $dport -j ACCEPT
  128                 fi
  129                 ip4tables -t nat -A NAT_LOOPBACK_SNAT -s $net -d $dhost \
  130                                  -p tcp --dport $dport -j SNAT --to-source $destip
  131               done
  132             fi
  133           done
  134         done
  135       done
  136     fi
  137   done
  138 
  139   unset IFS
  140   for rule in $NAT_FORWARD_UDP; do
  141     if parse_rule "$rule" NAT_FORWARD_UDP "interfaces:NAT_IF-destips-shosts-ports-dhost_dport"; then
  142 
  143       IFS=' ,'
  144       for port in $ports; do
  145         for destip in $destips; do
  146           for eif in $interfaces; do
  147             dport="$(get_ports_hp "$dhost_dport" "$port")"
  148             dhost="$(get_hosts_hp "$dhost_dport")"
  149             if [ "$destip" = "0/0" ]; then
  150               destip="$defaultip"
  151             fi
  152             if [ -n "$dhost" -a -n "$destip" ]; then
  153               for net in $NAT_LOOPBACK_NET; do
  154                 ip4tables -t nat -A NAT_LOOPBACK_DNAT -s $net -d $destip \
  155                                  -p udp --dport $port -j DNAT --to-destination $(echo "$dhost_dport" |tr "$SEP-" '::')
  156                 if [ "$NAT_LOOPBACK_FORWARD" = "1" ]; then
  157                   ip4tables -A POST_FORWARD_CHAIN -s $net -d $dhost -p udp --dport $dport -j ACCEPT
  158                 fi
  159                 ip4tables -t nat -A NAT_LOOPBACK_SNAT -s $net -d $dhost \
  160                                  -p udp --dport $dport -j SNAT --to-source $destip
  161               done
  162             fi
  163           done
  164         done
  165       done
  166     fi
  167   done
  168 
  169   ip4tables -t nat -A PREROUTING -j NAT_LOOPBACK_DNAT
  170   ip4tables -t nat -A POSTROUTING -j NAT_LOOPBACK_SNAT
  171 
  172   return 0
  173 }
  174 
  175 
  176 # Plugin restart function
  177 plugin_restart()
  178 {
  179 
  180   # Skip plugin_stop on a restart
  181   plugin_start
  182 
  183   return 0
  184 }
  185 
  186 
  187 # Plugin stop function
  188 plugin_stop()
  189 {
  190 
  191   ip4tables -t nat -D PREROUTING -j NAT_LOOPBACK_DNAT
  192   ip4tables -t nat -D POSTROUTING -j NAT_LOOPBACK_SNAT
  193 
  194   ip4tables -t nat -F NAT_LOOPBACK_DNAT
  195   ip4tables -t nat -X NAT_LOOPBACK_DNAT 2>/dev/null
  196 
  197   ip4tables -t nat -F NAT_LOOPBACK_SNAT
  198   ip4tables -t nat -X NAT_LOOPBACK_SNAT 2>/dev/null
  199 
  200   rm -f "$NAT_LOOPBACK_DEFAULT_IPV4"
  201 
  202   return 0
  203 }
  204 
  205 
  206 # Plugin status function
  207 plugin_status()
  208 {
  209   local defaultip old_defaultip
  210 
  211   if [ -f "$NAT_LOOPBACK_DEFAULT_IPV4" ]; then
  212     old_defaultip="$(cat "$NAT_LOOPBACK_DEFAULT_IPV4")"
  213   else
  214     old_defaultip=""
  215   fi
  216 
  217   defaultip="$(nat_loopback_default_ext_ipv4)"
  218   if [ -n "$defaultip" -a -n "$old_defaultip" ]; then
  219     if [ "$defaultip" != "$old_defaultip" ]; then
  220       if [ "$NAT_LOOPBACK_UPDATE_ON_STATUS" != "0" ]; then
  221         # update rules
  222         nat_loopback_update_default_ipv4 "$old_defaultip" "$defaultip"
  223         echo "$defaultip" > "$NAT_LOOPBACK_DEFAULT_IPV4"
  224         echo "  NAT Loopback default IPv4 (updated): $defaultip"
  225       else
  226         echo "  NAT Loopback default IPv4 needs updating from '$old_defaultip' to '$defaultip'"
  227       fi
  228       return 0
  229     fi
  230   fi
  231 
  232   if [ -n "$old_defaultip" ]; then
  233     echo "  NAT Loopback default IPv4: $old_defaultip"
  234   else
  235     echo "  NAT Loopback default IPv4: None"
  236   fi
  237 
  238   return 0
  239 }
  240 
  241 
  242 # Check sanity of eg. environment
  243 plugin_sanity_check()
  244 {
  245   # Sanity check
  246 
  247   return 0
  248 }
  249 
  250 
  251 ############
  252 # Mainline #
  253 ############
  254 
  255 # Check where to find the config file
  256 CONF_FILE=""
  257 if [ -n "$PLUGIN_CONF_PATH" ]; then
  258   CONF_FILE="$PLUGIN_CONF_PATH/$PLUGIN_CONF_FILE"
  259 fi
  260 
  261 # Preinit to success:
  262 PLUGIN_RET_VAL=0
  263 
  264 # Check if the config file exists
  265 if [ ! -f "$CONF_FILE" ]; then
  266   printf "NOTE: Config file \"$CONF_FILE\" not found!\n        Plugin \"$PLUGIN_NAME v$PLUGIN_VERSION\" ignored!\n" >&2
  267 else
  268   # Source the plugin config file
  269   . "$CONF_FILE"
  270 
  271   if [ "$ENABLED" = "1" -a "$PLUGIN_CMD" != "stop-restart" ] ||
  272      [ "$ENABLED" = "0" -a "$PLUGIN_CMD" = "stop-restart" ] ||
  273      [ -n "$PLUGIN_LOAD_FILE" -a "$PLUGIN_CMD" = "stop" ] ||
  274      [ -n "$PLUGIN_LOAD_FILE" -a "$PLUGIN_CMD" = "status" ]; then
  275     # Show who we are:
  276     echo "${INDENT}$PLUGIN_NAME v$PLUGIN_VERSION"
  277 
  278     # Increment indention
  279     INDENT="$INDENT "
  280 
  281     # Only proceed if environment ok
  282     if ! plugin_sanity_check; then
  283       PLUGIN_RET_VAL=1
  284     else
  285       case $PLUGIN_CMD in
  286         start|'') plugin_start; PLUGIN_RET_VAL=$? ;;
  287         restart ) plugin_restart; PLUGIN_RET_VAL=$? ;;
  288         stop|stop-restart) plugin_stop; PLUGIN_RET_VAL=$? ;;
  289         status  ) plugin_status; PLUGIN_RET_VAL=$? ;;
  290         *       ) PLUGIN_RET_VAL=1; printf "\033[40m\033[1;31m  ERROR: Invalid plugin option \"$PLUGIN_CMD\"!\033[0m\n" >&2 ;;
  291       esac
  292     fi
  293   fi
  294 fi