"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