"Fossies" - the Fresh Open Source Software Archive

Member "aif-2.1.1/share/arno-iptables-firewall/plugins/20parasitic-net.plugin" (16 Sep 2020, 9112 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 "20parasitic-net.plugin": 2.1.0_vs_2.1.1.

    1 # ------------------------------------------------------------------------------
    2 #     -= Arno's Iptables Firewall(AIF) - Parasitic (SNAT) Network plugin =-
    3 #
    4 PLUGIN_NAME="Parasitic (SNAT) Network plugin"
    5 PLUGIN_VERSION="1.01"
    6 PLUGIN_CONF_FILE="parasitic-net.conf"
    7 #
    8 # Last changed          : Jan 16, 2020
    9 # Requirements          : AIF 2.1.1 (or newer)
   10 # Comments              : This plugin allows "clients" on the same subnet to use this
   11 #                         device as a gateway upstream. This network of "clients" is
   12 #                         SNAT'ed to this device's external interface(s).
   13 #                         This parasitic network is useful for situations when the
   14 #                         upstream firewall is not under your control and you desire
   15 #                         added security for specific devices in your subnet.
   16 #                         Set the gateway address of parasitic network clients to an
   17 #                         external IPv4 address of this device. Note that this plugin
   18 #                         only works for IPv4, NOT IPv6
   19 #
   20 # Author                : (C) Copyright 2017-2020 by Arno van Amersfoort & Lonnie Abelbeck
   21 # Homepage              : https://rocky.eld.leidenuniv.nl/
   22 # 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
   23 #                         (note: you must remove all spaces and substitute the @ and the .
   24 #                         at the proper locations!)
   25 # ------------------------------------------------------------------------------
   26 # This program is free software; you can redistribute it and/or
   27 # modify it under the terms of the GNU General Public License
   28 # version 2 as published by the Free Software Foundation.
   29 #
   30 # This program is distributed in the hope that it will be useful,
   31 # but WITHOUT ANY WARRANTY; without even the implied warranty of
   32 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   33 # GNU General Public License for more details.
   34 #
   35 # You should have received a copy of the GNU General Public License
   36 # along with this program; if not, write to the Free Software
   37 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
   38 # ------------------------------------------------------------------------------
   39 
   40 # (Background) job name
   41 JOB_NAME="parasitic-net"
   42 
   43 # (Background) job helper script
   44 JOB_HELPER_SCRIPT="$PLUGIN_BIN_PATH/parasitic-net-helper"
   45 
   46 parasitic_net_init()
   47 {
   48   local IFS host if_ip snat_if snat_ip snat_ifs_ips snat_if_subnet
   49 
   50   ip4tables -t nat -N PARASITIC_NET_SNAT 2>/dev/null
   51   ip4tables -t nat -F PARASITIC_NET_SNAT
   52 
   53   ip4tables -N PARASITIC_NET_ACL 2>/dev/null
   54   ip4tables -F PARASITIC_NET_ACL
   55 
   56   ip4tables -N PARASITIC_NET_FORWARD 2>/dev/null
   57   ip4tables -F PARASITIC_NET_FORWARD
   58 
   59   if [ -z "$PARASITIC_NET_IF" ]; then
   60     PARASITIC_NET_IF="$EXT_IF"
   61   fi
   62 
   63   if [ -z "$PARASITIC_NET_DENY_POLICY" ]; then
   64     PARASITIC_NET_DENY_POLICY="DROP"
   65   fi
   66 
   67   snat_ifs_ips=""
   68   IFS=' ,'
   69   for if_ip in $(wildcard_ifs $PARASITIC_NET_IF); do
   70     snat_if="$(echo "$if_ip" |cut -d'~' -f1)"
   71     snat_ip="$(echo "$if_ip" |cut -s -d'~' -f2)"
   72 
   73     if [ -z "$snat_ip" ]; then
   74       # Add all interface IPs to list
   75       for if_ip in $(get_network_ipv4_address_all $snat_if); do
   76         snat_ifs_ips="$snat_ifs_ips${snat_ifs_ips:+ }$snat_if~$if_ip"
   77       done
   78     else
   79       snat_ifs_ips="$snat_ifs_ips${snat_ifs_ips:+ }$snat_if~$snat_ip"
   80     fi
   81   done
   82 
   83   if [ -z "$snat_ifs_ips" ]; then
   84     printf "\033[40m\033[1;31m${INDENT}ERROR: Unable to determine SNAT interface(s)/address(es)!\033[0m\n" >&2
   85     return 1
   86   fi
   87 
   88   echo "${INDENT}Parasitic network SNAT interface(s)/address(es): $snat_ifs_ips"
   89 
   90   if [ -z "$PARASITIC_NET_CLIENT_HOSTS" ]; then
   91     IFS=' ,'
   92     for if_ip in $(wildcard_ifs $PARASITIC_NET_IF); do
   93       snat_if="$(echo "$if_ip" |cut -d'~' -f1)"
   94       snat_if_subnet="$(get_network_ipv4_address_mask_all $snat_if)"
   95       PARASITIC_NET_CLIENT_HOSTS="$PARASITIC_NET_CLIENT_HOSTS${PARASITIC_NET_CLIENT_HOSTS:+ }$snat_if_subnet"
   96     done
   97   fi
   98 
   99   # Filter traffic related to the Parasitic Network
  100   echo "${INDENT}Allowing parasitic network access for client host(s): $PARASITIC_NET_CLIENT_HOSTS"
  101   IFS=' ,'
  102   for host in $(ip_range $PARASITIC_NET_CLIENT_HOSTS); do
  103     ip4tables -A PARASITIC_NET_FORWARD -s $host -j PARASITIC_NET_ACL
  104   done
  105 
  106   # Enable forwarding on the SNAT interfaces.
  107   # Note: can't check IF IP here, therefore only match interface(s)
  108   IFS=' ,'
  109   for if_ip in $(wildcard_ifs $PARASITIC_NET_IF); do
  110     snat_if="$(echo "$if_ip" |cut -d'~' -f1)"
  111     ip4tables -A POST_FORWARD_CHAIN -i $snat_if -o $snat_if -j PARASITIC_NET_FORWARD
  112   done
  113 
  114   # We do not want traffic generated on this machine to be NAT-ed, so skip all SNAT interface IPv4's
  115   IFS=' '
  116   for if_ip in $snat_ifs_ips; do
  117     snat_ip="$(echo "$if_ip" |cut -d'~' -f2)"
  118     ip4tables -t nat -A PARASITIC_NET_SNAT -s $snat_ip -j RETURN
  119   done
  120 
  121   IFS=' '
  122   for if_ip in $snat_ifs_ips; do
  123     snat_if="$(echo "$if_ip" |cut -d'~' -f1)"
  124     snat_ip="$(echo "$if_ip" |cut -d'~' -f2)"
  125 
  126     IFS=' ,'
  127     for host in $(ip_range $PARASITIC_NET_CLIENT_HOSTS); do
  128       ip4tables -t nat -A PARASITIC_NET_SNAT -o $snat_if -s $host -j SNAT --to-source $snat_ip
  129     done
  130   done
  131 
  132   # Hook into the POST POSTROUTING NAT chain
  133   ip4tables -t nat -A POST_NAT_POSTROUTING_CHAIN -j PARASITIC_NET_SNAT
  134 
  135   # Create background job
  136   if ! job_add "$JOB_NAME" "${PARASITIC_NET_TIME:-60}" "$JOB_HELPER_SCRIPT"; then
  137     return 1
  138   fi
  139 
  140   return 0
  141 }
  142 
  143 
  144 # Plugin start function
  145 plugin_start()
  146 {
  147   # Initialize
  148   if ! parasitic_net_init; then
  149     return 1
  150   fi
  151 
  152   return 0
  153 }
  154 
  155 
  156 # Plugin restart function
  157 plugin_restart()
  158 {
  159   # NOTE: Skip plugin_stop on a restart and basically do the same as with a normal start
  160   plugin_start
  161 
  162   return $?
  163 }
  164 
  165 
  166 # Plugin stop function
  167 plugin_stop()
  168 {
  169   ip4tables -t nat -D POST_NAT_POSTROUTING_CHAIN -j PARASITIC_NET_SNAT
  170 
  171   ip4tables -t nat -F PARASITIC_NET_SNAT
  172   ip4tables -t nat -X PARASITIC_NET_SNAT 2>/dev/null
  173 
  174   ip4tables -F PARASITIC_NET_ACL
  175   ip4tables -X PARASITIC_NET_ACL 2>/dev/null
  176 
  177   ip4tables -F PARASITIC_NET_FORWARD
  178   ip4tables -X PARASITIC_NET_FORWARD 2>/dev/null
  179 
  180   return 0
  181 }
  182 
  183 
  184 # Plugin status function
  185 plugin_status()
  186 {
  187   echo "  Interface forward policy:"
  188   echo "  =============================="
  189   ip4tables -nv -L POST_FORWARD_CHAIN | awk '$3 == "PARASITIC_NET_FORWARD" { print "  "$3" "$6" "$7" "$8" "$9 }'
  190   echo "  ------------------------------"
  191   echo ""
  192 
  193   echo "  Allowed client host(s):"
  194   echo "  =============================="
  195   ip4tables -n -L PARASITIC_NET_FORWARD | awk '$1 == "PARASITIC_NET_ACL" { print "  "$4 }'
  196   echo "  ------------------------------"
  197   echo ""
  198 
  199   echo "  Access Control List(ACL):"
  200   echo "  =============================="
  201   ip4tables -n -L PARASITIC_NET_ACL | sed -n -e 's/^ACCEPT.*$/  &/p' -e 's/^DROP.*$/  &/p'
  202   echo "  ------------------------------"
  203   echo ""
  204 
  205   return 0
  206 }
  207 
  208 
  209 # Check sanity of eg. environment
  210 plugin_sanity_check()
  211 {
  212   local IFS if1 if2
  213 
  214   if [ -n "$PARASITIC_NET_DENY_POLICY" -a "$PARASITIC_NET_DENY_POLICY" != "DROP" -a "$PARASITIC_NET_DENY_POLICY" != "REJECT" ]; then
  215     printf "\033[40m\033[1;31m${INDENT}ERROR: PARASITIC_NET_DENY_POLICY must be either \"DROP\" (or left empty) or \"REJECT\"!\033[0m\n" >&2
  216     return 1
  217   fi
  218 
  219   IFS=' ,'
  220   for if1 in $INT_IF $DMZ_IF; do
  221     for if2 in $PARASITIC_NET_IF; do
  222       if [ "$if1" = "$if2" ]; then
  223         printf "\033[40m\033[1;31m${INDENT}ERROR: INT_IF/DMZ_IF interface $if1 is not allowed as PARASITIC_NET_IF interface $if2.\033[0m\n" >&2
  224         return 1
  225       fi
  226     done
  227   done
  228 
  229   if [ ! -f "$JOB_HELPER_SCRIPT" ]; then
  230     printf "\033[40m\033[1;31m${INDENT}ERROR: The job helper script($JOB_HELPER_SCRIPT) can not be found!\033[0m\n" >&2
  231     return 1
  232   fi
  233 
  234   return 0
  235 }
  236 
  237 
  238 ############
  239 # Mainline #
  240 ############
  241 
  242 # Check where to find the config file
  243 CONF_FILE=""
  244 if [ -n "$PLUGIN_CONF_PATH" ]; then
  245   CONF_FILE="$PLUGIN_CONF_PATH/$PLUGIN_CONF_FILE"
  246 fi
  247 
  248 # Preinit to success:
  249 PLUGIN_RET_VAL=0
  250 
  251 # Check if the config file exists
  252 if [ ! -f "$CONF_FILE" ]; then
  253   printf "NOTE: Config file \"$CONF_FILE\" not found!\n        Plugin \"$PLUGIN_NAME v$PLUGIN_VERSION\" ignored!\n" >&2
  254 else
  255   # Source the plugin config file
  256   . "$CONF_FILE"
  257 
  258   if [ "$ENABLED" = "1" -a "$PLUGIN_CMD" != "stop-restart" ] ||
  259      [ "$ENABLED" = "0" -a "$PLUGIN_CMD" = "stop-restart" ] ||
  260      [ -n "$PLUGIN_LOAD_FILE" -a "$PLUGIN_CMD" = "stop" ] ||
  261      [ -n "$PLUGIN_LOAD_FILE" -a "$PLUGIN_CMD" = "status" ]; then
  262     # Show who we are:
  263     echo "${INDENT}$PLUGIN_NAME v$PLUGIN_VERSION"
  264 
  265     # Increment indention
  266     INDENT="$INDENT "
  267 
  268     # Only proceed if environment ok
  269     if ! plugin_sanity_check; then
  270       PLUGIN_RET_VAL=1
  271     else
  272       case $PLUGIN_CMD in
  273         start|'') plugin_start; PLUGIN_RET_VAL=$? ;;
  274         restart ) plugin_restart; PLUGIN_RET_VAL=$? ;;
  275         stop|stop-restart) plugin_stop; PLUGIN_RET_VAL=$? ;;
  276         status  ) plugin_status; PLUGIN_RET_VAL=$? ;;
  277         *       ) PLUGIN_RET_VAL=1; printf "\033[40m\033[1;31m${INDENT}ERROR: Invalid plugin option \"$PLUGIN_CMD\"!\033[0m\n" >&2 ;;
  278       esac
  279     fi
  280   fi
  281 fi